large-image-converter 1.29.7.dev18__py3-none-any.whl → 1.29.7.dev22__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.
Potentially problematic release.
This version of large-image-converter might be problematic. Click here for more details.
- large_image_converter/__init__.py +47 -10
- {large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/METADATA +4 -4
- large_image_converter-1.29.7.dev22.dist-info/RECORD +9 -0
- large_image_converter-1.29.7.dev18.dist-info/RECORD +0 -9
- {large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/LICENSE +0 -0
- {large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/WHEEL +0 -0
- {large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/entry_points.txt +0 -0
- {large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/top_level.txt +0 -0
|
@@ -109,7 +109,7 @@ def _data_from_large_image(path, outputPath, **kwargs):
|
|
|
109
109
|
_pool_add(tasks, (pool.submit(
|
|
110
110
|
_convert_via_vips, img, savePath, outputPath, mime=mime, forTiled=False), ))
|
|
111
111
|
results['images'][key] = savePath
|
|
112
|
-
_drain_pool(pool, tasks)
|
|
112
|
+
_drain_pool(pool, tasks, 'associated images')
|
|
113
113
|
return results
|
|
114
114
|
|
|
115
115
|
|
|
@@ -218,7 +218,7 @@ def _generate_multiframe_tiff(inputPath, outputPath, tempPath, lidata, **kwargs)
|
|
|
218
218
|
_pool_add(tasks, (pool.submit(
|
|
219
219
|
_convert_via_vips, subInputPath, savePath, tempPath, False), ))
|
|
220
220
|
extraImages[key] = savePath
|
|
221
|
-
_drain_pool(pool, tasks)
|
|
221
|
+
_drain_pool(pool, tasks, 'subpage')
|
|
222
222
|
_output_tiff(outputList, outputPath, tempPath, lidata, extraImages, **kwargs)
|
|
223
223
|
|
|
224
224
|
|
|
@@ -349,7 +349,7 @@ def _concurrency_to_value(_concurrency=None, **kwargs):
|
|
|
349
349
|
return max(1, large_image.config.cpu_count(logical=True) + _concurrency)
|
|
350
350
|
|
|
351
351
|
|
|
352
|
-
def _get_thread_pool(memoryLimit=None, **kwargs):
|
|
352
|
+
def _get_thread_pool(memoryLimit=None, parentConcurrency=None, numItems=None, **kwargs):
|
|
353
353
|
"""
|
|
354
354
|
Allocate a thread pool based on the specific concurrency.
|
|
355
355
|
|
|
@@ -357,12 +357,37 @@ def _get_thread_pool(memoryLimit=None, **kwargs):
|
|
|
357
357
|
process per memoryLimit bytes of total memory.
|
|
358
358
|
"""
|
|
359
359
|
concurrency = _concurrency_to_value(**kwargs)
|
|
360
|
+
if parentConcurrency and parentConcurrency > 1 and concurrency > 1:
|
|
361
|
+
concurrency = max(1, int(math.ceil(concurrency / parentConcurrency)))
|
|
360
362
|
if memoryLimit:
|
|
363
|
+
if parentConcurrency:
|
|
364
|
+
memoryLimit *= parentConcurrency
|
|
361
365
|
concurrency = min(concurrency, large_image.config.total_memory() // memoryLimit)
|
|
366
|
+
if numItems and numItems >= 1 and concurrency > numItems:
|
|
367
|
+
concurrency = numItems
|
|
362
368
|
concurrency = max(1, concurrency)
|
|
363
369
|
return concurrent.futures.ThreadPoolExecutor(max_workers=concurrency)
|
|
364
370
|
|
|
365
371
|
|
|
372
|
+
def _pool_log(left, total, label):
|
|
373
|
+
"""
|
|
374
|
+
Log processing within a pool.
|
|
375
|
+
|
|
376
|
+
:param left: units left to process.
|
|
377
|
+
:param total: total units left to process.
|
|
378
|
+
:param label: label to log describing what is being processed.
|
|
379
|
+
"""
|
|
380
|
+
if not hasattr(logger, '_pool_log_starttime'):
|
|
381
|
+
logger._pool_log_starttime = time.time()
|
|
382
|
+
if not hasattr(logger, '_pool_log_lastlog'):
|
|
383
|
+
logger._pool_log_lastlog = time.time()
|
|
384
|
+
if time.time() - logger._pool_log_lastlog < 10:
|
|
385
|
+
return
|
|
386
|
+
elapsed = time.time() - logger._pool_log_starttime
|
|
387
|
+
logger.debug('%d/%d %s left %4.2fs', left, total, label, elapsed)
|
|
388
|
+
logger._pool_log_lastlog = time.time()
|
|
389
|
+
|
|
390
|
+
|
|
366
391
|
def _pool_add(tasks, newtask):
|
|
367
392
|
"""
|
|
368
393
|
Add a new task to a pool, then drain any finished tasks at the start of the
|
|
@@ -381,7 +406,7 @@ def _pool_add(tasks, newtask):
|
|
|
381
406
|
tasks.pop(0)
|
|
382
407
|
|
|
383
408
|
|
|
384
|
-
def _drain_pool(pool, tasks):
|
|
409
|
+
def _drain_pool(pool, tasks, label=''):
|
|
385
410
|
"""
|
|
386
411
|
Wait for all tasks in a pool to complete, then shutdown the pool.
|
|
387
412
|
|
|
@@ -389,6 +414,8 @@ def _drain_pool(pool, tasks):
|
|
|
389
414
|
:param tasks: a list containing either lists or tuples, the last element
|
|
390
415
|
of which is a task submitted to the pool. Altered.
|
|
391
416
|
"""
|
|
417
|
+
numtasks = len(tasks)
|
|
418
|
+
_pool_log(len(tasks), numtasks, label)
|
|
392
419
|
while len(tasks):
|
|
393
420
|
# This allows better stopping on a SIGTERM
|
|
394
421
|
try:
|
|
@@ -396,6 +423,7 @@ def _drain_pool(pool, tasks):
|
|
|
396
423
|
except concurrent.futures.TimeoutError:
|
|
397
424
|
continue
|
|
398
425
|
tasks.pop(0)
|
|
426
|
+
_pool_log(len(tasks), numtasks, label)
|
|
399
427
|
pool.shutdown(False)
|
|
400
428
|
|
|
401
429
|
|
|
@@ -507,7 +535,8 @@ def _convert_large_image_tile(tilelock, strips, tile):
|
|
|
507
535
|
strips[ty] = strips[ty].insert(vimg, x, 0, expand=True)
|
|
508
536
|
|
|
509
537
|
|
|
510
|
-
def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
|
|
538
|
+
def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
|
|
539
|
+
parentConcurrency=None, **kwargs):
|
|
511
540
|
"""
|
|
512
541
|
Convert a single frame from a large_image source. This parallelizes tile
|
|
513
542
|
reads. Once all tiles are converted to a composited vips image, a tiff
|
|
@@ -518,18 +547,24 @@ def _convert_large_image_frame(frame, numFrames, ts, frameOutputPath, tempPath,
|
|
|
518
547
|
:param ts: the open tile source.
|
|
519
548
|
:param frameOutputPath: the destination name for the tiff file.
|
|
520
549
|
:param tempPath: a temporary file in a temporary directory.
|
|
550
|
+
:param parentConcurrency: amount of concurrency used by parent task.
|
|
521
551
|
"""
|
|
522
552
|
# The iterator tile size is a balance between memory use and fewer calls
|
|
523
553
|
# and file handles.
|
|
524
554
|
_iterTileSize = 4096
|
|
525
555
|
logger.info('Processing frame %d/%d', frame + 1, numFrames)
|
|
526
556
|
strips = []
|
|
527
|
-
pool = _get_thread_pool(
|
|
557
|
+
pool = _get_thread_pool(
|
|
558
|
+
memoryLimit=FrameMemoryEstimate,
|
|
559
|
+
# allow multiple tiles even if we are using all the cores, as it
|
|
560
|
+
# balances I/O and computation
|
|
561
|
+
parentConcurrency=(parentConcurrency // 2),
|
|
562
|
+
**kwargs)
|
|
528
563
|
tasks = []
|
|
529
564
|
tilelock = threading.Lock()
|
|
530
565
|
for tile in ts.tileIterator(tile_size=dict(width=_iterTileSize), frame=frame):
|
|
531
566
|
_pool_add(tasks, (pool.submit(_convert_large_image_tile, tilelock, strips, tile), ))
|
|
532
|
-
_drain_pool(pool, tasks)
|
|
567
|
+
_drain_pool(pool, tasks, f'tiles from frame {frame + 1}/{numFrames}')
|
|
533
568
|
minbands = min(strip.bands for strip in strips)
|
|
534
569
|
maxbands = max(strip.bands for strip in strips)
|
|
535
570
|
if minbands != maxbands:
|
|
@@ -556,20 +591,21 @@ def _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs):
|
|
|
556
591
|
numFrames = len(lidata['metadata'].get('frames', [0]))
|
|
557
592
|
outputList = []
|
|
558
593
|
tasks = []
|
|
559
|
-
pool = _get_thread_pool(memoryLimit=FrameMemoryEstimate, **kwargs)
|
|
560
594
|
startFrame = 0
|
|
561
595
|
endFrame = numFrames
|
|
562
596
|
if kwargs.get('onlyFrame') is not None and str(kwargs.get('onlyFrame')):
|
|
563
597
|
startFrame = int(kwargs.get('onlyFrame'))
|
|
564
598
|
endFrame = startFrame + 1
|
|
599
|
+
pool = _get_thread_pool(memoryLimit=FrameMemoryEstimate,
|
|
600
|
+
numItems=endFrame - startFrame, **kwargs)
|
|
565
601
|
for frame in range(startFrame, endFrame):
|
|
566
602
|
frameOutputPath = tempPath + '-%d-%s.tiff' % (
|
|
567
603
|
frame + 1, time.strftime('%Y%m%d-%H%M%S'))
|
|
568
604
|
_pool_add(tasks, (pool.submit(
|
|
569
605
|
_convert_large_image_frame, frame, numFrames, ts, frameOutputPath,
|
|
570
|
-
tempPath, **kwargs), ))
|
|
606
|
+
tempPath, pool._max_workers, **kwargs), ))
|
|
571
607
|
outputList.append(frameOutputPath)
|
|
572
|
-
_drain_pool(pool, tasks)
|
|
608
|
+
_drain_pool(pool, tasks, 'frames')
|
|
573
609
|
_output_tiff(outputList, outputPath, tempPath, lidata, **kwargs)
|
|
574
610
|
|
|
575
611
|
|
|
@@ -891,6 +927,7 @@ def convert(inputPath, outputPath=None, **kwargs): # noqa: C901
|
|
|
891
927
|
|
|
892
928
|
:returns: outputPath if successful
|
|
893
929
|
"""
|
|
930
|
+
logger._pool_log_starttime = time.time()
|
|
894
931
|
if kwargs.get('_concurrency'):
|
|
895
932
|
os.environ['VIPS_CONCURRENCY'] = str(_concurrency_to_value(**kwargs))
|
|
896
933
|
geospatial = kwargs.get('geospatial')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: large-image-converter
|
|
3
|
-
Version: 1.29.7.
|
|
3
|
+
Version: 1.29.7.dev22
|
|
4
4
|
Summary: Converter for Large Image.
|
|
5
5
|
Author: Kitware Inc
|
|
6
6
|
Author-email: kitware@kitware.com
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Requires-Python: >=3.8
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: large-image-source-tiff >=1.29.7.
|
|
21
|
+
Requires-Dist: large-image-source-tiff >=1.29.7.dev22
|
|
22
22
|
Requires-Dist: numpy
|
|
23
23
|
Requires-Dist: psutil
|
|
24
24
|
Requires-Dist: pyvips
|
|
@@ -26,7 +26,7 @@ Requires-Dist: tifftools
|
|
|
26
26
|
Provides-Extra: all
|
|
27
27
|
Requires-Dist: glymur ; extra == 'all'
|
|
28
28
|
Requires-Dist: gdal ; extra == 'all'
|
|
29
|
-
Requires-Dist: large-image[sources] >=1.29.7.
|
|
29
|
+
Requires-Dist: large-image[sources] >=1.29.7.dev22 ; extra == 'all'
|
|
30
30
|
Requires-Dist: packaging ; extra == 'all'
|
|
31
31
|
Requires-Dist: scikit-image ; extra == 'all'
|
|
32
32
|
Provides-Extra: geospatial
|
|
@@ -34,7 +34,7 @@ Requires-Dist: gdal ; extra == 'geospatial'
|
|
|
34
34
|
Provides-Extra: jp2k
|
|
35
35
|
Requires-Dist: glymur ; extra == 'jp2k'
|
|
36
36
|
Provides-Extra: sources
|
|
37
|
-
Requires-Dist: large-image[sources] >=1.29.7.
|
|
37
|
+
Requires-Dist: large-image[sources] >=1.29.7.dev22 ; extra == 'sources'
|
|
38
38
|
Provides-Extra: stats
|
|
39
39
|
Requires-Dist: packaging ; extra == 'stats'
|
|
40
40
|
Requires-Dist: scikit-image ; extra == 'stats'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
large_image_converter/__init__.py,sha256=_ixZBvfS3K_jOh2T98o37EF8jjZLrpNTw-ZXkW9r--w,41181
|
|
2
|
+
large_image_converter/__main__.py,sha256=bGQaCR01kTGTnW2c2Z9z5BIiPSpCRPfj7_kPgppLeB4,13353
|
|
3
|
+
large_image_converter/format_aperio.py,sha256=NkKY3gaSjPlfxvcTQgFiMADdq_mkdpKjGQ7WT_QsvaM,11761
|
|
4
|
+
large_image_converter-1.29.7.dev22.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
5
|
+
large_image_converter-1.29.7.dev22.dist-info/METADATA,sha256=R1FzqzhSNe5RQoNZmGdG4uS_RKrwgTXMYNaWLhxqIvA,4646
|
|
6
|
+
large_image_converter-1.29.7.dev22.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
|
7
|
+
large_image_converter-1.29.7.dev22.dist-info/entry_points.txt,sha256=TkXGWAaHgquk_ZXfqHTjQLjv8RZriv6ioiJd7JL6UIs,78
|
|
8
|
+
large_image_converter-1.29.7.dev22.dist-info/top_level.txt,sha256=cdRa-ZWWKzVHFsjK1Aq1f4bzAMPc3sgCpprmvpYczKg,22
|
|
9
|
+
large_image_converter-1.29.7.dev22.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
large_image_converter/__init__.py,sha256=tc_3t6OixaMdfSlwMMFLjQ3uuC8HZm7atoUbHU6UcHM,39472
|
|
2
|
-
large_image_converter/__main__.py,sha256=bGQaCR01kTGTnW2c2Z9z5BIiPSpCRPfj7_kPgppLeB4,13353
|
|
3
|
-
large_image_converter/format_aperio.py,sha256=NkKY3gaSjPlfxvcTQgFiMADdq_mkdpKjGQ7WT_QsvaM,11761
|
|
4
|
-
large_image_converter-1.29.7.dev18.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
5
|
-
large_image_converter-1.29.7.dev18.dist-info/METADATA,sha256=sk6boMA_RhQq-HaVno5AP__5DqCkKV303OS-rm0_89E,4646
|
|
6
|
-
large_image_converter-1.29.7.dev18.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
|
7
|
-
large_image_converter-1.29.7.dev18.dist-info/entry_points.txt,sha256=TkXGWAaHgquk_ZXfqHTjQLjv8RZriv6ioiJd7JL6UIs,78
|
|
8
|
-
large_image_converter-1.29.7.dev18.dist-info/top_level.txt,sha256=cdRa-ZWWKzVHFsjK1Aq1f4bzAMPc3sgCpprmvpYczKg,22
|
|
9
|
-
large_image_converter-1.29.7.dev18.dist-info/RECORD,,
|
|
File without changes
|
{large_image_converter-1.29.7.dev18.dist-info → large_image_converter-1.29.7.dev22.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|