• zlib push – Not in zlib package, Tcl 8.6b1 required
  • zlib stream – Not in zlib package, Tcl 8.6b1 required

Package (pre-8.6b1)

Zlib was distributed as a package prior to 8.6b1 (particularly in tclkits). The package did not include the subcommands notated above.


Creating a gzipped file:

proc gzip {file} {

    set fin open $file rb
    set header [dict create \
        filename $file
        time file mtime $file
        comment "Created by Tclinfo patchlevel"]
    set fout open $file.gz wb
    zlib push gzip $fout -header $header
    fcopy $fin $fout
    close $fin
    close $fout

A trivial zcat for viewing gzipped files:

#!/usr/bin/env tclsh
zlib push gunzip stdin
chan copy stdin stdout

For using zlib to compress command-response protocols (or datagrams), see zlib stream.


Zlib is a data compression library found at http://www.zlib.net . Its specification "achieved official Internet RFC status in 1996", and is part of standard Java, used, moreover, by JARs.

Apparently the only documentation available at the zlib home is the "Compressed Data Format Specification version 3.3" [L1 ], also available as RFC 1950 [L2 ].

The zlib c code is currently at version 1.2.5 .

The programming interface for the basic Tcl binding is simply

    zlib option data ?...?

http://www.equi4.com/critlib/zlib.README provides a bit more detail, including these specifics:

    set checksum [zlib adler32 data ?startvalue?]
        # adler32 calculates a quick "Adler-32" checksum

    set checksum [zlib crc32 data ?startvalue?]
        # crc32 calculates the standard "CRC-32" checksum

    set cdata [zlib compress data ?level?]
        # zlib-compress data with optional compression level

    set ddata [zlib deflate data ?level?]
        # headerless compression with optional compression level

    set data [zlib decompress cdata ?bufsize?]
        # zlib-decompress data with optional buffer size

    set data [zlib inflate ddata ?level?]
        # headerless decompression with optional buffer size

Since zlib is being used in at least Tclkit, there must be a Tcl binding of it. Is this (or some other) binding available as stand alone code for someone who was looking to use it? Could someone point to some documentation regarding the binding? At the very least, someone could download the sources to Tclkit (follow the link below and subsequent links to find that) and paw through the pieces...

KY A standalone source code is here:https://www.tcl-lang.org/cgi-bin/tct/tip/234

ZB 2009-05-04 I made a test using Pat's script mkzip.tcl (taken from creating zip file archives from tcl with zlib) - and I wanted to check it out in a bit more difficult conditions, than usual.

On the machine equipped with 64 MB RAM (Linux) I've turned off swap space to limit the available memory size. Then I tried to pack into one ZIP archive 4 files, of sizes (around): 33, 51, 55, 61 MB. The machine had about 44 MB free ("htop" utility's report), so - as you can see - 3 of the files had larger size than available memory (with no swapping possibility). Unfortunately: mkzip.tcl rather quickly gave up, answering "Can't allocate *some_size* bytes". But the zip utility present in the system was able to pack that files into one large archive.

Of course, having the new package will make archives handling now much easier. But perhaps could be possible to make its algorithms even better, to make it (if it's possible at all) quite independent from the available memory size - as it was in case of zip utility?

LV Have you submitted this suggestion to http://tcl.sf.net/ as a feature request? I don't know that it could technically be called a bug, since it does tell you that it can't get enough memory. But it certainly would be worth a feature request.

ZB No, not yet; I thought, this is quite valid place. But of course, I'll send. Yes, I realize, it probably isn't a bug, but the problem caused by currently used algorithms rather. And because of this I wrote about replacing algorithms, not about "fixing".

DKF: You'd have to use the streaming API (or rather APIs; command-based or channel-based) rather than the "slap all the data through at once" API. That's a bug in that script really...

ZB Well, maybe my assumption, that it should count bytes on its own - while creating an archive - and read the data in "chunks", wasn't quite proper (actually, I don't know the way ZIP algorithm works). OK, I'll try to check out the different way.

