chicken-zlib

  1. chicken-zlib
    1. Requirements
    2. Source code
    3. API
    4. Examples
    5. History
    6. TODOs
      1. string-string API

Bindings to the ubiquitous zlib library. zlib can compress and decompress:

The default compression output for zlib and this egg is RFC1950. Use the #:window-bits keyword argument to change this.

As of version 0.8, this egg repository replaces the previous zlib egg. It is a rewrite but aims to be a drop-in replacement. See below for details.

Requirements

Source code

The repository is hosted here.

API

[procedure] (zlib-compressing-output-port port . options)

Returns an output-port to which arbitrary data can be written. Its compressed form will be written to, usually with some delay, the supplied output-port port. It is important to call close-output-port on the returned port. Doing so does not close the supplied port.

The keyword arguments options are supplied to deflateInit2. They are as follows:

If some of the supplied options are invalid, zlib throws (error ...). Note that flush-output-port currently has no affect. Although zlib has support to flush the stream, providing immediate available data, this degrades the compression performance. As this is usually not the desired outcome of flush-output-port, we leave it as a no-op.

Here is an example to produce zlib compressed data:

(string->blob
 (call-with-output-string
  (lambda (os)
    (let ((op (zlib-compressing-output-port os)))
      (display "hello world" op)
      (close-output-port op)))))
;; => #${789ccb48cdc9c95728cf2fca4901001a0b045d}
;; echo  789ccb48cdc9c95728cf2fca4901001a0b045d | xxd -plain -revert | file -
/dev/stdin: zlib compressed data
[procedure] (zlib-decompressing-input-port ip #!key window-bits buffer)

These options are passed to inflateInit2.

For example, we can decompress the zlib data from the example above like this:

(read-string #f
  (zlib-decompressing-input-port
     (open-input-string
      (blob->string #${789ccb48cdc9c95728cf2fca4901001a0b045d}))))
;; => "hello world"

This will expect zlib headers. To detect gzip or zlib headers, specify higher values for window-bits:.

;; $ printf "hello world" | pigz -z | xxd -plain -c0
;; 785ecb48cdc9c95728cf2fca4901001a0b045d
(define hello.zlib (blob->string #${785ecb48cdc9c95728cf2fca4901001a0b045d}))
;; $ printf "hello world" | gzip - | xxd -plain -c0
;; 1f8b0800000000000003cb48cdc9c95728cf2fca49010085114a0d0b000000
(define hello.gz (blob->string #${1f8b0800000000000003cb48cdc9c95728cf2fca49010085114a0d0b000000}))
(read-string #f (zlib-decompressing-input-port (open-input-string hello.zlib) #:window-bits 47))
;; => "hello world"
(read-string #f (zlib-decompressing-input-port (open-input-string hello.gz)   #:window-bits 47))
;; => "hello world"

Examples

For more examples, see the ./examples directory. Example usage:

$ echo hello world | gzip -9 | csi -s examples/unzlib.scm
hello world
$ echo hello world | csi -s examples/zlib.scm | file -
/dev/stdin: zlib compressed data
$ pv -Ss8G /dev/zero | gzip | csi -s examples/unzlib.scm >/dev/null
8.00GiB 0:00:12 [ 680MiB/s] [====================================>] 100%

History

This is a replacement for r1b's zlib egg, and the new repository is here. The maintainer role has been transferred. The two eggs do not share any code, but version 0.8 onwards shares a lot of code with chicken-zstd.

It provides the same two procedures as 0.7, but these have been deprecated:

Here is an outline of a few other changes:

TODOs

string-string API

Some compression algorithm libraries provide procedures to compress and decompress strings directly, without using ports. These may be more convenient, but have size limits. Because of this, and since Scheme ports are relatively easy to use, only this port-based API is provided. The author is open for suggestions.