Skip to content

Commit

Permalink
Merge branch 'master' into jupyter-frame-selector
Browse files Browse the repository at this point in the history
  • Loading branch information
annehaley authored Jan 28, 2025
2 parents 2f029fa + 4b2b390 commit b831097
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
- Automatically set the JUPYTER_PROXY value ([#1781](../../pull/1781))
- Add a general channelNames property to tile sources ([#1783](../../pull/1783))
- Speed up compositing styles ([#1784](../../pull/1784))
- Better repr of large_image classes ([#1787](../../pull/1787))
- Better detect multiframe images in PIL ([#1791](../../pull/1791))

### Changes

- Allow umap-learn for graphing in girder annotations in python 3.13 ([#1780](../../pull/1780))
- List a few more known extensions for different sources ([#1790](../../pull/1790))

### Bug Fixes

Expand Down
7 changes: 4 additions & 3 deletions large_image/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ class SourcePriority(enum.IntEnum):
LOWER = 6
IMPLICIT_HIGH = 7
IMPLICIT = 8
FALLBACK_HIGH = 9
FALLBACK = 10
MANUAL = 11 # This and higher values will never be selected automatically
IMPLICIT_LOW = 9
FALLBACK_HIGH = 10
FALLBACK = 11
MANUAL = 12 # This and higher values will never be selected automatically


TILE_FORMAT_IMAGE = 'image'
Expand Down
21 changes: 20 additions & 1 deletion large_image/tilesource/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,30 @@ def __reduce__(self) -> Tuple[functools.partial, Tuple[str]]:
return functools.partial(type(self), **self._initValues[1]), self._initValues[0]

def __repr__(self) -> str:
return self.getState()
if hasattr(self, '_initValues') and not hasattr(self, '_unpickleable'):
param = [
f'{k}={v!r}' if k != 'style' or not isinstance(v, dict) or
not getattr(self, '_jsonstyle', None) else
f'style={json.loads(self._jsonstyle)}'
for k, v in self._initValues[1].items()]
return (
f'{self.__class__.__name__}('
f'{", ".join(repr(val) for val in self._initValues[0])}'
f'{", " if len(self._initValues[1]) else ""}'
f'{", ".join(param)}'
')')
return '<' + self.getState() + '>'

def _repr_png_(self) -> bytes:
return self.getThumbnail(encoding='PNG')[0]

def __rich_repr__(self) -> Iterator[Any]:
if not hasattr(self, '_initValues') or hasattr(self, '_unpickleable'):
yield self.getState()
else:
yield from self._initValues[0]
yield from self._initValues[1].items()

@property
def geospatial(self) -> bool:
return False
Expand Down
4 changes: 4 additions & 0 deletions sources/bioformats/large_image_source_bioformats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,10 @@ def addKnownExtensions(cls):
'fake', 'no'}:
if ext not in cls.extensions:
cls.extensions[ext] = SourcePriority.IMPLICIT
# These were found by reading some OMERO test files
for ext in {'columbusidx', 'dv_vol', 'lifext'}:
if ext.lower() not in cls.extensions:
cls.extensions[ext.lower()] = SourcePriority.IMPLICIT_LOW


def open(*args, **kwargs):
Expand Down
10 changes: 10 additions & 0 deletions sources/gdal/large_image_source_gdal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,16 @@ def addKnownExtensions(cls):
if drvmimes is not None:
if drvmimes not in cls.mimeTypes:
cls.mimeTypes[drvmimes] = SourcePriority.IMPLICIT
# This list was compiled by trying to read the test files in GDAL's
# repo.
for ext in {
'adf', 'aux', 'demtif', 'dim', 'doq', 'flt', 'fst',
'gdbtable', 'gsc', 'h3', 'idf', 'lan', 'los', 'lrc',
'mapml', 'mint.bin', 'mtw', 'nsf', 'nws', 'on2', 'on9',
'osm.pbf', 'pjg', 'prj', 'ptf', 'rasterlite', 'rdb', 'rl2',
'shx', 'sos', 'tif.grd', 'til', 'vic', 'xlb'}:
if ext.lower() not in cls.extensions:
cls.extensions[ext.lower()] = SourcePriority.IMPLICIT_LOW


def open(*args, **kwargs):
Expand Down
18 changes: 16 additions & 2 deletions sources/pil/large_image_source_pil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class PILFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
'jpg': SourcePriority.LOW,
'jpeg': SourcePriority.LOW,
'jpe': SourcePriority.LOW,
'nef': SourcePriority.LOW,
}
mimeTypes = {
None: SourcePriority.FALLBACK_HIGH,
Expand Down Expand Up @@ -222,11 +223,20 @@ def _fromRawpy(self, largeImagePath):
"""
Try to use rawpy to read an image.
"""
# if rawpy is present, try reading via that library first
# if rawpy is present, try reading via that library first, but only
# if PIL reports a single frame
try:
img = PIL.Image.open(largeImagePath)
if len(list(PIL.ImageSequence.Iterator(img))) > 1:
return
except Exception:
pass
try:
import builtins

import rawpy

with contextlib.redirect_stderr(open(os.devnull, 'w')):
with contextlib.redirect_stderr(builtins.open(os.devnull, 'w')):
rgb = rawpy.imread(largeImagePath).postprocess()
rgb = large_image.tilesource.utilities._imageToNumpy(rgb)[0]
if rgb.shape[2] == 2:
Expand Down Expand Up @@ -323,6 +333,10 @@ def addKnownExtensions(cls):
for mimeType in PIL.Image.MIME.values():
if mimeType not in cls.mimeTypes:
cls.mimeTypes[mimeType] = SourcePriority.IMPLICIT_HIGH
# These were found by reading various test files.
for ext in {'ppg'}:
if ext.lower() not in cls.extensions:
cls.extensions[ext.lower()] = SourcePriority.IMPLICIT_LOW


def open(*args, **kwargs):
Expand Down
3 changes: 2 additions & 1 deletion sources/pil/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def prerelease_local_scheme(version):
'all': [
'rawpy',
'pillow-heif',
'pillow-jxl-plugin',
'pillow-jxl-plugin < 1.3 ; python_version < "3.8"',
'pillow-jxl-plugin ; python_version >= "3.9"',
'pillow-jpls',
],
'girder': f'girder-large-image{limit_version}',
Expand Down
9 changes: 9 additions & 0 deletions sources/rasterio/large_image_source_rasterio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,15 @@ def addKnownExtensions(cls):
for ext in rasterio.drivers.raster_driver_extensions():
if ext not in cls.extensions:
cls.extensions[ext] = SourcePriority.IMPLICIT
# This list was compiled by trying to read the test files in GDAL's
# repo.
for ext in {
'adf', 'aux', 'demtif', 'dim', 'doq', 'flt', 'fst', 'gsc',
'h3', 'lan', 'los', 'lrc', 'mint.bin', 'mtw', 'nsf', 'nws',
'on9', 'pjg', 'png.ovr', 'prj', 'ptf', 'rasterlite', 'rdb',
'tif.grd', 'til', 'vic', 'xlb'}:
if ext.lower() not in cls.extensions:
cls.extensions[ext.lower()] = SourcePriority.IMPLICIT_LOW


def open(*args, **kwargs):
Expand Down
1 change: 1 addition & 0 deletions test/lisource_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ def command():
if not large_image.tilesource.AvailableTileSources:
large_image.tilesource.loadTileSources()
if opts.all:
large_image.config.setConfig('max_small_image_size', 16384)
for key in list(large_image.config.ConfigValues):
if '_ignored_names' in key:
del large_image.config.ConfigValues[key]
Expand Down

0 comments on commit b831097

Please sign in to comment.