-- ************************************************************************
-- Script: GZDEFLATE
-- Version: 0.2
-- Date: 2009-08-09
-- Author: Valentin Schmidt
--
-- Description:
-- implements DEFLATE compression according to RFC1951 (http://www.faqs.org/rfcs/rfc1951)
-- data is e.g. compatible with PHP's gzdeflate()/gzinflate() functions.
--
-- Notice: unfortunately the current implementation of the compress/uncompress functions of director's bytearray class use
-- ZLIB (i.e. gzcompress) instead of raw DEFLATE compression. this is no limitation for compressing data (as
-- DEFLATE/GZIP/ZIP files) since the 6 additional ZLIB bytes (2 bytes at the beginning, 4 adler32 checksum bytes at the end)
-- just need to be removed to create valid DEFLATE compressed data (that can then be used to create GZIP/ZIP files). but
-- unfortunately the bytearray's uncompress() function fails if the 4 adler32 checksum bytes at the end of the bytearray are
-- missing or incorrect, and therefor INFLATE, GZIP and ZIP decompression is only possible if the adler32 checksums of the
-- original file(s) are known.
-- one way to lessen this strong limitation a little bit, so at least GZIP and ZIP files created with those scripts can be
-- decompressed without requiring any additional info, is to store the adler32 checksums as comments inside the GZP/ZIP file.
-- such files can be decompresssed with any 3rd party tool (which just ignore the comments) as well as with code based on
-- byterrays's uncompress function.
--
-- Requirements:
-- * fileIO xtra
-- * fileIO wrapper functions file_get_bytes/file_put_bytes
--
-- ************************************************************************
----------------------------------------
-- deflate data
-- NOTICE:
-- passed bytearray baInput is changed (bytearray is compressed)!!!
-- if this is not wanted, either create a copy or use ba.uncompress to restore original state
----------------------------------------
on gzdeflate_bytearray (baInput)
info = [:]
baInput.compress()
info["data"] = bytearray()
info["data"].writeByteArray(baInput, 3, baInput.length-6) -- remove header and adler32 checksum bytes
baInput.position = baInput.length-3
baInput.endian=#bigEndian
info["adler32"] = baInput.readInt32()
return info
end
----------------------------------------
-- deflate file
----------------------------------------
on gzdeflate_file(inputFile, outputFile)
ba = file_get_bytes(inputFile)
ba.compress()
file_put_bytes (outputFile, ba, 3, ba.length-6) -- remove header and adler32 checksum bytes
end
----------------------------------------
-- uncompress (inflate) deflated data
-- unfortunately only possible if adler32 checksum of original file is known (=unnecessary limitation, bad conception by adobe)
----------------------------------------
on gzinflate_bytearray (ba, adler32)
ret = bytearray(ba.length+6)
-- add header (0x78 0xDA = 120 218)
ret[1] = 120
ret[2] = 218
-- copy deflated data
ret.position = 3
ret.writeByteArray(ba)
ret.endian = #bigEndian
-- add adler32 checksum
ret.writeInt32(adler32)
ret.uncompress()
return ret
end
----------------------------------------
-- uncompress (inflate) deflated file
-- unfortunately only possible if adler32 checksum of original file is known (=unnecessary limitation, bad conception by adobe)
----------------------------------------
on gzinflate_file(inputFile, outputFile, adler32)
ba = file_get_bytes(inputFile)
ok = file_put_bytes (outputFile, gzinflate_bytearray(ba, adler32))
end