[sfnt] add compress function to optionally use zopfli instead of zlib

This commit is contained in:
Cosimo Lupo 2016-01-31 13:26:31 +00:00
parent 090fd5f5f0
commit 7fafe1f9a7

View File

@ -133,6 +133,46 @@ class SFNTReader(object):
self.file.close()
# default compression level for WOFF 1.0 tables and metadata
ZLIB_COMPRESSION_LEVEL = 6
# if set to True, use zopfli instead of zlib for compressing WOFF 1.0.
# The Python bindings are available at https://github.com/anthrotype/py-zopfli
USE_ZOPFLI = False
# mapping between zlib's compression levels and zopfli's 'numiterations'.
# Use lower values for files over several MB in size or it will be too slow
ZOPFLI_LEVELS = {
# 0: 0, # can't do 0 iterations...
1: 1,
2: 3,
3: 5,
4: 8,
5: 10,
6: 15,
7: 25,
8: 50,
9: 100,
}
def compress(data, level=ZLIB_COMPRESSION_LEVEL):
""" Compress 'data' to Zlib format. If 'USE_ZOPFLI' variable is True,
zopfli is used instead of the zlib module.
The compression 'level' must be between 0 and 9. 1 gives best speed,
9 gives best compression (0 gives no compression at all).
The default value is a compromise between speed and compression (6).
"""
if not (0 <= level <= 9):
raise ValueError('Bad compression level: %s' % level)
if not USE_ZOPFLI or level == 0:
from zlib import compress
return compress(data, level)
else:
from zopfli.zlib import compress
return compress(data, numiterations=ZOPFLI_LEVELS[level])
class SFNTWriter(object):
def __new__(cls, *args, **kwargs):
@ -246,8 +286,7 @@ class SFNTWriter(object):
self.metaOrigLength = len(data.metaData)
self.file.seek(0,2)
self.metaOffset = self.file.tell()
import zlib
compressedMetaData = zlib.compress(data.metaData)
compressedMetaData = compress(data.metaData)
self.metaLength = len(compressedMetaData)
self.file.write(compressedMetaData)
else:
@ -439,7 +478,7 @@ class WOFFDirectoryEntry(DirectoryEntry):
format = woffDirectoryEntryFormat
formatSize = woffDirectoryEntrySize
zlibCompressionLevel = 6
zlibCompressionLevel = ZLIB_COMPRESSION_LEVEL
def decodeData(self, rawData):
import zlib
@ -448,14 +487,13 @@ class WOFFDirectoryEntry(DirectoryEntry):
else:
assert self.length < self.origLength
data = zlib.decompress(rawData)
assert len (data) == self.origLength
assert len(data) == self.origLength
return data
def encodeData(self, data):
import zlib
self.origLength = len(data)
if not self.uncompressed:
compressedData = zlib.compress(data, self.zlibCompressionLevel)
compressedData = compress(data, self.zlibCompressionLevel)
if self.uncompressed or len(compressedData) >= self.origLength:
# Encode uncompressed
rawData = data