xref: /third_party/node/deps/zlib/deflate.c (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci/* deflate.c -- compress data using the deflation algorithm
21cb0ef41Sopenharmony_ci * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler
31cb0ef41Sopenharmony_ci * For conditions of distribution and use, see copyright notice in zlib.h
41cb0ef41Sopenharmony_ci */
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci/*
71cb0ef41Sopenharmony_ci *  ALGORITHM
81cb0ef41Sopenharmony_ci *
91cb0ef41Sopenharmony_ci *      The "deflation" process depends on being able to identify portions
101cb0ef41Sopenharmony_ci *      of the input text which are identical to earlier input (within a
111cb0ef41Sopenharmony_ci *      sliding window trailing behind the input currently being processed).
121cb0ef41Sopenharmony_ci *
131cb0ef41Sopenharmony_ci *      The most straightforward technique turns out to be the fastest for
141cb0ef41Sopenharmony_ci *      most input files: try all possible matches and select the longest.
151cb0ef41Sopenharmony_ci *      The key feature of this algorithm is that insertions into the string
161cb0ef41Sopenharmony_ci *      dictionary are very simple and thus fast, and deletions are avoided
171cb0ef41Sopenharmony_ci *      completely. Insertions are performed at each input character, whereas
181cb0ef41Sopenharmony_ci *      string matches are performed only when the previous match ends. So it
191cb0ef41Sopenharmony_ci *      is preferable to spend more time in matches to allow very fast string
201cb0ef41Sopenharmony_ci *      insertions and avoid deletions. The matching algorithm for small
211cb0ef41Sopenharmony_ci *      strings is inspired from that of Rabin & Karp. A brute force approach
221cb0ef41Sopenharmony_ci *      is used to find longer strings when a small match has been found.
231cb0ef41Sopenharmony_ci *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
241cb0ef41Sopenharmony_ci *      (by Leonid Broukhis).
251cb0ef41Sopenharmony_ci *         A previous version of this file used a more sophisticated algorithm
261cb0ef41Sopenharmony_ci *      (by Fiala and Greene) which is guaranteed to run in linear amortized
271cb0ef41Sopenharmony_ci *      time, but has a larger average cost, uses more memory and is patented.
281cb0ef41Sopenharmony_ci *      However the F&G algorithm may be faster for some highly redundant
291cb0ef41Sopenharmony_ci *      files if the parameter max_chain_length (described below) is too large.
301cb0ef41Sopenharmony_ci *
311cb0ef41Sopenharmony_ci *  ACKNOWLEDGEMENTS
321cb0ef41Sopenharmony_ci *
331cb0ef41Sopenharmony_ci *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
341cb0ef41Sopenharmony_ci *      I found it in 'freeze' written by Leonid Broukhis.
351cb0ef41Sopenharmony_ci *      Thanks to many people for bug reports and testing.
361cb0ef41Sopenharmony_ci *
371cb0ef41Sopenharmony_ci *  REFERENCES
381cb0ef41Sopenharmony_ci *
391cb0ef41Sopenharmony_ci *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
401cb0ef41Sopenharmony_ci *      Available in http://tools.ietf.org/html/rfc1951
411cb0ef41Sopenharmony_ci *
421cb0ef41Sopenharmony_ci *      A description of the Rabin and Karp algorithm is given in the book
431cb0ef41Sopenharmony_ci *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
441cb0ef41Sopenharmony_ci *
451cb0ef41Sopenharmony_ci *      Fiala,E.R., and Greene,D.H.
461cb0ef41Sopenharmony_ci *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
471cb0ef41Sopenharmony_ci *
481cb0ef41Sopenharmony_ci */
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci/* @(#) $Id$ */
511cb0ef41Sopenharmony_ci#include <assert.h>
521cb0ef41Sopenharmony_ci#include "deflate.h"
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci#include "cpu_features.h"
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci#if defined(DEFLATE_SLIDE_HASH_SSE2) || defined(DEFLATE_SLIDE_HASH_NEON)
571cb0ef41Sopenharmony_ci#include "slide_hash_simd.h"
581cb0ef41Sopenharmony_ci#endif
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci#include "contrib/optimizations/insert_string.h"
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci#ifdef FASTEST
631cb0ef41Sopenharmony_ci/* See http://crbug.com/1113596 */
641cb0ef41Sopenharmony_ci#error "FASTEST is not supported in Chromium's zlib."
651cb0ef41Sopenharmony_ci#endif
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ciconst char deflate_copyright[] =
681cb0ef41Sopenharmony_ci   " deflate 1.3.0.1 Copyright 1995-2023 Jean-loup Gailly and Mark Adler ";
691cb0ef41Sopenharmony_ci/*
701cb0ef41Sopenharmony_ci  If you use the zlib library in a product, an acknowledgment is welcome
711cb0ef41Sopenharmony_ci  in the documentation of your product. If for some reason you cannot
721cb0ef41Sopenharmony_ci  include such an acknowledgment, I would appreciate that you keep this
731cb0ef41Sopenharmony_ci  copyright string in the executable of your product.
741cb0ef41Sopenharmony_ci */
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_citypedef enum {
771cb0ef41Sopenharmony_ci    need_more,      /* block not completed, need more input or more output */
781cb0ef41Sopenharmony_ci    block_done,     /* block flush performed */
791cb0ef41Sopenharmony_ci    finish_started, /* finish started, need only more output at next deflate */
801cb0ef41Sopenharmony_ci    finish_done     /* finish done, accept no more input or output */
811cb0ef41Sopenharmony_ci} block_state;
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_citypedef block_state (*compress_func)(deflate_state *s, int flush);
841cb0ef41Sopenharmony_ci/* Compression function. Returns the block state after the call. */
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cilocal block_state deflate_stored(deflate_state *s, int flush);
871cb0ef41Sopenharmony_cilocal block_state deflate_fast(deflate_state *s, int flush);
881cb0ef41Sopenharmony_ci#ifndef FASTEST
891cb0ef41Sopenharmony_cilocal block_state deflate_slow(deflate_state *s, int flush);
901cb0ef41Sopenharmony_ci#endif
911cb0ef41Sopenharmony_cilocal block_state deflate_rle(deflate_state *s, int flush);
921cb0ef41Sopenharmony_cilocal block_state deflate_huff(deflate_state *s, int flush);
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci/* From crc32.c */
951cb0ef41Sopenharmony_ciextern void ZLIB_INTERNAL crc_reset(deflate_state *const s);
961cb0ef41Sopenharmony_ciextern void ZLIB_INTERNAL crc_finalize(deflate_state *const s);
971cb0ef41Sopenharmony_ciextern void ZLIB_INTERNAL copy_with_crc(z_streamp strm, Bytef *dst, long size);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci/* ===========================================================================
1001cb0ef41Sopenharmony_ci * Local data
1011cb0ef41Sopenharmony_ci */
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci#define NIL 0
1041cb0ef41Sopenharmony_ci/* Tail of hash chains */
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci#ifndef TOO_FAR
1071cb0ef41Sopenharmony_ci#  define TOO_FAR 4096
1081cb0ef41Sopenharmony_ci#endif
1091cb0ef41Sopenharmony_ci/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci/* Values for max_lazy_match, good_match and max_chain_length, depending on
1121cb0ef41Sopenharmony_ci * the desired pack level (0..9). The values given below have been tuned to
1131cb0ef41Sopenharmony_ci * exclude worst case performance for pathological files. Better values may be
1141cb0ef41Sopenharmony_ci * found for specific files.
1151cb0ef41Sopenharmony_ci */
1161cb0ef41Sopenharmony_citypedef struct config_s {
1171cb0ef41Sopenharmony_ci   ush good_length; /* reduce lazy search above this match length */
1181cb0ef41Sopenharmony_ci   ush max_lazy;    /* do not perform lazy search above this match length */
1191cb0ef41Sopenharmony_ci   ush nice_length; /* quit search above this match length */
1201cb0ef41Sopenharmony_ci   ush max_chain;
1211cb0ef41Sopenharmony_ci   compress_func func;
1221cb0ef41Sopenharmony_ci} config;
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci#ifdef FASTEST
1251cb0ef41Sopenharmony_cilocal const config configuration_table[2] = {
1261cb0ef41Sopenharmony_ci/*      good lazy nice chain */
1271cb0ef41Sopenharmony_ci/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
1281cb0ef41Sopenharmony_ci/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
1291cb0ef41Sopenharmony_ci#else
1301cb0ef41Sopenharmony_cilocal const config configuration_table[10] = {
1311cb0ef41Sopenharmony_ci/*      good lazy nice chain */
1321cb0ef41Sopenharmony_ci/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
1331cb0ef41Sopenharmony_ci/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
1341cb0ef41Sopenharmony_ci/* 2 */ {4,    5, 16,    8, deflate_fast},
1351cb0ef41Sopenharmony_ci/* 3 */ {4,    6, 32,   32, deflate_fast},
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
1381cb0ef41Sopenharmony_ci/* 5 */ {8,   16, 32,   32, deflate_slow},
1391cb0ef41Sopenharmony_ci/* 6 */ {8,   16, 128, 128, deflate_slow},
1401cb0ef41Sopenharmony_ci/* 7 */ {8,   32, 128, 256, deflate_slow},
1411cb0ef41Sopenharmony_ci/* 8 */ {32, 128, 258, 1024, deflate_slow},
1421cb0ef41Sopenharmony_ci/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
1431cb0ef41Sopenharmony_ci#endif
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
1461cb0ef41Sopenharmony_ci * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
1471cb0ef41Sopenharmony_ci * meaning.
1481cb0ef41Sopenharmony_ci */
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
1511cb0ef41Sopenharmony_ci#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci/* ===========================================================================
1541cb0ef41Sopenharmony_ci * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
1551cb0ef41Sopenharmony_ci * prev[] will be initialized on the fly.
1561cb0ef41Sopenharmony_ci * TODO(cavalcantii): optimization opportunity, check comments on:
1571cb0ef41Sopenharmony_ci * https://chromium-review.googlesource.com/c/chromium/src/+/3561506/
1581cb0ef41Sopenharmony_ci */
1591cb0ef41Sopenharmony_ci#define CLEAR_HASH(s) \
1601cb0ef41Sopenharmony_ci    do { \
1611cb0ef41Sopenharmony_ci        s->head[s->hash_size - 1] = NIL; \
1621cb0ef41Sopenharmony_ci        zmemzero((Bytef *)s->head, \
1631cb0ef41Sopenharmony_ci                 (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
1641cb0ef41Sopenharmony_ci    } while (0)
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci/* ===========================================================================
1671cb0ef41Sopenharmony_ci * Slide the hash table when sliding the window down (could be avoided with 32
1681cb0ef41Sopenharmony_ci * bit values at the expense of memory usage). We slide even when level == 0 to
1691cb0ef41Sopenharmony_ci * keep the hash table consistent if we switch back to level > 0 later.
1701cb0ef41Sopenharmony_ci */
1711cb0ef41Sopenharmony_ci#if defined(__has_feature)
1721cb0ef41Sopenharmony_ci#  if __has_feature(memory_sanitizer)
1731cb0ef41Sopenharmony_ci     __attribute__((no_sanitize("memory")))
1741cb0ef41Sopenharmony_ci#  endif
1751cb0ef41Sopenharmony_ci#endif
1761cb0ef41Sopenharmony_cilocal void slide_hash(deflate_state *s) {
1771cb0ef41Sopenharmony_ci#if defined(DEFLATE_SLIDE_HASH_SSE2) || defined(DEFLATE_SLIDE_HASH_NEON)
1781cb0ef41Sopenharmony_ci    slide_hash_simd(s->head, s->prev, s->w_size, s->hash_size);
1791cb0ef41Sopenharmony_ci    return;
1801cb0ef41Sopenharmony_ci#endif
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci    unsigned n, m;
1831cb0ef41Sopenharmony_ci    Posf *p;
1841cb0ef41Sopenharmony_ci    uInt wsize = s->w_size;
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci    n = s->hash_size;
1871cb0ef41Sopenharmony_ci    p = &s->head[n];
1881cb0ef41Sopenharmony_ci    do {
1891cb0ef41Sopenharmony_ci        m = *--p;
1901cb0ef41Sopenharmony_ci        *p = (Pos)(m >= wsize ? m - wsize : NIL);
1911cb0ef41Sopenharmony_ci    } while (--n);
1921cb0ef41Sopenharmony_ci    n = wsize;
1931cb0ef41Sopenharmony_ci#ifndef FASTEST
1941cb0ef41Sopenharmony_ci    p = &s->prev[n];
1951cb0ef41Sopenharmony_ci    do {
1961cb0ef41Sopenharmony_ci        m = *--p;
1971cb0ef41Sopenharmony_ci        *p = (Pos)(m >= wsize ? m - wsize : NIL);
1981cb0ef41Sopenharmony_ci        /* If n is not on any hash chain, prev[n] is garbage but
1991cb0ef41Sopenharmony_ci         * its value will never be used.
2001cb0ef41Sopenharmony_ci         */
2011cb0ef41Sopenharmony_ci    } while (--n);
2021cb0ef41Sopenharmony_ci#endif
2031cb0ef41Sopenharmony_ci}
2041cb0ef41Sopenharmony_ci
2051cb0ef41Sopenharmony_ci/* ===========================================================================
2061cb0ef41Sopenharmony_ci * Read a new buffer from the current input stream, update the adler32
2071cb0ef41Sopenharmony_ci * and total number of bytes read.  All deflate() input goes through
2081cb0ef41Sopenharmony_ci * this function so some applications may wish to modify it to avoid
2091cb0ef41Sopenharmony_ci * allocating a large strm->next_in buffer and copying from it.
2101cb0ef41Sopenharmony_ci * (See also flush_pending()).
2111cb0ef41Sopenharmony_ci */
2121cb0ef41Sopenharmony_cilocal unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) {
2131cb0ef41Sopenharmony_ci    unsigned len = strm->avail_in;
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci    if (len > size) len = size;
2161cb0ef41Sopenharmony_ci    if (len == 0) return 0;
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci    strm->avail_in  -= len;
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci    /* TODO(cavalcantii): verify if we can remove 'copy_with_crc', it is legacy
2211cb0ef41Sopenharmony_ci     * of the Intel optimizations dating back to 2015.
2221cb0ef41Sopenharmony_ci     */
2231cb0ef41Sopenharmony_ci#ifdef GZIP
2241cb0ef41Sopenharmony_ci    if (strm->state->wrap == 2)
2251cb0ef41Sopenharmony_ci        copy_with_crc(strm, buf, len);
2261cb0ef41Sopenharmony_ci    else
2271cb0ef41Sopenharmony_ci#endif
2281cb0ef41Sopenharmony_ci    {
2291cb0ef41Sopenharmony_ci        zmemcpy(buf, strm->next_in, len);
2301cb0ef41Sopenharmony_ci        if (strm->state->wrap == 1)
2311cb0ef41Sopenharmony_ci            strm->adler = adler32(strm->adler, buf, len);
2321cb0ef41Sopenharmony_ci    }
2331cb0ef41Sopenharmony_ci    strm->next_in  += len;
2341cb0ef41Sopenharmony_ci    strm->total_in += len;
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci    return len;
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci/* ===========================================================================
2401cb0ef41Sopenharmony_ci * Fill the window when the lookahead becomes insufficient.
2411cb0ef41Sopenharmony_ci * Updates strstart and lookahead.
2421cb0ef41Sopenharmony_ci *
2431cb0ef41Sopenharmony_ci * IN assertion: lookahead < MIN_LOOKAHEAD
2441cb0ef41Sopenharmony_ci * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
2451cb0ef41Sopenharmony_ci *    At least one byte has been read, or avail_in == 0; reads are
2461cb0ef41Sopenharmony_ci *    performed for at least two bytes (required for the zip translate_eol
2471cb0ef41Sopenharmony_ci *    option -- not supported here).
2481cb0ef41Sopenharmony_ci */
2491cb0ef41Sopenharmony_cilocal void fill_window(deflate_state *s) {
2501cb0ef41Sopenharmony_ci    unsigned n;
2511cb0ef41Sopenharmony_ci    unsigned more;    /* Amount of free space at the end of the window. */
2521cb0ef41Sopenharmony_ci    uInt wsize = s->w_size;
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci    do {
2571cb0ef41Sopenharmony_ci        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci        /* Deal with !@#$% 64K limit: */
2601cb0ef41Sopenharmony_ci        if (sizeof(int) <= 2) {
2611cb0ef41Sopenharmony_ci            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
2621cb0ef41Sopenharmony_ci                more = wsize;
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci            } else if (more == (unsigned)(-1)) {
2651cb0ef41Sopenharmony_ci                /* Very unlikely, but possible on 16 bit machine if
2661cb0ef41Sopenharmony_ci                 * strstart == 0 && lookahead == 1 (input done a byte at time)
2671cb0ef41Sopenharmony_ci                 */
2681cb0ef41Sopenharmony_ci                more--;
2691cb0ef41Sopenharmony_ci            }
2701cb0ef41Sopenharmony_ci        }
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci        /* If the window is almost full and there is insufficient lookahead,
2731cb0ef41Sopenharmony_ci         * move the upper half to the lower one to make room in the upper half.
2741cb0ef41Sopenharmony_ci         */
2751cb0ef41Sopenharmony_ci        if (s->strstart >= wsize + MAX_DIST(s)) {
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
2781cb0ef41Sopenharmony_ci            s->match_start -= wsize;
2791cb0ef41Sopenharmony_ci            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
2801cb0ef41Sopenharmony_ci            s->block_start -= (long) wsize;
2811cb0ef41Sopenharmony_ci            if (s->insert > s->strstart)
2821cb0ef41Sopenharmony_ci                s->insert = s->strstart;
2831cb0ef41Sopenharmony_ci            slide_hash(s);
2841cb0ef41Sopenharmony_ci            more += wsize;
2851cb0ef41Sopenharmony_ci        }
2861cb0ef41Sopenharmony_ci        if (s->strm->avail_in == 0) break;
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci        /* If there was no sliding:
2891cb0ef41Sopenharmony_ci         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
2901cb0ef41Sopenharmony_ci         *    more == window_size - lookahead - strstart
2911cb0ef41Sopenharmony_ci         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
2921cb0ef41Sopenharmony_ci         * => more >= window_size - 2*WSIZE + 2
2931cb0ef41Sopenharmony_ci         * In the BIG_MEM or MMAP case (not yet supported),
2941cb0ef41Sopenharmony_ci         *   window_size == input_size + MIN_LOOKAHEAD  &&
2951cb0ef41Sopenharmony_ci         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
2961cb0ef41Sopenharmony_ci         * Otherwise, window_size == 2*WSIZE so more >= 2.
2971cb0ef41Sopenharmony_ci         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
2981cb0ef41Sopenharmony_ci         */
2991cb0ef41Sopenharmony_ci        Assert(more >= 2, "more < 2");
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
3021cb0ef41Sopenharmony_ci        s->lookahead += n;
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci        /* Initialize the hash value now that we have some input: */
3051cb0ef41Sopenharmony_ci        if (s->chromium_zlib_hash) {
3061cb0ef41Sopenharmony_ci            /* chromium hash reads 4 bytes */
3071cb0ef41Sopenharmony_ci            if (s->lookahead + s->insert > MIN_MATCH) {
3081cb0ef41Sopenharmony_ci                uInt str = s->strstart - s->insert;
3091cb0ef41Sopenharmony_ci                while (s->insert) {
3101cb0ef41Sopenharmony_ci                    insert_string(s, str);
3111cb0ef41Sopenharmony_ci                    str++;
3121cb0ef41Sopenharmony_ci                    s->insert--;
3131cb0ef41Sopenharmony_ci                    if (s->lookahead + s->insert <= MIN_MATCH)
3141cb0ef41Sopenharmony_ci                        break;
3151cb0ef41Sopenharmony_ci                }
3161cb0ef41Sopenharmony_ci            }
3171cb0ef41Sopenharmony_ci        } else
3181cb0ef41Sopenharmony_ci        /* Initialize the hash value now that we have some input: */
3191cb0ef41Sopenharmony_ci        if (s->lookahead + s->insert >= MIN_MATCH) {
3201cb0ef41Sopenharmony_ci            uInt str = s->strstart - s->insert;
3211cb0ef41Sopenharmony_ci            s->ins_h = s->window[str];
3221cb0ef41Sopenharmony_ci            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
3231cb0ef41Sopenharmony_ci#if MIN_MATCH != 3
3241cb0ef41Sopenharmony_ci            Call UPDATE_HASH() MIN_MATCH-3 more times
3251cb0ef41Sopenharmony_ci#endif
3261cb0ef41Sopenharmony_ci            while (s->insert) {
3271cb0ef41Sopenharmony_ci                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
3281cb0ef41Sopenharmony_ci#ifndef FASTEST
3291cb0ef41Sopenharmony_ci                s->prev[str & s->w_mask] = s->head[s->ins_h];
3301cb0ef41Sopenharmony_ci#endif
3311cb0ef41Sopenharmony_ci                s->head[s->ins_h] = (Pos)str;
3321cb0ef41Sopenharmony_ci                str++;
3331cb0ef41Sopenharmony_ci                s->insert--;
3341cb0ef41Sopenharmony_ci                if (s->lookahead + s->insert < MIN_MATCH)
3351cb0ef41Sopenharmony_ci                    break;
3361cb0ef41Sopenharmony_ci            }
3371cb0ef41Sopenharmony_ci        }
3381cb0ef41Sopenharmony_ci        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
3391cb0ef41Sopenharmony_ci         * but this is not important since only literal bytes will be emitted.
3401cb0ef41Sopenharmony_ci         */
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci    /* If the WIN_INIT bytes after the end of the current data have never been
3451cb0ef41Sopenharmony_ci     * written, then zero those bytes in order to avoid memory check reports of
3461cb0ef41Sopenharmony_ci     * the use of uninitialized (or uninitialised as Julian writes) bytes by
3471cb0ef41Sopenharmony_ci     * the longest match routines.  Update the high water mark for the next
3481cb0ef41Sopenharmony_ci     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
3491cb0ef41Sopenharmony_ci     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
3501cb0ef41Sopenharmony_ci     */
3511cb0ef41Sopenharmony_ci    if (s->high_water < s->window_size) {
3521cb0ef41Sopenharmony_ci        ulg curr = s->strstart + (ulg)(s->lookahead);
3531cb0ef41Sopenharmony_ci        ulg init;
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_ci        if (s->high_water < curr) {
3561cb0ef41Sopenharmony_ci            /* Previous high water mark below current data -- zero WIN_INIT
3571cb0ef41Sopenharmony_ci             * bytes or up to end of window, whichever is less.
3581cb0ef41Sopenharmony_ci             */
3591cb0ef41Sopenharmony_ci            init = s->window_size - curr;
3601cb0ef41Sopenharmony_ci            if (init > WIN_INIT)
3611cb0ef41Sopenharmony_ci                init = WIN_INIT;
3621cb0ef41Sopenharmony_ci            zmemzero(s->window + curr, (unsigned)init);
3631cb0ef41Sopenharmony_ci            s->high_water = curr + init;
3641cb0ef41Sopenharmony_ci        }
3651cb0ef41Sopenharmony_ci        else if (s->high_water < (ulg)curr + WIN_INIT) {
3661cb0ef41Sopenharmony_ci            /* High water mark at or above current data, but below current data
3671cb0ef41Sopenharmony_ci             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
3681cb0ef41Sopenharmony_ci             * to end of window, whichever is less.
3691cb0ef41Sopenharmony_ci             */
3701cb0ef41Sopenharmony_ci            init = (ulg)curr + WIN_INIT - s->high_water;
3711cb0ef41Sopenharmony_ci            if (init > s->window_size - s->high_water)
3721cb0ef41Sopenharmony_ci                init = s->window_size - s->high_water;
3731cb0ef41Sopenharmony_ci            zmemzero(s->window + s->high_water, (unsigned)init);
3741cb0ef41Sopenharmony_ci            s->high_water += init;
3751cb0ef41Sopenharmony_ci        }
3761cb0ef41Sopenharmony_ci    }
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
3791cb0ef41Sopenharmony_ci           "not enough room for search");
3801cb0ef41Sopenharmony_ci}
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci/* ========================================================================= */
3831cb0ef41Sopenharmony_ciint ZEXPORT deflateInit_(z_streamp strm, int level, const char *version,
3841cb0ef41Sopenharmony_ci                         int stream_size) {
3851cb0ef41Sopenharmony_ci    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
3861cb0ef41Sopenharmony_ci                         Z_DEFAULT_STRATEGY, version, stream_size);
3871cb0ef41Sopenharmony_ci    /* To do: ignore strm->next_in if we use it as window */
3881cb0ef41Sopenharmony_ci}
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci/* ========================================================================= */
3911cb0ef41Sopenharmony_ciint ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
3921cb0ef41Sopenharmony_ci                          int windowBits, int memLevel, int strategy,
3931cb0ef41Sopenharmony_ci                          const char *version, int stream_size) {
3941cb0ef41Sopenharmony_ci    unsigned window_padding = 8;
3951cb0ef41Sopenharmony_ci    deflate_state *s;
3961cb0ef41Sopenharmony_ci    int wrap = 1;
3971cb0ef41Sopenharmony_ci    static const char my_version[] = ZLIB_VERSION;
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci    // Needed to activate optimized insert_string() that helps compression
4001cb0ef41Sopenharmony_ci    // for all wrapper formats (e.g. RAW, ZLIB, GZIP).
4011cb0ef41Sopenharmony_ci    // Feature detection is not triggered while using RAW mode (i.e. we never
4021cb0ef41Sopenharmony_ci    // call crc32() with a NULL buffer).
4031cb0ef41Sopenharmony_ci#if defined(CRC32_ARMV8_CRC32) || defined(CRC32_SIMD_SSE42_PCLMUL)
4041cb0ef41Sopenharmony_ci    cpu_check_features();
4051cb0ef41Sopenharmony_ci#endif
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci    if (version == Z_NULL || version[0] != my_version[0] ||
4081cb0ef41Sopenharmony_ci        stream_size != sizeof(z_stream)) {
4091cb0ef41Sopenharmony_ci        return Z_VERSION_ERROR;
4101cb0ef41Sopenharmony_ci    }
4111cb0ef41Sopenharmony_ci    if (strm == Z_NULL) return Z_STREAM_ERROR;
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci    strm->msg = Z_NULL;
4141cb0ef41Sopenharmony_ci    if (strm->zalloc == (alloc_func)0) {
4151cb0ef41Sopenharmony_ci#ifdef Z_SOLO
4161cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
4171cb0ef41Sopenharmony_ci#else
4181cb0ef41Sopenharmony_ci        strm->zalloc = zcalloc;
4191cb0ef41Sopenharmony_ci        strm->opaque = (voidpf)0;
4201cb0ef41Sopenharmony_ci#endif
4211cb0ef41Sopenharmony_ci    }
4221cb0ef41Sopenharmony_ci    if (strm->zfree == (free_func)0)
4231cb0ef41Sopenharmony_ci#ifdef Z_SOLO
4241cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
4251cb0ef41Sopenharmony_ci#else
4261cb0ef41Sopenharmony_ci        strm->zfree = zcfree;
4271cb0ef41Sopenharmony_ci#endif
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci#ifdef FASTEST
4301cb0ef41Sopenharmony_ci    if (level != 0) level = 1;
4311cb0ef41Sopenharmony_ci#else
4321cb0ef41Sopenharmony_ci    if (level == Z_DEFAULT_COMPRESSION) level = 6;
4331cb0ef41Sopenharmony_ci#endif
4341cb0ef41Sopenharmony_ci
4351cb0ef41Sopenharmony_ci    if (windowBits < 0) { /* suppress zlib wrapper */
4361cb0ef41Sopenharmony_ci        wrap = 0;
4371cb0ef41Sopenharmony_ci        if (windowBits < -15)
4381cb0ef41Sopenharmony_ci            return Z_STREAM_ERROR;
4391cb0ef41Sopenharmony_ci        windowBits = -windowBits;
4401cb0ef41Sopenharmony_ci    }
4411cb0ef41Sopenharmony_ci#ifdef GZIP
4421cb0ef41Sopenharmony_ci    else if (windowBits > 15) {
4431cb0ef41Sopenharmony_ci        wrap = 2;       /* write gzip wrapper instead */
4441cb0ef41Sopenharmony_ci        windowBits -= 16;
4451cb0ef41Sopenharmony_ci    }
4461cb0ef41Sopenharmony_ci#endif
4471cb0ef41Sopenharmony_ci    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
4481cb0ef41Sopenharmony_ci        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
4491cb0ef41Sopenharmony_ci        strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
4501cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
4511cb0ef41Sopenharmony_ci    }
4521cb0ef41Sopenharmony_ci    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
4531cb0ef41Sopenharmony_ci    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
4541cb0ef41Sopenharmony_ci    if (s == Z_NULL) return Z_MEM_ERROR;
4551cb0ef41Sopenharmony_ci    strm->state = (struct internal_state FAR *)s;
4561cb0ef41Sopenharmony_ci    s->strm = strm;
4571cb0ef41Sopenharmony_ci    s->status = INIT_STATE;     /* to pass state test in deflateReset() */
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci    s->wrap = wrap;
4601cb0ef41Sopenharmony_ci    s->gzhead = Z_NULL;
4611cb0ef41Sopenharmony_ci    s->w_bits = (uInt)windowBits;
4621cb0ef41Sopenharmony_ci    s->w_size = 1 << s->w_bits;
4631cb0ef41Sopenharmony_ci    s->w_mask = s->w_size - 1;
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci    s->chromium_zlib_hash = 1;
4661cb0ef41Sopenharmony_ci#if defined(USE_ZLIB_RABIN_KARP_ROLLING_HASH)
4671cb0ef41Sopenharmony_ci    s->chromium_zlib_hash = 0;
4681cb0ef41Sopenharmony_ci#endif
4691cb0ef41Sopenharmony_ci
4701cb0ef41Sopenharmony_ci    s->hash_bits = memLevel + 7;
4711cb0ef41Sopenharmony_ci    if (s->chromium_zlib_hash && s->hash_bits < 15) {
4721cb0ef41Sopenharmony_ci        s->hash_bits = 15;
4731cb0ef41Sopenharmony_ci    }
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci    s->hash_size = 1 << s->hash_bits;
4761cb0ef41Sopenharmony_ci    s->hash_mask = s->hash_size - 1;
4771cb0ef41Sopenharmony_ci    s->hash_shift =  ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH);
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci    s->window = (Bytef *) ZALLOC(strm,
4801cb0ef41Sopenharmony_ci                                 s->w_size + window_padding,
4811cb0ef41Sopenharmony_ci                                 2*sizeof(Byte));
4821cb0ef41Sopenharmony_ci    /* Avoid use of unitialized values in the window, see crbug.com/1137613 and
4831cb0ef41Sopenharmony_ci     * crbug.com/1144420 */
4841cb0ef41Sopenharmony_ci    zmemzero(s->window, (s->w_size + window_padding) * (2 * sizeof(Byte)));
4851cb0ef41Sopenharmony_ci    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
4861cb0ef41Sopenharmony_ci    /* Avoid use of uninitialized value, see:
4871cb0ef41Sopenharmony_ci     * https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11360
4881cb0ef41Sopenharmony_ci     */
4891cb0ef41Sopenharmony_ci    zmemzero(s->prev, s->w_size * sizeof(Pos));
4901cb0ef41Sopenharmony_ci    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_ci    s->high_water = 0;      /* nothing written to s->window yet */
4931cb0ef41Sopenharmony_ci
4941cb0ef41Sopenharmony_ci    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ci    /* We overlay pending_buf and sym_buf. This works since the average size
4971cb0ef41Sopenharmony_ci     * for length/distance pairs over any compressed block is assured to be 31
4981cb0ef41Sopenharmony_ci     * bits or less.
4991cb0ef41Sopenharmony_ci     *
5001cb0ef41Sopenharmony_ci     * Analysis: The longest fixed codes are a length code of 8 bits plus 5
5011cb0ef41Sopenharmony_ci     * extra bits, for lengths 131 to 257. The longest fixed distance codes are
5021cb0ef41Sopenharmony_ci     * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
5031cb0ef41Sopenharmony_ci     * possible fixed-codes length/distance pair is then 31 bits total.
5041cb0ef41Sopenharmony_ci     *
5051cb0ef41Sopenharmony_ci     * sym_buf starts one-fourth of the way into pending_buf. So there are
5061cb0ef41Sopenharmony_ci     * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
5071cb0ef41Sopenharmony_ci     * in sym_buf is three bytes -- two for the distance and one for the
5081cb0ef41Sopenharmony_ci     * literal/length. As each symbol is consumed, the pointer to the next
5091cb0ef41Sopenharmony_ci     * sym_buf value to read moves forward three bytes. From that symbol, up to
5101cb0ef41Sopenharmony_ci     * 31 bits are written to pending_buf. The closest the written pending_buf
5111cb0ef41Sopenharmony_ci     * bits gets to the next sym_buf symbol to read is just before the last
5121cb0ef41Sopenharmony_ci     * code is written. At that time, 31*(n - 2) bits have been written, just
5131cb0ef41Sopenharmony_ci     * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at
5141cb0ef41Sopenharmony_ci     * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1
5151cb0ef41Sopenharmony_ci     * symbols are written.) The closest the writing gets to what is unread is
5161cb0ef41Sopenharmony_ci     * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and
5171cb0ef41Sopenharmony_ci     * can range from 128 to 32768.
5181cb0ef41Sopenharmony_ci     *
5191cb0ef41Sopenharmony_ci     * Therefore, at a minimum, there are 142 bits of space between what is
5201cb0ef41Sopenharmony_ci     * written and what is read in the overlain buffers, so the symbols cannot
5211cb0ef41Sopenharmony_ci     * be overwritten by the compressed data. That space is actually 139 bits,
5221cb0ef41Sopenharmony_ci     * due to the three-bit fixed-code block header.
5231cb0ef41Sopenharmony_ci     *
5241cb0ef41Sopenharmony_ci     * That covers the case where either Z_FIXED is specified, forcing fixed
5251cb0ef41Sopenharmony_ci     * codes, or when the use of fixed codes is chosen, because that choice
5261cb0ef41Sopenharmony_ci     * results in a smaller compressed block than dynamic codes. That latter
5271cb0ef41Sopenharmony_ci     * condition then assures that the above analysis also covers all dynamic
5281cb0ef41Sopenharmony_ci     * blocks. A dynamic-code block will only be chosen to be emitted if it has
5291cb0ef41Sopenharmony_ci     * fewer bits than a fixed-code block would for the same set of symbols.
5301cb0ef41Sopenharmony_ci     * Therefore its average symbol length is assured to be less than 31. So
5311cb0ef41Sopenharmony_ci     * the compressed data for a dynamic block also cannot overwrite the
5321cb0ef41Sopenharmony_ci     * symbols from which it is being constructed.
5331cb0ef41Sopenharmony_ci     */
5341cb0ef41Sopenharmony_ci#ifdef LIT_MEM
5351cb0ef41Sopenharmony_ci    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 5);
5361cb0ef41Sopenharmony_ci#else
5371cb0ef41Sopenharmony_ci    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
5381cb0ef41Sopenharmony_ci#endif
5391cb0ef41Sopenharmony_ci    s->pending_buf_size = (ulg)s->lit_bufsize * 4;
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
5421cb0ef41Sopenharmony_ci        s->pending_buf == Z_NULL) {
5431cb0ef41Sopenharmony_ci        s->status = FINISH_STATE;
5441cb0ef41Sopenharmony_ci        strm->msg = ERR_MSG(Z_MEM_ERROR);
5451cb0ef41Sopenharmony_ci        deflateEnd (strm);
5461cb0ef41Sopenharmony_ci        return Z_MEM_ERROR;
5471cb0ef41Sopenharmony_ci    }
5481cb0ef41Sopenharmony_ci#ifdef LIT_MEM
5491cb0ef41Sopenharmony_ci    s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
5501cb0ef41Sopenharmony_ci    s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
5511cb0ef41Sopenharmony_ci    s->sym_end = s->lit_bufsize - 1;
5521cb0ef41Sopenharmony_ci#else
5531cb0ef41Sopenharmony_ci    s->sym_buf = s->pending_buf + s->lit_bufsize;
5541cb0ef41Sopenharmony_ci    s->sym_end = (s->lit_bufsize - 1) * 3;
5551cb0ef41Sopenharmony_ci#endif
5561cb0ef41Sopenharmony_ci    /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
5571cb0ef41Sopenharmony_ci     * on 16 bit machines and because stored blocks are restricted to
5581cb0ef41Sopenharmony_ci     * 64K-1 bytes.
5591cb0ef41Sopenharmony_ci     */
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci    s->level = level;
5621cb0ef41Sopenharmony_ci    s->strategy = strategy;
5631cb0ef41Sopenharmony_ci    s->method = (Byte)method;
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci    return deflateReset(strm);
5661cb0ef41Sopenharmony_ci}
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci/* =========================================================================
5691cb0ef41Sopenharmony_ci * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
5701cb0ef41Sopenharmony_ci */
5711cb0ef41Sopenharmony_cilocal int deflateStateCheck(z_streamp strm) {
5721cb0ef41Sopenharmony_ci    deflate_state *s;
5731cb0ef41Sopenharmony_ci    if (strm == Z_NULL ||
5741cb0ef41Sopenharmony_ci        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
5751cb0ef41Sopenharmony_ci        return 1;
5761cb0ef41Sopenharmony_ci    s = strm->state;
5771cb0ef41Sopenharmony_ci    if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
5781cb0ef41Sopenharmony_ci#ifdef GZIP
5791cb0ef41Sopenharmony_ci                                           s->status != GZIP_STATE &&
5801cb0ef41Sopenharmony_ci#endif
5811cb0ef41Sopenharmony_ci                                           s->status != EXTRA_STATE &&
5821cb0ef41Sopenharmony_ci                                           s->status != NAME_STATE &&
5831cb0ef41Sopenharmony_ci                                           s->status != COMMENT_STATE &&
5841cb0ef41Sopenharmony_ci                                           s->status != HCRC_STATE &&
5851cb0ef41Sopenharmony_ci                                           s->status != BUSY_STATE &&
5861cb0ef41Sopenharmony_ci                                           s->status != FINISH_STATE))
5871cb0ef41Sopenharmony_ci        return 1;
5881cb0ef41Sopenharmony_ci    return 0;
5891cb0ef41Sopenharmony_ci}
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci/* ========================================================================= */
5921cb0ef41Sopenharmony_ciint ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary,
5931cb0ef41Sopenharmony_ci                                 uInt  dictLength) {
5941cb0ef41Sopenharmony_ci    deflate_state *s;
5951cb0ef41Sopenharmony_ci    uInt str, n;
5961cb0ef41Sopenharmony_ci    int wrap;
5971cb0ef41Sopenharmony_ci    unsigned avail;
5981cb0ef41Sopenharmony_ci    z_const unsigned char *next;
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm) || dictionary == Z_NULL)
6011cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
6021cb0ef41Sopenharmony_ci    s = strm->state;
6031cb0ef41Sopenharmony_ci    wrap = s->wrap;
6041cb0ef41Sopenharmony_ci    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
6051cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
6081cb0ef41Sopenharmony_ci    if (wrap == 1)
6091cb0ef41Sopenharmony_ci        strm->adler = adler32(strm->adler, dictionary, dictLength);
6101cb0ef41Sopenharmony_ci    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci    /* if dictionary would fill window, just replace the history */
6131cb0ef41Sopenharmony_ci    if (dictLength >= s->w_size) {
6141cb0ef41Sopenharmony_ci        if (wrap == 0) {            /* already empty otherwise */
6151cb0ef41Sopenharmony_ci            CLEAR_HASH(s);
6161cb0ef41Sopenharmony_ci            s->strstart = 0;
6171cb0ef41Sopenharmony_ci            s->block_start = 0L;
6181cb0ef41Sopenharmony_ci            s->insert = 0;
6191cb0ef41Sopenharmony_ci        }
6201cb0ef41Sopenharmony_ci        dictionary += dictLength - s->w_size;  /* use the tail */
6211cb0ef41Sopenharmony_ci        dictLength = s->w_size;
6221cb0ef41Sopenharmony_ci    }
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci    /* insert dictionary into window and hash */
6251cb0ef41Sopenharmony_ci    avail = strm->avail_in;
6261cb0ef41Sopenharmony_ci    next = strm->next_in;
6271cb0ef41Sopenharmony_ci    strm->avail_in = dictLength;
6281cb0ef41Sopenharmony_ci    strm->next_in = (z_const Bytef *)dictionary;
6291cb0ef41Sopenharmony_ci    fill_window(s);
6301cb0ef41Sopenharmony_ci    while (s->lookahead >= MIN_MATCH) {
6311cb0ef41Sopenharmony_ci        str = s->strstart;
6321cb0ef41Sopenharmony_ci        n = s->lookahead - (MIN_MATCH-1);
6331cb0ef41Sopenharmony_ci        do {
6341cb0ef41Sopenharmony_ci            insert_string(s, str);
6351cb0ef41Sopenharmony_ci            str++;
6361cb0ef41Sopenharmony_ci        } while (--n);
6371cb0ef41Sopenharmony_ci        s->strstart = str;
6381cb0ef41Sopenharmony_ci        s->lookahead = MIN_MATCH-1;
6391cb0ef41Sopenharmony_ci        fill_window(s);
6401cb0ef41Sopenharmony_ci    }
6411cb0ef41Sopenharmony_ci    s->strstart += s->lookahead;
6421cb0ef41Sopenharmony_ci    s->block_start = (long)s->strstart;
6431cb0ef41Sopenharmony_ci    s->insert = s->lookahead;
6441cb0ef41Sopenharmony_ci    s->lookahead = 0;
6451cb0ef41Sopenharmony_ci    s->match_length = s->prev_length = MIN_MATCH-1;
6461cb0ef41Sopenharmony_ci    s->match_available = 0;
6471cb0ef41Sopenharmony_ci    strm->next_in = next;
6481cb0ef41Sopenharmony_ci    strm->avail_in = avail;
6491cb0ef41Sopenharmony_ci    s->wrap = wrap;
6501cb0ef41Sopenharmony_ci    return Z_OK;
6511cb0ef41Sopenharmony_ci}
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci/* ========================================================================= */
6541cb0ef41Sopenharmony_ciint ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary,
6551cb0ef41Sopenharmony_ci                                 uInt *dictLength) {
6561cb0ef41Sopenharmony_ci    deflate_state *s;
6571cb0ef41Sopenharmony_ci    uInt len;
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm))
6601cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
6611cb0ef41Sopenharmony_ci    s = strm->state;
6621cb0ef41Sopenharmony_ci    len = s->strstart + s->lookahead;
6631cb0ef41Sopenharmony_ci    if (len > s->w_size)
6641cb0ef41Sopenharmony_ci        len = s->w_size;
6651cb0ef41Sopenharmony_ci    if (dictionary != Z_NULL && len)
6661cb0ef41Sopenharmony_ci        zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
6671cb0ef41Sopenharmony_ci    if (dictLength != Z_NULL)
6681cb0ef41Sopenharmony_ci        *dictLength = len;
6691cb0ef41Sopenharmony_ci    return Z_OK;
6701cb0ef41Sopenharmony_ci}
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci/* ========================================================================= */
6731cb0ef41Sopenharmony_ciint ZEXPORT deflateResetKeep(z_streamp strm) {
6741cb0ef41Sopenharmony_ci    deflate_state *s;
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) {
6771cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
6781cb0ef41Sopenharmony_ci    }
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci    strm->total_in = strm->total_out = 0;
6811cb0ef41Sopenharmony_ci    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
6821cb0ef41Sopenharmony_ci    strm->data_type = Z_UNKNOWN;
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci    s = (deflate_state *)strm->state;
6851cb0ef41Sopenharmony_ci    s->pending = 0;
6861cb0ef41Sopenharmony_ci    s->pending_out = s->pending_buf;
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci    if (s->wrap < 0) {
6891cb0ef41Sopenharmony_ci        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
6901cb0ef41Sopenharmony_ci    }
6911cb0ef41Sopenharmony_ci    s->status =
6921cb0ef41Sopenharmony_ci#ifdef GZIP
6931cb0ef41Sopenharmony_ci        s->wrap == 2 ? GZIP_STATE :
6941cb0ef41Sopenharmony_ci#endif
6951cb0ef41Sopenharmony_ci        INIT_STATE;
6961cb0ef41Sopenharmony_ci    strm->adler =
6971cb0ef41Sopenharmony_ci#ifdef GZIP
6981cb0ef41Sopenharmony_ci        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
6991cb0ef41Sopenharmony_ci#endif
7001cb0ef41Sopenharmony_ci        adler32(0L, Z_NULL, 0);
7011cb0ef41Sopenharmony_ci    s->last_flush = -2;
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci    _tr_init(s);
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci    return Z_OK;
7061cb0ef41Sopenharmony_ci}
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci/* ===========================================================================
7091cb0ef41Sopenharmony_ci * Initialize the "longest match" routines for a new zlib stream
7101cb0ef41Sopenharmony_ci */
7111cb0ef41Sopenharmony_cilocal void lm_init(deflate_state *s) {
7121cb0ef41Sopenharmony_ci    s->window_size = (ulg)2L*s->w_size;
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ci    CLEAR_HASH(s);
7151cb0ef41Sopenharmony_ci
7161cb0ef41Sopenharmony_ci    /* Set the default configuration parameters:
7171cb0ef41Sopenharmony_ci     */
7181cb0ef41Sopenharmony_ci    s->max_lazy_match   = configuration_table[s->level].max_lazy;
7191cb0ef41Sopenharmony_ci    s->good_match       = configuration_table[s->level].good_length;
7201cb0ef41Sopenharmony_ci    s->nice_match       = configuration_table[s->level].nice_length;
7211cb0ef41Sopenharmony_ci    s->max_chain_length = configuration_table[s->level].max_chain;
7221cb0ef41Sopenharmony_ci
7231cb0ef41Sopenharmony_ci    s->strstart = 0;
7241cb0ef41Sopenharmony_ci    s->block_start = 0L;
7251cb0ef41Sopenharmony_ci    s->lookahead = 0;
7261cb0ef41Sopenharmony_ci    s->insert = 0;
7271cb0ef41Sopenharmony_ci    s->match_length = s->prev_length = MIN_MATCH-1;
7281cb0ef41Sopenharmony_ci    s->match_available = 0;
7291cb0ef41Sopenharmony_ci    s->ins_h = 0;
7301cb0ef41Sopenharmony_ci}
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ci/* ========================================================================= */
7331cb0ef41Sopenharmony_ciint ZEXPORT deflateReset(z_streamp strm) {
7341cb0ef41Sopenharmony_ci    int ret;
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_ci    ret = deflateResetKeep(strm);
7371cb0ef41Sopenharmony_ci    if (ret == Z_OK)
7381cb0ef41Sopenharmony_ci        lm_init(strm->state);
7391cb0ef41Sopenharmony_ci    return ret;
7401cb0ef41Sopenharmony_ci}
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_ci/* ========================================================================= */
7431cb0ef41Sopenharmony_ciint ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {
7441cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm) || strm->state->wrap != 2)
7451cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
7461cb0ef41Sopenharmony_ci    strm->state->gzhead = head;
7471cb0ef41Sopenharmony_ci    return Z_OK;
7481cb0ef41Sopenharmony_ci}
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci/* ========================================================================= */
7511cb0ef41Sopenharmony_ciint ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
7521cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
7531cb0ef41Sopenharmony_ci    if (pending != Z_NULL)
7541cb0ef41Sopenharmony_ci        *pending = strm->state->pending;
7551cb0ef41Sopenharmony_ci    if (bits != Z_NULL)
7561cb0ef41Sopenharmony_ci        *bits = strm->state->bi_valid;
7571cb0ef41Sopenharmony_ci    return Z_OK;
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci/* ========================================================================= */
7611cb0ef41Sopenharmony_ciint ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
7621cb0ef41Sopenharmony_ci    deflate_state *s;
7631cb0ef41Sopenharmony_ci    int put;
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
7661cb0ef41Sopenharmony_ci    s = strm->state;
7671cb0ef41Sopenharmony_ci#ifdef LIT_MEM
7681cb0ef41Sopenharmony_ci    if (bits < 0 || bits > 16 ||
7691cb0ef41Sopenharmony_ci        (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
7701cb0ef41Sopenharmony_ci        return Z_BUF_ERROR;
7711cb0ef41Sopenharmony_ci#else
7721cb0ef41Sopenharmony_ci    if (bits < 0 || bits > 16 ||
7731cb0ef41Sopenharmony_ci        s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
7741cb0ef41Sopenharmony_ci        return Z_BUF_ERROR;
7751cb0ef41Sopenharmony_ci#endif
7761cb0ef41Sopenharmony_ci    do {
7771cb0ef41Sopenharmony_ci        put = Buf_size - s->bi_valid;
7781cb0ef41Sopenharmony_ci        if (put > bits)
7791cb0ef41Sopenharmony_ci            put = bits;
7801cb0ef41Sopenharmony_ci        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
7811cb0ef41Sopenharmony_ci        s->bi_valid += put;
7821cb0ef41Sopenharmony_ci        _tr_flush_bits(s);
7831cb0ef41Sopenharmony_ci        value >>= put;
7841cb0ef41Sopenharmony_ci        bits -= put;
7851cb0ef41Sopenharmony_ci    } while (bits);
7861cb0ef41Sopenharmony_ci    return Z_OK;
7871cb0ef41Sopenharmony_ci}
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ci/* ========================================================================= */
7901cb0ef41Sopenharmony_ciint ZEXPORT deflateParams(z_streamp strm, int level, int strategy) {
7911cb0ef41Sopenharmony_ci    deflate_state *s;
7921cb0ef41Sopenharmony_ci    compress_func func;
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
7951cb0ef41Sopenharmony_ci    s = strm->state;
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci#ifdef FASTEST
7981cb0ef41Sopenharmony_ci    if (level != 0) level = 1;
7991cb0ef41Sopenharmony_ci#else
8001cb0ef41Sopenharmony_ci    if (level == Z_DEFAULT_COMPRESSION) level = 6;
8011cb0ef41Sopenharmony_ci#endif
8021cb0ef41Sopenharmony_ci    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
8031cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
8041cb0ef41Sopenharmony_ci    }
8051cb0ef41Sopenharmony_ci    func = configuration_table[s->level].func;
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci    if ((strategy != s->strategy || func != configuration_table[level].func) &&
8081cb0ef41Sopenharmony_ci        s->last_flush != -2) {
8091cb0ef41Sopenharmony_ci        /* Flush the last buffer: */
8101cb0ef41Sopenharmony_ci        int err = deflate(strm, Z_BLOCK);
8111cb0ef41Sopenharmony_ci        if (err == Z_STREAM_ERROR)
8121cb0ef41Sopenharmony_ci            return err;
8131cb0ef41Sopenharmony_ci        if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
8141cb0ef41Sopenharmony_ci            return Z_BUF_ERROR;
8151cb0ef41Sopenharmony_ci    }
8161cb0ef41Sopenharmony_ci    if (s->level != level) {
8171cb0ef41Sopenharmony_ci        if (s->level == 0 && s->matches != 0) {
8181cb0ef41Sopenharmony_ci            if (s->matches == 1)
8191cb0ef41Sopenharmony_ci                slide_hash(s);
8201cb0ef41Sopenharmony_ci            else
8211cb0ef41Sopenharmony_ci                CLEAR_HASH(s);
8221cb0ef41Sopenharmony_ci            s->matches = 0;
8231cb0ef41Sopenharmony_ci        }
8241cb0ef41Sopenharmony_ci        s->level = level;
8251cb0ef41Sopenharmony_ci        s->max_lazy_match   = configuration_table[level].max_lazy;
8261cb0ef41Sopenharmony_ci        s->good_match       = configuration_table[level].good_length;
8271cb0ef41Sopenharmony_ci        s->nice_match       = configuration_table[level].nice_length;
8281cb0ef41Sopenharmony_ci        s->max_chain_length = configuration_table[level].max_chain;
8291cb0ef41Sopenharmony_ci    }
8301cb0ef41Sopenharmony_ci    s->strategy = strategy;
8311cb0ef41Sopenharmony_ci    return Z_OK;
8321cb0ef41Sopenharmony_ci}
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci/* ========================================================================= */
8351cb0ef41Sopenharmony_ciint ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy,
8361cb0ef41Sopenharmony_ci                        int nice_length, int max_chain) {
8371cb0ef41Sopenharmony_ci    deflate_state *s;
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
8401cb0ef41Sopenharmony_ci    s = strm->state;
8411cb0ef41Sopenharmony_ci    s->good_match = (uInt)good_length;
8421cb0ef41Sopenharmony_ci    s->max_lazy_match = (uInt)max_lazy;
8431cb0ef41Sopenharmony_ci    s->nice_match = nice_length;
8441cb0ef41Sopenharmony_ci    s->max_chain_length = (uInt)max_chain;
8451cb0ef41Sopenharmony_ci    return Z_OK;
8461cb0ef41Sopenharmony_ci}
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci/* =========================================================================
8491cb0ef41Sopenharmony_ci * For the default windowBits of 15 and memLevel of 8, this function returns a
8501cb0ef41Sopenharmony_ci * close to exact, as well as small, upper bound on the compressed size. This
8511cb0ef41Sopenharmony_ci * is an expansion of ~0.03%, plus a small constant.
8521cb0ef41Sopenharmony_ci *
8531cb0ef41Sopenharmony_ci * For any setting other than those defaults for windowBits and memLevel, one
8541cb0ef41Sopenharmony_ci * of two worst case bounds is returned. This is at most an expansion of ~4% or
8551cb0ef41Sopenharmony_ci * ~13%, plus a small constant.
8561cb0ef41Sopenharmony_ci *
8571cb0ef41Sopenharmony_ci * Both the 0.03% and 4% derive from the overhead of stored blocks. The first
8581cb0ef41Sopenharmony_ci * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second
8591cb0ef41Sopenharmony_ci * is for stored blocks of 127 bytes (the worst case memLevel == 1). The
8601cb0ef41Sopenharmony_ci * expansion results from five bytes of header for each stored block.
8611cb0ef41Sopenharmony_ci *
8621cb0ef41Sopenharmony_ci * The larger expansion of 13% results from a window size less than or equal to
8631cb0ef41Sopenharmony_ci * the symbols buffer size (windowBits <= memLevel + 7). In that case some of
8641cb0ef41Sopenharmony_ci * the data being compressed may have slid out of the sliding window, impeding
8651cb0ef41Sopenharmony_ci * a stored block from being emitted. Then the only choice is a fixed or
8661cb0ef41Sopenharmony_ci * dynamic block, where a fixed block limits the maximum expansion to 9 bits
8671cb0ef41Sopenharmony_ci * per 8-bit byte, plus 10 bits for every block. The smallest block size for
8681cb0ef41Sopenharmony_ci * which this can occur is 255 (memLevel == 2).
8691cb0ef41Sopenharmony_ci *
8701cb0ef41Sopenharmony_ci * Shifts are used to approximate divisions, for speed.
8711cb0ef41Sopenharmony_ci */
8721cb0ef41Sopenharmony_ciuLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
8731cb0ef41Sopenharmony_ci    deflate_state *s;
8741cb0ef41Sopenharmony_ci    uLong fixedlen, storelen, wraplen;
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci    /* upper bound for fixed blocks with 9-bit literals and length 255
8771cb0ef41Sopenharmony_ci       (memLevel == 2, which is the lowest that may not use stored blocks) --
8781cb0ef41Sopenharmony_ci       ~13% overhead plus a small constant */
8791cb0ef41Sopenharmony_ci    fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) +
8801cb0ef41Sopenharmony_ci               (sourceLen >> 9) + 4;
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_ci    /* upper bound for stored blocks with length 127 (memLevel == 1) --
8831cb0ef41Sopenharmony_ci       ~4% overhead plus a small constant */
8841cb0ef41Sopenharmony_ci    storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) +
8851cb0ef41Sopenharmony_ci               (sourceLen >> 11) + 7;
8861cb0ef41Sopenharmony_ci
8871cb0ef41Sopenharmony_ci    /* if can't get parameters, return larger bound plus a zlib wrapper */
8881cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm))
8891cb0ef41Sopenharmony_ci        return (fixedlen > storelen ? fixedlen : storelen) + 6;
8901cb0ef41Sopenharmony_ci
8911cb0ef41Sopenharmony_ci    /* compute wrapper length */
8921cb0ef41Sopenharmony_ci    s = strm->state;
8931cb0ef41Sopenharmony_ci    switch (s->wrap) {
8941cb0ef41Sopenharmony_ci    case 0:                                 /* raw deflate */
8951cb0ef41Sopenharmony_ci        wraplen = 0;
8961cb0ef41Sopenharmony_ci        break;
8971cb0ef41Sopenharmony_ci    case 1:                                 /* zlib wrapper */
8981cb0ef41Sopenharmony_ci        wraplen = 6 + (s->strstart ? 4 : 0);
8991cb0ef41Sopenharmony_ci        break;
9001cb0ef41Sopenharmony_ci#ifdef GZIP
9011cb0ef41Sopenharmony_ci    case 2:                                 /* gzip wrapper */
9021cb0ef41Sopenharmony_ci        wraplen = 18;
9031cb0ef41Sopenharmony_ci        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
9041cb0ef41Sopenharmony_ci            Bytef *str;
9051cb0ef41Sopenharmony_ci            if (s->gzhead->extra != Z_NULL)
9061cb0ef41Sopenharmony_ci                wraplen += 2 + s->gzhead->extra_len;
9071cb0ef41Sopenharmony_ci            str = s->gzhead->name;
9081cb0ef41Sopenharmony_ci            if (str != Z_NULL)
9091cb0ef41Sopenharmony_ci                do {
9101cb0ef41Sopenharmony_ci                    wraplen++;
9111cb0ef41Sopenharmony_ci                } while (*str++);
9121cb0ef41Sopenharmony_ci            str = s->gzhead->comment;
9131cb0ef41Sopenharmony_ci            if (str != Z_NULL)
9141cb0ef41Sopenharmony_ci                do {
9151cb0ef41Sopenharmony_ci                    wraplen++;
9161cb0ef41Sopenharmony_ci                } while (*str++);
9171cb0ef41Sopenharmony_ci            if (s->gzhead->hcrc)
9181cb0ef41Sopenharmony_ci                wraplen += 2;
9191cb0ef41Sopenharmony_ci        }
9201cb0ef41Sopenharmony_ci        break;
9211cb0ef41Sopenharmony_ci#endif
9221cb0ef41Sopenharmony_ci    default:                                /* for compiler happiness */
9231cb0ef41Sopenharmony_ci        wraplen = 6;
9241cb0ef41Sopenharmony_ci    }
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_ci    /* if not default parameters, return one of the conservative bounds */
9271cb0ef41Sopenharmony_ci    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
9281cb0ef41Sopenharmony_ci        return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
9291cb0ef41Sopenharmony_ci               wraplen;
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_ci    /* default settings: return tight bound for that case -- ~0.03% overhead
9321cb0ef41Sopenharmony_ci       plus a small constant */
9331cb0ef41Sopenharmony_ci    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
9341cb0ef41Sopenharmony_ci           (sourceLen >> 25) + 13 - 6 + wraplen;
9351cb0ef41Sopenharmony_ci}
9361cb0ef41Sopenharmony_ci
9371cb0ef41Sopenharmony_ci/* =========================================================================
9381cb0ef41Sopenharmony_ci * Put a short in the pending buffer. The 16-bit value is put in MSB order.
9391cb0ef41Sopenharmony_ci * IN assertion: the stream state is correct and there is enough room in
9401cb0ef41Sopenharmony_ci * pending_buf.
9411cb0ef41Sopenharmony_ci */
9421cb0ef41Sopenharmony_cilocal void putShortMSB(deflate_state *s, uInt b) {
9431cb0ef41Sopenharmony_ci    put_byte(s, (Byte)(b >> 8));
9441cb0ef41Sopenharmony_ci    put_byte(s, (Byte)(b & 0xff));
9451cb0ef41Sopenharmony_ci}
9461cb0ef41Sopenharmony_ci
9471cb0ef41Sopenharmony_ci/* =========================================================================
9481cb0ef41Sopenharmony_ci * Flush as much pending output as possible. All deflate() output, except for
9491cb0ef41Sopenharmony_ci * some deflate_stored() output, goes through this function so some
9501cb0ef41Sopenharmony_ci * applications may wish to modify it to avoid allocating a large
9511cb0ef41Sopenharmony_ci * strm->next_out buffer and copying into it. (See also read_buf()).
9521cb0ef41Sopenharmony_ci */
9531cb0ef41Sopenharmony_cilocal void flush_pending(z_streamp strm) {
9541cb0ef41Sopenharmony_ci    unsigned len;
9551cb0ef41Sopenharmony_ci    deflate_state *s = strm->state;
9561cb0ef41Sopenharmony_ci
9571cb0ef41Sopenharmony_ci    _tr_flush_bits(s);
9581cb0ef41Sopenharmony_ci    len = s->pending;
9591cb0ef41Sopenharmony_ci    if (len > strm->avail_out) len = strm->avail_out;
9601cb0ef41Sopenharmony_ci    if (len == 0) return;
9611cb0ef41Sopenharmony_ci
9621cb0ef41Sopenharmony_ci    zmemcpy(strm->next_out, s->pending_out, len);
9631cb0ef41Sopenharmony_ci    strm->next_out  += len;
9641cb0ef41Sopenharmony_ci    s->pending_out  += len;
9651cb0ef41Sopenharmony_ci    strm->total_out += len;
9661cb0ef41Sopenharmony_ci    strm->avail_out -= len;
9671cb0ef41Sopenharmony_ci    s->pending      -= len;
9681cb0ef41Sopenharmony_ci    if (s->pending == 0) {
9691cb0ef41Sopenharmony_ci        s->pending_out = s->pending_buf;
9701cb0ef41Sopenharmony_ci    }
9711cb0ef41Sopenharmony_ci}
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ci/* ===========================================================================
9741cb0ef41Sopenharmony_ci * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
9751cb0ef41Sopenharmony_ci */
9761cb0ef41Sopenharmony_ci#define HCRC_UPDATE(beg) \
9771cb0ef41Sopenharmony_ci    do { \
9781cb0ef41Sopenharmony_ci        if (s->gzhead->hcrc && s->pending > (beg)) \
9791cb0ef41Sopenharmony_ci            strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
9801cb0ef41Sopenharmony_ci                                s->pending - (beg)); \
9811cb0ef41Sopenharmony_ci    } while (0)
9821cb0ef41Sopenharmony_ci
9831cb0ef41Sopenharmony_ci/* ========================================================================= */
9841cb0ef41Sopenharmony_ciint ZEXPORT deflate(z_streamp strm, int flush) {
9851cb0ef41Sopenharmony_ci    int old_flush; /* value of flush param for previous deflate call */
9861cb0ef41Sopenharmony_ci    deflate_state *s;
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
9891cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
9901cb0ef41Sopenharmony_ci    }
9911cb0ef41Sopenharmony_ci    s = strm->state;
9921cb0ef41Sopenharmony_ci
9931cb0ef41Sopenharmony_ci    if (strm->next_out == Z_NULL ||
9941cb0ef41Sopenharmony_ci        (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
9951cb0ef41Sopenharmony_ci        (s->status == FINISH_STATE && flush != Z_FINISH)) {
9961cb0ef41Sopenharmony_ci        ERR_RETURN(strm, Z_STREAM_ERROR);
9971cb0ef41Sopenharmony_ci    }
9981cb0ef41Sopenharmony_ci    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ci    old_flush = s->last_flush;
10011cb0ef41Sopenharmony_ci    s->last_flush = flush;
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ci    /* Flush as much pending output as possible */
10041cb0ef41Sopenharmony_ci    if (s->pending != 0) {
10051cb0ef41Sopenharmony_ci        flush_pending(strm);
10061cb0ef41Sopenharmony_ci        if (strm->avail_out == 0) {
10071cb0ef41Sopenharmony_ci            /* Since avail_out is 0, deflate will be called again with
10081cb0ef41Sopenharmony_ci             * more output space, but possibly with both pending and
10091cb0ef41Sopenharmony_ci             * avail_in equal to zero. There won't be anything to do,
10101cb0ef41Sopenharmony_ci             * but this is not an error situation so make sure we
10111cb0ef41Sopenharmony_ci             * return OK instead of BUF_ERROR at next call of deflate:
10121cb0ef41Sopenharmony_ci             */
10131cb0ef41Sopenharmony_ci            s->last_flush = -1;
10141cb0ef41Sopenharmony_ci            return Z_OK;
10151cb0ef41Sopenharmony_ci        }
10161cb0ef41Sopenharmony_ci
10171cb0ef41Sopenharmony_ci    /* Make sure there is something to do and avoid duplicate consecutive
10181cb0ef41Sopenharmony_ci     * flushes. For repeated and useless calls with Z_FINISH, we keep
10191cb0ef41Sopenharmony_ci     * returning Z_STREAM_END instead of Z_BUF_ERROR.
10201cb0ef41Sopenharmony_ci     */
10211cb0ef41Sopenharmony_ci    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
10221cb0ef41Sopenharmony_ci               flush != Z_FINISH) {
10231cb0ef41Sopenharmony_ci        ERR_RETURN(strm, Z_BUF_ERROR);
10241cb0ef41Sopenharmony_ci    }
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci    /* User must not provide more input after the first FINISH: */
10271cb0ef41Sopenharmony_ci    if (s->status == FINISH_STATE && strm->avail_in != 0) {
10281cb0ef41Sopenharmony_ci        ERR_RETURN(strm, Z_BUF_ERROR);
10291cb0ef41Sopenharmony_ci    }
10301cb0ef41Sopenharmony_ci
10311cb0ef41Sopenharmony_ci    /* Write the header */
10321cb0ef41Sopenharmony_ci    if (s->status == INIT_STATE && s->wrap == 0)
10331cb0ef41Sopenharmony_ci        s->status = BUSY_STATE;
10341cb0ef41Sopenharmony_ci    if (s->status == INIT_STATE) {
10351cb0ef41Sopenharmony_ci        /* zlib header */
10361cb0ef41Sopenharmony_ci        uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8;
10371cb0ef41Sopenharmony_ci        uInt level_flags;
10381cb0ef41Sopenharmony_ci
10391cb0ef41Sopenharmony_ci        if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
10401cb0ef41Sopenharmony_ci            level_flags = 0;
10411cb0ef41Sopenharmony_ci        else if (s->level < 6)
10421cb0ef41Sopenharmony_ci            level_flags = 1;
10431cb0ef41Sopenharmony_ci        else if (s->level == 6)
10441cb0ef41Sopenharmony_ci            level_flags = 2;
10451cb0ef41Sopenharmony_ci        else
10461cb0ef41Sopenharmony_ci            level_flags = 3;
10471cb0ef41Sopenharmony_ci        header |= (level_flags << 6);
10481cb0ef41Sopenharmony_ci        if (s->strstart != 0) header |= PRESET_DICT;
10491cb0ef41Sopenharmony_ci        header += 31 - (header % 31);
10501cb0ef41Sopenharmony_ci
10511cb0ef41Sopenharmony_ci        putShortMSB(s, header);
10521cb0ef41Sopenharmony_ci
10531cb0ef41Sopenharmony_ci        /* Save the adler32 of the preset dictionary: */
10541cb0ef41Sopenharmony_ci        if (s->strstart != 0) {
10551cb0ef41Sopenharmony_ci            putShortMSB(s, (uInt)(strm->adler >> 16));
10561cb0ef41Sopenharmony_ci            putShortMSB(s, (uInt)(strm->adler & 0xffff));
10571cb0ef41Sopenharmony_ci        }
10581cb0ef41Sopenharmony_ci        strm->adler = adler32(0L, Z_NULL, 0);
10591cb0ef41Sopenharmony_ci        s->status = BUSY_STATE;
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ci        /* Compression must start with an empty pending buffer */
10621cb0ef41Sopenharmony_ci        flush_pending(strm);
10631cb0ef41Sopenharmony_ci        if (s->pending != 0) {
10641cb0ef41Sopenharmony_ci            s->last_flush = -1;
10651cb0ef41Sopenharmony_ci            return Z_OK;
10661cb0ef41Sopenharmony_ci        }
10671cb0ef41Sopenharmony_ci    }
10681cb0ef41Sopenharmony_ci#ifdef GZIP
10691cb0ef41Sopenharmony_ci    if (s->status == GZIP_STATE) {
10701cb0ef41Sopenharmony_ci        /* gzip header */
10711cb0ef41Sopenharmony_ci        crc_reset(s);
10721cb0ef41Sopenharmony_ci        put_byte(s, 31);
10731cb0ef41Sopenharmony_ci        put_byte(s, 139);
10741cb0ef41Sopenharmony_ci        put_byte(s, 8);
10751cb0ef41Sopenharmony_ci        if (s->gzhead == Z_NULL) {
10761cb0ef41Sopenharmony_ci            put_byte(s, 0);
10771cb0ef41Sopenharmony_ci            put_byte(s, 0);
10781cb0ef41Sopenharmony_ci            put_byte(s, 0);
10791cb0ef41Sopenharmony_ci            put_byte(s, 0);
10801cb0ef41Sopenharmony_ci            put_byte(s, 0);
10811cb0ef41Sopenharmony_ci            put_byte(s, s->level == 9 ? 2 :
10821cb0ef41Sopenharmony_ci                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
10831cb0ef41Sopenharmony_ci                      4 : 0));
10841cb0ef41Sopenharmony_ci            put_byte(s, OS_CODE);
10851cb0ef41Sopenharmony_ci            s->status = BUSY_STATE;
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ci            /* Compression must start with an empty pending buffer */
10881cb0ef41Sopenharmony_ci            flush_pending(strm);
10891cb0ef41Sopenharmony_ci            if (s->pending != 0) {
10901cb0ef41Sopenharmony_ci                s->last_flush = -1;
10911cb0ef41Sopenharmony_ci                return Z_OK;
10921cb0ef41Sopenharmony_ci            }
10931cb0ef41Sopenharmony_ci        }
10941cb0ef41Sopenharmony_ci        else {
10951cb0ef41Sopenharmony_ci            put_byte(s, (s->gzhead->text ? 1 : 0) +
10961cb0ef41Sopenharmony_ci                     (s->gzhead->hcrc ? 2 : 0) +
10971cb0ef41Sopenharmony_ci                     (s->gzhead->extra == Z_NULL ? 0 : 4) +
10981cb0ef41Sopenharmony_ci                     (s->gzhead->name == Z_NULL ? 0 : 8) +
10991cb0ef41Sopenharmony_ci                     (s->gzhead->comment == Z_NULL ? 0 : 16)
11001cb0ef41Sopenharmony_ci                     );
11011cb0ef41Sopenharmony_ci            put_byte(s, (Byte)(s->gzhead->time & 0xff));
11021cb0ef41Sopenharmony_ci            put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
11031cb0ef41Sopenharmony_ci            put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
11041cb0ef41Sopenharmony_ci            put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
11051cb0ef41Sopenharmony_ci            put_byte(s, s->level == 9 ? 2 :
11061cb0ef41Sopenharmony_ci                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
11071cb0ef41Sopenharmony_ci                      4 : 0));
11081cb0ef41Sopenharmony_ci            put_byte(s, s->gzhead->os & 0xff);
11091cb0ef41Sopenharmony_ci            if (s->gzhead->extra != Z_NULL) {
11101cb0ef41Sopenharmony_ci                put_byte(s, s->gzhead->extra_len & 0xff);
11111cb0ef41Sopenharmony_ci                put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
11121cb0ef41Sopenharmony_ci            }
11131cb0ef41Sopenharmony_ci            if (s->gzhead->hcrc)
11141cb0ef41Sopenharmony_ci                strm->adler = crc32(strm->adler, s->pending_buf,
11151cb0ef41Sopenharmony_ci                                    s->pending);
11161cb0ef41Sopenharmony_ci            s->gzindex = 0;
11171cb0ef41Sopenharmony_ci            s->status = EXTRA_STATE;
11181cb0ef41Sopenharmony_ci        }
11191cb0ef41Sopenharmony_ci    }
11201cb0ef41Sopenharmony_ci    if (s->status == EXTRA_STATE) {
11211cb0ef41Sopenharmony_ci        if (s->gzhead->extra != Z_NULL) {
11221cb0ef41Sopenharmony_ci            ulg beg = s->pending;   /* start of bytes to update crc */
11231cb0ef41Sopenharmony_ci            uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
11241cb0ef41Sopenharmony_ci            while (s->pending + left > s->pending_buf_size) {
11251cb0ef41Sopenharmony_ci                uInt copy = s->pending_buf_size - s->pending;
11261cb0ef41Sopenharmony_ci                zmemcpy(s->pending_buf + s->pending,
11271cb0ef41Sopenharmony_ci                        s->gzhead->extra + s->gzindex, copy);
11281cb0ef41Sopenharmony_ci                s->pending = s->pending_buf_size;
11291cb0ef41Sopenharmony_ci                HCRC_UPDATE(beg);
11301cb0ef41Sopenharmony_ci                s->gzindex += copy;
11311cb0ef41Sopenharmony_ci                flush_pending(strm);
11321cb0ef41Sopenharmony_ci                if (s->pending != 0) {
11331cb0ef41Sopenharmony_ci                    s->last_flush = -1;
11341cb0ef41Sopenharmony_ci                    return Z_OK;
11351cb0ef41Sopenharmony_ci                }
11361cb0ef41Sopenharmony_ci                beg = 0;
11371cb0ef41Sopenharmony_ci                left -= copy;
11381cb0ef41Sopenharmony_ci            }
11391cb0ef41Sopenharmony_ci            zmemcpy(s->pending_buf + s->pending,
11401cb0ef41Sopenharmony_ci                    s->gzhead->extra + s->gzindex, left);
11411cb0ef41Sopenharmony_ci            s->pending += left;
11421cb0ef41Sopenharmony_ci            HCRC_UPDATE(beg);
11431cb0ef41Sopenharmony_ci            s->gzindex = 0;
11441cb0ef41Sopenharmony_ci        }
11451cb0ef41Sopenharmony_ci        s->status = NAME_STATE;
11461cb0ef41Sopenharmony_ci    }
11471cb0ef41Sopenharmony_ci    if (s->status == NAME_STATE) {
11481cb0ef41Sopenharmony_ci        if (s->gzhead->name != Z_NULL) {
11491cb0ef41Sopenharmony_ci            ulg beg = s->pending;   /* start of bytes to update crc */
11501cb0ef41Sopenharmony_ci            int val;
11511cb0ef41Sopenharmony_ci            do {
11521cb0ef41Sopenharmony_ci                if (s->pending == s->pending_buf_size) {
11531cb0ef41Sopenharmony_ci                    HCRC_UPDATE(beg);
11541cb0ef41Sopenharmony_ci                    flush_pending(strm);
11551cb0ef41Sopenharmony_ci                    if (s->pending != 0) {
11561cb0ef41Sopenharmony_ci                        s->last_flush = -1;
11571cb0ef41Sopenharmony_ci                        return Z_OK;
11581cb0ef41Sopenharmony_ci                    }
11591cb0ef41Sopenharmony_ci                    beg = 0;
11601cb0ef41Sopenharmony_ci                }
11611cb0ef41Sopenharmony_ci                val = s->gzhead->name[s->gzindex++];
11621cb0ef41Sopenharmony_ci                put_byte(s, val);
11631cb0ef41Sopenharmony_ci            } while (val != 0);
11641cb0ef41Sopenharmony_ci            HCRC_UPDATE(beg);
11651cb0ef41Sopenharmony_ci            s->gzindex = 0;
11661cb0ef41Sopenharmony_ci        }
11671cb0ef41Sopenharmony_ci        s->status = COMMENT_STATE;
11681cb0ef41Sopenharmony_ci    }
11691cb0ef41Sopenharmony_ci    if (s->status == COMMENT_STATE) {
11701cb0ef41Sopenharmony_ci        if (s->gzhead->comment != Z_NULL) {
11711cb0ef41Sopenharmony_ci            ulg beg = s->pending;   /* start of bytes to update crc */
11721cb0ef41Sopenharmony_ci            int val;
11731cb0ef41Sopenharmony_ci            do {
11741cb0ef41Sopenharmony_ci                if (s->pending == s->pending_buf_size) {
11751cb0ef41Sopenharmony_ci                    HCRC_UPDATE(beg);
11761cb0ef41Sopenharmony_ci                    flush_pending(strm);
11771cb0ef41Sopenharmony_ci                    if (s->pending != 0) {
11781cb0ef41Sopenharmony_ci                        s->last_flush = -1;
11791cb0ef41Sopenharmony_ci                        return Z_OK;
11801cb0ef41Sopenharmony_ci                    }
11811cb0ef41Sopenharmony_ci                    beg = 0;
11821cb0ef41Sopenharmony_ci                }
11831cb0ef41Sopenharmony_ci                val = s->gzhead->comment[s->gzindex++];
11841cb0ef41Sopenharmony_ci                put_byte(s, val);
11851cb0ef41Sopenharmony_ci            } while (val != 0);
11861cb0ef41Sopenharmony_ci            HCRC_UPDATE(beg);
11871cb0ef41Sopenharmony_ci        }
11881cb0ef41Sopenharmony_ci        s->status = HCRC_STATE;
11891cb0ef41Sopenharmony_ci    }
11901cb0ef41Sopenharmony_ci    if (s->status == HCRC_STATE) {
11911cb0ef41Sopenharmony_ci        if (s->gzhead->hcrc) {
11921cb0ef41Sopenharmony_ci            if (s->pending + 2 > s->pending_buf_size) {
11931cb0ef41Sopenharmony_ci                flush_pending(strm);
11941cb0ef41Sopenharmony_ci                if (s->pending != 0) {
11951cb0ef41Sopenharmony_ci                    s->last_flush = -1;
11961cb0ef41Sopenharmony_ci                    return Z_OK;
11971cb0ef41Sopenharmony_ci                }
11981cb0ef41Sopenharmony_ci            }
11991cb0ef41Sopenharmony_ci            put_byte(s, (Byte)(strm->adler & 0xff));
12001cb0ef41Sopenharmony_ci            put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
12011cb0ef41Sopenharmony_ci            strm->adler = crc32(0L, Z_NULL, 0);
12021cb0ef41Sopenharmony_ci        }
12031cb0ef41Sopenharmony_ci        s->status = BUSY_STATE;
12041cb0ef41Sopenharmony_ci
12051cb0ef41Sopenharmony_ci        /* Compression must start with an empty pending buffer */
12061cb0ef41Sopenharmony_ci        flush_pending(strm);
12071cb0ef41Sopenharmony_ci        if (s->pending != 0) {
12081cb0ef41Sopenharmony_ci            s->last_flush = -1;
12091cb0ef41Sopenharmony_ci            return Z_OK;
12101cb0ef41Sopenharmony_ci        }
12111cb0ef41Sopenharmony_ci    }
12121cb0ef41Sopenharmony_ci#endif
12131cb0ef41Sopenharmony_ci
12141cb0ef41Sopenharmony_ci    /* Start a new block or continue the current one.
12151cb0ef41Sopenharmony_ci     */
12161cb0ef41Sopenharmony_ci    if (strm->avail_in != 0 || s->lookahead != 0 ||
12171cb0ef41Sopenharmony_ci        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
12181cb0ef41Sopenharmony_ci        block_state bstate;
12191cb0ef41Sopenharmony_ci
12201cb0ef41Sopenharmony_ci        bstate = s->level == 0 ? deflate_stored(s, flush) :
12211cb0ef41Sopenharmony_ci                 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
12221cb0ef41Sopenharmony_ci                 s->strategy == Z_RLE ? deflate_rle(s, flush) :
12231cb0ef41Sopenharmony_ci                 (*(configuration_table[s->level].func))(s, flush);
12241cb0ef41Sopenharmony_ci
12251cb0ef41Sopenharmony_ci        if (bstate == finish_started || bstate == finish_done) {
12261cb0ef41Sopenharmony_ci            s->status = FINISH_STATE;
12271cb0ef41Sopenharmony_ci        }
12281cb0ef41Sopenharmony_ci        if (bstate == need_more || bstate == finish_started) {
12291cb0ef41Sopenharmony_ci            if (strm->avail_out == 0) {
12301cb0ef41Sopenharmony_ci                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
12311cb0ef41Sopenharmony_ci            }
12321cb0ef41Sopenharmony_ci            return Z_OK;
12331cb0ef41Sopenharmony_ci            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
12341cb0ef41Sopenharmony_ci             * of deflate should use the same flush parameter to make sure
12351cb0ef41Sopenharmony_ci             * that the flush is complete. So we don't have to output an
12361cb0ef41Sopenharmony_ci             * empty block here, this will be done at next call. This also
12371cb0ef41Sopenharmony_ci             * ensures that for a very small output buffer, we emit at most
12381cb0ef41Sopenharmony_ci             * one empty block.
12391cb0ef41Sopenharmony_ci             */
12401cb0ef41Sopenharmony_ci        }
12411cb0ef41Sopenharmony_ci        if (bstate == block_done) {
12421cb0ef41Sopenharmony_ci            if (flush == Z_PARTIAL_FLUSH) {
12431cb0ef41Sopenharmony_ci                _tr_align(s);
12441cb0ef41Sopenharmony_ci            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
12451cb0ef41Sopenharmony_ci                _tr_stored_block(s, (char*)0, 0L, 0);
12461cb0ef41Sopenharmony_ci                /* For a full flush, this empty block will be recognized
12471cb0ef41Sopenharmony_ci                 * as a special marker by inflate_sync().
12481cb0ef41Sopenharmony_ci                 */
12491cb0ef41Sopenharmony_ci                if (flush == Z_FULL_FLUSH) {
12501cb0ef41Sopenharmony_ci                    CLEAR_HASH(s);             /* forget history */
12511cb0ef41Sopenharmony_ci                    if (s->lookahead == 0) {
12521cb0ef41Sopenharmony_ci                        s->strstart = 0;
12531cb0ef41Sopenharmony_ci                        s->block_start = 0L;
12541cb0ef41Sopenharmony_ci                        s->insert = 0;
12551cb0ef41Sopenharmony_ci                    }
12561cb0ef41Sopenharmony_ci                }
12571cb0ef41Sopenharmony_ci            }
12581cb0ef41Sopenharmony_ci            flush_pending(strm);
12591cb0ef41Sopenharmony_ci            if (strm->avail_out == 0) {
12601cb0ef41Sopenharmony_ci              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
12611cb0ef41Sopenharmony_ci              return Z_OK;
12621cb0ef41Sopenharmony_ci            }
12631cb0ef41Sopenharmony_ci        }
12641cb0ef41Sopenharmony_ci    }
12651cb0ef41Sopenharmony_ci
12661cb0ef41Sopenharmony_ci    if (flush != Z_FINISH) return Z_OK;
12671cb0ef41Sopenharmony_ci    if (s->wrap <= 0) return Z_STREAM_END;
12681cb0ef41Sopenharmony_ci
12691cb0ef41Sopenharmony_ci    /* Write the trailer */
12701cb0ef41Sopenharmony_ci#ifdef GZIP
12711cb0ef41Sopenharmony_ci    if (s->wrap == 2) {
12721cb0ef41Sopenharmony_ci        crc_finalize(s);
12731cb0ef41Sopenharmony_ci        put_byte(s, (Byte)(strm->adler & 0xff));
12741cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
12751cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
12761cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
12771cb0ef41Sopenharmony_ci        put_byte(s, (Byte)(strm->total_in & 0xff));
12781cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
12791cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
12801cb0ef41Sopenharmony_ci        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
12811cb0ef41Sopenharmony_ci    }
12821cb0ef41Sopenharmony_ci    else
12831cb0ef41Sopenharmony_ci#endif
12841cb0ef41Sopenharmony_ci    {
12851cb0ef41Sopenharmony_ci        putShortMSB(s, (uInt)(strm->adler >> 16));
12861cb0ef41Sopenharmony_ci        putShortMSB(s, (uInt)(strm->adler & 0xffff));
12871cb0ef41Sopenharmony_ci    }
12881cb0ef41Sopenharmony_ci    flush_pending(strm);
12891cb0ef41Sopenharmony_ci    /* If avail_out is zero, the application will call deflate again
12901cb0ef41Sopenharmony_ci     * to flush the rest.
12911cb0ef41Sopenharmony_ci     */
12921cb0ef41Sopenharmony_ci    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
12931cb0ef41Sopenharmony_ci    return s->pending != 0 ? Z_OK : Z_STREAM_END;
12941cb0ef41Sopenharmony_ci}
12951cb0ef41Sopenharmony_ci
12961cb0ef41Sopenharmony_ci/* ========================================================================= */
12971cb0ef41Sopenharmony_ciint ZEXPORT deflateEnd(z_streamp strm) {
12981cb0ef41Sopenharmony_ci    int status;
12991cb0ef41Sopenharmony_ci
13001cb0ef41Sopenharmony_ci    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
13011cb0ef41Sopenharmony_ci
13021cb0ef41Sopenharmony_ci    status = strm->state->status;
13031cb0ef41Sopenharmony_ci
13041cb0ef41Sopenharmony_ci    /* Deallocate in reverse order of allocations: */
13051cb0ef41Sopenharmony_ci    TRY_FREE(strm, strm->state->pending_buf);
13061cb0ef41Sopenharmony_ci    TRY_FREE(strm, strm->state->head);
13071cb0ef41Sopenharmony_ci    TRY_FREE(strm, strm->state->prev);
13081cb0ef41Sopenharmony_ci    TRY_FREE(strm, strm->state->window);
13091cb0ef41Sopenharmony_ci
13101cb0ef41Sopenharmony_ci    ZFREE(strm, strm->state);
13111cb0ef41Sopenharmony_ci    strm->state = Z_NULL;
13121cb0ef41Sopenharmony_ci
13131cb0ef41Sopenharmony_ci    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
13141cb0ef41Sopenharmony_ci}
13151cb0ef41Sopenharmony_ci
13161cb0ef41Sopenharmony_ci/* =========================================================================
13171cb0ef41Sopenharmony_ci * Copy the source state to the destination state.
13181cb0ef41Sopenharmony_ci * To simplify the source, this is not supported for 16-bit MSDOS (which
13191cb0ef41Sopenharmony_ci * doesn't have enough memory anyway to duplicate compression states).
13201cb0ef41Sopenharmony_ci */
13211cb0ef41Sopenharmony_ciint ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
13221cb0ef41Sopenharmony_ci#ifdef MAXSEG_64K
13231cb0ef41Sopenharmony_ci    (void)dest;
13241cb0ef41Sopenharmony_ci    (void)source;
13251cb0ef41Sopenharmony_ci    return Z_STREAM_ERROR;
13261cb0ef41Sopenharmony_ci#else
13271cb0ef41Sopenharmony_ci    deflate_state *ds;
13281cb0ef41Sopenharmony_ci    deflate_state *ss;
13291cb0ef41Sopenharmony_ci
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_ci    if (deflateStateCheck(source) || dest == Z_NULL) {
13321cb0ef41Sopenharmony_ci        return Z_STREAM_ERROR;
13331cb0ef41Sopenharmony_ci    }
13341cb0ef41Sopenharmony_ci
13351cb0ef41Sopenharmony_ci    ss = source->state;
13361cb0ef41Sopenharmony_ci
13371cb0ef41Sopenharmony_ci    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ci    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
13401cb0ef41Sopenharmony_ci    if (ds == Z_NULL) return Z_MEM_ERROR;
13411cb0ef41Sopenharmony_ci    dest->state = (struct internal_state FAR *) ds;
13421cb0ef41Sopenharmony_ci    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
13431cb0ef41Sopenharmony_ci    ds->strm = dest;
13441cb0ef41Sopenharmony_ci
13451cb0ef41Sopenharmony_ci    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
13461cb0ef41Sopenharmony_ci    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
13471cb0ef41Sopenharmony_ci    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
13481cb0ef41Sopenharmony_ci#ifdef LIT_MEM
13491cb0ef41Sopenharmony_ci    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 5);
13501cb0ef41Sopenharmony_ci#else
13511cb0ef41Sopenharmony_ci    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
13521cb0ef41Sopenharmony_ci#endif
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ci    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
13551cb0ef41Sopenharmony_ci        ds->pending_buf == Z_NULL) {
13561cb0ef41Sopenharmony_ci        deflateEnd (dest);
13571cb0ef41Sopenharmony_ci        return Z_MEM_ERROR;
13581cb0ef41Sopenharmony_ci    }
13591cb0ef41Sopenharmony_ci    /* following zmemcpy do not work for 16-bit MSDOS */
13601cb0ef41Sopenharmony_ci    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
13611cb0ef41Sopenharmony_ci    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
13621cb0ef41Sopenharmony_ci    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
13631cb0ef41Sopenharmony_ci#ifdef LIT_MEM
13641cb0ef41Sopenharmony_ci    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->lit_bufsize * 5);
13651cb0ef41Sopenharmony_ci#else
13661cb0ef41Sopenharmony_ci    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
13671cb0ef41Sopenharmony_ci#endif
13681cb0ef41Sopenharmony_ci
13691cb0ef41Sopenharmony_ci    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
13701cb0ef41Sopenharmony_ci#ifdef LIT_MEM
13711cb0ef41Sopenharmony_ci    ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
13721cb0ef41Sopenharmony_ci    ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
13731cb0ef41Sopenharmony_ci#else
13741cb0ef41Sopenharmony_ci    ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
13751cb0ef41Sopenharmony_ci#endif
13761cb0ef41Sopenharmony_ci
13771cb0ef41Sopenharmony_ci    ds->l_desc.dyn_tree = ds->dyn_ltree;
13781cb0ef41Sopenharmony_ci    ds->d_desc.dyn_tree = ds->dyn_dtree;
13791cb0ef41Sopenharmony_ci    ds->bl_desc.dyn_tree = ds->bl_tree;
13801cb0ef41Sopenharmony_ci
13811cb0ef41Sopenharmony_ci    return Z_OK;
13821cb0ef41Sopenharmony_ci#endif /* MAXSEG_64K */
13831cb0ef41Sopenharmony_ci}
13841cb0ef41Sopenharmony_ci
13851cb0ef41Sopenharmony_ci#ifndef FASTEST
13861cb0ef41Sopenharmony_ci/* ===========================================================================
13871cb0ef41Sopenharmony_ci * Set match_start to the longest match starting at the given string and
13881cb0ef41Sopenharmony_ci * return its length. Matches shorter or equal to prev_length are discarded,
13891cb0ef41Sopenharmony_ci * in which case the result is equal to prev_length and match_start is
13901cb0ef41Sopenharmony_ci * garbage.
13911cb0ef41Sopenharmony_ci * IN assertions: cur_match is the head of the hash chain for the current
13921cb0ef41Sopenharmony_ci *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
13931cb0ef41Sopenharmony_ci * OUT assertion: the match length is not greater than s->lookahead.
13941cb0ef41Sopenharmony_ci */
13951cb0ef41Sopenharmony_cilocal uInt longest_match(deflate_state *s, IPos cur_match) {
13961cb0ef41Sopenharmony_ci    unsigned chain_length = s->max_chain_length;/* max hash chain length */
13971cb0ef41Sopenharmony_ci    register Bytef *scan = s->window + s->strstart; /* current string */
13981cb0ef41Sopenharmony_ci    register Bytef *match;                      /* matched string */
13991cb0ef41Sopenharmony_ci    register int len;                           /* length of current match */
14001cb0ef41Sopenharmony_ci    int best_len = (int)s->prev_length;         /* best match length so far */
14011cb0ef41Sopenharmony_ci    int nice_match = s->nice_match;             /* stop if match long enough */
14021cb0ef41Sopenharmony_ci    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
14031cb0ef41Sopenharmony_ci        s->strstart - (IPos)MAX_DIST(s) : NIL;
14041cb0ef41Sopenharmony_ci    /* Stop when cur_match becomes <= limit. To simplify the code,
14051cb0ef41Sopenharmony_ci     * we prevent matches with the string of window index 0.
14061cb0ef41Sopenharmony_ci     */
14071cb0ef41Sopenharmony_ci    Posf *prev = s->prev;
14081cb0ef41Sopenharmony_ci    uInt wmask = s->w_mask;
14091cb0ef41Sopenharmony_ci
14101cb0ef41Sopenharmony_ci#ifdef UNALIGNED_OK
14111cb0ef41Sopenharmony_ci    /* Compare two bytes at a time. Note: this is not always beneficial.
14121cb0ef41Sopenharmony_ci     * Try with and without -DUNALIGNED_OK to check.
14131cb0ef41Sopenharmony_ci     */
14141cb0ef41Sopenharmony_ci    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
14151cb0ef41Sopenharmony_ci    register ush scan_start = *(ushf*)scan;
14161cb0ef41Sopenharmony_ci    register ush scan_end   = *(ushf*)(scan + best_len - 1);
14171cb0ef41Sopenharmony_ci#else
14181cb0ef41Sopenharmony_ci    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
14191cb0ef41Sopenharmony_ci    register Byte scan_end1  = scan[best_len - 1];
14201cb0ef41Sopenharmony_ci    register Byte scan_end   = scan[best_len];
14211cb0ef41Sopenharmony_ci#endif
14221cb0ef41Sopenharmony_ci
14231cb0ef41Sopenharmony_ci    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
14241cb0ef41Sopenharmony_ci     * It is easy to get rid of this optimization if necessary.
14251cb0ef41Sopenharmony_ci     */
14261cb0ef41Sopenharmony_ci    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
14271cb0ef41Sopenharmony_ci
14281cb0ef41Sopenharmony_ci    /* Do not waste too much time if we already have a good match: */
14291cb0ef41Sopenharmony_ci    if (s->prev_length >= s->good_match) {
14301cb0ef41Sopenharmony_ci        chain_length >>= 2;
14311cb0ef41Sopenharmony_ci    }
14321cb0ef41Sopenharmony_ci    /* Do not look for matches beyond the end of the input. This is necessary
14331cb0ef41Sopenharmony_ci     * to make deflate deterministic.
14341cb0ef41Sopenharmony_ci     */
14351cb0ef41Sopenharmony_ci    if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
14361cb0ef41Sopenharmony_ci
14371cb0ef41Sopenharmony_ci    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
14381cb0ef41Sopenharmony_ci           "need lookahead");
14391cb0ef41Sopenharmony_ci
14401cb0ef41Sopenharmony_ci    do {
14411cb0ef41Sopenharmony_ci        Assert(cur_match < s->strstart, "no future");
14421cb0ef41Sopenharmony_ci        match = s->window + cur_match;
14431cb0ef41Sopenharmony_ci
14441cb0ef41Sopenharmony_ci        /* Skip to next match if the match length cannot increase
14451cb0ef41Sopenharmony_ci         * or if the match length is less than 2.  Note that the checks below
14461cb0ef41Sopenharmony_ci         * for insufficient lookahead only occur occasionally for performance
14471cb0ef41Sopenharmony_ci         * reasons.  Therefore uninitialized memory will be accessed, and
14481cb0ef41Sopenharmony_ci         * conditional jumps will be made that depend on those values.
14491cb0ef41Sopenharmony_ci         * However the length of the match is limited to the lookahead, so
14501cb0ef41Sopenharmony_ci         * the output of deflate is not affected by the uninitialized values.
14511cb0ef41Sopenharmony_ci         */
14521cb0ef41Sopenharmony_ci#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
14531cb0ef41Sopenharmony_ci        /* This code assumes sizeof(unsigned short) == 2. Do not use
14541cb0ef41Sopenharmony_ci         * UNALIGNED_OK if your compiler uses a different size.
14551cb0ef41Sopenharmony_ci         */
14561cb0ef41Sopenharmony_ci        if (*(ushf*)(match + best_len - 1) != scan_end ||
14571cb0ef41Sopenharmony_ci            *(ushf*)match != scan_start) continue;
14581cb0ef41Sopenharmony_ci
14591cb0ef41Sopenharmony_ci        /* It is not necessary to compare scan[2] and match[2] since they are
14601cb0ef41Sopenharmony_ci         * always equal when the other bytes match, given that the hash keys
14611cb0ef41Sopenharmony_ci         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
14621cb0ef41Sopenharmony_ci         * strstart + 3, + 5, up to strstart + 257. We check for insufficient
14631cb0ef41Sopenharmony_ci         * lookahead only every 4th comparison; the 128th check will be made
14641cb0ef41Sopenharmony_ci         * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is
14651cb0ef41Sopenharmony_ci         * necessary to put more guard bytes at the end of the window, or
14661cb0ef41Sopenharmony_ci         * to check more often for insufficient lookahead.
14671cb0ef41Sopenharmony_ci         */
14681cb0ef41Sopenharmony_ci        if (!s->chromium_zlib_hash) {
14691cb0ef41Sopenharmony_ci          Assert(scan[2] == match[2], "scan[2]?");
14701cb0ef41Sopenharmony_ci        } else {
14711cb0ef41Sopenharmony_ci          /* When using CRC hashing, scan[2] and match[2] may mismatch, but in
14721cb0ef41Sopenharmony_ci           * that case at least one of the other hashed bytes will mismatch
14731cb0ef41Sopenharmony_ci           * also. Bytes 0 and 1 were already checked above, and we know there
14741cb0ef41Sopenharmony_ci           * are at least four bytes to check otherwise the mismatch would have
14751cb0ef41Sopenharmony_ci           * been found by the scan_end comparison above, so: */
14761cb0ef41Sopenharmony_ci          Assert(scan[2] == match[2] || scan[3] != match[3], "scan[2]??");
14771cb0ef41Sopenharmony_ci        }
14781cb0ef41Sopenharmony_ci        scan++, match++;
14791cb0ef41Sopenharmony_ci        do {
14801cb0ef41Sopenharmony_ci        } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
14811cb0ef41Sopenharmony_ci                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
14821cb0ef41Sopenharmony_ci                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
14831cb0ef41Sopenharmony_ci                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
14841cb0ef41Sopenharmony_ci                 scan < strend);
14851cb0ef41Sopenharmony_ci        /* The funny "do {}" generates better code on most compilers */
14861cb0ef41Sopenharmony_ci
14871cb0ef41Sopenharmony_ci        /* Here, scan <= window + strstart + 257 */
14881cb0ef41Sopenharmony_ci        Assert(scan <= s->window+(unsigned)(s->window_size - 1),
14891cb0ef41Sopenharmony_ci               "wild scan");
14901cb0ef41Sopenharmony_ci        if (*scan == *match) scan++;
14911cb0ef41Sopenharmony_ci
14921cb0ef41Sopenharmony_ci        len = (MAX_MATCH - 1) - (int)(strend - scan);
14931cb0ef41Sopenharmony_ci        scan = strend - (MAX_MATCH-1);
14941cb0ef41Sopenharmony_ci
14951cb0ef41Sopenharmony_ci#else /* UNALIGNED_OK */
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_ci        if (match[best_len]   != scan_end  ||
14981cb0ef41Sopenharmony_ci            match[best_len - 1] != scan_end1 ||
14991cb0ef41Sopenharmony_ci            *match            != *scan     ||
15001cb0ef41Sopenharmony_ci            *++match          != scan[1])      continue;
15011cb0ef41Sopenharmony_ci
15021cb0ef41Sopenharmony_ci        /* The check at best_len - 1 can be removed because it will be made
15031cb0ef41Sopenharmony_ci         * again later. (This heuristic is not always a win.)
15041cb0ef41Sopenharmony_ci         * It is not necessary to compare scan[2] and match[2] since they
15051cb0ef41Sopenharmony_ci         * are always equal when the other bytes match, given that
15061cb0ef41Sopenharmony_ci         * the hash keys are equal and that HASH_BITS >= 8.
15071cb0ef41Sopenharmony_ci         */
15081cb0ef41Sopenharmony_ci        scan += 2, match++;
15091cb0ef41Sopenharmony_ci        if (!s->chromium_zlib_hash) {
15101cb0ef41Sopenharmony_ci          Assert(*scan == *match, "match[2]?");
15111cb0ef41Sopenharmony_ci        } else {
15121cb0ef41Sopenharmony_ci          /* When using CRC hashing, scan[2] and match[2] may mismatch, but in
15131cb0ef41Sopenharmony_ci           * that case at least one of the other hashed bytes will mismatch
15141cb0ef41Sopenharmony_ci           * also. Bytes 0 and 1 were already checked above, and we know there
15151cb0ef41Sopenharmony_ci           * are at least four bytes to check otherwise the mismatch would have
15161cb0ef41Sopenharmony_ci           * been found by the scan_end comparison above, so: */
15171cb0ef41Sopenharmony_ci          Assert(*scan == *match || scan[1] != match[1], "match[2]??");
15181cb0ef41Sopenharmony_ci        }
15191cb0ef41Sopenharmony_ci
15201cb0ef41Sopenharmony_ci        /* We check for insufficient lookahead only every 8th comparison;
15211cb0ef41Sopenharmony_ci         * the 256th check will be made at strstart + 258.
15221cb0ef41Sopenharmony_ci         */
15231cb0ef41Sopenharmony_ci        do {
15241cb0ef41Sopenharmony_ci        } while (*++scan == *++match && *++scan == *++match &&
15251cb0ef41Sopenharmony_ci                 *++scan == *++match && *++scan == *++match &&
15261cb0ef41Sopenharmony_ci                 *++scan == *++match && *++scan == *++match &&
15271cb0ef41Sopenharmony_ci                 *++scan == *++match && *++scan == *++match &&
15281cb0ef41Sopenharmony_ci                 scan < strend);
15291cb0ef41Sopenharmony_ci
15301cb0ef41Sopenharmony_ci        Assert(scan <= s->window + (unsigned)(s->window_size - 1),
15311cb0ef41Sopenharmony_ci               "wild scan");
15321cb0ef41Sopenharmony_ci
15331cb0ef41Sopenharmony_ci        len = MAX_MATCH - (int)(strend - scan);
15341cb0ef41Sopenharmony_ci        scan = strend - MAX_MATCH;
15351cb0ef41Sopenharmony_ci
15361cb0ef41Sopenharmony_ci#endif /* UNALIGNED_OK */
15371cb0ef41Sopenharmony_ci
15381cb0ef41Sopenharmony_ci        if (len > best_len) {
15391cb0ef41Sopenharmony_ci            s->match_start = cur_match;
15401cb0ef41Sopenharmony_ci            best_len = len;
15411cb0ef41Sopenharmony_ci            if (len >= nice_match) break;
15421cb0ef41Sopenharmony_ci#ifdef UNALIGNED_OK
15431cb0ef41Sopenharmony_ci            scan_end = *(ushf*)(scan + best_len - 1);
15441cb0ef41Sopenharmony_ci#else
15451cb0ef41Sopenharmony_ci            scan_end1  = scan[best_len - 1];
15461cb0ef41Sopenharmony_ci            scan_end   = scan[best_len];
15471cb0ef41Sopenharmony_ci#endif
15481cb0ef41Sopenharmony_ci        }
15491cb0ef41Sopenharmony_ci    } while ((cur_match = prev[cur_match & wmask]) > limit
15501cb0ef41Sopenharmony_ci             && --chain_length != 0);
15511cb0ef41Sopenharmony_ci
15521cb0ef41Sopenharmony_ci    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15531cb0ef41Sopenharmony_ci    return s->lookahead;
15541cb0ef41Sopenharmony_ci}
15551cb0ef41Sopenharmony_ci
15561cb0ef41Sopenharmony_ci#else /* FASTEST */
15571cb0ef41Sopenharmony_ci
15581cb0ef41Sopenharmony_ci/* ---------------------------------------------------------------------------
15591cb0ef41Sopenharmony_ci * Optimized version for FASTEST only
15601cb0ef41Sopenharmony_ci */
15611cb0ef41Sopenharmony_cilocal uInt longest_match(deflate_state *s, IPos cur_match) {
15621cb0ef41Sopenharmony_ci    register Bytef *scan = s->window + s->strstart; /* current string */
15631cb0ef41Sopenharmony_ci    register Bytef *match;                       /* matched string */
15641cb0ef41Sopenharmony_ci    register int len;                           /* length of current match */
15651cb0ef41Sopenharmony_ci    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15661cb0ef41Sopenharmony_ci
15671cb0ef41Sopenharmony_ci    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15681cb0ef41Sopenharmony_ci     * It is easy to get rid of this optimization if necessary.
15691cb0ef41Sopenharmony_ci     */
15701cb0ef41Sopenharmony_ci    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15711cb0ef41Sopenharmony_ci
15721cb0ef41Sopenharmony_ci    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
15731cb0ef41Sopenharmony_ci           "need lookahead");
15741cb0ef41Sopenharmony_ci
15751cb0ef41Sopenharmony_ci    Assert(cur_match < s->strstart, "no future");
15761cb0ef41Sopenharmony_ci
15771cb0ef41Sopenharmony_ci    match = s->window + cur_match;
15781cb0ef41Sopenharmony_ci
15791cb0ef41Sopenharmony_ci    /* Return failure if the match length is less than 2:
15801cb0ef41Sopenharmony_ci     */
15811cb0ef41Sopenharmony_ci    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15821cb0ef41Sopenharmony_ci
15831cb0ef41Sopenharmony_ci    /* The check at best_len - 1 can be removed because it will be made
15841cb0ef41Sopenharmony_ci     * again later. (This heuristic is not always a win.)
15851cb0ef41Sopenharmony_ci     * It is not necessary to compare scan[2] and match[2] since they
15861cb0ef41Sopenharmony_ci     * are always equal when the other bytes match, given that
15871cb0ef41Sopenharmony_ci     * the hash keys are equal and that HASH_BITS >= 8.
15881cb0ef41Sopenharmony_ci     */
15891cb0ef41Sopenharmony_ci    scan += 2, match += 2;
15901cb0ef41Sopenharmony_ci    Assert(*scan == *match, "match[2]?");
15911cb0ef41Sopenharmony_ci
15921cb0ef41Sopenharmony_ci    /* We check for insufficient lookahead only every 8th comparison;
15931cb0ef41Sopenharmony_ci     * the 256th check will be made at strstart + 258.
15941cb0ef41Sopenharmony_ci     */
15951cb0ef41Sopenharmony_ci    do {
15961cb0ef41Sopenharmony_ci    } while (*++scan == *++match && *++scan == *++match &&
15971cb0ef41Sopenharmony_ci             *++scan == *++match && *++scan == *++match &&
15981cb0ef41Sopenharmony_ci             *++scan == *++match && *++scan == *++match &&
15991cb0ef41Sopenharmony_ci             *++scan == *++match && *++scan == *++match &&
16001cb0ef41Sopenharmony_ci             scan < strend);
16011cb0ef41Sopenharmony_ci
16021cb0ef41Sopenharmony_ci    Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan");
16031cb0ef41Sopenharmony_ci
16041cb0ef41Sopenharmony_ci    len = MAX_MATCH - (int)(strend - scan);
16051cb0ef41Sopenharmony_ci
16061cb0ef41Sopenharmony_ci    if (len < MIN_MATCH) return MIN_MATCH - 1;
16071cb0ef41Sopenharmony_ci
16081cb0ef41Sopenharmony_ci    s->match_start = cur_match;
16091cb0ef41Sopenharmony_ci    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
16101cb0ef41Sopenharmony_ci}
16111cb0ef41Sopenharmony_ci
16121cb0ef41Sopenharmony_ci#endif /* FASTEST */
16131cb0ef41Sopenharmony_ci
16141cb0ef41Sopenharmony_ci#ifdef ZLIB_DEBUG
16151cb0ef41Sopenharmony_ci
16161cb0ef41Sopenharmony_ci#define EQUAL 0
16171cb0ef41Sopenharmony_ci/* result of memcmp for equal strings */
16181cb0ef41Sopenharmony_ci
16191cb0ef41Sopenharmony_ci/* ===========================================================================
16201cb0ef41Sopenharmony_ci * Check that the match at match_start is indeed a match.
16211cb0ef41Sopenharmony_ci */
16221cb0ef41Sopenharmony_cilocal void check_match(deflate_state *s, IPos start, IPos match, int length) {
16231cb0ef41Sopenharmony_ci    /* check that the match is indeed a match */
16241cb0ef41Sopenharmony_ci    if (zmemcmp(s->window + match,
16251cb0ef41Sopenharmony_ci                s->window + start, length) != EQUAL) {
16261cb0ef41Sopenharmony_ci        fprintf(stderr, " start %u, match %u, length %d\n",
16271cb0ef41Sopenharmony_ci                start, match, length);
16281cb0ef41Sopenharmony_ci        do {
16291cb0ef41Sopenharmony_ci            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
16301cb0ef41Sopenharmony_ci        } while (--length != 0);
16311cb0ef41Sopenharmony_ci        z_error("invalid match");
16321cb0ef41Sopenharmony_ci    }
16331cb0ef41Sopenharmony_ci    if (z_verbose > 1) {
16341cb0ef41Sopenharmony_ci        fprintf(stderr,"\\[%d,%d]", start - match, length);
16351cb0ef41Sopenharmony_ci        do { putc(s->window[start++], stderr); } while (--length != 0);
16361cb0ef41Sopenharmony_ci    }
16371cb0ef41Sopenharmony_ci}
16381cb0ef41Sopenharmony_ci#else
16391cb0ef41Sopenharmony_ci#  define check_match(s, start, match, length)
16401cb0ef41Sopenharmony_ci#endif /* ZLIB_DEBUG */
16411cb0ef41Sopenharmony_ci
16421cb0ef41Sopenharmony_ci/* ===========================================================================
16431cb0ef41Sopenharmony_ci * Flush the current block, with given end-of-file flag.
16441cb0ef41Sopenharmony_ci * IN assertion: strstart is set to the end of the current match.
16451cb0ef41Sopenharmony_ci */
16461cb0ef41Sopenharmony_ci#define FLUSH_BLOCK_ONLY(s, last) { \
16471cb0ef41Sopenharmony_ci   _tr_flush_block(s, (s->block_start >= 0L ? \
16481cb0ef41Sopenharmony_ci                   (charf *)&s->window[(unsigned)s->block_start] : \
16491cb0ef41Sopenharmony_ci                   (charf *)Z_NULL), \
16501cb0ef41Sopenharmony_ci                (ulg)((long)s->strstart - s->block_start), \
16511cb0ef41Sopenharmony_ci                (last)); \
16521cb0ef41Sopenharmony_ci   s->block_start = s->strstart; \
16531cb0ef41Sopenharmony_ci   flush_pending(s->strm); \
16541cb0ef41Sopenharmony_ci   Tracev((stderr,"[FLUSH]")); \
16551cb0ef41Sopenharmony_ci}
16561cb0ef41Sopenharmony_ci
16571cb0ef41Sopenharmony_ci/* Same but force premature exit if necessary. */
16581cb0ef41Sopenharmony_ci#define FLUSH_BLOCK(s, last) { \
16591cb0ef41Sopenharmony_ci   FLUSH_BLOCK_ONLY(s, last); \
16601cb0ef41Sopenharmony_ci   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
16611cb0ef41Sopenharmony_ci}
16621cb0ef41Sopenharmony_ci
16631cb0ef41Sopenharmony_ci/* Maximum stored block length in deflate format (not including header). */
16641cb0ef41Sopenharmony_ci#define MAX_STORED 65535
16651cb0ef41Sopenharmony_ci
16661cb0ef41Sopenharmony_ci/* Minimum of a and b. */
16671cb0ef41Sopenharmony_ci#define MIN(a, b) ((a) > (b) ? (b) : (a))
16681cb0ef41Sopenharmony_ci
16691cb0ef41Sopenharmony_ci/* ===========================================================================
16701cb0ef41Sopenharmony_ci * Copy without compression as much as possible from the input stream, return
16711cb0ef41Sopenharmony_ci * the current block state.
16721cb0ef41Sopenharmony_ci *
16731cb0ef41Sopenharmony_ci * In case deflateParams() is used to later switch to a non-zero compression
16741cb0ef41Sopenharmony_ci * level, s->matches (otherwise unused when storing) keeps track of the number
16751cb0ef41Sopenharmony_ci * of hash table slides to perform. If s->matches is 1, then one hash table
16761cb0ef41Sopenharmony_ci * slide will be done when switching. If s->matches is 2, the maximum value
16771cb0ef41Sopenharmony_ci * allowed here, then the hash table will be cleared, since two or more slides
16781cb0ef41Sopenharmony_ci * is the same as a clear.
16791cb0ef41Sopenharmony_ci *
16801cb0ef41Sopenharmony_ci * deflate_stored() is written to minimize the number of times an input byte is
16811cb0ef41Sopenharmony_ci * copied. It is most efficient with large input and output buffers, which
16821cb0ef41Sopenharmony_ci * maximizes the opportunities to have a single copy from next_in to next_out.
16831cb0ef41Sopenharmony_ci */
16841cb0ef41Sopenharmony_cilocal block_state deflate_stored(deflate_state *s, int flush) {
16851cb0ef41Sopenharmony_ci    /* Smallest worthy block size when not flushing or finishing. By default
16861cb0ef41Sopenharmony_ci     * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
16871cb0ef41Sopenharmony_ci     * large input and output buffers, the stored block size will be larger.
16881cb0ef41Sopenharmony_ci     */
16891cb0ef41Sopenharmony_ci    unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
16901cb0ef41Sopenharmony_ci
16911cb0ef41Sopenharmony_ci    /* Copy as many min_block or larger stored blocks directly to next_out as
16921cb0ef41Sopenharmony_ci     * possible. If flushing, copy the remaining available input to next_out as
16931cb0ef41Sopenharmony_ci     * stored blocks, if there is enough space.
16941cb0ef41Sopenharmony_ci     */
16951cb0ef41Sopenharmony_ci    unsigned len, left, have, last = 0;
16961cb0ef41Sopenharmony_ci    unsigned used = s->strm->avail_in;
16971cb0ef41Sopenharmony_ci    do {
16981cb0ef41Sopenharmony_ci        /* Set len to the maximum size block that we can copy directly with the
16991cb0ef41Sopenharmony_ci         * available input data and output space. Set left to how much of that
17001cb0ef41Sopenharmony_ci         * would be copied from what's left in the window.
17011cb0ef41Sopenharmony_ci         */
17021cb0ef41Sopenharmony_ci        len = MAX_STORED;       /* maximum deflate stored block length */
17031cb0ef41Sopenharmony_ci        have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
17041cb0ef41Sopenharmony_ci        if (s->strm->avail_out < have)          /* need room for header */
17051cb0ef41Sopenharmony_ci            break;
17061cb0ef41Sopenharmony_ci            /* maximum stored block length that will fit in avail_out: */
17071cb0ef41Sopenharmony_ci        have = s->strm->avail_out - have;
17081cb0ef41Sopenharmony_ci        left = s->strstart - s->block_start;    /* bytes left in window */
17091cb0ef41Sopenharmony_ci        if (len > (ulg)left + s->strm->avail_in)
17101cb0ef41Sopenharmony_ci            len = left + s->strm->avail_in;     /* limit len to the input */
17111cb0ef41Sopenharmony_ci        if (len > have)
17121cb0ef41Sopenharmony_ci            len = have;                         /* limit len to the output */
17131cb0ef41Sopenharmony_ci
17141cb0ef41Sopenharmony_ci        /* If the stored block would be less than min_block in length, or if
17151cb0ef41Sopenharmony_ci         * unable to copy all of the available input when flushing, then try
17161cb0ef41Sopenharmony_ci         * copying to the window and the pending buffer instead. Also don't
17171cb0ef41Sopenharmony_ci         * write an empty block when flushing -- deflate() does that.
17181cb0ef41Sopenharmony_ci         */
17191cb0ef41Sopenharmony_ci        if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
17201cb0ef41Sopenharmony_ci                                flush == Z_NO_FLUSH ||
17211cb0ef41Sopenharmony_ci                                len != left + s->strm->avail_in))
17221cb0ef41Sopenharmony_ci            break;
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_ci        /* Make a dummy stored block in pending to get the header bytes,
17251cb0ef41Sopenharmony_ci         * including any pending bits. This also updates the debugging counts.
17261cb0ef41Sopenharmony_ci         */
17271cb0ef41Sopenharmony_ci        last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
17281cb0ef41Sopenharmony_ci        _tr_stored_block(s, (char *)0, 0L, last);
17291cb0ef41Sopenharmony_ci
17301cb0ef41Sopenharmony_ci        /* Replace the lengths in the dummy stored block with len. */
17311cb0ef41Sopenharmony_ci        s->pending_buf[s->pending - 4] = len;
17321cb0ef41Sopenharmony_ci        s->pending_buf[s->pending - 3] = len >> 8;
17331cb0ef41Sopenharmony_ci        s->pending_buf[s->pending - 2] = ~len;
17341cb0ef41Sopenharmony_ci        s->pending_buf[s->pending - 1] = ~len >> 8;
17351cb0ef41Sopenharmony_ci
17361cb0ef41Sopenharmony_ci        /* Write the stored block header bytes. */
17371cb0ef41Sopenharmony_ci        flush_pending(s->strm);
17381cb0ef41Sopenharmony_ci
17391cb0ef41Sopenharmony_ci#ifdef ZLIB_DEBUG
17401cb0ef41Sopenharmony_ci        /* Update debugging counts for the data about to be copied. */
17411cb0ef41Sopenharmony_ci        s->compressed_len += len << 3;
17421cb0ef41Sopenharmony_ci        s->bits_sent += len << 3;
17431cb0ef41Sopenharmony_ci#endif
17441cb0ef41Sopenharmony_ci
17451cb0ef41Sopenharmony_ci        /* Copy uncompressed bytes from the window to next_out. */
17461cb0ef41Sopenharmony_ci        if (left) {
17471cb0ef41Sopenharmony_ci            if (left > len)
17481cb0ef41Sopenharmony_ci                left = len;
17491cb0ef41Sopenharmony_ci            zmemcpy(s->strm->next_out, s->window + s->block_start, left);
17501cb0ef41Sopenharmony_ci            s->strm->next_out += left;
17511cb0ef41Sopenharmony_ci            s->strm->avail_out -= left;
17521cb0ef41Sopenharmony_ci            s->strm->total_out += left;
17531cb0ef41Sopenharmony_ci            s->block_start += left;
17541cb0ef41Sopenharmony_ci            len -= left;
17551cb0ef41Sopenharmony_ci        }
17561cb0ef41Sopenharmony_ci
17571cb0ef41Sopenharmony_ci        /* Copy uncompressed bytes directly from next_in to next_out, updating
17581cb0ef41Sopenharmony_ci         * the check value.
17591cb0ef41Sopenharmony_ci         */
17601cb0ef41Sopenharmony_ci        if (len) {
17611cb0ef41Sopenharmony_ci            read_buf(s->strm, s->strm->next_out, len);
17621cb0ef41Sopenharmony_ci            s->strm->next_out += len;
17631cb0ef41Sopenharmony_ci            s->strm->avail_out -= len;
17641cb0ef41Sopenharmony_ci            s->strm->total_out += len;
17651cb0ef41Sopenharmony_ci        }
17661cb0ef41Sopenharmony_ci    } while (last == 0);
17671cb0ef41Sopenharmony_ci
17681cb0ef41Sopenharmony_ci    /* Update the sliding window with the last s->w_size bytes of the copied
17691cb0ef41Sopenharmony_ci     * data, or append all of the copied data to the existing window if less
17701cb0ef41Sopenharmony_ci     * than s->w_size bytes were copied. Also update the number of bytes to
17711cb0ef41Sopenharmony_ci     * insert in the hash tables, in the event that deflateParams() switches to
17721cb0ef41Sopenharmony_ci     * a non-zero compression level.
17731cb0ef41Sopenharmony_ci     */
17741cb0ef41Sopenharmony_ci    used -= s->strm->avail_in;      /* number of input bytes directly copied */
17751cb0ef41Sopenharmony_ci    if (used) {
17761cb0ef41Sopenharmony_ci        /* If any input was used, then no unused input remains in the window,
17771cb0ef41Sopenharmony_ci         * therefore s->block_start == s->strstart.
17781cb0ef41Sopenharmony_ci         */
17791cb0ef41Sopenharmony_ci        if (used >= s->w_size) {    /* supplant the previous history */
17801cb0ef41Sopenharmony_ci            s->matches = 2;         /* clear hash */
17811cb0ef41Sopenharmony_ci            zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
17821cb0ef41Sopenharmony_ci            s->strstart = s->w_size;
17831cb0ef41Sopenharmony_ci            s->insert = s->strstart;
17841cb0ef41Sopenharmony_ci        }
17851cb0ef41Sopenharmony_ci        else {
17861cb0ef41Sopenharmony_ci            if (s->window_size - s->strstart <= used) {
17871cb0ef41Sopenharmony_ci                /* Slide the window down. */
17881cb0ef41Sopenharmony_ci                s->strstart -= s->w_size;
17891cb0ef41Sopenharmony_ci                zmemcpy(s->window, s->window + s->w_size, s->strstart);
17901cb0ef41Sopenharmony_ci                if (s->matches < 2)
17911cb0ef41Sopenharmony_ci                    s->matches++;   /* add a pending slide_hash() */
17921cb0ef41Sopenharmony_ci                if (s->insert > s->strstart)
17931cb0ef41Sopenharmony_ci                    s->insert = s->strstart;
17941cb0ef41Sopenharmony_ci            }
17951cb0ef41Sopenharmony_ci            zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
17961cb0ef41Sopenharmony_ci            s->strstart += used;
17971cb0ef41Sopenharmony_ci            s->insert += MIN(used, s->w_size - s->insert);
17981cb0ef41Sopenharmony_ci        }
17991cb0ef41Sopenharmony_ci        s->block_start = s->strstart;
18001cb0ef41Sopenharmony_ci    }
18011cb0ef41Sopenharmony_ci    if (s->high_water < s->strstart)
18021cb0ef41Sopenharmony_ci        s->high_water = s->strstart;
18031cb0ef41Sopenharmony_ci
18041cb0ef41Sopenharmony_ci    /* If the last block was written to next_out, then done. */
18051cb0ef41Sopenharmony_ci    if (last)
18061cb0ef41Sopenharmony_ci        return finish_done;
18071cb0ef41Sopenharmony_ci
18081cb0ef41Sopenharmony_ci    /* If flushing and all input has been consumed, then done. */
18091cb0ef41Sopenharmony_ci    if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
18101cb0ef41Sopenharmony_ci        s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
18111cb0ef41Sopenharmony_ci        return block_done;
18121cb0ef41Sopenharmony_ci
18131cb0ef41Sopenharmony_ci    /* Fill the window with any remaining input. */
18141cb0ef41Sopenharmony_ci    have = s->window_size - s->strstart;
18151cb0ef41Sopenharmony_ci    if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
18161cb0ef41Sopenharmony_ci        /* Slide the window down. */
18171cb0ef41Sopenharmony_ci        s->block_start -= s->w_size;
18181cb0ef41Sopenharmony_ci        s->strstart -= s->w_size;
18191cb0ef41Sopenharmony_ci        zmemcpy(s->window, s->window + s->w_size, s->strstart);
18201cb0ef41Sopenharmony_ci        if (s->matches < 2)
18211cb0ef41Sopenharmony_ci            s->matches++;           /* add a pending slide_hash() */
18221cb0ef41Sopenharmony_ci        have += s->w_size;          /* more space now */
18231cb0ef41Sopenharmony_ci        if (s->insert > s->strstart)
18241cb0ef41Sopenharmony_ci            s->insert = s->strstart;
18251cb0ef41Sopenharmony_ci    }
18261cb0ef41Sopenharmony_ci    if (have > s->strm->avail_in)
18271cb0ef41Sopenharmony_ci        have = s->strm->avail_in;
18281cb0ef41Sopenharmony_ci    if (have) {
18291cb0ef41Sopenharmony_ci        read_buf(s->strm, s->window + s->strstart, have);
18301cb0ef41Sopenharmony_ci        s->strstart += have;
18311cb0ef41Sopenharmony_ci        s->insert += MIN(have, s->w_size - s->insert);
18321cb0ef41Sopenharmony_ci    }
18331cb0ef41Sopenharmony_ci    if (s->high_water < s->strstart)
18341cb0ef41Sopenharmony_ci        s->high_water = s->strstart;
18351cb0ef41Sopenharmony_ci
18361cb0ef41Sopenharmony_ci    /* There was not enough avail_out to write a complete worthy or flushed
18371cb0ef41Sopenharmony_ci     * stored block to next_out. Write a stored block to pending instead, if we
18381cb0ef41Sopenharmony_ci     * have enough input for a worthy block, or if flushing and there is enough
18391cb0ef41Sopenharmony_ci     * room for the remaining input as a stored block in the pending buffer.
18401cb0ef41Sopenharmony_ci     */
18411cb0ef41Sopenharmony_ci    have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
18421cb0ef41Sopenharmony_ci        /* maximum stored block length that will fit in pending: */
18431cb0ef41Sopenharmony_ci    have = MIN(s->pending_buf_size - have, MAX_STORED);
18441cb0ef41Sopenharmony_ci    min_block = MIN(have, s->w_size);
18451cb0ef41Sopenharmony_ci    left = s->strstart - s->block_start;
18461cb0ef41Sopenharmony_ci    if (left >= min_block ||
18471cb0ef41Sopenharmony_ci        ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
18481cb0ef41Sopenharmony_ci         s->strm->avail_in == 0 && left <= have)) {
18491cb0ef41Sopenharmony_ci        len = MIN(left, have);
18501cb0ef41Sopenharmony_ci        last = flush == Z_FINISH && s->strm->avail_in == 0 &&
18511cb0ef41Sopenharmony_ci               len == left ? 1 : 0;
18521cb0ef41Sopenharmony_ci        _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
18531cb0ef41Sopenharmony_ci        s->block_start += len;
18541cb0ef41Sopenharmony_ci        flush_pending(s->strm);
18551cb0ef41Sopenharmony_ci    }
18561cb0ef41Sopenharmony_ci
18571cb0ef41Sopenharmony_ci    /* We've done all we can with the available input and output. */
18581cb0ef41Sopenharmony_ci    return last ? finish_started : need_more;
18591cb0ef41Sopenharmony_ci}
18601cb0ef41Sopenharmony_ci
18611cb0ef41Sopenharmony_ci/* ===========================================================================
18621cb0ef41Sopenharmony_ci * Compress as much as possible from the input stream, return the current
18631cb0ef41Sopenharmony_ci * block state.
18641cb0ef41Sopenharmony_ci * This function does not perform lazy evaluation of matches and inserts
18651cb0ef41Sopenharmony_ci * new strings in the dictionary only for unmatched strings or for short
18661cb0ef41Sopenharmony_ci * matches. It is used only for the fast compression options.
18671cb0ef41Sopenharmony_ci */
18681cb0ef41Sopenharmony_cilocal block_state deflate_fast(deflate_state *s, int flush) {
18691cb0ef41Sopenharmony_ci    IPos hash_head;       /* head of the hash chain */
18701cb0ef41Sopenharmony_ci    int bflush;           /* set if current block must be flushed */
18711cb0ef41Sopenharmony_ci
18721cb0ef41Sopenharmony_ci    for (;;) {
18731cb0ef41Sopenharmony_ci        /* Make sure that we always have enough lookahead, except
18741cb0ef41Sopenharmony_ci         * at the end of the input file. We need MAX_MATCH bytes
18751cb0ef41Sopenharmony_ci         * for the next match, plus MIN_MATCH bytes to insert the
18761cb0ef41Sopenharmony_ci         * string following the next match.
18771cb0ef41Sopenharmony_ci         */
18781cb0ef41Sopenharmony_ci        if (s->lookahead < MIN_LOOKAHEAD) {
18791cb0ef41Sopenharmony_ci            fill_window(s);
18801cb0ef41Sopenharmony_ci            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
18811cb0ef41Sopenharmony_ci                return need_more;
18821cb0ef41Sopenharmony_ci            }
18831cb0ef41Sopenharmony_ci            if (s->lookahead == 0) break; /* flush the current block */
18841cb0ef41Sopenharmony_ci        }
18851cb0ef41Sopenharmony_ci
18861cb0ef41Sopenharmony_ci        /* Insert the string window[strstart .. strstart + 2] in the
18871cb0ef41Sopenharmony_ci         * dictionary, and set hash_head to the head of the hash chain:
18881cb0ef41Sopenharmony_ci         */
18891cb0ef41Sopenharmony_ci        hash_head = NIL;
18901cb0ef41Sopenharmony_ci        if (s->lookahead >= MIN_MATCH) {
18911cb0ef41Sopenharmony_ci            hash_head = insert_string(s, s->strstart);
18921cb0ef41Sopenharmony_ci        }
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_ci        /* Find the longest match, discarding those <= prev_length.
18951cb0ef41Sopenharmony_ci         * At this point we have always match_length < MIN_MATCH
18961cb0ef41Sopenharmony_ci         */
18971cb0ef41Sopenharmony_ci        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
18981cb0ef41Sopenharmony_ci            /* To simplify the code, we prevent matches with the string
18991cb0ef41Sopenharmony_ci             * of window index 0 (in particular we have to avoid a match
19001cb0ef41Sopenharmony_ci             * of the string with itself at the start of the input file).
19011cb0ef41Sopenharmony_ci             */
19021cb0ef41Sopenharmony_ci            s->match_length = longest_match (s, hash_head);
19031cb0ef41Sopenharmony_ci            /* longest_match() sets match_start */
19041cb0ef41Sopenharmony_ci        }
19051cb0ef41Sopenharmony_ci        if (s->match_length >= MIN_MATCH) {
19061cb0ef41Sopenharmony_ci            check_match(s, s->strstart, s->match_start, s->match_length);
19071cb0ef41Sopenharmony_ci
19081cb0ef41Sopenharmony_ci            _tr_tally_dist(s, s->strstart - s->match_start,
19091cb0ef41Sopenharmony_ci                           s->match_length - MIN_MATCH, bflush);
19101cb0ef41Sopenharmony_ci
19111cb0ef41Sopenharmony_ci            s->lookahead -= s->match_length;
19121cb0ef41Sopenharmony_ci
19131cb0ef41Sopenharmony_ci            /* Insert new strings in the hash table only if the match length
19141cb0ef41Sopenharmony_ci             * is not too large. This saves time but degrades compression.
19151cb0ef41Sopenharmony_ci             */
19161cb0ef41Sopenharmony_ci#ifndef FASTEST
19171cb0ef41Sopenharmony_ci            if (s->match_length <= s->max_insert_length &&
19181cb0ef41Sopenharmony_ci                s->lookahead >= MIN_MATCH) {
19191cb0ef41Sopenharmony_ci                s->match_length--; /* string at strstart already in table */
19201cb0ef41Sopenharmony_ci                do {
19211cb0ef41Sopenharmony_ci                    s->strstart++;
19221cb0ef41Sopenharmony_ci                    hash_head = insert_string(s, s->strstart);
19231cb0ef41Sopenharmony_ci                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
19241cb0ef41Sopenharmony_ci                     * always MIN_MATCH bytes ahead.
19251cb0ef41Sopenharmony_ci                     */
19261cb0ef41Sopenharmony_ci                } while (--s->match_length != 0);
19271cb0ef41Sopenharmony_ci                s->strstart++;
19281cb0ef41Sopenharmony_ci            } else
19291cb0ef41Sopenharmony_ci#endif
19301cb0ef41Sopenharmony_ci            {
19311cb0ef41Sopenharmony_ci                s->strstart += s->match_length;
19321cb0ef41Sopenharmony_ci                s->match_length = 0;
19331cb0ef41Sopenharmony_ci
19341cb0ef41Sopenharmony_ci                if (!s->chromium_zlib_hash) {
19351cb0ef41Sopenharmony_ci                  s->ins_h = s->window[s->strstart];
19361cb0ef41Sopenharmony_ci                  UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]);
19371cb0ef41Sopenharmony_ci#if MIN_MATCH != 3
19381cb0ef41Sopenharmony_ci                  Call UPDATE_HASH() MIN_MATCH-3 more times
19391cb0ef41Sopenharmony_ci#endif
19401cb0ef41Sopenharmony_ci                  /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
19411cb0ef41Sopenharmony_ci                   * matter since it will be recomputed at next deflate call.
19421cb0ef41Sopenharmony_ci                   */
19431cb0ef41Sopenharmony_ci                }
19441cb0ef41Sopenharmony_ci            }
19451cb0ef41Sopenharmony_ci        } else {
19461cb0ef41Sopenharmony_ci            /* No match, output a literal byte */
19471cb0ef41Sopenharmony_ci            Tracevv((stderr,"%c", s->window[s->strstart]));
19481cb0ef41Sopenharmony_ci            _tr_tally_lit(s, s->window[s->strstart], bflush);
19491cb0ef41Sopenharmony_ci            s->lookahead--;
19501cb0ef41Sopenharmony_ci            s->strstart++;
19511cb0ef41Sopenharmony_ci        }
19521cb0ef41Sopenharmony_ci        if (bflush) FLUSH_BLOCK(s, 0);
19531cb0ef41Sopenharmony_ci    }
19541cb0ef41Sopenharmony_ci    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
19551cb0ef41Sopenharmony_ci    if (flush == Z_FINISH) {
19561cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 1);
19571cb0ef41Sopenharmony_ci        return finish_done;
19581cb0ef41Sopenharmony_ci    }
19591cb0ef41Sopenharmony_ci    if (s->sym_next)
19601cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 0);
19611cb0ef41Sopenharmony_ci    return block_done;
19621cb0ef41Sopenharmony_ci}
19631cb0ef41Sopenharmony_ci
19641cb0ef41Sopenharmony_ci#ifndef FASTEST
19651cb0ef41Sopenharmony_ci/* ===========================================================================
19661cb0ef41Sopenharmony_ci * Same as above, but achieves better compression. We use a lazy
19671cb0ef41Sopenharmony_ci * evaluation for matches: a match is finally adopted only if there is
19681cb0ef41Sopenharmony_ci * no better match at the next window position.
19691cb0ef41Sopenharmony_ci */
19701cb0ef41Sopenharmony_cilocal block_state deflate_slow(deflate_state *s, int flush) {
19711cb0ef41Sopenharmony_ci    IPos hash_head;          /* head of hash chain */
19721cb0ef41Sopenharmony_ci    int bflush;              /* set if current block must be flushed */
19731cb0ef41Sopenharmony_ci
19741cb0ef41Sopenharmony_ci    /* Process the input block. */
19751cb0ef41Sopenharmony_ci    for (;;) {
19761cb0ef41Sopenharmony_ci        /* Make sure that we always have enough lookahead, except
19771cb0ef41Sopenharmony_ci         * at the end of the input file. We need MAX_MATCH bytes
19781cb0ef41Sopenharmony_ci         * for the next match, plus MIN_MATCH bytes to insert the
19791cb0ef41Sopenharmony_ci         * string following the next match.
19801cb0ef41Sopenharmony_ci         */
19811cb0ef41Sopenharmony_ci        if (s->lookahead < MIN_LOOKAHEAD) {
19821cb0ef41Sopenharmony_ci            fill_window(s);
19831cb0ef41Sopenharmony_ci            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
19841cb0ef41Sopenharmony_ci                return need_more;
19851cb0ef41Sopenharmony_ci            }
19861cb0ef41Sopenharmony_ci            if (s->lookahead == 0) break; /* flush the current block */
19871cb0ef41Sopenharmony_ci        }
19881cb0ef41Sopenharmony_ci
19891cb0ef41Sopenharmony_ci        /* Insert the string window[strstart .. strstart + 2] in the
19901cb0ef41Sopenharmony_ci         * dictionary, and set hash_head to the head of the hash chain:
19911cb0ef41Sopenharmony_ci         */
19921cb0ef41Sopenharmony_ci        hash_head = NIL;
19931cb0ef41Sopenharmony_ci        if (s->lookahead >= MIN_MATCH) {
19941cb0ef41Sopenharmony_ci            hash_head = insert_string(s, s->strstart);
19951cb0ef41Sopenharmony_ci        }
19961cb0ef41Sopenharmony_ci
19971cb0ef41Sopenharmony_ci        /* Find the longest match, discarding those <= prev_length.
19981cb0ef41Sopenharmony_ci         */
19991cb0ef41Sopenharmony_ci        s->prev_length = s->match_length, s->prev_match = s->match_start;
20001cb0ef41Sopenharmony_ci        s->match_length = MIN_MATCH-1;
20011cb0ef41Sopenharmony_ci
20021cb0ef41Sopenharmony_ci        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
20031cb0ef41Sopenharmony_ci            s->strstart - hash_head <= MAX_DIST(s)) {
20041cb0ef41Sopenharmony_ci            /* To simplify the code, we prevent matches with the string
20051cb0ef41Sopenharmony_ci             * of window index 0 (in particular we have to avoid a match
20061cb0ef41Sopenharmony_ci             * of the string with itself at the start of the input file).
20071cb0ef41Sopenharmony_ci             */
20081cb0ef41Sopenharmony_ci            s->match_length = longest_match (s, hash_head);
20091cb0ef41Sopenharmony_ci            /* longest_match() sets match_start */
20101cb0ef41Sopenharmony_ci
20111cb0ef41Sopenharmony_ci            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
20121cb0ef41Sopenharmony_ci#if TOO_FAR <= 32767
20131cb0ef41Sopenharmony_ci                || (s->match_length == MIN_MATCH &&
20141cb0ef41Sopenharmony_ci                    s->strstart - s->match_start > TOO_FAR)
20151cb0ef41Sopenharmony_ci#endif
20161cb0ef41Sopenharmony_ci                )) {
20171cb0ef41Sopenharmony_ci
20181cb0ef41Sopenharmony_ci                /* If prev_match is also MIN_MATCH, match_start is garbage
20191cb0ef41Sopenharmony_ci                 * but we will ignore the current match anyway.
20201cb0ef41Sopenharmony_ci                 */
20211cb0ef41Sopenharmony_ci                s->match_length = MIN_MATCH-1;
20221cb0ef41Sopenharmony_ci            }
20231cb0ef41Sopenharmony_ci        }
20241cb0ef41Sopenharmony_ci        /* If there was a match at the previous step and the current
20251cb0ef41Sopenharmony_ci         * match is not better, output the previous match:
20261cb0ef41Sopenharmony_ci         */
20271cb0ef41Sopenharmony_ci        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
20281cb0ef41Sopenharmony_ci            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
20291cb0ef41Sopenharmony_ci            /* Do not insert strings in hash table beyond this. */
20301cb0ef41Sopenharmony_ci
20311cb0ef41Sopenharmony_ci            if (s->prev_match == -1) {
20321cb0ef41Sopenharmony_ci                /* The window has slid one byte past the previous match,
20331cb0ef41Sopenharmony_ci                 * so the first byte cannot be compared. */
20341cb0ef41Sopenharmony_ci                check_match(s, s->strstart, s->prev_match + 1, s->prev_length - 1);
20351cb0ef41Sopenharmony_ci            } else {
20361cb0ef41Sopenharmony_ci                check_match(s, s->strstart - 1, s->prev_match, s->prev_length);
20371cb0ef41Sopenharmony_ci            }
20381cb0ef41Sopenharmony_ci
20391cb0ef41Sopenharmony_ci            _tr_tally_dist(s, s->strstart - 1 - s->prev_match,
20401cb0ef41Sopenharmony_ci                           s->prev_length - MIN_MATCH, bflush);
20411cb0ef41Sopenharmony_ci
20421cb0ef41Sopenharmony_ci            /* Insert in hash table all strings up to the end of the match.
20431cb0ef41Sopenharmony_ci             * strstart - 1 and strstart are already inserted. If there is not
20441cb0ef41Sopenharmony_ci             * enough lookahead, the last two strings are not inserted in
20451cb0ef41Sopenharmony_ci             * the hash table.
20461cb0ef41Sopenharmony_ci             */
20471cb0ef41Sopenharmony_ci            s->lookahead -= s->prev_length - 1;
20481cb0ef41Sopenharmony_ci            s->prev_length -= 2;
20491cb0ef41Sopenharmony_ci            do {
20501cb0ef41Sopenharmony_ci                if (++s->strstart <= max_insert) {
20511cb0ef41Sopenharmony_ci                    hash_head = insert_string(s, s->strstart);
20521cb0ef41Sopenharmony_ci                }
20531cb0ef41Sopenharmony_ci            } while (--s->prev_length != 0);
20541cb0ef41Sopenharmony_ci            s->match_available = 0;
20551cb0ef41Sopenharmony_ci            s->match_length = MIN_MATCH-1;
20561cb0ef41Sopenharmony_ci            s->strstart++;
20571cb0ef41Sopenharmony_ci
20581cb0ef41Sopenharmony_ci            if (bflush) FLUSH_BLOCK(s, 0);
20591cb0ef41Sopenharmony_ci
20601cb0ef41Sopenharmony_ci        } else if (s->match_available) {
20611cb0ef41Sopenharmony_ci            /* If there was no match at the previous position, output a
20621cb0ef41Sopenharmony_ci             * single literal. If there was a match but the current match
20631cb0ef41Sopenharmony_ci             * is longer, truncate the previous match to a single literal.
20641cb0ef41Sopenharmony_ci             */
20651cb0ef41Sopenharmony_ci            Tracevv((stderr,"%c", s->window[s->strstart - 1]));
20661cb0ef41Sopenharmony_ci            _tr_tally_lit(s, s->window[s->strstart - 1], bflush);
20671cb0ef41Sopenharmony_ci            if (bflush) {
20681cb0ef41Sopenharmony_ci                FLUSH_BLOCK_ONLY(s, 0);
20691cb0ef41Sopenharmony_ci            }
20701cb0ef41Sopenharmony_ci            s->strstart++;
20711cb0ef41Sopenharmony_ci            s->lookahead--;
20721cb0ef41Sopenharmony_ci            if (s->strm->avail_out == 0) return need_more;
20731cb0ef41Sopenharmony_ci        } else {
20741cb0ef41Sopenharmony_ci            /* There is no previous match to compare with, wait for
20751cb0ef41Sopenharmony_ci             * the next step to decide.
20761cb0ef41Sopenharmony_ci             */
20771cb0ef41Sopenharmony_ci            s->match_available = 1;
20781cb0ef41Sopenharmony_ci            s->strstart++;
20791cb0ef41Sopenharmony_ci            s->lookahead--;
20801cb0ef41Sopenharmony_ci        }
20811cb0ef41Sopenharmony_ci    }
20821cb0ef41Sopenharmony_ci    Assert (flush != Z_NO_FLUSH, "no flush?");
20831cb0ef41Sopenharmony_ci    if (s->match_available) {
20841cb0ef41Sopenharmony_ci        Tracevv((stderr,"%c", s->window[s->strstart - 1]));
20851cb0ef41Sopenharmony_ci        _tr_tally_lit(s, s->window[s->strstart - 1], bflush);
20861cb0ef41Sopenharmony_ci        s->match_available = 0;
20871cb0ef41Sopenharmony_ci    }
20881cb0ef41Sopenharmony_ci    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
20891cb0ef41Sopenharmony_ci    if (flush == Z_FINISH) {
20901cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 1);
20911cb0ef41Sopenharmony_ci        return finish_done;
20921cb0ef41Sopenharmony_ci    }
20931cb0ef41Sopenharmony_ci    if (s->sym_next)
20941cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 0);
20951cb0ef41Sopenharmony_ci    return block_done;
20961cb0ef41Sopenharmony_ci}
20971cb0ef41Sopenharmony_ci#endif /* FASTEST */
20981cb0ef41Sopenharmony_ci
20991cb0ef41Sopenharmony_ci/* ===========================================================================
21001cb0ef41Sopenharmony_ci * For Z_RLE, simply look for runs of bytes, generate matches only of distance
21011cb0ef41Sopenharmony_ci * one.  Do not maintain a hash table.  (It will be regenerated if this run of
21021cb0ef41Sopenharmony_ci * deflate switches away from Z_RLE.)
21031cb0ef41Sopenharmony_ci */
21041cb0ef41Sopenharmony_cilocal block_state deflate_rle(deflate_state *s, int flush) {
21051cb0ef41Sopenharmony_ci    int bflush;             /* set if current block must be flushed */
21061cb0ef41Sopenharmony_ci    uInt prev;              /* byte at distance one to match */
21071cb0ef41Sopenharmony_ci    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
21081cb0ef41Sopenharmony_ci
21091cb0ef41Sopenharmony_ci    for (;;) {
21101cb0ef41Sopenharmony_ci        /* Make sure that we always have enough lookahead, except
21111cb0ef41Sopenharmony_ci         * at the end of the input file. We need MAX_MATCH bytes
21121cb0ef41Sopenharmony_ci         * for the longest run, plus one for the unrolled loop.
21131cb0ef41Sopenharmony_ci         */
21141cb0ef41Sopenharmony_ci        if (s->lookahead <= MAX_MATCH) {
21151cb0ef41Sopenharmony_ci            fill_window(s);
21161cb0ef41Sopenharmony_ci            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
21171cb0ef41Sopenharmony_ci                return need_more;
21181cb0ef41Sopenharmony_ci            }
21191cb0ef41Sopenharmony_ci            if (s->lookahead == 0) break; /* flush the current block */
21201cb0ef41Sopenharmony_ci        }
21211cb0ef41Sopenharmony_ci
21221cb0ef41Sopenharmony_ci        /* See how many times the previous byte repeats */
21231cb0ef41Sopenharmony_ci        s->match_length = 0;
21241cb0ef41Sopenharmony_ci        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
21251cb0ef41Sopenharmony_ci            scan = s->window + s->strstart - 1;
21261cb0ef41Sopenharmony_ci            prev = *scan;
21271cb0ef41Sopenharmony_ci            if (prev == *++scan && prev == *++scan && prev == *++scan) {
21281cb0ef41Sopenharmony_ci                strend = s->window + s->strstart + MAX_MATCH;
21291cb0ef41Sopenharmony_ci                do {
21301cb0ef41Sopenharmony_ci                } while (prev == *++scan && prev == *++scan &&
21311cb0ef41Sopenharmony_ci                         prev == *++scan && prev == *++scan &&
21321cb0ef41Sopenharmony_ci                         prev == *++scan && prev == *++scan &&
21331cb0ef41Sopenharmony_ci                         prev == *++scan && prev == *++scan &&
21341cb0ef41Sopenharmony_ci                         scan < strend);
21351cb0ef41Sopenharmony_ci                s->match_length = MAX_MATCH - (uInt)(strend - scan);
21361cb0ef41Sopenharmony_ci                if (s->match_length > s->lookahead)
21371cb0ef41Sopenharmony_ci                    s->match_length = s->lookahead;
21381cb0ef41Sopenharmony_ci            }
21391cb0ef41Sopenharmony_ci            Assert(scan <= s->window + (uInt)(s->window_size - 1),
21401cb0ef41Sopenharmony_ci                   "wild scan");
21411cb0ef41Sopenharmony_ci        }
21421cb0ef41Sopenharmony_ci
21431cb0ef41Sopenharmony_ci        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
21441cb0ef41Sopenharmony_ci        if (s->match_length >= MIN_MATCH) {
21451cb0ef41Sopenharmony_ci            check_match(s, s->strstart, s->strstart - 1, s->match_length);
21461cb0ef41Sopenharmony_ci
21471cb0ef41Sopenharmony_ci            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
21481cb0ef41Sopenharmony_ci
21491cb0ef41Sopenharmony_ci            s->lookahead -= s->match_length;
21501cb0ef41Sopenharmony_ci            s->strstart += s->match_length;
21511cb0ef41Sopenharmony_ci            s->match_length = 0;
21521cb0ef41Sopenharmony_ci        } else {
21531cb0ef41Sopenharmony_ci            /* No match, output a literal byte */
21541cb0ef41Sopenharmony_ci            Tracevv((stderr,"%c", s->window[s->strstart]));
21551cb0ef41Sopenharmony_ci            _tr_tally_lit(s, s->window[s->strstart], bflush);
21561cb0ef41Sopenharmony_ci            s->lookahead--;
21571cb0ef41Sopenharmony_ci            s->strstart++;
21581cb0ef41Sopenharmony_ci        }
21591cb0ef41Sopenharmony_ci        if (bflush) FLUSH_BLOCK(s, 0);
21601cb0ef41Sopenharmony_ci    }
21611cb0ef41Sopenharmony_ci    s->insert = 0;
21621cb0ef41Sopenharmony_ci    if (flush == Z_FINISH) {
21631cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 1);
21641cb0ef41Sopenharmony_ci        return finish_done;
21651cb0ef41Sopenharmony_ci    }
21661cb0ef41Sopenharmony_ci    if (s->sym_next)
21671cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 0);
21681cb0ef41Sopenharmony_ci    return block_done;
21691cb0ef41Sopenharmony_ci}
21701cb0ef41Sopenharmony_ci
21711cb0ef41Sopenharmony_ci/* ===========================================================================
21721cb0ef41Sopenharmony_ci * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
21731cb0ef41Sopenharmony_ci * (It will be regenerated if this run of deflate switches away from Huffman.)
21741cb0ef41Sopenharmony_ci */
21751cb0ef41Sopenharmony_cilocal block_state deflate_huff(deflate_state *s, int flush) {
21761cb0ef41Sopenharmony_ci    int bflush;             /* set if current block must be flushed */
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_ci    for (;;) {
21791cb0ef41Sopenharmony_ci        /* Make sure that we have a literal to write. */
21801cb0ef41Sopenharmony_ci        if (s->lookahead == 0) {
21811cb0ef41Sopenharmony_ci            fill_window(s);
21821cb0ef41Sopenharmony_ci            if (s->lookahead == 0) {
21831cb0ef41Sopenharmony_ci                if (flush == Z_NO_FLUSH)
21841cb0ef41Sopenharmony_ci                    return need_more;
21851cb0ef41Sopenharmony_ci                break;      /* flush the current block */
21861cb0ef41Sopenharmony_ci            }
21871cb0ef41Sopenharmony_ci        }
21881cb0ef41Sopenharmony_ci
21891cb0ef41Sopenharmony_ci        /* Output a literal byte */
21901cb0ef41Sopenharmony_ci        s->match_length = 0;
21911cb0ef41Sopenharmony_ci        Tracevv((stderr,"%c", s->window[s->strstart]));
21921cb0ef41Sopenharmony_ci        _tr_tally_lit(s, s->window[s->strstart], bflush);
21931cb0ef41Sopenharmony_ci        s->lookahead--;
21941cb0ef41Sopenharmony_ci        s->strstart++;
21951cb0ef41Sopenharmony_ci        if (bflush) FLUSH_BLOCK(s, 0);
21961cb0ef41Sopenharmony_ci    }
21971cb0ef41Sopenharmony_ci    s->insert = 0;
21981cb0ef41Sopenharmony_ci    if (flush == Z_FINISH) {
21991cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 1);
22001cb0ef41Sopenharmony_ci        return finish_done;
22011cb0ef41Sopenharmony_ci    }
22021cb0ef41Sopenharmony_ci    if (s->sym_next)
22031cb0ef41Sopenharmony_ci        FLUSH_BLOCK(s, 0);
22041cb0ef41Sopenharmony_ci    return block_done;
22051cb0ef41Sopenharmony_ci}
2206