Commit 46fb29c4 authored by Jérome Perrin's avatar Jérome Perrin

patches/python: workaround safeimage impacted by this round2 patch

parent a54072d8
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
import contextlib
import io import io
import os, sys, shutil, tempfile import os, sys, shutil, tempfile
from zLOG import LOG,ERROR,INFO,WARNING from zLOG import LOG,ERROR,INFO,WARNING
...@@ -32,6 +33,29 @@ import random ...@@ -32,6 +33,29 @@ import random
import base64 import base64
from OFS.Folder import Folder from OFS.Folder import Folder
import six
# XXX zope4py3, we patch builtin round to keep python2 behavior
# but this interfers with PIL, because python2 round sometimes
# returns an int where python3 round is supposed to return a float.
# This context manager swaps the implementation with the native
# float on python3, which is NOT THREAD SAFE. Don't use it in
# production, for now this makes the test pass 🤐.
import Products.ERP5Type.patches.python
@contextlib.contextmanager
def native_round():
if six.PY3:
round_original = __builtins__['round']
try:
__builtins__['round'] = Products.ERP5Type.patches.python.round_native
yield
finally:
__builtins__['round'] = round_original
else:
# on python2 do nothing
yield
class ZoomifyBase: class ZoomifyBase:
_v_imageFilename = '' _v_imageFilename = ''
...@@ -179,7 +203,8 @@ class ZoomifyBase: ...@@ -179,7 +203,8 @@ class ZoomifyBase:
saveFilename = root + str(tier) + '-' + str(row) + ext saveFilename = root + str(tier) + '-' + str(row) + ext
if imageRow.mode != 'RGB': if imageRow.mode != 'RGB':
imageRow = imageRow.convert('RGB') imageRow = imageRow.convert('RGB')
imageRow.save(os.path.join(tempfile.gettempdir(), saveFilename), with native_round():
imageRow.save(os.path.join(tempfile.gettempdir(), saveFilename),
# see https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg-saving # see https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg-saving
# for quality, Values above 95 should be avoided; # for quality, Values above 95 should be avoided;
'JPEG', quality=95) 'JPEG', quality=95)
...@@ -258,9 +283,12 @@ class ZoomifyBase: ...@@ -258,9 +283,12 @@ class ZoomifyBase:
# a bug was discovered when a row was exactly 1 pixel in height # a bug was discovered when a row was exactly 1 pixel in height
# this extra checking accounts for that # this extra checking accounts for that
if imageHeight > 1: if imageHeight > 1:
tempImage = imageRow.resize((imageWidth//2, imageHeight//2), tempImage = imageRow.resize(
PIL_Image.ANTIALIAS) (imageWidth//2, imageHeight//2),
tempImage.save(os.path.join(tempfile.gettempdir(), root + str(tier) PIL_Image.LANCZOS if six.PY3 else PIL_Image.ANTIALIAS,
)
with native_round():
tempImage.save(os.path.join(tempfile.gettempdir(), root + str(tier)
+ '-' + str(row) + ext)) + '-' + str(row) + ext))
tempImage = None tempImage = None
rowImage = None rowImage = None
...@@ -272,8 +300,6 @@ class ZoomifyBase: ...@@ -272,8 +300,6 @@ class ZoomifyBase:
def ZoomifyProcess(self, imageNames): def ZoomifyProcess(self, imageNames):
""" the method the client calls to generate zoomify metadata """ """ the method the client calls to generate zoomify metadata """
pass
return return
def preProcess(self): def preProcess(self):
...@@ -541,7 +567,8 @@ class ERP5ZoomifyZopeProcessor(ZoomifyZopeProcessor): ...@@ -541,7 +567,8 @@ class ERP5ZoomifyZopeProcessor(ZoomifyZopeProcessor):
tile_group_id = self.getAssignedTileContainerName() tile_group_id = self.getAssignedTileContainerName()
tile_group=self.document[tile_group_id] tile_group=self.document[tile_group_id]
tileImageData= io.BytesIO() tileImageData= io.BytesIO()
image.save(tileImageData, 'JPEG', quality=self.qualitySetting) with native_round():
image.save(tileImageData, 'JPEG', quality=self.qualitySetting)
tileImageData.seek(0) tileImageData.seek(0)
if tile_group is None: if tile_group is None:
raise AttributeError('unable to fine tile group %r' % tile_group_id) raise AttributeError('unable to fine tile group %r' % tile_group_id)
......
...@@ -251,6 +251,8 @@ def round2(number, ndigits=None): ...@@ -251,6 +251,8 @@ def round2(number, ndigits=None):
return float(d) return float(d)
round_native = round
if sys.version_info > (2, ): if sys.version_info > (2, ):
__builtins__['round'] = round2 __builtins__['round'] = round2
from AccessControl.ZopeGuards import safe_builtins from AccessControl.ZopeGuards import safe_builtins
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment