Skip to content

Commit 436225a

Browse files
authored
Merge pull request #95 from bgilbert/performance
Drop fallback code for missing extension module
2 parents 9e9f960 + 7afbb00 commit 436225a

File tree

3 files changed

+9
-69
lines changed

3 files changed

+9
-69
lines changed

openslide/lowlevel.py

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import platform
3838
import sys
3939

40+
from . import _convert
41+
4042
if platform.system() == 'Windows':
4143
_lib = cdll.LoadLibrary('libopenslide-0.dll')
4244
elif platform.system() == 'Darwin':
@@ -57,58 +59,6 @@
5759
else:
5860
_lib = cdll.LoadLibrary('libopenslide.so.0')
5961

60-
try:
61-
from . import _convert
62-
def _load_image(buf, size):
63-
'''buf must be a mutable buffer.'''
64-
_convert.argb2rgba(buf)
65-
return PIL.Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
66-
except ImportError:
67-
def _load_image(buf, size):
68-
'''buf must be a buffer.'''
69-
70-
# Load entire buffer at once if possible
71-
MAX_PIXELS_PER_LOAD = (1 << 29) - 1
72-
# Otherwise, use chunks smaller than the maximum to reduce memory
73-
# requirements
74-
PIXELS_PER_LOAD = 1 << 26
75-
76-
def do_load(buf, size):
77-
'''buf can be a string, but should be a ctypes buffer to avoid an
78-
extra copy in the caller.'''
79-
# First reorder the bytes in a pixel from native-endian aRGB to
80-
# big-endian RGBa to work around limitations in RGBa loader
81-
rawmode = (sys.byteorder == 'little') and 'BGRA' or 'ARGB'
82-
buf = PIL.Image.frombuffer('RGBA', size, buf, 'raw', rawmode, 0, 1)
83-
# Image.tobytes() is named tostring() in Pillow 1.x and PIL
84-
buf = (getattr(buf, 'tobytes', None) or buf.tostring)()
85-
# Now load the image as RGBA, undoing premultiplication
86-
return PIL.Image.frombuffer('RGBA', size, buf, 'raw', 'RGBa', 0, 1)
87-
88-
# Fast path for small buffers
89-
w, h = size
90-
if w * h <= MAX_PIXELS_PER_LOAD:
91-
return do_load(buf, size)
92-
93-
# Load in chunks to avoid OverflowError in PIL.Image.frombuffer()
94-
# https://github.com/python-pillow/Pillow/issues/1475
95-
if w > PIXELS_PER_LOAD:
96-
# We could support this, but it seems like overkill
97-
raise ValueError('Width %d is too large (maximum %d)' %
98-
(w, PIXELS_PER_LOAD))
99-
rows_per_load = PIXELS_PER_LOAD // w
100-
img = PIL.Image.new('RGBA', (w, h))
101-
for y in range(0, h, rows_per_load):
102-
rows = min(h - y, rows_per_load)
103-
if sys.version[0] == '2':
104-
chunk = buffer(buf, 4 * y * w, 4 * rows * w)
105-
else:
106-
# PIL.Image.frombuffer() won't take a memoryview or
107-
# bytearray, so we can't avoid copying
108-
chunk = memoryview(buf)[y * w:(y + rows) * w].tobytes()
109-
img.paste(do_load(chunk, (w, rows)), (0, y))
110-
return img
111-
11262
class OpenSlideError(Exception):
11363
"""An error produced by the OpenSlide library.
11464
@@ -167,6 +117,11 @@ def from_param(cls, obj):
167117
else:
168118
raise TypeError('Incorrect type')
169119

120+
def _load_image(buf, size):
121+
'''buf must be a mutable buffer.'''
122+
_convert.argb2rgba(buf)
123+
return PIL.Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
124+
170125
# check for errors opening an image file and wrap the resulting handle
171126
def _check_open(result, _func, _args):
172127
if result is None:

tests/__init__.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@
2222
from PIL import Image
2323
import unittest
2424

25-
try:
26-
import openslide._convert as _
27-
have_optimizations = True
28-
except ImportError:
29-
have_optimizations = False
30-
31-
3225
# PIL.Image cannot have zero width or height on Pillow 3.4.0 - 3.4.2
3326
# https://github.com/python-pillow/Pillow/issues/2259
3427
try:

tests/test_openslide.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
import sys
2626
import unittest
2727

28-
from . import (file_path, have_optimizations, image_dimensions_cannot_be_zero,
29-
skip_if)
28+
from . import file_path, image_dimensions_cannot_be_zero, skip_if
3029

3130
# Tests should be written to be compatible with Python 2.6 unittest.
3231

@@ -127,8 +126,7 @@ def test_read_region_bad_size(self):
127126
@skip_if(sys.maxsize < 1 << 32, '32-bit Python')
128127
# Broken on PIL and on Pillow >= 3.4.0, < 6.2.0.
129128
# https://github.com/python-pillow/Pillow/issues/3963
130-
@skip_if(have_optimizations and
131-
[int(i) for i in getattr(Image, '__version__', '0').split('.')] < [6,2,0],
129+
@skip_if([int(i) for i in getattr(Image, '__version__', '0').split('.')] < [6,2,0],
132130
'broken on PIL and Pillow < 6.2.0')
133131
# Disabled to avoid OOM killer on small systems, since the stdlib
134132
# doesn't provide a way to find out how much RAM we have
@@ -137,12 +135,6 @@ def _test_read_region_2GB(self):
137135
self.osr.read_region((1000, 1000), 0, (32768, 16384)).size,
138136
(32768, 16384))
139137

140-
@skip_if(have_optimizations, 'only relevant --without-performance')
141-
@skip_if(sys.maxsize < 1 << 32, '32-bit Python')
142-
def test_read_region_2GB_width(self):
143-
self.assertRaises(ValueError,
144-
lambda: self.osr.read_region((1000, 1000), 0, (1 << 29, 1)))
145-
146138
def test_thumbnail(self):
147139
self.assertEqual(self.osr.get_thumbnail((100, 100)).size, (100, 83))
148140

0 commit comments

Comments
 (0)