Skip to content

Commit

Permalink
🗜️ Support zstd compression algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
tmdvs committed Sep 10, 2024
1 parent bd5845c commit b74ff9c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ name = "fig2sketch"
readme = "README.md"
requires-python = ">=3.10"
dynamic = ["version"]
dependencies = ["Pillow==10.3.0", "fonttools==4.43.0", "appdirs==1.4.4"]
dependencies = [
"Pillow==10.3.0",
"fonttools==4.43.0",
"appdirs==1.4.4",
"zstd==1.5.5.1",
]

[project.scripts]
fig2sketch = "fig2sketch:main"
Expand Down
12 changes: 6 additions & 6 deletions src/figformat/decodefig.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ def decode(path):
if header == b"PK":
fig_zip = zipfile.ZipFile(reader)

try:
import fig_kiwi
# try:
# import fig_kiwi

logging.debug("Using fast (rust) kiwi reader")
return fig_kiwi.decode(path, type_converters), fig_zip
# logging.debug("Using fast (rust) kiwi reader")
# return fig_kiwi.decode(path, type_converters), fig_zip

except ImportError:
logging.debug("Falling back to slow (python) kiwi reader")
# except ImportError:
# logging.debug("Falling back to slow (python) kiwi reader")

if fig_zip:
reader = fig_zip.open("canvas.fig")
Expand Down
30 changes: 27 additions & 3 deletions src/figformat/kiwi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import ctypes
from collections import OrderedDict
import zlib
import zstd
import struct
import io
import logging
Expand Down Expand Up @@ -146,6 +147,10 @@ def decode(reader, type_converters):
MIN_SUPPORTED_VERSIONS = 15
MAX_SUPPORTED_VERSION = 25

# `zstd` data will start with a magic number frame
# the value of which is `0xfd2fb528`
ZSTD_MAGIC_NUMBER = b"\x28\xb5\x2f\xfd"

header = reader.read(12)
fig_version = struct.unpack("<I", header[8:12])[0]
if fig_version < MIN_SUPPORTED_VERSIONS:
Expand All @@ -159,10 +164,29 @@ def decode(reader, type_converters):

segment_header = reader.read(4)
size = struct.unpack("<I", segment_header)[0]
data = io.BytesIO(zlib.decompress(reader.read(size), wbits=-15))
schema = KiwiSchema(data)
compressedSchema = reader.read(size)

schemaData = b""
# Check to see if the first four bytes are the zstd magic number.
# If so we need to use zstd to decompress, not zlib
if compressedSchema.startswith(ZSTD_MAGIC_NUMBER):
schemaData = io.BytesIO(zstd.decompress(compressedSchema))
else:
schemaData = io.BytesIO(zlib.decompress(compressedSchema, wbits=-15))

schema = KiwiSchema(schemaData)

segment_header = reader.read(4)
size = struct.unpack("<I", segment_header)[0]
data = io.BytesIO(zlib.decompress(reader.read(size), wbits=-15))
compressedData = reader.read(size)

data = b""
# Check to see if the first four bytes are the zstd magic number.
# If so we need to use zstd to decompress, not zlib

if compressedData.startswith(ZSTD_MAGIC_NUMBER):
data = io.BytesIO(zstd.decompress(compressedData))
else:
data = io.BytesIO(zlib.decompress(compressedData, wbits=-15))

return KiwiDecoder(schema, type_converters).decode(data, "Message")

0 comments on commit b74ff9c

Please sign in to comment.