large-image-source-multi 1.29.7.dev38__tar.gz → 1.29.8.dev6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (16) hide show
  1. {large-image-source-multi-1.29.7.dev38/large_image_source_multi.egg-info → large-image-source-multi-1.29.8.dev6}/PKG-INFO +4 -3
  2. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi/__init__.py +68 -24
  3. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6/large_image_source_multi.egg-info}/PKG-INFO +4 -3
  4. large-image-source-multi-1.29.8.dev6/large_image_source_multi.egg-info/requires.txt +9 -0
  5. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/setup.py +1 -0
  6. large-image-source-multi-1.29.7.dev38/large_image_source_multi.egg-info/requires.txt +0 -9
  7. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/LICENSE +0 -0
  8. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/README.rst +0 -0
  9. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/docs/specification.rst +0 -0
  10. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi/girder_source.py +0 -0
  11. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi.egg-info/SOURCES.txt +0 -0
  12. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi.egg-info/dependency_links.txt +0 -0
  13. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi.egg-info/entry_points.txt +0 -0
  14. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/large_image_source_multi.egg-info/top_level.txt +0 -0
  15. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/pyproject.toml +0 -0
  16. {large-image-source-multi-1.29.7.dev38 → large-image-source-multi-1.29.8.dev6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: large-image-source-multi
3
- Version: 1.29.7.dev38
3
+ Version: 1.29.8.dev6
4
4
  Summary: A tilesource for large_image to composite other tile sources
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -16,14 +16,15 @@ Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Requires-Python: >=3.6
19
+ Description-Content-Type: text/x-rst
19
20
  License-File: LICENSE
20
21
  Requires-Dist: jsonschema
21
- Requires-Dist: large-image>=1.29.7.dev38
22
+ Requires-Dist: large-image>=1.29.8.dev6
22
23
  Requires-Dist: pyyaml
23
24
  Provides-Extra: all
24
25
  Requires-Dist: scikit-image; extra == "all"
25
26
  Provides-Extra: girder
26
- Requires-Dist: girder-large-image>=1.29.7.dev38; extra == "girder"
27
+ Requires-Dist: girder-large-image>=1.29.8.dev6; extra == "girder"
27
28
 
28
29
  A tilesource for large_image to composite other tile sources
29
30
 
@@ -288,6 +288,18 @@ SourceEntrySchema = {
288
288
  'type': 'array',
289
289
  'items': {'type': 'integer'},
290
290
  },
291
+ 'sampleScale': {
292
+ 'description':
293
+ 'Each pixel sample values is divided by this scale after any '
294
+ 'sampleOffset has been applied',
295
+ 'type': 'number',
296
+ },
297
+ 'sampleOffset': {
298
+ 'description':
299
+ 'This is added to each pixel sample value before any '
300
+ 'sampleScale is applied',
301
+ 'type': 'number',
302
+ },
291
303
  'style': {'type': 'object'},
292
304
  'params': {
293
305
  'description':
@@ -806,7 +818,7 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
806
818
  self._bands = {}
807
819
  self._bands.update(tsMeta['bands'])
808
820
  lastSource = source
809
- self._bandcount = 1 if self._info.get('singleBand') else (
821
+ self._bandCount = 1 if self._info.get('singleBand') else (
810
822
  len(self._bands) if hasattr(self, '_bands') else (bandCount or None))
811
823
  bbox = self._sourceBoundingBox(source, tsMeta['sizeX'], tsMeta['sizeY'])
812
824
  computedWidth = max(computedWidth, int(math.ceil(bbox['right'])))
@@ -875,6 +887,20 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
875
887
  if params is None:
876
888
  params = source.get('params', {})
877
889
  ts = openFunc(source['path'], **params)
890
+ if (self._dtype and np.dtype(ts.dtype).kind == 'f' and self._dtype.kind != 'f' and
891
+ 'sampleScale' not in source and 'sampleOffset' not in source):
892
+ minval = maxval = 0
893
+ for f in range(ts.frames):
894
+ ftile = ts.getTile(x=0, y=0, z=0, frame=f, numpyAllowed='always')
895
+ minval = min(minval, np.amin(ftile))
896
+ maxval = max(maxval, np.amax(ftile))
897
+ if minval >= 0 and maxval <= 1:
898
+ source['sampleScale'] = None
899
+ elif minval >= 0:
900
+ source['sampleScale'] = 2 ** math.ceil(math.log2(maxval))
901
+ else:
902
+ source['sampleScale'] = 2 ** math.ceil(math.log2(max(-minval, maxval)) + 1)
903
+ source['sampleOffset'] = source['sampleScale'] / 2
878
904
  source['sourceName'] = ts.name
879
905
  with self._lastOpenSourceLock:
880
906
  self._lastOpenSource = {
@@ -1002,8 +1028,8 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1002
1028
  """
1003
1029
  Determine where the target tile's corners are located on the source.
1004
1030
  Fetch that so that we have at least sqrt(2) more resolution, then use
1005
- scikit-image warp to transform it. scikit-image does a better job than
1006
- scipy.ndimage.affine_transform.
1031
+ scikit-image warp to transform it. scikit-image does a better and
1032
+ faster job than scipy.ndimage.affine_transform.
1007
1033
 
1008
1034
  :param ts: the source of the image to transform.
1009
1035
  :param transform: a 3x3 affine 2d matrix for transforming the source
@@ -1045,7 +1071,7 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1045
1071
  # we only need every 1/srcscale pixel.
1046
1072
  srcscale = int(2 ** math.log2(max(1, srcscale)))
1047
1073
  # Pad to reduce edge effects at tile boundaries
1048
- border = int(math.ceil(2 * srcscale))
1074
+ border = int(math.ceil(4 * srcscale))
1049
1075
  region = {
1050
1076
  'left': int(max(0, minx - border) // srcscale) * srcscale,
1051
1077
  'top': int(max(0, miny - border) // srcscale) * srcscale,
@@ -1092,28 +1118,35 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1092
1118
  x, y = int(math.floor(x)), int(math.floor(y))
1093
1119
  # Recompute where the source corners will land
1094
1120
  destcorners = (np.dot(transform, regioncorners.T).T).tolist()
1095
- destsize = (max(math.ceil(c[0]) for c in destcorners),
1096
- max(math.ceil(c[1]) for c in destcorners))
1121
+ destShape = [
1122
+ max(max(math.ceil(c[0]) for c in destcorners), srcImage.shape[1]),
1123
+ max(max(math.ceil(c[1]) for c in destcorners), srcImage.shape[0]),
1124
+ ]
1125
+ if max(0, -x) or max(0, -y):
1126
+ transform[0][2] -= max(0, -x)
1127
+ transform[1][2] -= max(0, -y)
1128
+ destShape[0] -= max(0, -y)
1129
+ destShape[1] -= max(0, -x)
1130
+ x += max(0, -x)
1131
+ y += max(0, -y)
1132
+ destShape = [min(destShape[0], outh - y), min(destShape[1], outw - x)]
1133
+ if destShape[0] <= 0 or destShape[1] <= 0:
1134
+ return None, None, None
1097
1135
  # Add an alpha band if needed
1098
1136
  if srcImage.shape[2] in {1, 3}:
1099
1137
  _, srcImage = _makeSameChannelDepth(np.zeros((1, 1, srcImage.shape[2] + 1)), srcImage)
1100
- # Add enough space to warp the source image in place
1101
- srcImage = np.pad(srcImage, (
1102
- (0, max(0, destsize[1] - srcImage.shape[0])),
1103
- (0, max(0, destsize[0] - srcImage.shape[1])),
1104
- (0, 0)), mode='constant')
1138
+ # skimage.transform.warp is faster and has less artifacts than
1139
+ # scipy.ndimage.affine_transform. It is faster than using cupy's
1140
+ # version of scipy's affine_transform when the source and destination
1141
+ # images are converted from numpy to cupy and back in this method.
1105
1142
  destImage = skimage.transform.warp(
1143
+ # Although using np.float32 could reduce memory use, it doesn't
1144
+ # provide any speed improvement
1106
1145
  srcImage.astype(float),
1107
- skimage.transform.AffineTransform(np.linalg.inv(
1108
- transform))).astype(srcImage.dtype)
1109
- # Trim to target size and location
1110
- destImage = destImage[max(0, -y):, max(0, -x):, :]
1111
- x += max(0, -x)
1112
- y += max(0, -y)
1113
- if x >= outw or y >= outh:
1114
- return None, None, None
1115
- destImage = destImage[:min(destImage.shape[0], outh - y),
1116
- :min(destImage.shape[1], outw - x), :]
1146
+ skimage.transform.AffineTransform(np.linalg.inv(transform)),
1147
+ order=3,
1148
+ output_shape=(destShape[0], destShape[1], srcImage.shape[2]),
1149
+ ).astype(srcImage.dtype)
1117
1150
  return destImage, x, y
1118
1151
 
1119
1152
  def _addSourceToTile(self, tile, sourceEntry, corners, scale):
@@ -1190,9 +1223,20 @@ class MultiFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1190
1223
  ts, transform, corners, scale, sourceEntry.get('frame', 0),
1191
1224
  source.get('position', {}).get('crop'))
1192
1225
  if sourceTile is not None and all(dim > 0 for dim in sourceTile.shape):
1193
- sourceTile = sourceTile.astype(
1194
- ts.dtype if not self._info.get('dtype') else
1195
- np.dtype(self._info['dtype']))
1226
+ targetDtype = np.dtype(self._info.get('dtype', ts.dtype))
1227
+ changeDtype = sourceTile.dtype != targetDtype
1228
+ if source.get('sampleScale') or source.get('sampleOffset'):
1229
+ sourceTile = sourceTile.astype(float)
1230
+ if source.get('sampleOffset'):
1231
+ sourceTile[:, :, :-1] += source['sampleOffset']
1232
+ if source.get('sampleScale') and source.get('sampleScale') != 1:
1233
+ sourceTile[:, :, :-1] /= source['sampleScale']
1234
+ if sourceTile.dtype != targetDtype:
1235
+ if changeDtype:
1236
+ sourceTile = (
1237
+ sourceTile.astype(float) * fullAlphaValue(targetDtype) /
1238
+ fullAlphaValue(sourceTile))
1239
+ sourceTile = sourceTile.astype(targetDtype)
1196
1240
  tile = self._mergeTiles(tile, sourceTile, x, y)
1197
1241
  return tile
1198
1242
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: large-image-source-multi
3
- Version: 1.29.7.dev38
3
+ Version: 1.29.8.dev6
4
4
  Summary: A tilesource for large_image to composite other tile sources
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -16,14 +16,15 @@ Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Requires-Python: >=3.6
19
+ Description-Content-Type: text/x-rst
19
20
  License-File: LICENSE
20
21
  Requires-Dist: jsonschema
21
- Requires-Dist: large-image>=1.29.7.dev38
22
+ Requires-Dist: large-image>=1.29.8.dev6
22
23
  Requires-Dist: pyyaml
23
24
  Provides-Extra: all
24
25
  Requires-Dist: scikit-image; extra == "all"
25
26
  Provides-Extra: girder
26
- Requires-Dist: girder-large-image>=1.29.7.dev38; extra == "girder"
27
+ Requires-Dist: girder-large-image>=1.29.8.dev6; extra == "girder"
27
28
 
28
29
  A tilesource for large_image to composite other tile sources
29
30
 
@@ -0,0 +1,9 @@
1
+ jsonschema
2
+ large-image>=1.29.8.dev6
3
+ pyyaml
4
+
5
+ [all]
6
+ scikit-image
7
+
8
+ [girder]
9
+ girder-large-image>=1.29.8.dev6
@@ -37,6 +37,7 @@ setup(
37
37
  'fallback_version': '0.0.0'},
38
38
  description=description,
39
39
  long_description=long_description,
40
+ long_description_content_type='text/x-rst',
40
41
  license='Apache Software License 2.0',
41
42
  author='Kitware, Inc.',
42
43
  author_email='kitware@kitware.com',
@@ -1,9 +0,0 @@
1
- jsonschema
2
- large-image>=1.29.7.dev38
3
- pyyaml
4
-
5
- [all]
6
- scikit-image
7
-
8
- [girder]
9
- girder-large-image>=1.29.7.dev38