Version 8 of gzip

Updated 2004-08-18 12:10:59

GNU Zip (or gzip for short) is a stream compression program (like the UNIX compress program), and not an archiver (like the DOS pkzip program) that uses an unpatented (and unpatentable) algorithm for its compression. The program bzip2 can compress even more, but takes more memory to do so. The zlib library uses the same algorithms, and can be used to process or produce gzipped files (IIRC, though there might be a header too.)

This governed by two RFC's

  • RFC 1950 [L1 ] - Zlib Compressed Data Format
  • RFC 1951 [L2 ] - Deflate Compressed Data format
  • RFC 1952 [L3 ] - Gzip File Format

See also http://en.wikipedia.org/wiki/Gzip

See GASP, tkArchive, TkZip,

Are there any Tcl bindings for zlib?

18Aug04 PS Yes there is! tclkit has it by default and I created an extension from that. See the zlib page.


gunzip a file with zlib and Tcl

 proc gunzip { file {outfile ""} } {
    package require zlib
    # Gunzip the file
    # See http://www.gzip.org/zlib/rfc-gzip.html for gzip file description

    set in [open $file r]    
    fconfigure $in -translation binary -buffering none

    set id [read $in 2]
    if { ![string equal $id \x1f\x8b] } {
        error "$file is not a gzip file."
    }
    set cm [read $in 1]
    if { ![string equal $cm \x8] } {
        error "$file: unknown compression method"
    }
    binary scan [read $in 1] b5 FLAGS 
    puts $FLAGS
    foreach {FTEXT FHCRC FEXTRA FNAME FCOMMENT} [split $FLAGS ""] {}
    binary scan [read $in 4] i MTIME
    set XFL [read $in 1]
    set OS [read $in 1]

    if { $FEXTRA } {
        binary scan [read $in 2] S XLEN
        set ExtraData [read $in $XLEN]
    }
    set name ""
    if { $FNAME } {        
        set c [read $in 1]
        while { $c != "\x0" } {
            append name $c
            set c [read $in 1]
        }
    }
    set comment ""
    if { $FCOMMENT } {
        set c [read $in 1]
        while { $c != "\x0" } {
            append comment $c
            set c [read $in 1]
        }
    }
    set CRC16 ""
    if { $FHCRC } {
        set CRC16 [read $in 2]
    }

    set cdata [read $in]
    close $in

    binary scan [string range $cdata end-7 end] ii CRC32 ISIZE

    set data [zlib inflate [string range $cdata 0 end-8]]

    if { $CRC32 != [zlib crc32 $data] } {
        error "gunzip Checksum mismatch."
    } 
    if { $outfile == "" } {
        set outfile $file
        if { [string equal -nocase [file extension $file] ".gz"] } {
            set outfile [file rootname $file]
        }
    }
    if { [string equal $outfile $file] } {
        error "Will not overwrite input file. sorry."
    }
    set out [open $outfile w]
    fconfigure $out -translation binary -buffering none
    puts -nonewline $out $data
    close $out
    file mtime $outfile $MTIME
 }

18Aug04 PS


LES: Would someone tell me HOW this is better than [exec gzip filename]?


Category Application | Category Compression