Skip to content

Commit

Permalink
Harden tile source detection.
Browse files Browse the repository at this point in the history
Detecting geospatial files was brittler than intended.  Bioformats
throws poor errors.
  • Loading branch information
manthey committed Aug 24, 2021
1 parent 649a2be commit 214c3c4
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 7 deletions.
2 changes: 2 additions & 0 deletions large_image/tilesource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def isGeospatial(path):
ds = gdal.Open(path, gdalconst.GA_ReadOnly)
except Exception:
return False
if ds.GetGCPs() and ds.GetGCPProjection():
return True
if ds.GetProjection():
return True
if ds.GetDriver().ShortName in {'NITF', 'netCDF'}:
Expand Down
10 changes: 7 additions & 3 deletions large_image/tilesource/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,13 @@ def _vipsCast(image, mustBe8Bit=False, originalScale=None):
return image


def _gdalParameters(defaultCompression=None, **kwargs):
def _gdalParameters(defaultCompression=None, eightbit=None, **kwargs):
"""
Return an array of gdal translation parameters.
:param defaultCompression: if not specified, use this value.
:param eightbit: True or False to indicate that the bit depth per sample is
known. None for unknown.
Optional parameters that can be specified in kwargs:
Expand All @@ -227,8 +229,9 @@ def _gdalParameters(defaultCompression=None, **kwargs):
'tileSize': 256,
'compression': 'lzw',
'quality': 90,
'predictor': 'yes',
}
if eightbit is not None:
options['predictor'] = 'yes' if eightbit else 'none'
predictor = {
'none': 'NO',
'horizontal': 'STANDARD',
Expand All @@ -240,7 +243,8 @@ def _gdalParameters(defaultCompression=None, **kwargs):
cmdopt += ['-co', 'BLOCKSIZE=%d' % options['tileSize']]
cmdopt += ['-co', 'COMPRESS=%s' % options['compression'].upper()]
cmdopt += ['-co', 'QUALITY=%s' % options['quality']]
cmdopt += ['-co', 'PREDICTOR=%s' % predictor[options['predictor']]]
if 'predictor' in options:
cmdopt += ['-co', 'PREDICTOR=%s' % predictor[options['predictor']]]
if 'level' in options:
cmdopt += ['-co', 'LEVEL=%s' % options['level']]
return cmdopt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def __init__(self, path, **kwargs): # noqa
javabridge.attach()
try:
self._bioimage = bioformats.ImageReader(largeImagePath)
except AttributeError as exc:
except (AttributeError, FileNotFoundError) as exc:
self.logger.debug('File cannot be opened via Bioformats. (%r)' % exc)
raise TileSourceException('File cannot be opened via Bioformats. (%r)' % exc)
_openImages.append(self)
Expand Down
1 change: 1 addition & 0 deletions sources/gdal/large_image_source_gdal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class GDALFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
name = 'gdalfile'
extensions = {
None: SourcePriority.MEDIUM,
'geotiff': SourcePriority.PREFERRED,
# National Imagery Transmission Format
'ntf': SourcePriority.PREFERRED,
'nitf': SourcePriority.PREFERRED,
Expand Down
10 changes: 7 additions & 3 deletions utilities/converter/large_image_converter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ def convert(inputPath, outputPath=None, **kwargs): # noqa: C901
geospatial = kwargs.get('geospatial')
if geospatial is None:
geospatial = is_geospatial(inputPath)
logger.debug('Is file geospatial: %r', geospatial)
suffix = format_hook('adjust_params', geospatial, kwargs, **kwargs)
if suffix is False:
return
Expand All @@ -871,16 +872,16 @@ def convert(inputPath, outputPath=None, **kwargs): # noqa: C901
tiffinfo = tifftools.read_tiff(inputPath)
except Exception:
tiffinfo = None
eightbit = _is_eightbit(inputPath, tiffinfo)
if not kwargs.get('compression', None):
kwargs = kwargs.copy()
lossy = _is_lossy(inputPath, tiffinfo)
logger.debug('Is file lossy: %r', lossy)
eightbit = _is_eightbit(inputPath, tiffinfo)
logger.debug('Is file 8 bits per samples: %r', eightbit)
kwargs['_compression'] = None
kwargs['compression'] = 'jpeg' if lossy and eightbit else 'lzw'
if geospatial:
_generate_geotiff(inputPath, outputPath, **kwargs)
_generate_geotiff(inputPath, outputPath, eightbit=eightbit or None, **kwargs)
else:
with TemporaryDirectory() as tempDir:
tempPath = os.path.join(tempDir, os.path.basename(outputPath))
Expand Down Expand Up @@ -917,7 +918,10 @@ def is_geospatial(path):
ds = gdal.Open(path, gdalconst.GA_ReadOnly)
except Exception:
return False
if ds and (ds.GetProjection() or ds.GetDriver().ShortName in {'NITF', 'netCDF'}):
if ds and (
(ds.GetGCPs() and ds.GetGCPProjection()) or
ds.GetProjection() or
ds.GetDriver().ShortName in {'NITF', 'netCDF'}):
return True
return False

Expand Down

0 comments on commit 214c3c4

Please sign in to comment.