|
2 | 2 | # openslide-python - Python bindings for the OpenSlide library |
3 | 3 | # |
4 | 4 | # Copyright (c) 2010-2014 Carnegie Mellon University |
| 5 | +# Copyright (c) 2021 Benjamin Gilbert |
5 | 6 | # |
6 | 7 | # This library is free software; you can redistribute it and/or modify it |
7 | 8 | # under the terms of version 2.1 of the GNU Lesser General Public License |
@@ -123,6 +124,12 @@ def read_region(self, location, level, size): |
123 | 124 | size: (width, height) tuple giving the region size.""" |
124 | 125 | raise NotImplementedError |
125 | 126 |
|
| 127 | + def set_cache(self, cache): |
| 128 | + """Use the specified cache to store recently decoded slide tiles. |
| 129 | +
|
| 130 | + cache: an OpenSlideCache object.""" |
| 131 | + raise NotImplementedError |
| 132 | + |
126 | 133 | def get_thumbnail(self, size): |
127 | 134 | """Return a PIL.Image containing an RGB thumbnail of the image. |
128 | 135 |
|
@@ -230,6 +237,18 @@ def read_region(self, location, level, size): |
230 | 237 | self._osr, location[0], location[1], level, size[0], size[1] |
231 | 238 | ) |
232 | 239 |
|
| 240 | + def set_cache(self, cache): |
| 241 | + """Use the specified cache to store recently decoded slide tiles. |
| 242 | +
|
| 243 | + By default, the object has a private cache with a default size. |
| 244 | +
|
| 245 | + cache: an OpenSlideCache object.""" |
| 246 | + try: |
| 247 | + llcache = cache._openslide_cache |
| 248 | + except AttributeError: |
| 249 | + raise TypeError('Not a cache object') |
| 250 | + lowlevel.set_cache(self._osr, llcache) |
| 251 | + |
233 | 252 |
|
234 | 253 | class _OpenSlideMap(Mapping): |
235 | 254 | def __init__(self, osr): |
@@ -270,6 +289,23 @@ def __getitem__(self, key): |
270 | 289 | return lowlevel.read_associated_image(self._osr, key) |
271 | 290 |
|
272 | 291 |
|
| 292 | +class OpenSlideCache: |
| 293 | + """An in-memory tile cache. |
| 294 | +
|
| 295 | + Tile caches can be attached to one or more OpenSlide objects with |
| 296 | + OpenSlide.set_cache() to cache recently-decoded tiles. By default, |
| 297 | + each OpenSlide object has its own cache with a default size. |
| 298 | + """ |
| 299 | + |
| 300 | + def __init__(self, capacity): |
| 301 | + """Create a tile cache with the specified capacity in bytes.""" |
| 302 | + self._capacity = capacity |
| 303 | + self._openslide_cache = lowlevel.cache_create(capacity) |
| 304 | + |
| 305 | + def __repr__(self): |
| 306 | + return f'{self.__class__.__name__}({self._capacity!r})' |
| 307 | + |
| 308 | + |
273 | 309 | class ImageSlide(AbstractSlide): |
274 | 310 | """A wrapper for a PIL.Image that provides the OpenSlide interface.""" |
275 | 311 |
|
@@ -382,6 +418,14 @@ def read_region(self, location, level, size): |
382 | 418 | tile.paste(crop, tile_offset) |
383 | 419 | return tile |
384 | 420 |
|
| 421 | + def set_cache(self, cache): |
| 422 | + """Use the specified cache to store recently decoded slide tiles. |
| 423 | +
|
| 424 | + ImageSlide does not support caching, so this method does nothing. |
| 425 | +
|
| 426 | + cache: an OpenSlideCache object.""" |
| 427 | + pass |
| 428 | + |
385 | 429 |
|
386 | 430 | def open_slide(filename): |
387 | 431 | """Open a whole-slide or regular image. |
|
0 commit comments