DKF: I believe it is possible to write things that way. It just isn't actually done in that script; right now it just does open;read everything;zlib blah...

18Aug2004 PS: I created an extension that provides the [zlib] command from tclkit for non-tclkit Tcl. You can download the source at [L3 ]. For Msys+Mingw builds on win32, I suggest you download [L4 ] instead, which has zlib bundled. I also have a Windows binary for your pleasure: [L5 ] -- enjoy!


Included in Tclkit (yes in 8.4.1, but not in 8.4a3).

Regarding ActiveTcl, this distribution comes with two different bindings. A low-level one is provided by Img (1.3rc), basically just loading zlib and providing a stub table for it. A high-level binding is provided by Trf. This uses the low-level binding when available, and loads zlib directly if not.

"Grab the zlib source from http://www.equi4.com/pub/tk/tars , look at what genkit does with it."

"Another source of the same zlib as in tclkit is http://www.equi4.com/critlib - so you can use critcl to build a zlib which is equivalent to tclkit's."

mkZiplib is a wrapper for Zlib 1.1.3 and Minizip 0.15. With mkZiplib you can compress/decompress data on-the-fly and work with .gz and .zip files from within Tcl. [L6 ]

LES on 15 Apr 2005: mkZiplib is very interesting, but I ran into a couple of bad issues with it. One specific command causes tclsh/wish to crash on my machine [L7 ]. Besides, mkZiplib requires zlib 1.1.3. I could only find 1.1.4 on the Web, and the rest of Tcl doesn't seem to like it. mkZiplib also has its own copy of zlib.dll in its directory, while ActiveTcl already is shipped with a zlib.dll in its /bin directory, which is in the $PATH by default. I wonder which zlib.dll is used by ActiveTcl and which one is used by mkZiplib when either requires zlib.dll. Finally, I could read the contents of zip files remarkably easy, but could not write to them as per the instructions in the manual. Maybe I am doing something wrong, but I think I tried everything.

AMSN [L8 ] contains a pure-Tcl zlib decompression procedure.

CJU Where? I couldn't find it...

It was taken out after version 0.94. A somewhat improved version can be found at: zlib - inflate in tcl.

July 08, 2005: Beware of new security issues [L9 ] in the zlib library.

DKFNovember 15, 2009: This does not apply to zlib-in-Tcl (i.e. 8.6) which requires zlib 1.2 or later.

RLE (Aug 11, 2011): Is there a bug in the 8.6b1 implementation of zlib? If I attempt the example at the top of this page, I get an invalid gzip file:

% set file critcl.kit
% set fin [open $file rb]
% set header [dict create \
        filename $file time [file mtime $file] comment "Created by Tcl[info patchlevel]"]
filename critcl.kit time 1306892638 comment {Created by Tcl8.6b1}
% set fout [zlib push gzip [open $file.gz wb] -header $header]
% fcopy $fin $fout
% close $fin
% close $fout
% exit
$ gunzip -tv critcl.kit.gz
gzip: critcl.kit.gz: invalid compressed data--format violated

DKF: Could be. Have you retried with 8.6b2?

RLE: Just did, same effect:

% set file critcl.kit 
% set fin [open $file rb]
% set header [dict create \
        filename $file time [file mtime $file] comment "Created by Tcl[info patchlevel]"]
filename critcl.kit time 1313070437 comment {Created by Tcl8.6b2}
% set fout [zlib push gzip [open $file.gz wb] -header $header]
% fcopy $fin $fout
% close $fin
% close $fout
% exit
rellis@d820:~/downloads/tcl86b2/inst/usr/local/bin$ gunzip -tv critcl.kit.gz 
gzip: critcl.kit.gz: invalid compressed data--format violated

DKF: That's a bug. Please file a bug report.