Skip to content

Commit

Permalink
Speed up style composition.
Browse files Browse the repository at this point in the history
The speed up is achieved by have a special case for palettes that have
two entries with the first entry 0 and for conditions where no mask is
required.

Slightly speed up source comparison
  • Loading branch information
manthey committed Jan 22, 2025
1 parent e817806 commit 9b56008
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Default to not caching source in notebooks ([#1776](../../pull/1776))
- 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))

### Changes

Expand Down
2 changes: 1 addition & 1 deletion docs/tilesource_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ A band definition is an object which can contain the following keys:

- ``band``: the band numpy image in a band stage.

- ``mask``: a mask numpy image to use when applying the band.
- ``mask``: a mask numpy image to use when applying the band. None for no mask (this is the equivalent of the mask being all True).

- ``palette``: the normalized palette for a band.

Expand Down
26 changes: 15 additions & 11 deletions large_image/tilesource/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,9 +1070,11 @@ def _applyStyle( # noqa
if sc.nodata is not None:
sc.mask = sc.band != float(sc.nodata)
else:
sc.mask = np.full(image.shape[:2], True)
sc.mask = None
sc.band = (sc.band - sc.min) / delta
if not sc.clamp:
if sc.mask is None:
sc.mask = np.full(image.shape[:2], True)
sc.mask = sc.mask & (sc.band >= 0) & (sc.band <= 1)
sc.band = self._applyStyleFunction(sc.band, sc, 'band')
# To implement anything other multiply or lighten, we should mimic
Expand All @@ -1097,25 +1099,27 @@ def _applyStyle( # noqa
if not channel or np.any(
sc.palette[:, channel] != sc.palette[:, channel - 1]):
if not sc.discrete:
clrs = np.interp(sc.band, sc.palettebase, sc.palette[:, channel])
if len(sc.palette) == 2 and sc.palette[0, channel] == 0:
clrs = sc.band * sc.palette[1, channel]
else:
clrs = np.interp(sc.band, sc.palettebase, sc.palette[:, channel])
else:
clrs = sc.palette[
np.floor(sc.band * len(sc.palette)).astype(int).clip(
0, len(sc.palette) - 1), channel]
if sc.composite == 'multiply':
if eidx:
sc.output[:sc.mask.shape[0], :sc.mask.shape[1], channel] = np.multiply(
sc.output[:sc.mask.shape[0], :sc.mask.shape[1], channel],
np.where(sc.mask, clrs / 255, 1))
sc.output[:clrs.shape[0], :clrs.shape[1], channel] = np.multiply(
sc.output[:clrs.shape[0], :clrs.shape[1], channel],
(clrs / 255) if sc.mask is None else np.where(sc.mask, clrs / 255, 1))
else:
if not eidx:
sc.output[:sc.mask.shape[0],
:sc.mask.shape[1],
channel] = np.where(sc.mask, clrs, 0)
sc.output[:clrs.shape[0], :clrs.shape[1], channel] = (
clrs if sc.mask is None else np.where(sc.mask, clrs, 0))
else:
sc.output[:sc.mask.shape[0], :sc.mask.shape[1], channel] = np.maximum(
sc.output[:sc.mask.shape[0], :sc.mask.shape[1], channel],
np.where(sc.mask, clrs, 0))
sc.output[:clrs.shape[0], :clrs.shape[1], channel] = np.maximum(
sc.output[:clrs.shape[0], :clrs.shape[1], channel],
clrs if sc.mask is None else np.where(sc.mask, clrs, 0))
sc.output = self._applyStyleFunction(sc.output, sc, 'postband')
if hasattr(sc, 'styleIndex'):
del sc.styleIndex
Expand Down
4 changes: 2 additions & 2 deletions test/lisource_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ def source_compare(sourcePath, opts): # noqa
canread = large_image.canReadList(sourcePath, availableSources=sublist)
if opts.can_read and not len([cr for cr in canread if cr[1]]):
return None
large_image.cache_util.cachesClear()
slen = max([len(source) for source, _ in canread] + [10])
sys.stdout.write('Source' + ' ' * (slen - 6))
sys.stdout.write(' Width Height')
Expand Down Expand Up @@ -208,7 +207,8 @@ def source_compare(sourcePath, opts): # noqa
'_geospatial_source', None):
continue
result = results['styles'][-1]['sources'][source] = {}
large_image.cache_util.cachesClear()
if couldread:
large_image.cache_util.cachesClear()
try:
t = time.time()
ts = large_image.tilesource.AvailableTileSources[source](sourcePath, **kwargs)
Expand Down

0 comments on commit 9b56008

Please sign in to comment.