large-image-converter 1.31.0__tar.gz → 1.31.1__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.

Potentially problematic release.


This version of large-image-converter might be problematic. Click here for more details.

Files changed (15) hide show
  1. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/PKG-INFO +4 -4
  2. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter/__init__.py +71 -7
  3. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/PKG-INFO +4 -4
  4. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/requires.txt +3 -3
  5. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/LICENSE +0 -0
  6. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/README.rst +0 -0
  7. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter/__main__.py +0 -0
  8. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter/format_aperio.py +0 -0
  9. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/SOURCES.txt +0 -0
  10. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/dependency_links.txt +0 -0
  11. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/entry_points.txt +0 -0
  12. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/large_image_converter.egg-info/top_level.txt +0 -0
  13. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/pyproject.toml +0 -0
  14. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/setup.cfg +0 -0
  15. {large_image_converter-1.31.0 → large_image_converter-1.31.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: large-image-converter
3
- Version: 1.31.0
3
+ Version: 1.31.1
4
4
  Summary: Converter for Large Image.
5
5
  Author: Kitware Inc
6
6
  Author-email: kitware@kitware.com
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
19
19
  Requires-Python: >=3.8
20
20
  Description-Content-Type: text/x-rst
21
21
  License-File: LICENSE
22
- Requires-Dist: large-image-source-tiff>=1.31.0
22
+ Requires-Dist: large-image-source-tiff>=1.31.1
23
23
  Requires-Dist: numpy
24
24
  Requires-Dist: psutil
25
25
  Requires-Dist: pyvips
@@ -29,14 +29,14 @@ Requires-Dist: glymur; extra == "jp2k"
29
29
  Provides-Extra: geospatial
30
30
  Requires-Dist: gdal; extra == "geospatial"
31
31
  Provides-Extra: sources
32
- Requires-Dist: large-image[sources]>=1.31.0; extra == "sources"
32
+ Requires-Dist: large-image[sources]>=1.31.1; extra == "sources"
33
33
  Provides-Extra: stats
34
34
  Requires-Dist: packaging; extra == "stats"
35
35
  Requires-Dist: scikit-image; extra == "stats"
36
36
  Provides-Extra: all
37
37
  Requires-Dist: glymur; extra == "all"
38
38
  Requires-Dist: gdal; extra == "all"
39
- Requires-Dist: large-image[sources]>=1.31.0; extra == "all"
39
+ Requires-Dist: large-image[sources]>=1.31.1; extra == "all"
40
40
  Requires-Dist: packaging; extra == "all"
41
41
  Requires-Dist: scikit-image; extra == "all"
42
42
 
@@ -249,7 +249,7 @@ def _generate_tiff(inputPath, outputPath, tempPath, lidata, **kwargs):
249
249
 
250
250
 
251
251
  def _convert_via_vips(inputPathOrBuffer, outputPath, tempPath, forTiled=True,
252
- status=None, **kwargs):
252
+ status=None, preferredVipsCast=None, **kwargs):
253
253
  """
254
254
  Convert a file, buffer, or vips image to a tiff file. This is equivalent
255
255
  to a vips command line of
@@ -263,6 +263,7 @@ def _convert_via_vips(inputPathOrBuffer, outputPath, tempPath, forTiled=True,
263
263
  also stores files in TMPDIR
264
264
  :param forTiled: True if the output should be tiled, false if not.
265
265
  :param status: an optional additional string to add to log messages.
266
+ :param preferredVipsCast: vips scaling parameters to use in a cast.
266
267
  :param kwargs: addition arguments that get passed to _vipsParameters
267
268
  and _convert_to_jp2k.
268
269
  """
@@ -294,7 +295,8 @@ def _convert_via_vips(inputPathOrBuffer, outputPath, tempPath, forTiled=True,
294
295
  image = _vipsCast(
295
296
  image,
296
297
  convertParams['compression'] in {'webp', 'jpeg'} or
297
- kwargs.get('compression') in {'jp2k'})
298
+ kwargs.get('compression') in {'jp2k'},
299
+ preferredVipsCast)
298
300
  # TODO: revisit the TMPDIR override; this is not thread safe
299
301
  # oldtmpdir = os.environ.get('TMPDIR')
300
302
  # os.environ['TMPDIR'] = os.path.dirname(tempPath)
@@ -535,8 +537,9 @@ def _convert_large_image_tile(tilelock, strips, tile):
535
537
  strips[ty] = strips[ty].insert(vimg, x, 0, expand=True)
536
538
 
537
539
 
