sync with src
authortb <tb@openbsd.org>
Thu, 1 Aug 2024 04:03:10 +0000 (04:03 +0000)
committertb <tb@openbsd.org>
Thu, 1 Aug 2024 04:03:10 +0000 (04:03 +0000)
sys/lib/libz/deflate.c
sys/lib/libz/deflate.h
sys/lib/libz/trees.c
sys/lib/libz/zconf.h
sys/lib/libz/zlib.h

index e653d53..2a4fc28 100644 (file)
@@ -715,6 +715,14 @@ int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
     return Z_OK;
 }
 
+/* ========================================================================= */
+int ZEXPORT deflateUsed(z_streamp strm, int *bits) {
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+    if (bits != Z_NULL)
+        *bits = strm->state->bi_used;
+    return Z_OK;
+}
+
 /* ========================================================================= */
 int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
     deflate_state *s;
@@ -1744,8 +1752,10 @@ local block_state deflate_stored(deflate_state *s, int flush) {
         s->high_water = s->strstart;
 
     /* If the last block was written to next_out, then done. */
-    if (last)
+    if (last) {
+        s->bi_used = 8;
         return finish_done;
+    }
 
     /* If flushing and all input has been consumed, then done. */
     if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
@@ -1797,6 +1807,8 @@ local block_state deflate_stored(deflate_state *s, int flush) {
     }
 
     /* We've done all we can with the available input and output. */
+    if (last)
+        s->bi_used = 8;
     return last ? finish_started : need_more;
 }
 
index 8182a26..ad230ef 100644 (file)
@@ -269,6 +269,9 @@ typedef struct internal_state {
     /* Number of valid bits in bi_buf.  All bits above the last valid bit
      * are always zero.
      */
+    int bi_used;
+    /* Last number of used bits when going to a byte boundary.
+     */
 
     ulg high_water;
     /* High water mark offset in window for initialized bytes -- bytes above
index cba0708..7ce629a 100644 (file)
@@ -182,6 +182,7 @@ local void bi_windup(deflate_state *s) {
     } else if (s->bi_valid > 0) {
         put_byte(s, (Byte)s->bi_buf);
     }
+    s->bi_used = ((s->bi_valid - 1) & 7) + 1;
     s->bi_buf = 0;
     s->bi_valid = 0;
 #ifdef ZLIB_DEBUG
@@ -464,6 +465,7 @@ void ZLIB_INTERNAL _tr_init(deflate_state *s) {
 
     s->bi_buf = 0;
     s->bi_valid = 0;
+    s->bi_used = 0;
 #ifdef ZLIB_DEBUG
     s->compressed_len = 0L;
     s->bits_sent = 0L;
index 1a3d41e..7221b89 100644 (file)
@@ -57,6 +57,7 @@
 #  define deflateSetDictionary  z_deflateSetDictionary
 #  define deflateSetHeader      z_deflateSetHeader
 #  define deflateTune           z_deflateTune
+#  define deflateUsed           z_deflateUsed
 #  define deflate_copyright     z_deflate_copyright
 #  define get_crc_table         z_get_crc_table
 #  ifndef Z_SOLO
index 5322a85..6c0e02d 100644 (file)
@@ -791,6 +791,18 @@ ZEXTERN int ZEXPORT deflatePending(z_streamp strm,
    stream state was inconsistent.
  */
 
+ZEXTERN int ZEXPORT deflateUsed(z_streamp strm,
+                                int *bits);
+/*
+     deflateUsed() returns in *bits the most recent number of deflate bits used
+   in the last byte when flushing to a byte boundary. The result is in 1..8, or
+   0 if there has not yet been a flush. This helps determine the location of
+   the last bit of a deflate stream.
+
+     deflateUsed returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
 ZEXTERN int ZEXPORT deflatePrime(z_streamp strm,
                                  int bits,
                                  int value);