summaryrefslogtreecommitdiff
path: root/deflate_quick.c
diff options
context:
space:
mode:
authorNathan Moinvaziri <nathan@nathanm.com>2020-06-25 22:52:59 -0700
committerHans Kristian Rosbach <hk-github@circlestorm.org>2020-06-28 11:17:44 +0200
commit3f6e40d8fc36ad46ea4e78d4a213dc5546f60196 (patch)
tree068820ba97065372e2710cad2b01254eac0e2992 /deflate_quick.c
parent2026830ceab48a364d0bc8d5d36f31fa745f1368 (diff)
Fixed avail_out == 0 conditional not returning need_more in deflate_quick.
Fixed ending block when returning need_more caused problems with inflate. So instead of ending the block each time the function returns to finish the last block, we check upon start to see if it is the last block and if the last block has been started, and if not it will close the previous block and start the last block.
Diffstat (limited to 'deflate_quick.c')
-rw-r--r--deflate_quick.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/deflate_quick.c b/deflate_quick.c
index ad1dc2e..3e47f2b 100644
--- a/deflate_quick.c
+++ b/deflate_quick.c
@@ -28,7 +28,7 @@ extern const ct_data static_dtree[D_CODES];
#define QUICK_START_BLOCK(s, last) { \
zng_tr_emit_tree(s, STATIC_TREES, last); \
- s->block_open = 1; \
+ s->block_open = 1 + last; \
s->block_start = s->strstart; \
}
@@ -45,10 +45,15 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
unsigned dist, match_len, last;
- if (s->block_open == 0 && s->lookahead > 0) {
+ last = (flush == Z_FINISH) ? 1 : 0;
+ if (last && s->block_open != 2) {
+ /* Emit end of previous block */
+ QUICK_END_BLOCK(s, 0);
+ /* Emit start of last block */
+ QUICK_START_BLOCK(s, last);
+ } else if (s->block_open == 0 && s->lookahead > 0) {
/* Start new block only when we have lookahead data, so that if no
input data is given an empty block will not be written */
- last = (flush == Z_FINISH) ? 1 : 0;
QUICK_START_BLOCK(s, last);
}
@@ -56,17 +61,13 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
if (s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size) {
flush_pending(s->strm);
if (s->strm->avail_out == 0 && flush != Z_FINISH) {
- /* Break to emit end block and return need_more */
- break;
+ return need_more;
}
}
if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- /* Always emit end block, in case next call is with Z_FINISH,
- and we need to emit start of last block */
- QUICK_END_BLOCK(s, 0);
return need_more;
}
if (s->lookahead == 0)
@@ -75,7 +76,6 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
if (s->block_open == 0) {
/* Start new block when we have lookahead data, so that if no
input data is given an empty block will not be written */
- last = (flush == Z_FINISH) ? 1 : 0;
QUICK_START_BLOCK(s, last);
}
}
@@ -108,7 +108,6 @@ ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
- last = (flush == Z_FINISH) ? 1 : 0;
QUICK_END_BLOCK(s, last);
flush_pending(s->strm);