2
2
# openslide-python - Python bindings for the OpenSlide library
3
3
#
4
4
# Copyright (c) 2010-2013 Carnegie Mellon University
5
- # Copyright (c) 2016-2023 Benjamin Gilbert
5
+ # Copyright (c) 2016-2024 Benjamin Gilbert
6
6
#
7
7
# This library is free software; you can redistribute it and/or modify it
8
8
# under the terms of version 2.1 of the GNU Lesser General Public License
48
48
cdll ,
49
49
)
50
50
from itertools import count
51
+ import os
51
52
import platform
52
53
from typing import TYPE_CHECKING , Any , Callable , Protocol , TypeVar , cast
53
54
56
57
from . import _convert
57
58
58
59
if TYPE_CHECKING :
59
- # Python 3.10+ for ParamSpec
60
+ # Python 3.10+
60
61
from typing import ParamSpec , TypeAlias
61
62
62
63
from _convert import _Buffer
@@ -196,6 +197,28 @@ def from_param(cls, obj: _OpenSlideCache) -> _OpenSlideCache:
196
197
return obj
197
198
198
199
200
+ if TYPE_CHECKING :
201
+ # Python 3.10+
202
+ Filename : TypeAlias = str | bytes | os .PathLike [Any ]
203
+
204
+
205
+ class _filename_p :
206
+ """Wrapper class to convert filename arguments to bytes."""
207
+
208
+ @classmethod
209
+ def from_param (cls , obj : Filename ) -> bytes :
210
+ # fspath and fsencode raise TypeError on unexpected types
211
+ if platform .system () == 'Windows' :
212
+ # OpenSlide 4.0.0+ requires UTF-8 on Windows
213
+ obj = os .fspath (obj )
214
+ if isinstance (obj , str ):
215
+ return obj .encode ('UTF-8' )
216
+ else :
217
+ return obj
218
+ else :
219
+ return os .fsencode (obj )
220
+
221
+
199
222
class _utf8_p :
200
223
"""Wrapper class to convert string arguments to bytes."""
201
224
@@ -350,14 +373,14 @@ def decorator(fn: Callable[_P, _T]) -> _Func[_P, _T]:
350
373
351
374
352
375
try :
353
- detect_vendor : _Func [[str ], str ] = _func (
354
- 'openslide_detect_vendor' , c_char_p , [_utf8_p ], _check_string
376
+ detect_vendor : _Func [[Filename ], str ] = _func (
377
+ 'openslide_detect_vendor' , c_char_p , [_filename_p ], _check_string
355
378
)
356
379
except AttributeError :
357
380
raise OpenSlideVersionError ('3.4.0' )
358
381
359
- open : _Func [[str ], _OpenSlide ] = _func (
360
- 'openslide_open' , c_void_p , [_utf8_p ], _check_open
382
+ open : _Func [[Filename ], _OpenSlide ] = _func (
383
+ 'openslide_open' , c_void_p , [_filename_p ], _check_open
361
384
)
362
385
363
386
close : _Func [[_OpenSlide ], None ] = _func (
@@ -452,7 +475,7 @@ def read_icc_profile(slide: _OpenSlide) -> bytes | None:
452
475
'openslide_get_property_names' , POINTER (c_char_p ), [_OpenSlide ], _check_name_list
453
476
)
454
477
455
- get_property_value : _Func [[_OpenSlide , str ], str ] = _func (
478
+ get_property_value : _Func [[_OpenSlide , str | bytes ], str ] = _func (
456
479
'openslide_get_property_value' , c_char_p , [_OpenSlide , _utf8_p ]
457
480
)
458
481
@@ -464,7 +487,7 @@ def read_icc_profile(slide: _OpenSlide) -> bytes | None:
464
487
)
465
488
466
489
_get_associated_image_dimensions : _Func [
467
- [_OpenSlide , str , _Pointer [c_int64 ], _Pointer [c_int64 ]], None
490
+ [_OpenSlide , str | bytes , _Pointer [c_int64 ], _Pointer [c_int64 ]], None
468
491
] = _func (
469
492
'openslide_get_associated_image_dimensions' ,
470
493
None ,
@@ -473,46 +496,54 @@ def read_icc_profile(slide: _OpenSlide) -> bytes | None:
473
496
474
497
475
498
@_wraps_funcs ([_get_associated_image_dimensions ])
476
- def get_associated_image_dimensions (slide : _OpenSlide , name : str ) -> tuple [int , int ]:
499
+ def get_associated_image_dimensions (
500
+ slide : _OpenSlide , name : str | bytes
501
+ ) -> tuple [int , int ]:
477
502
w , h = c_int64 (), c_int64 ()
478
503
_get_associated_image_dimensions (slide , name , byref (w ), byref (h ))
479
504
return w .value , h .value
480
505
481
506
482
- _read_associated_image : _Func [[_OpenSlide , str , _Pointer [c_uint32 ]], None ] = _func (
483
- 'openslide_read_associated_image' , None , [_OpenSlide , _utf8_p , POINTER (c_uint32 )]
507
+ _read_associated_image : _Func [[_OpenSlide , str | bytes , _Pointer [c_uint32 ]], None ] = (
508
+ _func (
509
+ 'openslide_read_associated_image' ,
510
+ None ,
511
+ [_OpenSlide , _utf8_p , POINTER (c_uint32 )],
512
+ )
484
513
)
485
514
486
515
487
516
@_wraps_funcs ([get_associated_image_dimensions , _read_associated_image ])
488
- def read_associated_image (slide : _OpenSlide , name : str ) -> Image .Image :
517
+ def read_associated_image (slide : _OpenSlide , name : str | bytes ) -> Image .Image :
489
518
w , h = get_associated_image_dimensions (slide , name )
490
519
buf = (w * h * c_uint32 )()
491
520
_read_associated_image (slide , name , buf )
492
521
return _load_image (buf , (w , h ))
493
522
494
523
495
- get_associated_image_icc_profile_size : _Func [[_OpenSlide , str ], int ] = _func (
524
+ get_associated_image_icc_profile_size : _Func [[_OpenSlide , str | bytes ], int ] = _func (
496
525
'openslide_get_associated_image_icc_profile_size' ,
497
526
c_int64 ,
498
527
[_OpenSlide , _utf8_p ],
499
528
minimum_version = '4.0.0' ,
500
529
)
501
530
502
- _read_associated_image_icc_profile : _Func [[ _OpenSlide , str , _Pointer [ c_char ]], None ] = (
503
- _func (
504
- 'openslide_read_associated_image_icc_profile' ,
505
- None ,
506
- [ _OpenSlide , _utf8_p , POINTER ( c_char )] ,
507
- minimum_version = '4.0.0' ,
508
- )
531
+ _read_associated_image_icc_profile : _Func [
532
+ [ _OpenSlide , str | bytes , _Pointer [ c_char ]], None
533
+ ] = _func (
534
+ 'openslide_read_associated_image_icc_profile' ,
535
+ None ,
536
+ [ _OpenSlide , _utf8_p , POINTER ( c_char )] ,
537
+ minimum_version = '4.0.0' ,
509
538
)
510
539
511
540
512
541
@_wraps_funcs (
513
542
[get_associated_image_icc_profile_size , _read_associated_image_icc_profile ]
514
543
)
515
- def read_associated_image_icc_profile (slide : _OpenSlide , name : str ) -> bytes | None :
544
+ def read_associated_image_icc_profile (
545
+ slide : _OpenSlide , name : str | bytes
546
+ ) -> bytes | None :
516
547
size = get_associated_image_icc_profile_size (slide , name )
517
548
if size == 0 :
518
549
return None
0 commit comments