Skip to content

Commit

Permalink
Merge pull request #1650 from girder/style-with-empty-levels
Browse files Browse the repository at this point in the history
Fix styling images with empty tile layers
  • Loading branch information
manthey authored Sep 25, 2024
2 parents 9911354 + d38b499 commit af9a8a7
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Better handle images without enough tile layers ([#1648](../../pull/1648))
- Add users option to config files; have a default config file ([#1649](../../pull/1649))

### Bug Fixes

- Fix styling images with empty tile layers ([#1650](../../pull/1650))

## 1.29.11

### Changes
Expand Down
9 changes: 5 additions & 4 deletions large_image/tilesource/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ def _getTileFromEmptyLevel(self, x: int, y: int, z: int, **kwargs) -> Tuple[
'Compositing tile from higher resolution tiles x=%d y=%d z=%d',
x * scale + newX, y * scale + newY, z)
lastlog = time.time()
subtile = self.getTile(
subtile = getattr(self, '_unstyledInstance', self).getTile(
x * scale + newX, y * scale + newY, z,
pilImageAllowed=False, numpyAllowed='always',
sparseFallback=True, edge=False, frame=kwargs.get('frame'))
Expand All @@ -1559,7 +1559,7 @@ def _getTileFromEmptyLevel(self, x: int, y: int, z: int, **kwargs) -> Tuple[
'Compositing tile from higher resolution tiles x=%d y=%d z=%d',
x * scale + newX, y * scale + newY, z)
lastlog = time.time()
subtile = self.getTile(
subtile = getattr(self, '_unstyledInstance', self).getTile(
x * scale + newX, y * scale + newY, z,
pilImageAllowed=True, numpyAllowed=False,
sparseFallback=True, edge=False, frame=kwargs.get('frame'))
Expand Down Expand Up @@ -1815,7 +1815,8 @@ def getRegion(self, format: Union[str, Tuple[str]] = (TILE_FORMAT_IMAGE, ), **kw
cast(Dict[str, Any], tiledimage), outWidth, outHeight, tileIter.info, **kwargs)
if outWidth != regionWidth or outHeight != regionHeight:
dtype = cast(np.ndarray, image).dtype
if dtype == np.uint8 or resample is not None:
if dtype == np.uint8 or (resample is not None and (
dtype != np.uint16 or cast(np.ndarray, image).shape[-1] != 1)):
image = _imageToPIL(cast(np.ndarray, image), mode).resize(
(outWidth, outHeight),
getattr(PIL.Image, 'Resampling', PIL.Image).NEAREST
Expand All @@ -1828,7 +1829,7 @@ def getRegion(self, format: Union[str, Tuple[str]] = (TILE_FORMAT_IMAGE, ), **kw
else:
cols = [int(idx * regionWidth / outWidth) for idx in range(outWidth)]
rows = [int(idx * regionHeight / outHeight) for idx in range(outHeight)]
image = np.take(np.take(image, rows, axis=0), cols, axis=1)
image = np.take(np.take(cast(np.ndarray, image), rows, axis=0), cols, axis=1)
maxWidth = kwargs.get('output', {}).get('maxWidth')
maxHeight = kwargs.get('output', {}).get('maxHeight')
if kwargs.get('fill') and maxWidth and maxHeight:
Expand Down
6 changes: 2 additions & 4 deletions sources/tiff/large_image_source_tiff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,6 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False,
else:
dir = self._tiffDirectories[z]
try:
allowStyle = True
if dir is None:
try:
if not kwargs.get('inSparseFallback'):
Expand All @@ -676,7 +675,6 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False,
raise IOTiffError('Missing z level %d' % z)
else:
raise
allowStyle = False
else:
tile = dir.getTile(x, y, asarray=numpyAllowed == 'always')
format = 'JPEG'
Expand All @@ -685,7 +683,7 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False,
if isinstance(tile, np.ndarray):
format = TILE_FORMAT_NUMPY
return self._outputTile(tile, format, x, y, z, pilImageAllowed,
numpyAllowed, applyStyle=allowStyle, **kwargs)
numpyAllowed, **kwargs)
except InvalidOperationTiffError as e:
raise TileSourceError(e.args[0])
except IOTiffError as e:
Expand Down Expand Up @@ -734,7 +732,7 @@ def getTileIOTiffError(self, x, y, z, pilImageAllowed=False,
else:
image = PIL.Image.new('RGBA', (self.tileWidth, self.tileHeight))
return self._outputTile(image, TILE_FORMAT_PIL, x, y, z, pilImageAllowed,
numpyAllowed, applyStyle=False, **kwargs)
numpyAllowed, **kwargs)
raise TileSourceError('Internal I/O failure: %s' % exception.args[0])

def _nonemptyLevelsList(self, frame=0):
Expand Down

0 comments on commit af9a8a7

Please sign in to comment.