Script Library: 1238 scripts
 

gunzip.r

REBOL [ Title: "gunzip" Date: 30-Dec-2004 Version: 1.0.0 File: %gunzip.r Author: "Vincent Ecuyer" Purpose: "Decompresses gzip archives." Usage: { write/binary %my-file.txt gunzip %my-file.txt.gz or c-data: read/binary %my-file.txt.gz my-data: gunzip c-data } Comment: { It only works with rebol/view or rebol/face. PiNG file format uses "deflate" compression, like gzip and Rebol COMPRESS command. This hack builds a PiNG picture with the compressed data, loads it, then extracts the uncompressed data. Tested with .gz files from %gzip.r, gzip32 1.2.4 and 7-Zip 3.13. } Library: [ level: 'advanced platform: 'all type: [module tool] domain: [compression file-handling files] tested-under: [ view 1.2.1.3.1 on [Win2K] view 1.2.1.1.1 on [AmigaOS30] face 1.2.48.3.1 on [Win2K] ] support: none license: 'public-domain see-also: %gzip.r ] ] ctx-gunzip: context [ to-bin: func [value][load join "#{" [to-hex value "}"]] set?: func [value bit][not zero? value and to-integer 2 ** bit] os-codes: [ 'FAT 'Amiga 'VMS 'Unix 'VM/CMS 'Atari-TOS 'HPFS 'Macintosh 'Z-System 'CP/M 'TOPS-20 'NTFS 'QDOS 'Acorn-RISCOS ] set 'gunzip func [ "Decompresses a gzip encoding - returns a binary." data [any-string! file!] "Data to decompress" /info "Returns a block with [data filename date comment OS]" /local flags os filename filecomment time size r ][ if not all [value? 'view? view?][make error! "/View needed"] if string? data [data: to-binary data] if file? data [data: read/binary data] if data/1 <> 31 [make error! "Bad ID"] if data/2 <> 139 [make error! "Bad ID"] if data/3 <> 8 [make error! "Unknown Method"] flags: data/4 time: to-integer head reverse copy/part skip data 4 4 time: either zero? time [none][ 01-01-1970/0:0:0 + now/zone + to-time time ] os: pick os-codes data/10 + 1 filename: filecomment: none data: skip data 10 if set? flags 2 [ ; extra? data: skip data 2 data: skip data data/2 * 256 + data/1 + 2 ] if set? flags 3 [ ; name? filename: data data: find/tail data #"^@" filename: copy/part filename back data ] if set? flags 4 [ ; comment? filecomment: data filecomment: find/tail data #"^@" filecomment: copy/part filecomment back data ] if set? flags 1 [ ; crc-16? data: skip data 2 ] size: to-integer head reverse copy skip tail data -4 data: copy/part data skip tail data -8 data: to-binary rejoin [ #{89504E47} #{0D0A1A0A} ; signature #{0000000D} ; IHDR length "IHDR" ; type: header to-bin size ; width = uncompressed size #{00000001} ; height = 1 line #{08} ; bit depth #{00} ; color type = grayscale #{00} ; compression method #{00} ; filter method = none #{00} ; interlace method = no interlace #{00000000} ; no checksum to-bin 2 + 6 + length? data ; length "IDAT" ; type: data #{789C} ; zlib header #{00 0100 FEFF 00} ; 0 = no filter for scanline data #{00000000} ; no checksum #{00000000} ; length "IEND" ; type: end #{00000000} ; no checksum ] if error? try [data: load data][ make error! "Unable to decompress" ] r: make binary! size repeat i size [insert tail r to-char pick pick data i 1] either info [ reduce [ r either filename [to-file filename][none] time either filecomment [to-string comment][none] either os [os]['Unknown] ] ][r] ] ]
halt ;; to terminate script if DO'ne from webpage