=========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */
| 2036 | * deflate switches away from Z_RLE.) |
| 2037 | */ |
| 2038 | local block_state deflate_rle(deflate_state *s, int flush) { |
| 2039 | int bflush; /* set if current block must be flushed */ |
| 2040 | uInt prev; /* byte at distance one to match */ |
| 2041 | Bytef *scan, *strend; /* scan goes up to strend for length of run */ |
| 2042 | |
| 2043 | for (;;) { |
| 2044 | /* Make sure that we always have enough lookahead, except |
| 2045 | * at the end of the input file. We need MAX_MATCH bytes |
| 2046 | * for the longest run, plus one for the unrolled loop. |
| 2047 | */ |
| 2048 | if (s->lookahead <= MAX_MATCH) { |
| 2049 | fill_window(s); |
| 2050 | if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { |
| 2051 | return need_more; |
| 2052 | } |
| 2053 | if (s->lookahead == 0) break; /* flush the current block */ |
| 2054 | } |
| 2055 | |
| 2056 | /* See how many times the previous byte repeats */ |
| 2057 | s->match_length = 0; |
| 2058 | if (s->lookahead >= MIN_MATCH && s->strstart > 0) { |
| 2059 | scan = s->window + s->strstart - 1; |
| 2060 | prev = *scan; |
| 2061 | if (prev == *++scan && prev == *++scan && prev == *++scan) { |
| 2062 | strend = s->window + s->strstart + MAX_MATCH; |
| 2063 | do { |
| 2064 | } while (prev == *++scan && prev == *++scan && |
| 2065 | prev == *++scan && prev == *++scan && |
| 2066 | prev == *++scan && prev == *++scan && |
| 2067 | prev == *++scan && prev == *++scan && |
| 2068 | scan < strend); |
| 2069 | s->match_length = MAX_MATCH - (uInt)(strend - scan); |
| 2070 | if (s->match_length > s->lookahead) |
| 2071 | s->match_length = s->lookahead; |
| 2072 | } |
| 2073 | Assert(scan <= s->window + (uInt)(s->window_size - 1), |
| 2074 | "wild scan"); |
| 2075 | } |
| 2076 | |
| 2077 | /* Emit match if have run of MIN_MATCH or longer, else emit literal */ |
| 2078 | if (s->match_length >= MIN_MATCH) { |
| 2079 | check_match(s, s->strstart, s->strstart - 1, s->match_length); |
| 2080 | |
| 2081 | _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); |
| 2082 | |
| 2083 | s->lookahead -= s->match_length; |
| 2084 | s->strstart += s->match_length; |
| 2085 | s->match_length = 0; |
| 2086 | } else { |
| 2087 | /* No match, output a literal byte */ |
| 2088 | Tracevv((stderr,"%c", s->window[s->strstart])); |
| 2089 | _tr_tally_lit(s, s->window[s->strstart], bflush); |
| 2090 | s->lookahead--; |
| 2091 | s->strstart++; |
| 2092 | } |
| 2093 | if (bflush) FLUSH_BLOCK(s, 0); |
| 2094 | } |
| 2095 | s->insert = 0; |
no test coverage detected