Skip to content

Commit fa391e9

Browse files
committed
Emit EOB marker when Z_FINISH arrives with no pending input
1 parent b37f2dd commit fa391e9

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

src/lib/deflate-enc.inc.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ typedef struct {
55
/* Compression parameters */
66
int level; /* Compression level */
77
int is_last_block; /* Is this the final block? */
8+
int finalized; /* End-of-stream marker already emitted */
89

910
/* Sliding window for LZ77 */
1011
uint8_t *window; /* Sliding window buffer */
@@ -319,7 +320,12 @@ int deflate(z_stream *strm, int flush) {
319320
return flush == Z_FINISH? Z_STREAM_END: Z_OK;
320321
}
321322

323+
if (state->finalized) {
324+
return flush == Z_FINISH? Z_STREAM_END: Z_OK;
325+
}
326+
322327
/* Use fixed Huffman codes for simplicity */
328+
int block_opened = 0;
323329
if (strm->avail_in > 0) {
324330
/* Write block header - type 01 (fixed Huffman) */
325331
int ret = write_bits (strm, state, state->is_last_block? 1: 0, 1); /* Final block bit */
@@ -331,6 +337,7 @@ int deflate(z_stream *strm, int flush) {
331337
if (ret != Z_OK) {
332338
return ret;
333339
}
340+
block_opened = 1;
334341

335342
/* Process all input data */
336343
while (strm->avail_in > 0) {
@@ -515,13 +522,26 @@ int deflate(z_stream *strm, int flush) {
515522
}
516523
}
517524

518-
/* If this is the end of stream, write end of block marker */
519-
if (flush == Z_FINISH) {
520-
/* Write end of block symbol (256) */
521-
write_huffman_code (strm, state, state->literals.codes[256], state->literals.lengths[256]);
522-
/* Flush remaining bits */
523-
flush_bits (strm, state);
525+
}
526+
527+
/* Close the stream with a final block when Z_FINISH was requested.
528+
* If no block was opened above (avail_in was 0), open an empty fixed
529+
* Huffman block first so the EOB symbol is properly framed. */
530+
if (flush == Z_FINISH && !state->finalized) {
531+
if (!block_opened) {
532+
int ret = write_bits (strm, state, 1, 1); /* Final block bit */
533+
if (ret != Z_OK) {
534+
return ret;
535+
}
536+
ret = write_bits (strm, state, 1, 2); /* Block type 01 */
537+
if (ret != Z_OK) {
538+
return ret;
539+
}
524540
}
541+
/* Write end of block symbol (256) and flush remaining bits. */
542+
write_huffman_code (strm, state, state->literals.codes[256], state->literals.lengths[256]);
543+
flush_bits (strm, state);
544+
state->finalized = 1;
525545
}
526546

527547
return flush == Z_FINISH? Z_STREAM_END: Z_OK;

0 commit comments

Comments
 (0)