large-image-source-zarr 1.31.0__py3-none-any.whl → 1.33.6a188__py3-none-any.whl

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.
@@ -1,3 +1,6 @@
1
+ import contextlib
2
+ import importlib.metadata
3
+ import json
1
4
  import math
2
5
  import multiprocessing
3
6
  import os
@@ -6,8 +9,6 @@ import tempfile
6
9
  import threading
7
10
  import uuid
8
11
  import warnings
9
- from importlib.metadata import PackageNotFoundError
10
- from importlib.metadata import version as _importlib_version
11
12
  from pathlib import Path
12
13
 
13
14
  import numpy as np
@@ -21,11 +22,8 @@ from large_image.tilesource import FileTileSource
21
22
  from large_image.tilesource.resample import ResampleMethod, downsampleTileHalfRes
22
23
  from large_image.tilesource.utilities import _imageToNumpy, nearPowerOfTwo
23
24
 
24
- try:
25
- __version__ = _importlib_version(__name__)
26
- except PackageNotFoundError:
27
- # package is not installed
28
- pass
25
+ with contextlib.suppress(importlib.metadata.PackageNotFoundError):
26
+ __version__ = importlib.metadata.version(__name__)
29
27
 
30
28
 
31
29
  zarr = None
@@ -92,6 +90,10 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
92
90
  self._initNew(path, **kwargs)
93
91
  else:
94
92
  self._initOpen(**kwargs)
93
+ internal = self.getInternalMetadata().get('zarr', {}).get('base', {})
94
+ multiscale = internal.get('multiscales', [None])[0]
95
+ if multiscale is not None:
96
+ self._imageDescription = multiscale.get('metadata', {}).get('description')
95
97
  self._tileLock = threading.RLock()
96
98
 
97
99
  def _initOpen(self, **kwargs):
@@ -110,10 +112,8 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
110
112
  self._zarr = zarr.open(self._largeImagePath, mode='r')
111
113
  except Exception:
112
114
  if os.path.basename(self._largeImagePath) in {'.zgroup', '.zattrs', '.zarray'}:
113
- try:
115
+ with contextlib.suppress(Exception):
114
116
  self._zarr = zarr.open(os.path.dirname(self._largeImagePath), mode='r')
115
- except Exception:
116
- pass
117
117
  if self._zarr is None:
118
118
  if not os.path.isfile(self._largeImagePath):
119
119
  raise TileSourceFileNotFoundError(self._largeImagePath) from None
@@ -148,6 +148,8 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
148
148
  self._threadLock = threading.RLock()
149
149
  self._processLock = multiprocessing.Lock()
150
150
  self._framecount = 0
151
+ self._minWidth = None
152
+ self._minHeight = None
151
153
  self._mm_x = 0
152
154
  self._mm_y = 0
153
155
  self._channelNames = []
@@ -158,18 +160,16 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
158
160
  self._frameValues = None
159
161
  self._frameAxes = None
160
162
  self._frameUnits = None
163
+ self._projection = None
164
+ self._gcps = None
161
165
  if not self._created:
162
- try:
166
+ with contextlib.suppress(Exception):
163
167
  self._validateZarr()
164
- except Exception:
165
- pass
166
168
 
167
169
  def __del__(self):
168
170
  if not hasattr(self, '_derivedSource'):
169
- try:
171
+ with contextlib.suppress(Exception):
170
172
  self._zarr.close()
171
- except Exception:
172
- pass
173
173
  try:
174
174
  if self._created:
175
175
  shutil.rmtree(self._tempdir)
@@ -281,7 +281,7 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
281
281
  elif check == results['best']:
282
282
  results['series'].append((group, arr))
283
283
  if not any(group is g for g, _ in results['associated']):
