56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
import os
|
|
import tempfile
|
|
from io import BytesIO
|
|
from typing import *
|
|
|
|
import defusedxml.cElementTree
|
|
from glymur import jp2box, Jp2k
|
|
|
|
# Replace glymur's ElementTree with a safe one
|
|
jp2box.ET = defusedxml.cElementTree
|
|
|
|
|
|
SL_DEFAULT_ENCODE = {
|
|
"cratios": (1920.0, 480.0, 120.0, 30.0, 10.0),
|
|
"irreversible": True,
|
|
}
|
|
|
|
|
|
class BufferedJp2k(Jp2k):
|
|
"""
|
|
For manipulating JP2K from within a binary buffer.
|
|
|
|
For many operations glymur expects to be able to re-read from a file
|
|
based on filename, so this is the least brittle approach.
|
|
"""
|
|
|
|
def __init__(self, contents: bytes, encode_kwargs: Optional[Dict] = None):
|
|
if encode_kwargs is None:
|
|
self.encode_kwargs = SL_DEFAULT_ENCODE.copy()
|
|
else:
|
|
self.encode_kwargs = encode_kwargs
|
|
|
|
stream = BytesIO(contents)
|
|
self.temp_file = tempfile.NamedTemporaryFile(delete=False)
|
|
stream.seek(0)
|
|
self.temp_file.write(stream.read())
|
|
# Windows NT can't handle two FHs open on a tempfile at once
|
|
self.temp_file.close()
|
|
|
|
super().__init__(self.temp_file.name)
|
|
|
|
def __del__(self):
|
|
if self.temp_file is not None:
|
|
os.remove(self.temp_file.name)
|
|
self.temp_file = None
|
|
|
|
def _write(self, img_array, verbose=False, **kwargs):
|
|
# Glymur normally only lets you control encode params when a write happens within
|
|
# the constructor. Keep around the encode params from the constructor and pass
|
|
# them to successive write calls.
|
|
return super()._write(img_array, verbose=False, **self.encode_kwargs, **kwargs)
|
|
|
|
def __bytes__(self):
|
|
with open(self.temp_file.name, "rb") as f:
|
|
return f.read()
|