538
- def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
539
- parentConcurrency=None, **kwargs):
540
+ def _convert_large_image_frame(
541
+ frame, numFrames, ts, frameOutputPath, tempPath, preferredVipsCast=None,
542
+ parentConcurrency=None, **kwargs):
540
543
  """
541
544
  Convert a single frame from a large_image source. This parallelizes tile
542
545
  reads. Once all tiles are converted to a composited vips image, a tiff
@@ -547,6 +550,7 @@ def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
547
550
  :param ts: the open tile source.
548
551
  :param frameOutputPath: the destination name for the tiff file.
549
552
  :param tempPath: a temporary file in a temporary directory.
553
+ :param preferredVipsCast: vips scaling parameters to use in a cast.
550
554
  :param parentConcurrency: amount of concurrency used by parent task.
551
555
  """
552
556
  # The iterator tile size is a balance between memory use and fewer calls
@@ -573,7 +577,64 @@ def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
573
577
  for stripidx in range(1, len(strips)):
574
578
  img = img.insert(strips[stripidx], 0, stripidx * _iterTileSize, expand=True)
575
579
  _convert_via_vips(
576
- img, frameOutputPath, tempPath, status='%d/%d' % (frame + 1, numFrames), **kwargs)
580
+ img, frameOutputPath, tempPath, status='%d/%d' % (frame + 1, numFrames),
581
+ preferredVipsCast=preferredVipsCast, **kwargs)
582
+
583
+
584
+ def _output_type(lidata): # noqa
585
+ """
586
+ Determine how to cast and scale vips data based on actual image contents.
587
+ """
588
+ try:
589
+ intype = np.dtype(lidata['tilesource'].dtype)
590
+ except Exception:
591
+ return None
592
+ if intype == np.uint8 or intype == np.uint16:
593
+ return None
594
+ logger.debug('Checking data range')
595
+ minval = maxval = None
596
+ for frame in range(len(lidata['metadata'].get('frames', [0]))):
597
+ h = lidata['tilesource'].histogram(
598
+ onlyMinMax=True, output=dict(maxWidth=2048, maxHeight=2048),
599
+ resample=0, frame=frame)
600
+ if 'max' not in h:
601
+ continue
602
+ if maxval is None:
603
+ maxval = max(h['max'].tolist())
604
+ minval = min(h['min'].tolist())
605
+ else:
606
+ maxval = max(maxval, max(h['max'].tolist()))
607
+ minval = min(minval, min(h['min'].tolist()))
608
+ lidata['range'] = (minval, maxval)
609
+ logger.debug('Data range is [%r, %r]', minval, maxval)
610
+ if minval >= 0 and intype == np.int8:
611
+ return (pyvips.BandFormat.UCHAR, 0, 1)
612
+ if minval >= 0 and intype == np.int16:
613
+ return (pyvips.BandFormat.USHORT, 0, 1)
614
+ if minval >= 0 and maxval == 0:
615
+ return (pyvips.BandFormat.UCHAR, 0, 1)
616
+ if minval >= 0 and maxval <= 2 ** -8:
617
+ return (pyvips.BandFormat.USHORT, 0,
618
+ 2 ** -(math.ceil(math.log2(maxval)) - 16) - 2 ** -math.ceil(math.log2(maxval)))
619
+ if minval >= 0 and maxval <= 1:
620
+ return (pyvips.BandFormat.USHORT, 0, 65535)
621
+ if minval >= 0 and maxval < 256:
622
+ return (pyvips.BandFormat.UCHAR, 0, 1)
623
+ if minval >= 0 and maxval < 65536:
624
+ return (pyvips.BandFormat.USHORT, 0, 1)
625
+ if minval >= 0:
626
+ return (pyvips.BandFormat.USHORT, 0,
627
+ 2 ** -(math.ceil(math.log2(maxval)) - 16) - 2 ** -math.ceil(math.log2(maxval)))
628
+ if minval >= -2 ** -8 and maxval <= 2 ** -8:
629
+ return (pyvips.BandFormat.USHORT, 1,
630
+ 2 ** -(math.ceil(math.log2(maxval)) - 15) - 2 ** -math.ceil(math.log2(maxval)))
631
+ if minval >= -1 and maxval <= 1:
632
+ return (pyvips.BandFormat.USHORT, 1, 32767)
633
+ if minval >= -32768 and maxval < 32768:
634
+ return (pyvips.BandFormat.USHORT, 32768, 1)
635
+ return (pyvips.BandFormat.USHORT, 0,
636
+ 2 ** -(math.ceil(math.log2(max(-minval, maxval))) - 16) -
637
+ 2 ** -math.ceil(math.log2(max(-minval, maxval))))
577
638
 
