large-image-source-tiff 1.26.4.dev14__py3-none-any.whl → 1.27.1__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.
- large_image_source_tiff/__init__.py +1 -1
- large_image_source_tiff/tiff_reader.py +52 -40
- {large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/METADATA +3 -3
- large_image_source_tiff-1.27.1.dist-info/RECORD +10 -0
- large_image_source_tiff-1.26.4.dev14.dist-info/RECORD +0 -10
- {large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/LICENSE +0 -0
- {large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/WHEEL +0 -0
- {large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/entry_points.txt +0 -0
- {large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/top_level.txt +0 -0
@@ -645,7 +645,7 @@ class TiffFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
645
645
|
allowStyle = False
|
646
646
|
format = TILE_FORMAT_PIL
|
647
647
|
else:
|
648
|
-
tile = dir.getTile(x, y)
|
648
|
+
tile = dir.getTile(x, y, asarray=numpyAllowed == 'always')
|
649
649
|
format = 'JPEG'
|
650
650
|
if isinstance(tile, PIL.Image.Image):
|
651
651
|
format = TILE_FORMAT_PIL
|
@@ -53,6 +53,21 @@ libtiff_ctypes.suppress_warnings()
|
|
53
53
|
libtiff_ctypes.suppress_errors()
|
54
54
|
|
55
55
|
|
56
|
+
_ctypesFormattbl = {
|
57
|
+
(8, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint8,
|
58
|
+
(8, libtiff_ctypes.SAMPLEFORMAT_INT): np.int8,
|
59
|
+
(16, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint16,
|
60
|
+
(16, libtiff_ctypes.SAMPLEFORMAT_INT): np.int16,
|
61
|
+
(16, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float16,
|
62
|
+
(32, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint32,
|
63
|
+
(32, libtiff_ctypes.SAMPLEFORMAT_INT): np.int32,
|
64
|
+
(32, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float32,
|
65
|
+
(64, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint64,
|
66
|
+
(64, libtiff_ctypes.SAMPLEFORMAT_INT): np.int64,
|
67
|
+
(64, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float64,
|
68
|
+
}
|
69
|
+
|
70
|
+
|
56
71
|
def patchLibtiff():
|
57
72
|
libtiff_ctypes.libtiff.TIFFFieldWithTag.restype = \
|
58
73
|
ctypes.POINTER(libtiff_ctypes.TIFFFieldInfo)
|
@@ -286,6 +301,7 @@ class TiledTiffDirectory:
|
|
286
301
|
self._tileHeight = info.get('tilelength') or info.get('rowsperstrip')
|
287
302
|
self._imageWidth = info.get('imagewidth')
|
288
303
|
self._imageHeight = info.get('imagelength')
|
304
|
+
self._tilesAcross = (self._imageWidth + self._tileWidth - 1) // self._tileWidth
|
289
305
|
if not info.get('tilelength'):
|
290
306
|
self._stripsPerTile = int(max(1, math.ceil(256.0 / self._tileHeight)))
|
291
307
|
self._stripHeight = self._tileHeight
|
@@ -404,12 +420,11 @@ class TiledTiffDirectory:
|
|
404
420
|
# raise InvalidOperationTiffError(
|
405
421
|
# 'Tile x=%d, y=%d does not exist' % (x, y))
|
406
422
|
if self._tiffInfo.get('istiled'):
|
407
|
-
tileNum =
|
408
|
-
self._tiffFile, pixelX, pixelY, 0, 0).value
|
423
|
+
tileNum = pixelX // self._tileWidth + (pixelY // self._tileHeight) * self._tilesAcross
|
409
424
|
else:
|
410
425
|
# TIFFComputeStrip with sample=0 is just the row divided by the
|
411
426
|
# strip height
|
412
|
-
tileNum =
|
427
|
+
tileNum = pixelY // self._stripHeight
|
413
428
|
return tileNum
|
414
429
|
|
415
430
|
@methodcache(key=partial(strhash, '_getTileByteCountsType'))
|
@@ -569,34 +584,39 @@ class TiledTiffDirectory:
|
|
569
584
|
:rtype: PIL.Image
|
570
585
|
:raises: IOTiffError
|
571
586
|
"""
|
572
|
-
|
573
|
-
if self
|
574
|
-
|
575
|
-
|
587
|
+
if self._tiffInfo.get('istiled'):
|
588
|
+
if not hasattr(self, '_uncompressedTileSize'):
|
589
|
+
with self._tileLock:
|
590
|
+
self._uncompressedTileSize = libtiff_ctypes.libtiff.TIFFTileSize(
|
591
|
+
self._tiffFile).value
|
592
|
+
tileSize = self._uncompressedTileSize
|
593
|
+
else:
|
594
|
+
with self._tileLock:
|
576
595
|
stripSize = libtiff_ctypes.libtiff.TIFFStripSize(
|
577
596
|
self._tiffFile).value
|
578
|
-
|
579
|
-
|
597
|
+
stripsCount = min(self._stripsPerTile, self._stripCount - tileNum)
|
598
|
+
tileSize = stripSize * self._stripsPerTile
|
580
599
|
imageBuffer = ctypes.create_string_buffer(tileSize)
|
581
|
-
|
582
|
-
|
600
|
+
if self._tiffInfo.get('istiled'):
|
601
|
+
with self._tileLock:
|
583
602
|
readSize = libtiff_ctypes.libtiff.TIFFReadEncodedTile(
|
584
603
|
self._tiffFile, tileNum, imageBuffer, tileSize)
|
585
|
-
|
586
|
-
|
587
|
-
|
604
|
+
else:
|
605
|
+
readSize = 0
|
606
|
+
for stripNum in range(stripsCount):
|
607
|
+
with self._tileLock:
|
588
608
|
chunkSize = libtiff_ctypes.libtiff.TIFFReadEncodedStrip(
|
589
609
|
self._tiffFile,
|
590
610
|
tileNum + stripNum,
|
591
611
|
ctypes.byref(imageBuffer, stripSize * stripNum),
|
592
612
|
stripSize).value
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
613
|
+
if chunkSize <= 0:
|
614
|
+
msg = 'Read an unexpected number of bytes from an encoded strip'
|
615
|
+
raise IOTiffError(msg)
|
616
|
+
readSize += chunkSize
|
617
|
+
if readSize < tileSize:
|
618
|
+
ctypes.memset(ctypes.byref(imageBuffer, readSize), 0, tileSize - readSize)
|
619
|
+
readSize = tileSize
|
600
620
|
if readSize < tileSize:
|
601
621
|
raise IOTiffError(
|
602
622
|
'Read an unexpected number of bytes from an encoded tile' if readSize >= 0 else
|
@@ -612,23 +632,10 @@ class TiledTiffDirectory:
|
|
612
632
|
self._tiffInfo.get('bitspersample'),
|
613
633
|
self._tiffInfo.get('sampleformat') if self._tiffInfo.get(
|
614
634
|
'sampleformat') is not None else libtiff_ctypes.SAMPLEFORMAT_UINT)
|
615
|
-
formattbl = {
|
616
|
-
(8, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint8,
|
617
|
-
(8, libtiff_ctypes.SAMPLEFORMAT_INT): np.int8,
|
618
|
-
(16, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint16,
|
619
|
-
(16, libtiff_ctypes.SAMPLEFORMAT_INT): np.int16,
|
620
|
-
(16, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float16,
|
621
|
-
(32, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint32,
|
622
|
-
(32, libtiff_ctypes.SAMPLEFORMAT_INT): np.int32,
|
623
|
-
(32, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float32,
|
624
|
-
(64, libtiff_ctypes.SAMPLEFORMAT_UINT): np.uint64,
|
625
|
-
(64, libtiff_ctypes.SAMPLEFORMAT_INT): np.int64,
|
626
|
-
(64, libtiff_ctypes.SAMPLEFORMAT_IEEEFP): np.float64,
|
627
|
-
}
|
628
635
|
image = np.ctypeslib.as_array(ctypes.cast(
|
629
636
|
imageBuffer, ctypes.POINTER(ctypes.c_uint8)), (tileSize, )).view(
|
630
|
-
|
631
|
-
(th, tw, self._tiffInfo
|
637
|
+
_ctypesFormattbl[format]).reshape(
|
638
|
+
(th, tw, self._tiffInfo['samplesperpixel']))
|
632
639
|
if (self._tiffInfo.get('samplesperpixel') == 3 and
|
633
640
|
self._tiffInfo.get('photometric') == libtiff_ctypes.PHOTOMETRIC_YCBCR):
|
634
641
|
if self._tiffInfo.get('bitspersample') == 16:
|
@@ -754,7 +761,7 @@ class TiledTiffDirectory:
|
|
754
761
|
def pixelInfo(self):
|
755
762
|
return self._pixelInfo
|
756
763
|
|
757
|
-
def getTile(self, x, y):
|
764
|
+
def getTile(self, x, y, asarray=False):
|
758
765
|
"""
|
759
766
|
Get the complete JPEG image from a tile.
|
760
767
|
|
@@ -762,6 +769,8 @@ class TiledTiffDirectory:
|
|
762
769
|
:type x: int
|
763
770
|
:param y: The row index of the desired tile.
|
764
771
|
:type y: int
|
772
|
+
:param asarray: If True, read jpeg compressed images as arrays.
|
773
|
+
:type asarray: boolean
|
765
774
|
:return: either a buffer with a JPEG or a PIL image.
|
766
775
|
:rtype: bytes
|
767
776
|
:raises: InvalidOperationTiffError or IOTiffError
|
@@ -774,11 +783,14 @@ class TiledTiffDirectory:
|
|
774
783
|
tileNum = self._toTileNum(x, y)
|
775
784
|
|
776
785
|
if (not self._tiffInfo.get('istiled') or
|
777
|
-
self._tiffInfo.get('compression') not in
|
778
|
-
libtiff_ctypes.COMPRESSION_JPEG, 33003, 33005, 34712
|
786
|
+
self._tiffInfo.get('compression') not in {
|
787
|
+
libtiff_ctypes.COMPRESSION_JPEG, 33003, 33005, 34712} or
|
779
788
|
self._tiffInfo.get('bitspersample') != 8 or
|
780
789
|
self._tiffInfo.get('sampleformat') not in {
|
781
|
-
None, libtiff_ctypes.SAMPLEFORMAT_UINT}
|
790
|
+
None, libtiff_ctypes.SAMPLEFORMAT_UINT} or
|
791
|
+
(asarray and self._tiffInfo.get('compression') not in {33003, 33005, 34712} and (
|
792
|
+
self._tiffInfo.get('compression') != libtiff_ctypes.COMPRESSION_JPEG or
|
793
|
+
self._tiffInfo.get('photometric') != libtiff_ctypes.PHOTOMETRIC_YCBCR))):
|
782
794
|
return self._getUncompressedTile(tileNum)
|
783
795
|
|
784
796
|
imageBuffer = io.BytesIO()
|
{large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: large-image-source-tiff
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.27.1
|
4
4
|
Summary: A TIFF tilesource for large_image.
|
5
5
|
Home-page: https://github.com/girder/large_image
|
6
6
|
Author: Kitware, Inc.
|
@@ -17,11 +17,11 @@ Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
18
18
|
Requires-Python: >=3.8
|
19
19
|
License-File: LICENSE
|
20
|
-
Requires-Dist: large-image >=1.
|
20
|
+
Requires-Dist: large-image >=1.27.1
|
21
21
|
Requires-Dist: pylibtiff
|
22
22
|
Requires-Dist: tifftools >=1.2.0
|
23
23
|
Provides-Extra: girder
|
24
|
-
Requires-Dist: girder-large-image >=1.
|
24
|
+
Requires-Dist: girder-large-image >=1.27.1 ; extra == 'girder'
|
25
25
|
|
26
26
|
A TIFF tilesource for large_image.
|
27
27
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
large_image_source_tiff/__init__.py,sha256=0XCpYfa6BDT4m22xtLYO6qlxJ7vCFrWopWQQQo37FGQ,33986
|
2
|
+
large_image_source_tiff/exceptions.py,sha256=NgdwloaDCtbtUMe2BU2lXEU8IwQSYtaokIwGIFypCps,617
|
3
|
+
large_image_source_tiff/girder_source.py,sha256=Dp2e3O4VTANYXZI_eybgzs5BcyuMcw2-MAzCUJ8zzPg,1031
|
4
|
+
large_image_source_tiff/tiff_reader.py,sha256=hv9ux30nLh_A46MRJqgUJoEGUIoOuJAQfLh_5VrVyDk,38643
|
5
|
+
large_image_source_tiff-1.27.1.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
6
|
+
large_image_source_tiff-1.27.1.dist-info/METADATA,sha256=aTXwXf7KHZ4eMbMz7a6_6JvWvQOZSE9tmJe45xv07JA,1016
|
7
|
+
large_image_source_tiff-1.27.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
8
|
+
large_image_source_tiff-1.27.1.dist-info/entry_points.txt,sha256=iZ43sIcj98SND7nDUC-_4qroBL6apyXN4iSbPXZ8LE4,166
|
9
|
+
large_image_source_tiff-1.27.1.dist-info/top_level.txt,sha256=QRx_D2oeiOOz_5FlBOAoDPF-E4Q-aFmerUWlaeP14B8,24
|
10
|
+
large_image_source_tiff-1.27.1.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
large_image_source_tiff/__init__.py,sha256=mCcJqAbDqdaaCPqD5Zfu8saj-j8KZZoTqdMyy9RAlWw,33952
|
2
|
-
large_image_source_tiff/exceptions.py,sha256=NgdwloaDCtbtUMe2BU2lXEU8IwQSYtaokIwGIFypCps,617
|
3
|
-
large_image_source_tiff/girder_source.py,sha256=Dp2e3O4VTANYXZI_eybgzs5BcyuMcw2-MAzCUJ8zzPg,1031
|
4
|
-
large_image_source_tiff/tiff_reader.py,sha256=i6HztBXfPWEIncUo_y3rWuhUNrv3CG8oAVKOUWCkn2A,38094
|
5
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
6
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/METADATA,sha256=HdPgl7LxXryjQEjMuBCC18-chQteiScTLHTW-g2ut2k,1034
|
7
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
8
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/entry_points.txt,sha256=iZ43sIcj98SND7nDUC-_4qroBL6apyXN4iSbPXZ8LE4,166
|
9
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/top_level.txt,sha256=QRx_D2oeiOOz_5FlBOAoDPF-E4Q-aFmerUWlaeP14B8,24
|
10
|
-
large_image_source_tiff-1.26.4.dev14.dist-info/RECORD,,
|
{large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/LICENSE
RENAMED
File without changes
|
{large_image_source_tiff-1.26.4.dev14.dist-info → large_image_source_tiff-1.27.1.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|