284
- axes = {k: v for k, v in axes.items() if arr.shape[axes[k]] > 1}
284
+ axes = {k: v for k, v in axes.items() if arr.shape[axes[k]] > 1 or k in {'x', 'y'}}
285
285
  if (len(axes) <= 3 and
286
286
  self._minAssociatedImageSize <= arr.shape[axes['x']] <=
287
287
  self._maxAssociatedImageSize and
@@ -371,7 +371,7 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
371
371
  self._frameValues = None
372
372
  frame_values_shape = [baseArray.shape[self._axes[a]] for a in self.frameAxes]
373
373
  frame_values_shape.append(len(frame_values_shape))
374
- frame_values = np.empty(frame_values_shape, dtype=object)
374
+ frame_values = np.zeros(frame_values_shape, dtype=object)
375
375
  all_frame_specs = self.getMetadata().get('frames')
376
376
  for axis, values in axes_values.items():
377
377
  if axis in self.frameAxes:
@@ -453,10 +453,16 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
453
453
  stride = 1
454
454
  self._strides = {}
455
455
  self._axisCounts = {}
456
- for _, k in sorted(
457
- (-self._axes.get(k, 'tzc'.index(k) if k in 'tzc' else -1), k)
458
- for k in self._axes if k not in 'xys'
459
- ):
456
+ # If we aren't in editable mode, prefer the channel axis to have a
457
+ # stride of 1, then the z axis, then the t axis, then sorted by the
458
+ # axis name.
459
+ axisOrder = ((-'tzc'.index(k) if k in 'tzc' else 1, k)
460
+ for k in self._axes if k not in {'x', 'y', 's'})
461
+ # In editable mode, prefer the order that the axes are being written.
462
+ if self._editable:
463
+ axisOrder = ((-self._axes.get(k, 'tzc'.index(k) if k in 'tzc' else -1), k)
464
+ for k in self._axes if k not in {'x', 'y', 's'})
465
+ for _, k in sorted(axisOrder):
460
466
  self._strides[k] = stride
461
467
  self._axisCounts[k] = baseArray.shape[self._axes[k]]
462
468
  stride *= baseArray.shape[self._axes[k]]
@@ -545,10 +551,8 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
545
551
  result['zarr'] = {
546
552
  'base': self._zarr.attrs.asdict(),
547
553
  }
548
- try:
554
+ with contextlib.suppress(Exception):
549
555
  result['zarr']['main'] = self._series[0][0].attrs.asdict()
550
- except Exception:
551
- pass
552
556
  return result
553
557
 
554
558
  def getAssociatedImagesList(self):
@@ -629,7 +633,7 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
629
633
 
630
634
  def _validateNewTile(self, tile, mask, placement, axes):
631
635
  if not isinstance(tile, np.ndarray) or axes is None:
632
- axes = 'yxs'
636
+ axes = self._axes if hasattr(self, '_axes') else 'yxs'
633
637
  tile, mode = _imageToNumpy(tile)
634
638
  elif not isinstance(axes, str) and not isinstance(axes, list):
635
639
  err = 'Invalid type for axes. Must be str or list[str].'
@@ -637,6 +641,7 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
637
641
  axes = [x.lower() for x in axes]
638
642
  if axes[-1] != 's':
639
643
  axes.append('s')
644
+ tile = tile[..., np.newaxis]
640
645
  if mask is not None and len(axes) - 1 == len(mask.shape):
641
646
  mask = mask[:, :, np.newaxis]
642
647
  if 'x' not in axes or 'y' not in axes:
@@ -689,7 +694,9 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
689
694
  arr,
690
695
  [(0, s - arr.shape[i]) for i, s in enumerate(new_shape)],
691
696
  )
692
- new_arr = zarr.empty(new_shape, chunks=chunking, dtype=arr.dtype)
697
+ new_arr = zarr.zeros(
698
+ new_shape, chunks=chunking, dtype=arr.dtype,
699
+ write_empty_chunks=False)
693
700
  new_arr[:] = arr[:]
694
701
  arr = new_arr
695
702
  else:
@@ -716,11 +723,9 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
716
723
  ``level`` is a reserved word and not permitted for an axis name.