578
639
 
579
640
  def _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs):
@@ -588,6 +649,7 @@ def _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs):
588
649
  images.
589
650
  """
590
651
  ts = lidata['tilesource']
652
+ lidata['_vips_cast'] = _output_type(lidata)
591
653
  numFrames = len(lidata['metadata'].get('frames', [0]))
592
654
  outputList = []
593
655
  tasks = []
@@ -603,7 +665,7 @@ def _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs):
603
665
  frame + 1, time.strftime('%Y%m%d-%H%M%S'))
604
666
  _pool_add(tasks, (pool.submit(
605
667
  _convert_large_image_frame, frame, numFrames, ts, frameOutputPath,
606
- tempPath, pool._max_workers, **kwargs), ))
668
+ tempPath, lidata['_vips_cast'], pool._max_workers, **kwargs), ))
607
669
  outputList.append(frameOutputPath)
608
670
  _drain_pool(pool, tasks, 'frames')
609
671
  _output_tiff(outputList, outputPath, tempPath, lidata, **kwargs)
@@ -971,7 +1033,9 @@ def convert(inputPath, outputPath=None, **kwargs): # noqa: C901
971
1033
  if lidata and (not is_vips(
972
1034
  inputPath, (lidata['metadata']['sizeX'], lidata['metadata']['sizeY'])) or (
973
1035
  len(lidata['metadata'].get('frames', [])) >= 2 and
974
- not _is_multiframe(inputPath))):
1036
+ not _is_multiframe(inputPath)) or
1037
+ (np.dtype(lidata['tilesource'].dtype) != np.uint8 and
1038
+ np.dtype(lidata['tilesource'].dtype) != np.uint16)):
975
1039
  _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs)
976
1040
  elif _is_multiframe(inputPath):
977
1041
  _generate_multiframe_tiff(inputPath, outputPath, tempPath, lidata, **kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: large-image-converter
3
- Version: 1.31.0
3
+ Version: 1.31.1
4
4
  Summary: Converter for Large Image.
5
5
  Author: Kitware Inc
6
6
  Author-email: kitware@kitware.com
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
19
19
  Requires-Python: >=3.8
20
20
  Description-Content-Type: text/x-rst
21
21
  License-File: LICENSE
22
- Requires-Dist: large-image-source-tiff>=1.31.0
22
+ Requires-Dist: large-image-source-tiff>=1.31.1
23
23
  Requires-Dist: numpy
24
24
  Requires-Dist: psutil
25
25
  Requires-Dist: pyvips
@@ -29,14 +29,14 @@ Requires-Dist: glymur; extra == "jp2k"
29
29
  Provides-Extra: geospatial
30
30
  Requires-Dist: gdal; extra == "geospatial"
31
31
  Provides-Extra: sources
32
- Requires-Dist: large-image[sources]>=1.31.0; extra == "sources"
32
+ Requires-Dist: large-image[sources]>=1.31.1; extra == "sources"
33
33
  Provides-Extra: stats
34
34
  Requires-Dist: packaging; extra == "stats"
35
35
  Requires-Dist: scikit-image; extra == "stats"
36
36
  Provides-Extra: all
37
37
  Requires-Dist: glymur; extra == "all"
38
38
  Requires-Dist: gdal; extra == "all"
39
- Requires-Dist: large-image[sources]>=1.31.0; extra == "all"
39
+ Requires-Dist: large-image[sources]>=1.31.1; extra == "all"
40
40
  Requires-Dist: packaging; extra == "all"
41
41
  Requires-Dist: scikit-image; extra == "all"
42
42
 
@@ -1,4 +1,4 @@
1
- large-image-source-tiff>=1.31.0
1
+ large-image-source-tiff>=1.31.1
2
2
  numpy
3
3
  psutil
4
4
  pyvips
@@ -7,7 +7,7 @@ tifftools
7
7
  [all]
8
8
  glymur
9
9
  gdal
10
- large-image[sources]>=1.31.0
10
+ large-image[sources]>=1.31.1
11
11
  packaging
12
12
  scikit-image
13
13
 
@@ -18,7 +18,7 @@ gdal
18
18
  glymur
19
19
 
20
20
  [sources]
21
- large-image[sources]>=1.31.0
21
+ large-image[sources]>=1.31.1
22
22
 
23
23
  [stats]
24
24
  packaging