717
724
  """
718
725
  self._checkEditable()
719
- try:
726
+ with contextlib.suppress(TileSourceError):
720
727
  # read any info written by other processes
721
728
  self._validateZarr()
722
- except TileSourceError:
723
- pass
724
729
  updateMetadata = False
725
730
  store_path = str(kwargs.pop('level', 0))
726
731
  placement = {
@@ -765,12 +770,22 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
765
770
  self._zarr_store.rmdir(path)
766
771
  chunking = None
767
772
  if store_path not in current_arrays:
768
- arr = np.empty(tuple(new_dims.values()), dtype=tile.dtype)
769
773
  chunking = tuple([
770
774
  self._tileSize if a in ['x', 'y'] else
771
775
  new_dims.get('s') if a == 's' else 1
772
776
  for a in axes
773
777
  ])
778
+ # If we have to create the array, do so with the desired store
779
+ # and chunking so we don't have to immediately rechunk it
780
+ arr = zarr.zeros(
781
+ tuple(new_dims.values()),
782
+ dtype=tile.dtype,
783
+ chunks=chunking,
784
+ store=self._zarr_store,
785
+ path=store_path,
786
+ write_empty_chunks=False,
787
+ )
788
+ chunking = None
774
789
  else:
775
790
  arr = current_arrays[store_path]
776
791
  new_shape = tuple(
@@ -885,31 +900,33 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
885
900
  with self._threadLock and self._processLock:
886
901
  name = str(self._tempdir.name).split('/')[-1]
887
902
  arrays = dict(self._zarr.arrays())
888
- channel_axis = self._axes.get('c', self._axes.get('s'))
889
903
  datasets = []
890
904
  axes = []
891
905
  channels = []
892
- rdefs = {'model': 'color' if len(self._channelColors) else 'greyscale'}
893
- sorted_axes = [a[0] for a in sorted(self._axes.items(), key=lambda item: item[1])]
894
- for arr_name in arrays:
895
- level = int(arr_name)
896
- scale = [1.0 for a in sorted_axes]
897
- scale[self._axes.get('x')] = (self._mm_x or 0) * (2 ** level)
898
- scale[self._axes.get('y')] = (self._mm_y or 0) * (2 ** level)
899
- dataset_metadata = {
900
- 'path': arr_name,
901
- 'coordinateTransformations': [{
902
- 'type': 'scale',
903
- 'scale': scale,
904
- }],
905
- }
906
- datasets.append(dataset_metadata)
907
- for a in sorted_axes:
908
- if a == 't':
909
- rdefs['defaultT'] = 0
910
- elif a == 'z':
911
- rdefs['defaultZ'] = 0
912
- axes.append(self._getAxisInternalMetadata(a))
906
+ channel_axis = rdefs = None
907
+ if hasattr(self, '_axes'):
908
+ channel_axis = self._axes.get('c', self._axes.get('s'))
909
+ rdefs = {'model': 'color' if len(self._channelColors) else 'greyscale'}
910
+ sorted_axes = [a[0] for a in sorted(self._axes.items(), key=lambda item: item[1])]
911
+ for arr_name in arrays:
912
+ level = int(arr_name)
913
+ scale = [1.0 for a in sorted_axes]
914
+ scale[self._axes.get('x')] = (self._mm_x or 0) * (2 ** level)
915
+ scale[self._axes.get('y')] = (self._mm_y or 0) * (2 ** level)
916
+ dataset_metadata = {
917
+ 'path': arr_name,
918
+ 'coordinateTransformations': [{
919
+ 'type': 'scale',
920
+ 'scale': scale,
921
+ }],
922
+ }
923
+ datasets.append(dataset_metadata)
924
+ for a in sorted_axes:
925
+ if a == 't':
926
+ rdefs['defaultT'] = 0
927
+ elif a == 'z':
928
+ rdefs['defaultZ'] = 0
929
+ axes.append(self._getAxisInternalMetadata(a))
913
930
  if channel_axis is not None and len(arrays) > 0:
914
931
  base_array = list(arrays.values())[0]
915
932
  base_shape = base_array.shape
@@ -991,6 +1008,32 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
991
1008
  raise TileSourceError(msg)
992
1009
  self._crop = (x, y, w, h)
993
1010
 
1011
+ @property
1012
+ def minWidth(self):
1013
+ return self._minWidth
1014
+
1015
+ @minWidth.setter
1016
+ def minWidth(self, value):
1017
+ self._checkEditable()
1018
+ value = int(value) if value is not None else None
1019
+ if value is not None and value <= 0:
1020
+ msg = 'minWidth must be positive or None'
1021
+ raise TileSourceError(msg)
1022
+ self._minWidth = value
1023
+
1024
+ @property
1025
+ def minHeight(self):
1026
+ return self._minHeight
1027
+
1028
+ @minHeight.setter
1029
+ def minHeight(self, value):
1030
+ self._checkEditable()
1031
+ value = int(value) if value is not None else None
1032
+ if value is not None and value <= 0:
1033
+ msg = 'minHeight must be positive or None'
1034
+ raise TileSourceError(msg)
1035
+ self._minHeight = value
1036
+
994
1037
  @property
995
1038
  def mm_x(self):
996
1039
  return self._mm_x
@@ -1019,12 +1062,54 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1019
1062
 
1020
1063
  @property
1021
1064
  def imageDescription(self):
1065
+ if not hasattr(self, '_imageDescription'):
1066
+ return None
1067
+ if isinstance(self._imageDescription, dict):
1068
+ return self._imageDescription.get('description')
1022
1069
  return self._imageDescription
1023
1070
 
1024
1071
  @imageDescription.setter
1025
1072
  def imageDescription(self, description):
1026
1073
  self._checkEditable()
1027
- self._imageDescription = description
1074
+ try:
1075
+ json.dumps(description)
1076
+ except TypeError:
1077
+ msg = 'Description must be JSON serializable'
1078
+ raise TileSourceError(msg)
1079
+ if (
1080
+ hasattr(self, '_imageDescription') and
1081
+ isinstance(self._imageDescription, dict)
1082
+ ):
1083
+ self._imageDescription['description'] = description
1084
+ else:
1085
+ self._imageDescription = description
1086
+
1087
+ @property
1088
+ def additionalMetadata(self):
1089
+ if not hasattr(self, '_imageDescription'):
1090
+ return None
1091
+ if isinstance(self._imageDescription, dict):
1092
+ return self._imageDescription.get('additionalMetadata')
1093
+ return None
1094
+
1095
+ @additionalMetadata.setter
1096
+ def additionalMetadata(self, data):
1097
+ self._checkEditable()
1098
+ try:
1099
+ json.dumps(data)
1100
+ except TypeError:
1101
+ msg = 'Metadata must be JSON serializable'
1102
+ raise TileSourceError(msg)
1103
+ if (
1104
+ hasattr(self, '_imageDescription') and
1105
+ isinstance(self._imageDescription, dict)
1106
+ ):
1107
+ self._imageDescription['additionalMetadata'] = data
1108
+ else:
1109
+ self.imageDescription = dict(
1110
+ description=self._imageDescription,
1111
+ additionalMetadata=data,
1112
+ )
1028
1113
 
1029
1114
  @property
1030
1115
  def channelNames(self):
@@ -1067,7 +1152,7 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1067
1152
  err = 'frameAxes must be set first with a list of frame axis names.'
1068
1153
  raise ValueError(err)
1069
1154
  if not isinstance(units, dict) or not all(
1070
- k in self.frameAxes for k in units.keys()
1155
+ k in self.frameAxes for k in units
1071
1156
  ):
1072
1157
  err = 'frameUnits must be a dictionary with keys that exist in frameAxes.'
1073
1158
  raise ValueError(err)
@@ -1089,6 +1174,76 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1089
1174
  self._frameValues = a
1090
1175
  self._writeInternalMetadata()
1091
1176
 
1177
+ @property
1178
+ def projection(self):
1179
+ return self._projection
1180
+
1181
+ @projection.setter
1182
+ def projection(self, proj):
1183
+ import pyproj
1184
+
1185
+ self._checkEditable()
1186
+ try:
1187
+ pyproj.CRS.from_string(str(proj))
1188
+ except Exception as e:
1189
+ msg = f'Invalid projection value. Cannot be interpreted by pyproj: {str(e)}'
1190
+ raise TileSourceError(msg)
1191
+ self._projection = proj
1192
+ self._writeInternalMetadata()
1193
+
1194
+ @property
1195
+ def gcps(self):
1196
+ return self._gcps
1197
+
1198
+ @gcps.setter
1199
+ def gcps(self, gcps):
1200
+ self._checkEditable()
1201
+ if isinstance(gcps, str):
1202
+ gcps = list(zip(*[iter(gcps.split())] * 4, strict=False))
1203
+ if (isinstance(gcps, (list, tuple))):
1204
+ gcps = [
1205
+ [float(v) for v in gcp.split()]
1206
+ if isinstance(gcp, str) else gcp
1207
+ for gcp in gcps
1208
+ ]
1209
+ if any(
1210
+ not isinstance(gcp, list) and not isinstance(gcp, tuple)
1211
+ for gcp in gcps
1212
+ ):
1213
+ msg = 'Each GCP must be specified as a list, tuple, or space-separated string.'
1214
+ raise TileSourceError(msg)
1215
+ if any(len(gcp) != 4 for gcp in gcps):
1216
+ msg = (
1217
+ 'Each GCP must contain four values: '
1218
+ '[projected_x, projected_y, pixel_x, pixel_y].'
1219
+ )
1220
+ raise TileSourceError(msg)
1221
+ unique_gcps = []
1222
+ dup_gcps = []
1223
+ for gcp in gcps:
1224
+ if not any(
1225
+ u[0:2] == gcp[0:2] or u[2:4] == gcp[2:4]
1226
+ for u in unique_gcps
1227
+ ):
1228
+ unique_gcps.append(gcp)
1229
+ else:
1230
+ dup_gcps.append(gcp)
1231
+ gcps = unique_gcps
1232
+ if len(dup_gcps):
1233
+ msg = (
1234
+ f'Removed duplicate GCPs {dup_gcps} from list; shared projected '
1235
+ 'coordinate or pixel coordinate with another GCP.'
1236
+ )
1237
+ warnings.warn(msg, stacklevel=2)
1238
+ if len(gcps) < 2:
1239
+ msg = 'Must specify at least 2 unique GCPs.'
1240
+ raise TileSourceError(msg)
1241
+ else:
1242
+ msg = 'GCPs must be specified as a list, tuple, or space-separated string.'
1243
+ raise TileSourceError(msg)
1244
+ self._gcps = gcps
1245
+ self._writeInternalMetadata()
1246
+
1092
1247
  def _generateDownsampledLevels(self, resample_method):
1093
1248
  self._checkEditable()
1094
1249
  current_arrays = dict(self._zarr.arrays())
@@ -1132,7 +1287,10 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1132
1287
  output=iterator_output,
1133
1288
  resample=False, # TODO: incorporate resampling in core
1134
1289
  ):
1135
- new_tile = downsampleTileHalfRes(tile['tile'], resample_method)
1290
+ tile_data = tile['tile']
1291
+ if tile_data.shape[-1] == 1:
1292
+ tile_data = np.squeeze(tile['tile'], axis=(-1,))
1293
+ new_tile = downsampleTileHalfRes(tile_data, resample_method)
1136
1294
  overlap = {k: int(v / 2) for k, v in tile['tile_overlap'].items()}
1137
1295
  new_tile = new_tile[
1138
1296
  slice(overlap['top'], new_tile.shape[0] - overlap['bottom']),
@@ -1152,6 +1310,23 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1152
1310
  )
1153
1311
  self._validateZarr() # refresh self._levels before continuing
1154
1312
 
1313
+ def _applyGeoReferencing(self, path):
1314
+ if self.projection and not self.gcps:
1315
+ msg = (
1316
+ 'Projection was specified but GCPs were not specified. '
1317
+ 'Cannot write georeferenced file.'
1318
+ )
1319
+ raise TileSourceError(msg)
1320
+ import tifftools
1321
+
1322
+ setlist = []
1323
+ if self.projection is not None:
1324
+ setlist.append(('projection', self.projection))
1325
+ if self.gcps is not None and len(self.gcps):
1326
+ setlist.append(('gcps', self.gcps))
1327
+
1328
+ tifftools.tiff_set(path, setlist=setlist, overwrite=True)
1329
+
1155
1330
  def write(
1156
1331
  self,
1157
1332
  path,
@@ -1210,6 +1385,21 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1210
1385
  **frame_position,
1211
1386
  )
1212
1387
 
1388
+ if self.minWidth or self.minHeight:
1389
+ old_axes = self._axes if hasattr(self, '_axes') else {}
1390
+ current_arrays = dict(self._zarr.arrays())
1391
+ arr = current_arrays['0']
1392
+ new_shape = tuple(
1393
+ max(
1394
+ v,
1395
+ self.minWidth if self.minWidth is not None and k == 'x' else
1396
+ self.minHeight if self.minHeight is not None and k == 'y' else
1397
+ arr.shape[old_axes[k]],
1398
+ )
1399
+ for k, v in old_axes.items()
1400
+ )
1401
+ self._resizeImage(arr, new_shape, {}, None)
1402
+
1213
1403
  source._validateZarr()
1214
1404
 
1215
1405
  if suffix in ['.zarr', '.db', '.sqlite', '.zip']:
@@ -1240,8 +1430,11 @@ class ZarrFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
1240
1430
  params = {}
1241
1431
  if lossy and self.dtype == np.uint8:
1242
1432
  params['compression'] = 'jpeg'
1433
+ params['overwrite'] = overwriteAllowed
1243
1434
  params.update(converterParams)
1244
- convert(str(attrs_path), path, overwrite=overwriteAllowed, **params)
1435
+ convert(str(attrs_path), path, **params)
1436
+
1437
+ self._applyGeoReferencing(path)
1245
1438
 
1246
1439
 
1247
1440
  def open(*args, **kwargs):
@@ -1,30 +1,29 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: large-image-source-zarr
3
- Version: 1.31.0
3
+ Version: 1.33.6a188
4
4
  Summary: A OME Zarr tilesource for large_image.
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
7
7
  Author-email: kitware@kitware.com
8
- License: Apache Software License 2.0
8
+ License: Apache-2.0
9
9
  Keywords: large_image,tile source
10
10
  Classifier: Development Status :: 5 - Production/Stable
11
- Classifier: License :: OSI Approved :: Apache Software License
12
11
  Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
12
  Classifier: Programming Language :: Python :: 3.10
16
13
  Classifier: Programming Language :: Python :: 3.11
17
14
  Classifier: Programming Language :: Python :: 3.12
18
15
  Classifier: Programming Language :: Python :: 3.13
19
- Requires-Python: >=3.6
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Requires-Python: >=3.10
20
18
  Description-Content-Type: text/x-rst
21
19
  License-File: LICENSE
22
- Requires-Dist: large-image>=1.31.0
20
+ Requires-Dist: large-image>=1.33.6.a188
23
21
  Requires-Dist: zarr<3
24
- Requires-Dist: numcodecs
22
+ Requires-Dist: imagecodecs
23
+ Requires-Dist: numcodecs<0.16
25
24
  Requires-Dist: imagecodecs-numcodecs!=2024.9.22
26
25
  Provides-Extra: girder
27
- Requires-Dist: girder-large-image>=1.31.0; extra == "girder"
26
+ Requires-Dist: girder-large-image>=1.33.6.a188; extra == "girder"
28
27
  Provides-Extra: all
29
28
  Requires-Dist: large-image-converter; extra == "all"
30
29
  Dynamic: author
@@ -35,6 +34,7 @@ Dynamic: description-content-type
35
34
  Dynamic: home-page
36
35
  Dynamic: keywords
37
36
  Dynamic: license
37
+ Dynamic: license-file
38
38
  Dynamic: provides-extra
39
39
  Dynamic: requires-dist
40
40
  Dynamic: requires-python
@@ -0,0 +1,8 @@
1
+ large_image_source_zarr/__init__.py,sha256=BJq47bX_ZR0M0laIJWlI_7RbmUIZgyHwq-A7zDzitH0,58921
2
+ large_image_source_zarr/girder_source.py,sha256=RljxQ49-2PyTPZ4xxTipyyaXiwLAC7npdwWVx7XEhLE,342
3
+ large_image_source_zarr-1.33.6a188.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
4
+ large_image_source_zarr-1.33.6a188.dist-info/METADATA,sha256=TKAqpuCo2XwIikJU-vyJWl7TcQGJ9npiLMhSMBCuXcA,1415
5
+ large_image_source_zarr-1.33.6a188.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ large_image_source_zarr-1.33.6a188.dist-info/entry_points.txt,sha256=VakBZBTOHxWMsYsOO8Egale1mPhLTlLruMfhSBUOwkk,166
7
+ large_image_source_zarr-1.33.6a188.dist-info/top_level.txt,sha256=cMYOehfHJ55_mkRAFS3h2lsO0Pe4jYvMrNKbEznImZI,24
8
+ large_image_source_zarr-1.33.6a188.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,8 +0,0 @@
1
- large_image_source_zarr/__init__.py,sha256=GiPnjdIVWz7yK-JWtkUmaKFanXeiakI8DvGmF78pmaY,51369
2
- large_image_source_zarr/girder_source.py,sha256=RljxQ49-2PyTPZ4xxTipyyaXiwLAC7npdwWVx7XEhLE,342
3
- large_image_source_zarr-1.31.0.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
4
- large_image_source_zarr-1.31.0.dist-info/METADATA,sha256=2v5TQfjswYs4uCpxV8gfXtybyjGGjKy3eKLH1s0N_LY,1475
5
- large_image_source_zarr-1.31.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6
- large_image_source_zarr-1.31.0.dist-info/entry_points.txt,sha256=VakBZBTOHxWMsYsOO8Egale1mPhLTlLruMfhSBUOwkk,166
7
- large_image_source_zarr-1.31.0.dist-info/top_level.txt,sha256=cMYOehfHJ55_mkRAFS3h2lsO0Pe4jYvMrNKbEznImZI,24
8
- large_image_source_zarr-1.31.0.dist-info/RECORD,,