3
# Copyright (c) 2008-2024, Christoph Gohlke
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions are met:
9
# 1. Redistributions of source code must retain the above copyright notice,
10
# this list of conditions and the following disclaimer.
12
# 2. Redistributions in binary form must reproduce the above copyright notice,
13
# this list of conditions and the following disclaimer in the documentation
14
# and/or other materials provided with the distribution.
16
# 3. Neither the name of the copyright holder nor the names of its
17
# contributors may be used to endorse or promote products derived from
18
# this software without specific prior written permission.
20
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
# POSSIBILITY OF SUCH DAMAGE.
32
# mypy: allow-untyped-defs
33
# mypy: check-untyped-defs=False
35
"""Unittests for the tifffile package.
37
Public data files can be requested from the author.
38
Private data files are not available due to size and copyright restrictions.
65
from numpy.testing import (
67
assert_array_almost_equal,
73
from tifffile import * # noqa: F403
93
natural_sorted, # noqa
100
askopenfilename, # noqa
101
read_scanimage_metadata, # noqa
102
read_micromanager_metadata, # noqa
105
) # type: tuple[object, ...]
109
from tifffile import ( # noqa: F401
140
ZarrFileSequenceStore,
144
from tifffile.tifffile import _squeeze_axes as squeeze_axes
145
from tifffile.tifffile import ( # noqa: F401
149
astrotiff_description_metadata,
158
fluoview_description_metadata,
162
imagej_description_metadata,
173
metaseries_description_metadata,
178
pilatus_description_metadata,
180
read_micromanager_metadata,
181
read_scanimage_metadata,
186
scanimage_artist_metadata,
187
scanimage_description_metadata,
190
shaped_description_metadata,
192
stk_description_metadata,
197
svs_description_metadata,
206
HERE = os.path.dirname(__file__)
207
TEMP_DIR = os.path.join(HERE, '_tmp')
208
PRIVATE_DIR = os.path.join(HERE, 'data', 'private')
209
PUBLIC_DIR = os.path.join(HERE, 'data', 'public')
211
IS_BE = sys.byteorder == 'big'
212
IS_PYPY = 'pypy' in sys.version.lower()
213
IS_WIN = sys.platform == 'win32'
214
IS_CG = os.environ.get('COMPUTERNAME', '').startswith('CG-K')
218
def skip(key, default):
219
return os.getenv(key, default) in {True, 1, '1'}
222
# skip tests requiring large memory
223
SKIP_LARGE = skip('SKIP_LARGE', sys.maxsize < 2**32)
224
SKIP_EXTENDED = skip('SKIP_EXTENDED', False)
226
SKIP_PUBLIC = skip('SKIP_PUBLIC', not os.path.exists(PUBLIC_DIR))
228
SKIP_PRIVATE = skip('SKIP_PRIVATE', not os.path.exists(PRIVATE_DIR))
229
# skip validate written files with jhove
230
SKIP_VALIDATE = skip('SKIP_VALIDATE', True)
231
SKIP_CODECS = skip('SKIP_CODECS', False)
232
SKIP_ZARR = skip('SKIP_ZARR', False)
233
SKIP_DASK = skip('SKIP_DASK', False)
234
SKIP_NDTIFF = skip('SKIP_NDTIFF', False)
235
SKIP_HTTP = skip('SKIP_HTTP', not IS_CG)
238
FILE_FLAGS = ['is_' + a for a in TIFF.FILE_FLAGS]
239
FILE_FLAGS += [name for name in dir(TiffFile) if name.startswith('is_')]
240
PAGE_FLAGS = [name for name in dir(TiffPage) if name.startswith('is_')]
242
URL = 'http://localhost:8386/' # TEMP_DIR
246
urllib.request.urlopen(URL + '/test/test.txt', timeout=0.5)
247
except (urllib.error.URLError, TimeoutError):
250
if not os.path.exists(TEMP_DIR):
251
TEMP_DIR = tempfile.gettempdir()
270
import fsspec # type: ignore
271
import zarr # type: ignore
274
fsspec = None # type: ignore
281
import dask # type: ignore
282
import dask.array # type: ignore
291
import ndtiff # type: ignore
298
"""Return test configuration."""
299
this = sys.modules[__name__]
301
a for a in dir(this) if a.startswith('SKIP_') and getattr(this, a)
305
def data_file(pathname, base, expand=True):
306
"""Return path to test file(s)."""
307
path = os.path.join(base, *pathname.split('/'))
308
if expand and any(i in path for i in '*?'):
309
return glob.glob(path)
313
def private_file(pathname, base=PRIVATE_DIR, expand=True):
314
"""Return path to private test file(s)."""
315
return data_file(pathname, base, expand=expand)
318
def public_file(pathname, base=PUBLIC_DIR, expand=True):
319
"""Return path to public test file(s)."""
320
return data_file(pathname, base, expand=expand)
323
def random_data(dtype, shape):
324
"""Return random numpy array."""
327
return numpy.random.rand(*shape) < 0.5
328
data = numpy.random.rand(*shape) * 255
329
data = data.astype(dtype)
333
def assert_file_flags(tiff_file):
334
"""Access all flags of TiffFile."""
335
for flag in FILE_FLAGS:
336
getattr(tiff_file, flag)
339
def assert_page_flags(tiff_page):
340
"""Access all flags of TiffPage."""
341
for flag in PAGE_FLAGS:
342
getattr(tiff_page, flag)
345
def assert__str__(tif, detail=3):
346
"""Call TiffFile._str and __repr__ functions."""
347
for i in range(detail + 1):
353
if len(tif.pages) > 0:
354
page = tif.pages.first
365
if len(tif.series) > 0:
366
series = tif.series[0]
371
def assert__repr__(obj):
372
"""Call object's __repr__ and __str__ function."""
377
def assert_valid_omexml(omexml):
378
"""Validate OME-XML schema."""
380
OmeXml.validate(omexml, assert_=True)
383
def assert_valid_tiff(filename, *args, **kwargs):
384
"""Validate TIFF file using jhove script."""
387
validate_jhove(filename, 'jhove.cmd', *args, **kwargs)
390
def assert_decode_method(page, image=None):
391
"""Call TiffPage.decode on all segments and compare to TiffPage.asarray."""
392
fh = page.parent.filehandle
394
offsets = page.tags['TileOffsets'].value
395
bytecounts = page.tags['TileByteCounts'].value
397
offsets = page.tags['StripOffsets'].value
398
bytecounts = page.tags['StripByteCounts'].value
400
image = page.asarray()
401
for i, (o, b) in enumerate(zip(offsets, bytecounts)):
404
strile, index, shape = page.decode(strile, i)
405
assert image.reshape(page.shaped)[index] == strile[0, 0, 0, 0]
408
def assert_aszarr_method(obj, image=None, chunkmode=None, **kwargs):
409
"""Assert aszarr returns same data as asarray."""
410
if SKIP_ZARR or zarr is None:
413
image = obj.asarray(**kwargs)
414
with obj.aszarr(chunkmode=chunkmode, **kwargs) as store:
415
data = zarr.open(store, mode='r')
416
if isinstance(data, zarr.Group):
418
assert_array_equal(data, image)
423
"""Temporary file name context manager."""
428
def __init__(self, name=None, ext='.tif', remove=False):
429
self.remove = remove or TEMP_DIR == tempfile.gettempdir()
431
fh = tempfile.NamedTemporaryFile(prefix='test_')
435
self.name = os.path.join(TEMP_DIR, f'test_{name}{ext}')
437
def __enter__(self) -> str:
440
def __exit__(self, exc_type, exc_value, traceback):
448
numpy.set_printoptions(suppress=True, precision=5)
451
###############################################################################
453
# Tests for specific issues
456
def test_issue_star_import():
457
"""Test from tifffile import *."""
458
assert len(STAR_IMPORTED) > 0
459
assert lsm2bin not in STAR_IMPORTED
462
@pytest.mark.skipif(__doc__ is None, reason='__doc__ is None')
463
def test_issue_version_mismatch():
464
"""Test 'tifffile.__version__' matches docstrings."""
465
ver = ':Version: ' + tifffile.__version__
466
assert ver in __doc__
467
assert ver in tifffile.__doc__
470
def test_issue_deprecated_import():
471
"""Test deprecated functions can still be imported."""
472
from tifffile import imsave
474
with TempFileName('issue_deprecated_import') as fname:
475
with pytest.warns(DeprecationWarning):
478
with TiffWriter(fname) as tif:
479
with pytest.warns(DeprecationWarning):
483
# from tifffile import decodelzw
484
# from tifffile import decode_lzw
487
def test_issue_imread_kwargs():
488
"""Test that is_flags are handled by imread."""
489
data = random_data(numpy.uint16, (5, 63, 95))
490
with TempFileName('issue_imread_kwargs') as fname:
491
with TiffWriter(fname) as tif:
493
tif.write(image) # create 5 series
494
assert_valid_tiff(fname)
495
image = imread(fname, pattern=None) # reads first series
496
assert_array_equal(image, data[0])
497
image = imread(fname, is_shaped=False) # reads all pages
498
assert_array_equal(image, data)
501
def test_issue_imread_kwargs_legacy():
502
"""Test legacy arguments no longer work as of 2022.4.22
504
Specifying 'fastij', 'movie', 'multifile', 'multifile_close', or
505
'pages' raises TypeError.
506
Specifying 'key' and 'pages' raises TypeError.
507
Specifying 'pages' in TiffFile constructor raises TypeError.
510
data = random_data(numpy.uint8, (3, 21, 31))
511
with TempFileName('issue_imread_kwargs_legacy') as fname:
512
imwrite(fname, data, photometric=PHOTOMETRIC.MINISBLACK)
513
with pytest.raises(TypeError):
514
imread(fname, fastij=True)
515
with pytest.raises(TypeError):
516
imread(fname, movie=True)
517
with pytest.raises(TypeError):
518
imread(fname, multifile=True)
519
with pytest.raises(TypeError):
520
imread(fname, multifile_close=True)
522
with pytest.raises(TypeError):
523
TiffFile(fname, fastij=True)
524
with pytest.raises(TypeError):
525
TiffFile(fname, multifile=True)
526
with pytest.raises(TypeError):
527
TiffFile(fname, multifile_close=True)
528
with pytest.raises(TypeError):
529
imread(fname, key=0, pages=[1, 2])
530
with pytest.raises(TypeError):
531
TiffFile(fname, pages=[1, 2])
534
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
535
def test_issue_infinite_loop():
536
"""Test infinite loop reading more than two tags of same code in IFD."""
537
# Reported by D. Hughes on 2019.7.26
538
# the test file is corrupted but should not cause infinite loop
539
fname = private_file('gdk-pixbuf/bug784903-overflow-dimensions.tiff')
540
with TiffFile(fname) as tif:
541
page = tif.pages.first
542
assert page.compression == 0 # invalid
547
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
550
def test_issue_jpeg_ia():
551
"""Test JPEG compressed intensity image with alpha channel."""
553
fname = private_file('issues/jpeg_ia.tiff')
554
with TiffFile(fname) as tif:
555
page = tif.pages.first
556
assert page.compression == COMPRESSION.JPEG
559
numpy.array([[[0, 0], [255, 255]]], dtype=numpy.uint8),
565
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
568
def test_issue_jpeg_palette():
569
"""Test invalid JPEG compressed intensity image with palette."""
570
# https://forum.image.sc/t/viv-and-avivator/45999/24
571
fname = private_file('issues/FL_cells.ome.tif')
572
with TiffFile(fname) as tif:
573
page = tif.pages.first
574
assert page.compression == COMPRESSION.JPEG
575
assert page.colormap is not None
577
assert data.shape == (4, 1024, 1024)
578
assert data.dtype == numpy.uint8
579
assert data[2, 512, 512] == 10
580
assert_aszarr_method(tif, data)
584
def test_issue_specific_pages():
585
"""Test read second page."""
586
data = random_data(numpy.uint8, (3, 21, 31))
587
with TempFileName('issue_specific_pages') as fname:
588
imwrite(fname, data, photometric=PHOTOMETRIC.MINISBLACK)
589
image = imread(fname)
590
assert image.shape == (3, 21, 31)
591
# UserWarning: can not reshape (21, 31) to (3, 21, 31)
592
image = imread(fname, key=1)
593
assert image.shape == (21, 31)
594
assert_array_equal(image, data[1])
595
with TempFileName('issue_specific_pages_bigtiff') as fname:
596
imwrite(fname, data, bigtiff=True, photometric=PHOTOMETRIC.MINISBLACK)
597
image = imread(fname)
598
assert image.shape == (3, 21, 31)
599
# UserWarning: can not reshape (21, 31) to (3, 21, 31)
600
image = imread(fname, key=1)
601
assert image.shape == (21, 31)
602
assert_array_equal(image, data[1])
605
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
606
def test_issue_circular_ifd(caplog):
607
"""Test circular IFD logs error but is still readable."""
608
fname = public_file('Tiff-Library-4J/IFD struct/Circular E.tif')
609
with TiffFile(fname) as tif:
610
assert len(tif.pages) == 2
611
assert 'invalid circular reference' in caplog.text
612
image = tif.asarray()
613
assert image.shape == (2, 1500, 2000, 3)
614
assert image[1, 1499, 1999, 2] == 110
617
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
618
def test_issue_bad_description(caplog):
619
"""Test page.description is empty when ImageDescription is not ASCII."""
620
# ImageDescription is not ASCII but bytes
621
fname = private_file('stk/cells in the eye2.stk')
622
with TiffFile(fname) as tif:
623
page = tif.pages.first
624
assert page.description == ''
626
assert 'coercing invalid ASCII to bytes' in caplog.text
629
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
630
def test_issue_bad_ascii(caplog):
631
"""Test coerce invalid ASCII to bytes."""
632
# ImageID is not ASCII but bytes
633
# https://github.com/blink1073/tifffile/pull/38
634
fname = private_file('issues/tifffile_013_tagfail.tif')
635
with TiffFile(fname) as tif:
636
tags = tif.pages.first.tags
637
assert tags['ImageID'].value[-8:] == b'rev 2893'
639
assert 'coercing invalid ASCII to bytes' in caplog.text
642
def test_issue_sampleformat():
643
"""Test write correct number of SampleFormat values."""
644
# https://github.com/ngageoint/geopackage-tiff-java/issues/5
645
data = random_data(numpy.int16, (256, 256, 4))
646
with TempFileName('issue_sampleformat') as fname:
647
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
648
with TiffFile(fname) as tif:
649
tags = tif.pages.first.tags
650
assert tags['SampleFormat'].value == (2, 2, 2, 2)
651
assert tags['ExtraSamples'].value == (2,)
655
def test_issue_sampleformat_default():
656
"""Test SampleFormat are not written for UINT."""
657
data = random_data(numpy.uint8, (256, 256, 4))
658
with TempFileName('issue_sampleformat_default') as fname:
659
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
660
with TiffFile(fname) as tif:
661
tags = tif.pages.first.tags
662
'SampleFormat' not in tags
663
assert tags['ExtraSamples'].value == (2,)
667
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
668
def test_issue_palette_with_extrasamples():
669
"""Test read palette with extra samples."""
670
# https://github.com/python-pillow/Pillow/issues/1597
671
fname = private_file('issues/palette_with_extrasamples.tif')
672
with TiffFile(fname) as tif:
673
assert len(tif.pages) == 1
674
page = tif.pages.first
675
assert page.photometric == PHOTOMETRIC.PALETTE
676
assert page.compression == COMPRESSION.LZW
677
assert page.imagewidth == 518
678
assert page.imagelength == 556
679
assert page.bitspersample == 8
680
assert page.samplesperpixel == 2
683
assert image.shape == (556, 518, 3)
684
assert image.dtype == numpy.uint16
685
image = tif.asarray()
686
# self.assertEqual(image.shape[-3:], (556, 518, 2))
687
assert image.shape == (556, 518, 2)
688
assert image.dtype == numpy.uint8
689
assert_aszarr_method(tif, image)
694
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
695
def test_issue_incorrect_rowsperstrip_count():
696
"""Test read incorrect count for rowsperstrip; bitspersample = 4."""
697
# https://github.com/python-pillow/Pillow/issues/1544
698
fname = private_file('bad/incorrect_count.tiff')
699
with TiffFile(fname) as tif:
700
assert len(tif.pages) == 1
701
page = tif.pages.first
702
assert page.photometric == PHOTOMETRIC.PALETTE
703
assert page.compression == COMPRESSION.ADOBE_DEFLATE
704
assert page.imagewidth == 32
705
assert page.imagelength == 32
706
assert page.bitspersample == 4
707
assert page.samplesperpixel == 1
708
assert page.rowsperstrip == 32
709
assert page.dataoffsets[0] == 8
710
assert page.databytecounts[0] == 89
713
assert image.shape == (32, 32, 3)
714
assert_aszarr_method(page)
719
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
720
def test_issue_extra_strips(caplog):
721
"""Test read extra strips."""
722
# https://github.com/opencv/opencv/issues/17054
723
fname = private_file('issues/extra_strips.tif')
724
with TiffFile(fname) as tif:
725
assert not tif.is_bigtiff
726
assert len(tif.pages) == 1
727
page = tif.pages.first
728
assert page.tags['StripOffsets'].value == (8, 0, 0)
729
assert page.tags['StripByteCounts'].value == (55064448, 0, 0)
730
assert page.dataoffsets[0] == 8
731
assert page.databytecounts[0] == 55064448
732
assert page.is_contiguous
734
image = tif.asarray()
735
assert image.shape == (2712, 3384, 3)
736
assert_aszarr_method(page, image)
737
assert 'incorrect StripOffsets count' in caplog.text
738
assert 'incorrect StripByteCounts count' in caplog.text
741
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
742
def test_issue_no_bytecounts(caplog):
743
"""Test read no bytecounts."""
744
fname = private_file('bad/img2_corrupt.tif')
745
with TiffFile(fname) as tif:
746
assert not tif.is_bigtiff
747
assert len(tif.pages) == 1
748
page = tif.pages.first
749
assert page.is_contiguous
750
assert page.planarconfig == PLANARCONFIG.CONTIG
751
assert page.dataoffsets[0] == 512
752
assert page.databytecounts[0] == 0
754
image = tif.asarray()
755
assert image.shape == (800, 1200)
756
# fails: assert_aszarr_method(tif, image)
757
assert 'invalid value offset 0' in caplog.text
758
assert 'invalid data type 31073' in caplog.text
759
assert 'invalid page offset 808333686' in caplog.text
762
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
763
def test_issue_missing_eoi_in_strips():
764
"""Test read LZW strips without EOI."""
765
# 256x256 uint16, lzw, imagej
766
# Strips do not contain an EOI code as required by the TIFF spec.
767
# File generated by `tiffcp -c lzw Z*.tif stack.tif` from
769
# Failed with "series 0 failed: string size must be a multiple of
771
# Reported by Kai Wohlfahrt on 3/7/2014
772
fname = private_file('issues/stack.tif')
773
with TiffFile(fname) as tif:
775
assert tif.byteorder == '<'
776
assert len(tif.pages) == 128
777
assert len(tif.series) == 1
778
# assert page properties
779
page = tif.pages.first
780
assert page.imagewidth == 256
781
assert page.imagelength == 256
782
assert page.bitspersample == 16
783
# assert series properties
784
series = tif.series[0]
785
assert series.shape == (128, 256, 256)
786
assert series.dtype == numpy.uint16
787
assert series.axes == 'IYX'
789
ijmeta = tif.imagej_metadata
790
assert ijmeta is not None
791
assert ijmeta['ImageJ'] == '1.41e'
794
assert data.shape == (128, 256, 256)
795
assert data.dtype == numpy.uint16
796
assert data[64, 128, 128] == 19226
797
assert_aszarr_method(tif, data)
802
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
803
def test_issue_imagej_grascalemode():
804
"""Test read ImageJ grayscale mode RGB image."""
805
# https://github.com/cgohlke/tifffile/issues/6
806
fname = private_file('issues/hela-cells.tif')
807
with TiffFile(fname) as tif:
809
assert tif.byteorder == '>'
810
assert len(tif.pages) == 1
811
assert len(tif.series) == 1
812
# assert page properties
813
page = tif.pages.first
814
assert page.photometric == PHOTOMETRIC.RGB
815
assert page.imagewidth == 672
816
assert page.imagelength == 512
817
assert page.bitspersample == 16
818
assert page.is_contiguous
819
# assert series properties
820
series = tif.series[0]
821
assert series.shape == (512, 672, 3)
822
assert series.dtype == numpy.uint16
823
assert series.axes == 'YXS'
825
ijmeta = tif.imagej_metadata
826
assert ijmeta is not None
827
assert ijmeta['ImageJ'] == '1.52p'
828
assert ijmeta['channels'] == 3
831
assert isinstance(data, numpy.ndarray)
832
assert data.shape == (512, 672, 3)
833
assert data.dtype == numpy.uint16
834
assert tuple(data[255, 336]) == (440, 378, 298)
835
assert_aszarr_method(tif, data)
839
@pytest.mark.parametrize('byteorder', ['>', '<'])
840
def test_issue_valueoffset(byteorder):
841
"""Test read TiffTag.valueoffsets."""
842
unpack = struct.unpack
843
data = random_data(byteorder + 'u2', (2, 19, 31))
844
software = 'test_tifffile'
845
bo = {'>': 'be', '<': 'le'}[byteorder]
846
with TempFileName(f'issue_valueoffset_{bo}') as fname:
851
photometric=PHOTOMETRIC.MINISBLACK,
852
extratags=[(65535, 3, 2, (21, 22), True)],
854
with TiffFile(fname, _useframes=True) as tif:
855
with open(fname, 'rb') as fh:
856
page = tif.pages.first
858
fh.seek(page.tags['ImageLength'].valueoffset)
861
== unpack(tif.byteorder + 'I', fh.read(4))[0]
864
fh.seek(page.tags[65535].valueoffset)
865
assert unpack(tif.byteorder + 'H', fh.read(2))[0] == 21
867
fh.seek(page.tags['Software'].valueoffset)
868
assert page.software == bytes2str(fh.read(13))
870
page = tif.pages[1].aspage()
871
fh.seek(page.tags['StripOffsets'].valueoffset)
874
== unpack(tif.byteorder + 'I', fh.read(4))[0]
876
tag = page.tags['ImageLength']
877
assert tag.name == 'ImageLength'
878
assert tag.dtype_name == 'LONG'
879
assert tag.dataformat == '1I'
880
assert tag.valuebytecount == 4
883
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
884
def test_issue_pages_number():
885
"""Test number of pages."""
886
fname = public_file('tifffile/100000_pages.tif')
887
with TiffFile(fname) as tif:
888
assert len(tif.pages) == 100000
889
assert__str__(tif, 0)
892
def test_issue_pages_iterator():
893
"""Test iterate over pages in series."""
894
data = random_data(numpy.int8, (8, 219, 301))
895
with TempFileName('issue_page_iterator') as fname:
896
imwrite(fname, data[0])
900
photometric=PHOTOMETRIC.MINISBLACK,
902
metadata={'axes': 'ZYX'},
904
imwrite(fname, data[-1], append=True)
905
with TiffFile(fname) as tif:
906
assert len(tif.pages) == 10
907
assert len(tif.series) == 3
909
assert isinstance(page, TiffPage)
910
assert page.is_contiguous
911
assert page.photometric == PHOTOMETRIC.MINISBLACK
912
assert page.imagewidth == 301
913
assert page.imagelength == 219
914
assert page.samplesperpixel == 1
916
series = tif.series[1]
917
assert len(series._pages) == 1
918
assert len(series.pages) == 8
919
image = series.asarray()
920
assert_array_equal(data, image)
921
for i, page in enumerate(series.pages):
922
assert page is not None
924
assert_array_equal(image[i], im)
928
def test_issue_tile_partial():
929
"""Test write single tiles larger than image data."""
930
# https://github.com/cgohlke/tifffile/issues/3
931
data = random_data(numpy.uint8, (3, 15, 15, 15))
932
with TempFileName('issue_tile_partial_2d') as fname:
933
imwrite(fname, data[0, 0], tile=(16, 16))
934
with TiffFile(fname) as tif:
935
assert len(tif.pages) == 1
936
page = tif.pages.first
937
assert not page.is_contiguous
940
page.tags['TileOffsets'].value[0]
941
+ page.tags['TileByteCounts'].value[0]
942
== tif.filehandle.size
944
assert_array_equal(page.asarray(), data[0, 0])
945
assert_aszarr_method(page, data[0, 0])
948
with TempFileName('issue_tile_partial_3d') as fname:
949
imwrite(fname, data[0], tile=(16, 16, 16))
950
with TiffFile(fname) as tif:
951
assert len(tif.pages) == 1
952
page = tif.pages.first
953
assert not page.is_contiguous
955
assert page.is_volumetric
957
page.tags['TileOffsets'].value[0]
958
+ page.tags['TileByteCounts'].value[0]
959
== tif.filehandle.size
961
assert_array_equal(page.asarray(), data[0])
962
assert_aszarr_method(page, data[0])
965
with TempFileName('issue_tile_partial_3d_separate') as fname:
970
planarconfig=PLANARCONFIG.SEPARATE,
971
photometric=PHOTOMETRIC.RGB,
973
with TiffFile(fname) as tif:
974
assert len(tif.pages) == 1
975
page = tif.pages.first
976
assert not page.is_contiguous
979
page.tags['TileOffsets'].value[0]
980
+ page.tags['TileByteCounts'].value[0] * 3
981
== tif.filehandle.size
983
assert_array_equal(page.asarray(), data)
984
assert_aszarr_method(page, data)
987
# test complete tile is contiguous
988
data = random_data(numpy.uint8, (16, 16))
989
with TempFileName('issue_tile_partial_not') as fname:
990
imwrite(fname, data, tile=(16, 16))
991
with TiffFile(fname) as tif:
992
assert len(tif.pages) == 1
993
page = tif.pages.first
994
assert page.is_contiguous
995
assert page.is_memmappable
998
page.tags['TileOffsets'].value[0]
999
+ page.tags['TileByteCounts'].value[0]
1000
== tif.filehandle.size
1002
assert_array_equal(page.asarray(), data)
1003
assert_aszarr_method(page, data)
1007
@pytest.mark.parametrize('compression', [1, 8])
1008
@pytest.mark.parametrize('samples', [1, 3])
1009
def test_issue_tiles_pad(samples, compression):
1010
"""Test tiles from iterator get padded."""
1011
# https://github.com/cgohlke/tifffile/issues/38
1013
data = numpy.random.randint(0, 2**12, (31, 33, 3), numpy.uint16)
1016
data = numpy.random.randint(0, 2**12, (31, 33), numpy.uint16)
1019
def tiles(data, tileshape, pad=False):
1020
for y in range(0, data.shape[0], tileshape[0]):
1021
for x in range(0, data.shape[1], tileshape[1]):
1022
tile = data[y : y + tileshape[0], x : x + tileshape[1]]
1023
if pad and tile.shape != tileshape:
1027
(0, tileshape[0] - tile.shape[0]),
1028
(0, tileshape[1] - tile.shape[1]),
1034
f'issue_issue_tiles_pad_{compression}{samples}'
1038
tiles(data, (16, 16)),
1042
photometric=photometric,
1043
compression=compression,
1045
assert_array_equal(imread(fname), data)
1046
assert_valid_tiff(fname)
1049
def test_issue_fcontiguous():
1050
"""Test write F-contiguous arrays."""
1051
# https://github.com/cgohlke/tifffile/issues/24
1052
data = numpy.asarray(random_data(numpy.uint8, (31, 33)), order='F')
1053
with TempFileName('issue_fcontiguous') as fname:
1054
imwrite(fname, data, compression=COMPRESSION.ADOBE_DEFLATE)
1055
with TiffFile(fname) as tif:
1056
assert len(tif.pages) == 1
1057
page = tif.pages.first
1058
assert_array_equal(page.asarray(), data)
1062
def test_issue_pathlib():
1063
"""Test support for pathlib.Path."""
1064
data = random_data(numpy.uint16, (219, 301))
1065
with TempFileName('issue_pathlib') as fname:
1066
fname = pathlib.Path(fname)
1067
assert isinstance(fname, os.PathLike)
1069
imwrite(fname, data)
1072
assert_array_equal(im, data)
1076
assert_array_equal(im, data)
1080
with TiffFile(fname) as tif:
1081
with TempFileName('issue_pathlib_out') as outfname:
1082
outfname = pathlib.Path(outfname)
1084
im = tif.asarray(out=outfname)
1086
assert isinstance(im, numpy.memmap)
1087
assert_array_equal(im, data)
1088
assert os.path.samefile(im.filename, str(outfname))
1092
with TiffSequence(fname) as tifs:
1094
assert_array_equal(im[0], data)
1095
with TiffSequence([fname]) as tifs:
1097
assert_array_equal(im[0], data)
1099
# TiffSequence container
1100
if SKIP_PRIVATE or SKIP_CODECS:
1102
fname = pathlib.Path(private_file('TiffSequence.zip'))
1103
with TiffSequence('*.tif', container=fname, pattern=None) as tifs:
1105
assert im[9, 256, 256] == 135
1108
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
1109
def test_issue_lzw_corrupt():
1110
"""Test decode corrupted LZW segment raises RuntimeError."""
1111
# reported by S Richter on 2020.2.17
1112
fname = private_file('issues/lzw_corrupt.tiff')
1113
with pytest.raises(RuntimeError):
1114
with TiffFile(fname) as tif:
1118
def test_issue_iterable_compression():
1119
"""Test write iterable of pages with compression."""
1120
# https://github.com/cgohlke/tifffile/issues/20
1121
data = numpy.random.rand(10, 10, 10) * 127
1122
data = data.astype(numpy.int8)
1123
with TempFileName('issue_iterable_compression') as fname:
1124
with TiffWriter(fname) as tif:
1125
tif.write(data, shape=(10, 10, 10), dtype=numpy.int8)
1130
compression=COMPRESSION.ADOBE_DEFLATE,
1132
with TiffFile(fname) as tif:
1133
assert_array_equal(tif.series[0].asarray(), data)
1134
assert_array_equal(tif.series[1].asarray(), data)
1135
# fail with wrong dtype
1136
with TempFileName('issue_iterable_compression_fail') as fname:
1137
with TiffWriter(fname) as tif:
1138
with pytest.raises(ValueError):
1139
tif.write(data, shape=(10, 10, 10), dtype=numpy.uint8)
1140
with TiffWriter(fname) as tif:
1141
with pytest.raises(ValueError):
1146
compression=COMPRESSION.ADOBE_DEFLATE,
1150
def test_issue_write_separated():
1151
"""Test write SEPARATED colorspace."""
1152
# https://github.com/cgohlke/tifffile/issues/37
1153
contig = random_data(numpy.uint8, (63, 95, 4))
1154
separate = random_data(numpy.uint8, (4, 63, 95))
1155
extrasample = random_data(numpy.uint8, (63, 95, 5))
1156
with TempFileName('issue_write_separated') as fname:
1157
with TiffWriter(fname) as tif:
1158
tif.write(contig, photometric=PHOTOMETRIC.SEPARATED)
1159
tif.write(separate, photometric=PHOTOMETRIC.SEPARATED)
1162
photometric=PHOTOMETRIC.SEPARATED,
1165
assert_valid_tiff(fname)
1166
with TiffFile(fname) as tif:
1167
assert len(tif.pages) == 3
1168
assert len(tif.series) == 3
1169
page = tif.pages.first
1170
assert page.photometric == PHOTOMETRIC.SEPARATED
1171
assert_array_equal(page.asarray(), contig)
1173
assert page.photometric == PHOTOMETRIC.SEPARATED
1174
assert_array_equal(page.asarray(), separate)
1176
assert page.photometric == PHOTOMETRIC.SEPARATED
1177
assert page.extrasamples == (1,)
1178
assert_array_equal(page.asarray(), extrasample)
1181
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
1182
def test_issue_mmap():
1183
"""Test read from mmap object with no readinto function.."""
1184
fname = public_file('OME/bioformats-artificial/4D-series.ome.tiff')
1185
with open(fname, 'rb') as fh:
1186
mm = mmap.mmap(fh.fileno(), 0, access=mmap.ACCESS_READ)
1187
assert_array_equal(imread(mm), imread(fname))
1191
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
1192
def test_issue_micromanager(caplog):
1193
"""Test fallback to ImageJ metadata if OME series fails."""
1194
# https://github.com/cgohlke/tifffile/issues/54
1195
# https://forum.image.sc/t/47567/9
1196
# OME-XML does not contain reference to master file
1197
# file has corrupted MicroManager DisplaySettings metadata
1198
fname = private_file(
1200
'image_stack_tpzc_50tp_2p_5z_3c_512k_1_MMStack_2-Pos001_000.ome.tif'
1203
fname, is_mmstack=False, is_ndtiff=False, is_mdgel=False
1205
assert len(tif.pages) == 750
1206
with caplog.at_level(logging.DEBUG):
1207
assert len(tif.series) == 1
1208
assert 'OME series is BinaryOnly' in caplog.text
1209
assert tif.is_micromanager
1211
assert tif.is_imagej
1212
assert tif.micromanager_metadata is not None
1213
assert 'DisplaySettings' not in tif.micromanager_metadata
1214
assert 'failed to read display settings' not in caplog.text
1215
series = tif.series[0]
1216
assert series.shape == (50, 5, 3, 256, 256)
1219
@pytest.mark.skipif(IS_PYPY, reason=REASON)
1220
def test_issue_pickle():
1221
"""Test that TIFF constants are picklable."""
1222
# https://github.com/cgohlke/tifffile/issues/64
1223
from pickle import dumps, loads
1225
with pytest.warns(DeprecationWarning):
1226
assert loads(dumps(TIFF)).CHUNKMODE.PLANE == TIFF.CHUNKMODE.PLANE
1227
assert loads(dumps(TIFF.CHUNKMODE)).PLANE == TIFF.CHUNKMODE.PLANE
1228
assert loads(dumps(TIFF.CHUNKMODE.PLANE)) == TIFF.CHUNKMODE.PLANE
1231
def test_issue_imagej_singlet_dimensions():
1232
"""Test that ImageJ files can be read preserving singlet dimensions."""
1233
# https://github.com/cgohlke/tifffile/issues/19
1234
# https://github.com/cgohlke/tifffile/issues/66
1236
data = numpy.random.randint(0, 2**8, (1, 10, 1, 248, 260, 1), numpy.uint8)
1238
with TempFileName('issue_imagej_singlet_dimensions') as fname:
1239
imwrite(fname, data, imagej=True)
1240
image = imread(fname, squeeze=False)
1241
assert_array_equal(image, data)
1243
with TiffFile(fname) as tif:
1244
assert tif.is_imagej
1245
series = tif.series[0]
1246
assert series.axes == 'ZYX'
1247
assert series.shape == (10, 248, 260)
1248
assert series.get_axes(squeeze=False) == 'TZCYXS'
1249
assert series.get_shape(squeeze=False) == (1, 10, 1, 248, 260, 1)
1250
data = tif.asarray(squeeze=False)
1251
assert_array_equal(image, data)
1252
assert_aszarr_method(series, data, squeeze=False)
1253
assert_aszarr_method(series, data, squeeze=False, chunkmode='page')
1257
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
1260
def test_issue_cr2_ojpeg():
1261
"""Test read OJPEG image from CR2."""
1262
# https://github.com/cgohlke/tifffile/issues/75
1264
fname = private_file('CanonCR2/Canon - EOS M6 - RAW (3 2).cr2')
1266
with TiffFile(fname) as tif:
1267
assert len(tif.pages) == 4
1268
page = tif.pages.first
1269
assert page.compression == 6
1270
assert page.shape == (4000, 6000, 3)
1271
assert page.dtype == numpy.uint8
1272
assert page.photometric == PHOTOMETRIC.YCBCR
1273
assert page.compression == COMPRESSION.OJPEG
1274
data = page.asarray()
1275
assert data.shape == (4000, 6000, 3)
1276
assert data.dtype == numpy.uint8
1277
assert tuple(data[1640, 2372]) == (71, 75, 58)
1278
assert_aszarr_method(page, data)
1281
assert page.shape == (120, 160, 3)
1282
assert page.dtype == numpy.uint8
1283
assert page.photometric == PHOTOMETRIC.YCBCR
1284
assert page.compression == COMPRESSION.OJPEG
1285
data = page.asarray()
1286
assert tuple(data[60, 80]) == (124, 144, 107)
1287
assert_aszarr_method(page, data)
1290
assert page.shape == (400, 600, 3)
1291
assert page.dtype == numpy.uint16
1292
assert page.photometric == PHOTOMETRIC.RGB
1293
assert page.compression == COMPRESSION.NONE
1294
data = page.asarray()
1295
assert tuple(data[200, 300]) == (1648, 2340, 1348)
1296
assert_aszarr_method(page, data)
1299
assert page.shape == (4056, 3144, 2)
1300
assert page.dtype == numpy.uint16
1301
assert page.photometric == PHOTOMETRIC.MINISWHITE
1302
assert page.compression == COMPRESSION.OJPEG # SOF3
1303
data = page.asarray()
1304
assert tuple(data[2000, 1500]) == (1759, 2467)
1305
assert_aszarr_method(page, data)
1309
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
1312
def test_issue_ojpeg_preview():
1313
"""Test read JPEGInterchangeFormat from RAW image."""
1314
# https://github.com/cgohlke/tifffile/issues/93
1316
fname = private_file('RAW/RAW_NIKON_D3X.NEF')
1318
with TiffFile(fname) as tif:
1319
assert len(tif.pages) == 1
1320
page = tif.pages.first
1321
assert page.compression == COMPRESSION.NONE
1322
assert page.shape == (120, 160, 3)
1323
assert page.dtype == numpy.uint8
1324
assert page.photometric == PHOTOMETRIC.RGB
1325
data = page.asarray()
1326
assert data.shape == (120, 160, 3)
1327
assert data.dtype == numpy.uint8
1328
assert tuple(data[60, 80]) == (180, 167, 159)
1329
assert_aszarr_method(page, data)
1331
page = tif.pages.first.pages[0]
1332
assert page.shape == (4032, 6048, 3)
1333
assert page.dtype == numpy.uint8
1334
assert page.photometric == COMPRESSION.OJPEG
1335
data = page.asarray()
1336
assert tuple(data[60, 80]) == (67, 13, 11)
1337
assert_aszarr_method(page, data)
1339
page = tif.pages.first.pages[1]
1340
assert page.shape == (4044, 6080)
1341
assert page.bitspersample == 14
1342
assert page.photometric == PHOTOMETRIC.CFA
1343
assert page.compression == COMPRESSION.NIKON_NEF
1344
with pytest.raises(ValueError):
1345
data = page.asarray()
1349
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
1352
def test_issue_arw(caplog):
1353
"""Test read Sony ARW RAW image."""
1354
# https://github.com/cgohlke/tifffile/issues/95
1356
fname = private_file('RAW/A1_full_lossless_compressed.ARW')
1358
with TiffFile(fname) as tif:
1359
assert len(tif.pages) == 3
1360
assert len(tif.series) == 4
1362
page = tif.pages.first
1363
assert page.compression == COMPRESSION.OJPEG
1364
assert page.photometric == PHOTOMETRIC.YCBCR
1365
assert page.shape == (1080, 1616, 3)
1366
assert page.dtype == numpy.uint8
1367
data = page.asarray()
1368
assert data.shape == (1080, 1616, 3)
1369
assert data.dtype == numpy.uint8
1370
assert tuple(data[60, 80]) == (122, 119, 104)
1371
assert_aszarr_method(page, data)
1372
assert tif.pages.first.pages is not None
1373
page = tif.pages.first.pages[0]
1374
assert page.is_tiled
1375
assert page.compression == COMPRESSION.JPEG
1376
assert page.photometric == PHOTOMETRIC.CFA
1377
assert page.bitspersample == 14
1378
assert page.tags['SonyRawFileType'].value == 4
1379
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
1380
assert page.tags['CFAPattern'].value == b'\0\1\1\2'
1381
assert page.shape == (6144, 8704)
1382
assert page.dtype == numpy.uint16
1383
data = page.asarray()
1384
assert 'SonyRawFileType' in caplog.text
1385
assert data[60, 80] == 1000 # might not be correct according to #95
1386
assert_aszarr_method(page, data)
1389
assert page.compression == COMPRESSION.OJPEG
1390
assert page.photometric == PHOTOMETRIC.YCBCR
1391
assert page.shape == (120, 160, 3)
1392
assert page.dtype == numpy.uint8
1393
data = page.asarray()
1394
assert tuple(data[60, 80]) == (56, 54, 29)
1395
assert_aszarr_method(page, data)
1398
assert page.compression == COMPRESSION.JPEG
1399
assert page.photometric == PHOTOMETRIC.YCBCR
1400
assert page.shape == (5760, 8640, 3)
1401
assert page.dtype == numpy.uint8
1402
data = page.asarray()
1403
assert tuple(data[60, 80]) == (243, 238, 218)
1404
assert_aszarr_method(page, data)
1407
def test_issue_rational_rounding():
1408
"""Test rational are rounded to 64-bit."""
1409
# https://github.com/cgohlke/tifffile/issues/81
1411
data = numpy.array([[255]])
1413
with TempFileName('issue_rational_rounding') as fname:
1414
imwrite(fname, data, resolution=(7411.824413635355, 7411.824413635355))
1416
with TiffFile(fname) as tif:
1417
tags = tif.pages.first.tags
1418
assert tags['XResolution'].value == (4294967295, 579475)
1419
assert tags['YResolution'].value == (4294967295, 579475)
1422
def test_issue_omexml_micron():
1423
"""Test OME-TIFF can be created with micron character in XML."""
1424
# https://forum.image.sc/t/micro-character-in-omexml-from-python/53578/4
1426
with TempFileName('issue_omexml_micron', ext='.ome.tif') as fname:
1430
metadata={'PhysicalSizeX': 1.0, 'PhysicalSizeXUnit': 'µm'},
1432
with TiffFile(fname) as tif:
1435
'PhysicalSizeXUnit="µm"'
1436
in tif.pages.first.tags['ImageDescription'].value
1440
def test_issue_svs_doubleheader():
1441
"""Test svs_description_metadata for SVS with double header."""
1442
# https://github.com/cgohlke/tifffile/pull/88
1444
assert svs_description_metadata(
1445
'Aperio Image Library v11.2.1\r\n'
1446
'2220x2967 -> 574x768 - ;Aperio Image Library v10.0.51\r\n'
1447
'46920x33014 [0,100 46000x32914] (256x256) JPEG/RGB Q=30'
1448
'|AppMag = 20|StripeWidth = 2040|ScanScope ID = CPAPERIOCS'
1449
'|Filename = CMU-1|Date = 12/29/09|Time = 09:59:15'
1450
'|User = b414003d-95c6-48b0-9369-8010ed517ba7|Parmset = USM Filter'
1451
'|MPP = 0.4990|Left = 25.691574|Top = 23.449873'
1452
'|LineCameraSkew = -0.000424|LineAreaXOffset = 0.019265'
1453
'|LineAreaYOffset = -0.000313|Focus Offset = 0.000000'
1454
'|ImageID = 1004486|OriginalWidth = 46920|Originalheight = 33014'
1455
'|Filtered = 5|OriginalWidth = 46000|OriginalHeight = 32914'
1458
'Aperio Image Library v11.2.1\r\n'
1459
'2220x2967 -> 574x768 - ;Aperio Image Library v10.0.51\r\n'
1460
'46920x33014 [0,100 46000x32914] (256x256) JPEG/RGB Q=30'
1463
'StripeWidth': 2040,
1464
'ScanScope ID': 'CPAPERIOCS',
1465
'Filename': 'CMU-1',
1468
'User': 'b414003d-95c6-48b0-9369-8010ed517ba7',
1469
'Parmset': 'USM Filter',
1473
'LineCameraSkew': -0.000424,
1474
'LineAreaXOffset': 0.019265,
1475
'LineAreaYOffset': -0.000313,
1476
'Focus Offset': 0.0,
1478
'OriginalWidth': 46000,
1479
'Originalheight': 33014,
1481
'OriginalHeight': 32914,
1485
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
1486
def test_issue_packbits_dtype():
1487
"""Test read and efficiently write PackBits compressed int16 image."""
1488
# https://github.com/blink1073/tifffile/issues/61
1489
# requires imagecodecs > 2021.6.8
1491
fname = private_file('packbits/imstack_packbits-int16.tif')
1493
with TiffFile(fname) as tif:
1494
assert len(tif.pages) == 519
1495
page = tif.pages[181]
1496
assert page.compression == COMPRESSION.PACKBITS
1497
assert page.photometric == PHOTOMETRIC.MINISBLACK
1498
assert page.shape == (348, 185)
1499
assert page.dtype == numpy.int16
1500
data = page.asarray()
1501
assert data.shape == (348, 185)
1502
assert data.dtype == numpy.int16
1503
assert data[184, 72] == 24
1504
assert_aszarr_method(page, data)
1505
data = tif.asarray()
1506
assert_aszarr_method(tif, data)
1509
imwrite(buf, data, compression='packbits')
1510
assert buf.seek(0, 2) < 1700000 # efficiently compressed
1513
with TiffFile(buf) as tif:
1514
assert len(tif.pages) == 519
1515
page = tif.pages[181]
1516
assert page.compression == COMPRESSION.PACKBITS
1517
assert page.photometric == PHOTOMETRIC.MINISBLACK
1518
assert page.shape == (348, 185)
1519
assert page.dtype == numpy.int16
1520
data = page.asarray()
1521
assert data.shape == (348, 185)
1522
assert data.dtype == numpy.int16
1523
assert data[184, 72] == 24
1524
assert_aszarr_method(page, data)
1525
data = tif.asarray()
1526
assert_aszarr_method(tif, data)
1529
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
1530
def test_issue_predictor_byteorder():
1531
"""Test read big-endian uint32 RGB with horizontal predictor."""
1533
fname = private_file('issues/flower-rgb-contig-32_msb_zip_predictor.tiff')
1535
with TiffFile(fname) as tif:
1536
assert tif.tiff.byteorder == '>'
1537
assert len(tif.pages) == 1
1538
page = tif.pages.first
1539
assert page.compression == COMPRESSION.ADOBE_DEFLATE
1540
assert page.photometric == PHOTOMETRIC.RGB
1541
assert page.predictor == PREDICTOR.HORIZONTAL
1542
assert page.shape == (43, 73, 3)
1543
assert page.dtype == numpy.uint32
1544
data = page.asarray()
1545
assert data.shape == (43, 73, 3)
1546
assert data.dtype == numpy.uint32
1547
assert tuple(data[30, 2]) == (0, 246337650, 191165795)
1548
assert data.dtype.byteorder == '='
1549
assert_aszarr_method(page, data)
1550
data = tif.asarray()
1551
assert_aszarr_method(tif, data)
1554
@pytest.mark.skipif(SKIP_ZARR or SKIP_DASK, reason=REASON)
1555
@pytest.mark.parametrize('truncate', [False, True])
1556
@pytest.mark.parametrize('chunkmode', [0, 2])
1557
def test_issue_dask_multipage(truncate, chunkmode):
1558
"""Test multi-threaded access of memory-mapable, multi-page Zarr stores."""
1559
# https://github.com/cgohlke/tifffile/issues/67#issuecomment-908529425
1560
data = numpy.arange(5 * 99 * 101, dtype=numpy.uint16).reshape((5, 99, 101))
1562
f'issue_dask_multipage_{int(truncate)}_{chunkmode}'
1564
kwargs = {'truncate': truncate}
1566
kwargs['tile'] = (32, 32)
1567
imwrite(fname, data, **kwargs)
1568
with imread(fname, aszarr=True, chunkmode=chunkmode) as store:
1569
daskarray = dask.array.from_zarr(store).compute()
1570
assert_array_equal(data, daskarray)
1573
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_ZARR, reason=REASON)
1574
@pytest.mark.parametrize('chunkmode', [0, 2])
1575
def test_issue_zarr_store_closed(chunkmode):
1576
"""Test Zarr store filehandle is open when reading from unloaded pages."""
1577
# https://github.com/cgohlke/tifffile/issues/67#issuecomment-2246367891
1578
fname = private_file('ImageJ/_malaria_parasites.tif')
1579
data = imread(fname)
1580
store = imread(fname, aszarr=True, chunkmode=chunkmode)
1582
z = zarr.open(store, mode='r')
1583
chunk = z[10:11, 3:-3] # seek of closed file
1586
assert_array_equal(chunk, data[10:11, 3:-3])
1588
store = imread(fname, aszarr=True, chunkmode=chunkmode)
1590
z = zarr.open(store, mode='r')
1594
assert_array_equal(chunk, data)
1597
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_ZARR, reason=REASON)
1598
@pytest.mark.parametrize('chunkmode', [0, 2])
1599
def test_issue_zarr_store_multifile_closed(chunkmode):
1600
"""Test Zarr store can read from closed files."""
1601
fname = private_file('OME/tubhiswt-4D-lzw/tubhiswt_C0_T0.ome.tif')
1602
data = imread(fname)
1603
assert data.shape == (43, 10, 2, 512, 512)
1604
store = imread(fname, aszarr=True, chunkmode=chunkmode)
1606
z = zarr.open(store, mode='r')
1607
chunk = z[32:35, 3:7, :, 31:-31, 33:-33] # seek of closed file
1610
assert_array_equal(chunk, data[32:35, 3:7, :, 31:-31, 33:-33])
1614
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.LZW.available, reason=REASON
1616
def test_issue_read_from_closed_file():
1617
"""Test read from closed file handles."""
1618
fname = private_file('OME/tubhiswt-4D-lzw/tubhiswt_C0_T0.ome.tif')
1619
with tifffile.TiffFile(fname) as tif:
1621
for frame in tif.series[0].pages[:10]:
1622
# most file handles are closed
1625
isclosed = frame.parent.filehandle.closed
1630
if isinstance(frame, TiffFrame):
1631
with pytest.warns(UserWarning):
1632
page = frame.aspage() # re-load frame as page
1633
assert isclosed == page.parent.filehandle.closed
1637
with pytest.warns(UserWarning):
1638
page.colormap # delay load tag value
1639
assert isclosed == page.parent.filehandle.closed
1641
with pytest.warns(UserWarning):
1642
frame.asarray() # read data
1643
assert isclosed == page.parent.filehandle.closed
1648
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.PNG.available, reason=REASON
1650
def test_issue_filesequence_categories(caplog):
1651
"""Test FileSequence with categories."""
1652
# https://github.com/cgohlke/tifffile/issues/76
1654
with tifffile.FileSequence(
1656
private_file('dataset-A1-20200531/*.png'),
1658
r'(?P<sampleid>.{2})-'
1659
r'(?P<experiment>.+)-\d{8}T\d{6}-PSII0-'
1662
categories={'sampleid': {'A1': 0, 'B1': 1}, 'experiment': {'doi': 0}},
1664
with pytest.warns(DeprecationWarning):
1665
assert len(pngs.files) == 2
1666
assert len(pngs) == 2
1667
assert pngs.files_missing == 2
1668
assert pngs.shape == (2, 1, 2)
1669
assert pngs.dims == ('sampleid', 'experiment', 'frameid')
1670
data = pngs.asarray()
1671
assert data.shape == (2, 1, 2, 200, 200)
1672
assert data[1, 0, 1, 100, 100] == 353
1675
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
1676
def test_issue_filesequence_file_parameter():
1677
"""Test FileSequence.asarray with 'file' parameter removed in 2022.4.22."""
1678
# https://github.com/bluesky/tiled/pull/97
1680
files = public_file('tifffile/temp_C001T00*.tif')
1681
with TiffSequence(files) as tiffs:
1682
assert tiffs.shape == (2,)
1683
with pytest.raises(TypeError):
1684
assert_array_equal(tiffs.asarray(file=files[0]), imread(files[0]))
1685
with pytest.raises(TypeError):
1686
assert_array_equal(tiffs.asarray(file=1), imread(files[1]))
1689
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
1690
def test_issue_imagej_prop():
1691
"""Test read and write ImageJ prop metadata type."""
1692
# https://github.com/cgohlke/tifffile/issues/103
1693
# also test write indexed ImageJ file
1695
fname = private_file('issues/triple-sphere-big-distance=035.tif')
1696
with tifffile.TiffFile(fname) as tif:
1697
assert tif.is_imagej
1698
ijmeta = tif.imagej_metadata
1699
assert ijmeta is not None
1700
prop = ijmeta['Properties']
1701
assert ijmeta['slices'] == 500
1702
assert not ijmeta['loop']
1703
assert prop['CurrentLUT'] == 'glasbey_on_dark'
1704
assert tif.pages.first.photometric == PHOTOMETRIC.PALETTE
1705
colormap = tif.pages.first.colormap
1706
data = tif.asarray()
1709
with TempFileName('issue_imagej_prop') as fname:
1710
ijmeta['axes'] = 'ZYX'
1711
imwrite(fname, data, imagej=True, colormap=colormap, metadata=ijmeta)
1713
with tifffile.TiffFile(fname) as tif:
1714
assert tif.is_imagej
1715
ijmeta = tif.imagej_metadata
1716
assert ijmeta is not None
1717
prop = ijmeta['Properties']
1718
assert ijmeta['slices'] == 500
1719
assert not ijmeta['loop']
1720
assert prop['CurrentLUT'] == 'glasbey_on_dark'
1721
assert prop['Test'] == '0.1'
1722
assert tif.pages.first.photometric == PHOTOMETRIC.PALETTE
1723
colormap = tif.pages.first.colormap
1724
image = tif.asarray()
1725
assert_array_equal(image, data)
1728
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
1729
def test_issue_missing_dataoffset(caplog):
1730
"""Test read file with missing data offset."""
1731
fname = private_file('gdal/bigtiff_header_extract.tif')
1732
with tifffile.TiffFile(fname) as tif:
1733
page = tif.pages.first
1734
assert page.imagewidth == 100000
1735
assert page.imagelength == 100000
1736
assert page.rowsperstrip == 1
1737
assert page.databytecounts == (10000000000,)
1738
assert page.dataoffsets == ()
1739
assert 'incorrect StripOffsets count' in caplog.text
1740
assert 'incorrect StripByteCounts count' in caplog.text
1741
assert 'missing data offset tag' in caplog.text
1742
with pytest.raises(TiffFileError):
1746
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
1747
def test_issue_imagej_metadatabytecounts():
1748
"""Test read ImageJ file with many IJMetadataByteCounts."""
1749
# https://github.com/cgohlke/tifffile/issues/111
1750
fname = private_file('imagej/issue111.tif')
1751
with tifffile.TiffFile(fname) as tif:
1752
assert tif.is_imagej
1753
page = tif.pages.first
1754
assert isinstance(page.tags['IJMetadataByteCounts'].value, tuple)
1755
assert isinstance(page.tags['IJMetadata'].value, dict)
1758
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
1759
def test_issue_description_bytes():
1760
"""Test read file with imagedescription bytes."""
1761
# https://github.com/cgohlke/tifffile/issues/112
1762
with TempFileName('issue_description_bytes') as fname:
1766
description='1st description',
1768
('ImageDescription', 1, None, b'\1\128\0', True),
1769
('ImageDescription', 1, None, b'\2\128\0', True),
1773
with TiffFile(fname) as tif:
1774
page = tif.pages.first
1775
assert page.description == '1st description'
1776
assert page.description1 == ''
1777
assert page.tags.get(270).value == '1st description'
1778
assert page.tags.get(270, index=1).value == b'\1\128\0'
1779
assert page.tags.get(270, index=2).value == b'\2\128\0'
1782
def test_issue_imagej_colormap():
1783
"""Test write 32-bit imagej file with colormap."""
1784
# https://github.com/cgohlke/tifffile/issues/115
1785
colormap = numpy.vstack(
1787
numpy.zeros(256, dtype=numpy.uint16),
1788
numpy.arange(0, 2**16, 2**8, dtype=numpy.uint16),
1789
numpy.arange(0, 2**16, 2**8, dtype=numpy.uint16),
1792
metadata = {'min': 0.0, 'max': 1.0, 'Properties': {'CurrentLUT': 'cyan'}}
1793
with TempFileName('issue_imagej_colormap') as fname:
1796
numpy.zeros((16, 16), numpy.float32),
1801
with TiffFile(fname) as tif:
1802
assert tif.is_imagej
1803
assert tif.imagej_metadata is not None
1804
assert tif.imagej_metadata['Properties']['CurrentLUT'] == 'cyan'
1805
assert tif.pages.first.photometric == PHOTOMETRIC.MINISBLACK
1806
assert_array_equal(tif.pages.first.colormap, colormap)
1810
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.WEBP.available,
1813
@pytest.mark.parametrize('name', ['tile', 'strip'])
1814
def test_issue_webp_rgba(name, caplog):
1815
"""Test read WebP segments with missing alpha channel."""
1816
# https://github.com/cgohlke/tifffile/issues/122
1817
fname = private_file(f'issues/CMU-1-Small-Region.{name}.webp.tiff')
1818
with tifffile.TiffFile(fname) as tif:
1819
page = tif.pages.first
1820
assert page.compression == COMPRESSION.WEBP
1821
assert page.shape == (2967, 2220, 4)
1822
assert tuple(page.asarray()[25, 25]) == (246, 244, 245, 255)
1823
assert f'corrupted {name}' not in caplog.text
1827
SKIP_PRIVATE or SKIP_ZARR or SKIP_CODECS or not imagecodecs.WEBP.available,
1830
def test_issue_webp_fsspec():
1831
"""Test read WebP segments with missing alpha channel via fsspec."""
1833
from imagecodecs.numcodecs import register_codecs
1835
register_codecs = None
1837
register_codecs('imagecodecs_webp', verbose=False)
1839
fname = private_file('issues/CMU-1-Small-Region.tile.webp.tiff')
1840
url = os.path.dirname(fname).replace('\\', '/')
1841
data = imread(fname, series=0)
1842
with TempFileName('issue_webp_fsspec', ext='.json') as jsonfile:
1851
mapper = fsspec.get_mapper(
1854
target_protocol='file',
1855
remote_protocol='file',
1857
zobj = zarr.open(mapper, mode='r')
1858
assert_array_equal(zobj[:], data)
1861
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_ZARR, reason=REASON)
1862
def test_issue_tiffslide():
1863
"""Test no ValueError when closing TiffSlide with Zarr group."""
1864
# https://github.com/bayer-science-for-a-better-life/tiffslide/issues/25
1866
from tiffslide import TiffSlide
1868
pytest.skip('tiffslide missing')
1870
fname = private_file('AperioSVS/CMU-1.svs')
1871
with TiffSlide(fname) as slide:
1872
_ = slide.ts_zarr_grp
1873
arr = slide.read_region((100, 200), 0, (256, 256), as_array=True)
1874
assert arr.shape == (256, 256, 3)
1877
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
1878
def test_issue_xarray():
1879
"""Test read Zarr store with fsspec and xarray."""
1883
pytest.skip('xarray missing')
1885
data = numpy.random.randint(0, 2**8, (5, 31, 33, 3), numpy.uint8)
1887
with TempFileName('issue_xarry.ome') as fname:
1888
with tifffile.TiffWriter(fname) as tif:
1893
metadata={'axes': 'TYXC'},
1896
for squeeze in (True, False):
1898
f'issue_xarry_{squeeze}', ext='.json'
1900
with tifffile.TiffFile(fname) as tif:
1901
store = tif.series[0].aszarr(squeeze=squeeze)
1904
url=os.path.split(jsonfile)[0],
1909
mapper = fsspec.get_mapper(
1912
target_protocol='file',
1913
remote_protocol='file',
1915
dataset = xarray.open_dataset(
1918
mask_and_scale=False,
1919
backend_kwargs={'consolidated': False},
1923
assert dataset['x'].shape == (5, 31, 33, 3)
1924
assert dataset['x'].dims == ('T', 'Y', 'X', 'S')
1926
assert dataset['x'].shape == (5, 1, 1, 31, 33, 3)
1927
assert dataset['x'].dims == ('T', 'Z', 'C', 'Y', 'X', 'S')
1929
assert_array_equal(data, numpy.squeeze(dataset['x'][:]))
1934
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
1935
def test_issue_xarray_multiscale():
1936
"""Test read multiscale Zarr store with fsspec and xarray."""
1940
pytest.skip('xarray missing')
1942
data = numpy.random.randint(0, 2**8, (8, 3, 128, 128), numpy.uint8)
1944
with TempFileName('issue_xarry_multiscale.ome') as fname:
1945
with tifffile.TiffWriter(fname) as tif:
1949
planarconfig='separate',
1952
metadata={'axes': 'TCYX'},
1955
data[:, :, ::2, ::2],
1957
planarconfig='separate',
1961
data[:, :, ::4, ::4],
1963
planarconfig='separate',
1967
for squeeze in (True, False):
1969
f'issue_xarry_multiscale_{squeeze}', ext='.json'
1971
with tifffile.TiffFile(fname) as tif:
1972
store = tif.series[0].aszarr(squeeze=squeeze)
1975
url=os.path.split(jsonfile)[0],
1980
mapper = fsspec.get_mapper(
1983
target_protocol='file',
1984
remote_protocol='file',
1986
dataset = xarray.open_dataset(
1989
mask_and_scale=False,
1990
backend_kwargs={'consolidated': False},
1993
assert dataset['0'].shape == (8, 3, 128, 128)
1994
assert dataset['0'].dims == ('T', 'S', 'Y', 'X')
1995
assert dataset['2'].shape == (8, 3, 32, 32)
1996
assert dataset['2'].dims == ('T', 'S', 'Y2', 'X2')
1998
assert dataset['0'].shape == (8, 1, 1, 3, 128, 128)
1999
assert dataset['0'].dims == ('T', 'Z', 'C', 'S', 'Y', 'X')
2000
assert dataset['2'].shape == (8, 1, 1, 3, 32, 32)
2001
assert dataset['2'].dims == (
2010
assert_array_equal(data, numpy.squeeze(dataset['0'][:]))
2012
data[:, :, ::4, ::4], numpy.squeeze(dataset['2'][:])
2018
@pytest.mark.parametrize('resolution', [(1, 0), (0, 0)])
2019
def test_issue_invalid_resolution(resolution):
2020
# https://github.com/imageio/imageio/blob/master/tests/test_tifffile.py
2022
data = numpy.zeros((20, 10), dtype=numpy.uint8)
2024
with TempFileName(f'issue_invalid_resolution{resolution[0]}') as fname:
2025
imwrite(fname, data)
2027
with TiffFile(fname, mode='r+') as tif:
2028
tags = tif.pages.first.tags
2029
tags['XResolution'].overwrite(resolution)
2030
tags['YResolution'].overwrite(resolution)
2032
with tifffile.TiffFile(fname) as tif:
2033
tags = tif.pages.first.tags
2034
assert tags['XResolution'].value == resolution
2035
assert tags['YResolution'].value == resolution
2039
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
2040
def test_issue_indexing():
2041
"""Test indexing methods."""
2042
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
2043
data0 = imread(fname)
2044
assert isinstance(data0, numpy.ndarray)
2045
assert data0.shape == (16, 32, 2, 256, 256)
2046
level1 = imread(fname, level=1)
2047
assert isinstance(level1, numpy.ndarray)
2048
assert level1.shape == (16, 32, 2, 128, 128)
2049
data1 = imread(fname, series=1)
2050
assert isinstance(data1, numpy.ndarray)
2051
assert data1.shape == (128, 128, 3)
2053
assert_array_equal(data1, imread(fname, key=1024))
2054
assert_array_equal(data1, imread(fname, key=[1024]))
2055
assert_array_equal(data1, imread(fname, key=range(1024, 1025)))
2056
assert_array_equal(data1, imread(fname, series=1, key=0))
2057
assert_array_equal(data1, imread(fname, series=1, key=[0]))
2059
data1, imread(fname, series=1, level=0, key=slice(None))
2062
assert_array_equal(data0, imread(fname, series=0))
2064
data0.reshape(-1, 256, 256), imread(fname, series=0, key=slice(None))
2067
data0.reshape(-1, 256, 256), imread(fname, key=slice(0, -1, 1))
2070
data0.reshape(-1, 256, 256), imread(fname, key=range(1024))
2072
assert_array_equal(data0[0, 0], imread(fname, key=[0, 1]))
2073
assert_array_equal(data0[0, 0], imread(fname, series=0, key=(0, 1)))
2076
level1.reshape(-1, 128, 128),
2077
imread(fname, series=0, level=1, key=slice(None)),
2080
level1.reshape(-1, 128, 128),
2081
imread(fname, series=0, level=1, key=range(1024)),
2085
def test_issue_shaped_metadata():
2086
"""Test shaped_metadata property."""
2087
# https://github.com/cgohlke/tifffile/issues/127
2088
shapes = ([5, 33, 31], [31, 33, 3])
2089
with TempFileName('issue_shaped_metadata') as fname:
2090
with TiffWriter(fname) as tif:
2091
for shape in shapes:
2095
metadata={'comment': 'a comment', 'number': 42},
2097
with TiffFile(fname) as tif:
2098
assert tif.is_shaped
2099
assert len(tif.series) == 2
2100
assert tif.series[0].kind == 'shaped'
2101
assert tif.series[1].kind == 'shaped'
2102
meta = tif.shaped_metadata
2103
assert meta is not None
2104
assert len(meta) == 2
2105
assert meta[0]['shape'] == shapes[0]
2106
assert meta[0]['comment'] == 'a comment'
2107
assert meta[0]['number'] == 42
2108
assert meta[1]['shape'] == shapes[1]
2109
assert meta[1]['comment'] == 'a comment'
2110
assert meta[1]['number'] == 42
2113
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2114
def test_issue_uic_dates(caplog):
2115
"""Test read MetaMorph STK metadata with invalid julian dates."""
2116
# https://github.com/cgohlke/tifffile/issues/129
2117
fname = private_file('issues/Cells-003_Cycle00001_Ch1_000001.ome.tif')
2118
with TiffFile(fname) as tif:
2121
assert tif.byteorder == '<'
2122
assert len(tif.pages) == 1
2123
# assert page properties
2124
page = tif.pages.first
2125
assert page.is_memmappable
2126
assert page.shape == (256, 256)
2127
assert page.tags['Software'].value == 'Prairie View 5.4.64.40'
2128
assert page.tags['DateTime'].value == '2019:03:18 10:13:33'
2130
with pytest.warns(RuntimeWarning):
2131
meta = tif.stk_metadata
2132
assert 'no datetime before year 1' in caplog.text
2133
assert meta is not None
2134
assert meta['CreateTime'] is None
2135
assert meta['LastSavedTime'] is None
2136
assert meta['DatetimeCreated'] is None
2137
assert meta['DatetimeModified'] is None
2138
assert meta['Name'] == 'Gattaca'
2139
assert meta['NumberPlanes'] == 1
2140
# assert meta['TimeCreated'] ...
2141
# assert meta['TimeModified'] ...
2142
assert meta['Wavelengths'][0] == 1.7906976744186047
2145
def test_issue_subfiletype_zero():
2146
"""Test write NewSubfileType=0."""
2147
# https://github.com/cgohlke/tifffile/issues/132
2148
with TempFileName('issue_subfiletype_zero') as fname:
2149
imwrite(fname, [[0]], subfiletype=0)
2150
with TiffFile(fname) as tif:
2152
tif.pages.first.tags['NewSubfileType'].value
2153
== FILETYPE.UNDEFINED
2157
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2158
def test_issue_imagej_zct_order(caplog):
2159
"""Test read ImageJ hyperstack with non-TZC order."""
2160
# https://forum.image.sc/t/69430
2161
fname = private_file(
2162
'MMStack/mosaic/d220708_HybISS_AS_cycles1to5_NoBridgeProbes_'
2163
'dim3x3__3_MMStack_2-Pos_000_000.ome.tif'
2165
data = imread(fname, series=5, is_mmstack=False)
2167
fname = private_file(
2168
'MMStack/mosaic/d220708_HybISS_AS_cycles1to5_NoBridgeProbes_'
2169
'dim3x3__3_MMStack_2-Pos_000_001.ome.tif'
2171
with TiffFile(fname, is_mmstack=False) as tif:
2172
assert not tif.is_mmstack
2174
assert tif.is_imagej
2175
assert tif.imagej_metadata is not None
2176
assert tif.imagej_metadata['order'] == 'zct'
2177
with caplog.at_level(logging.DEBUG):
2178
series = tif.series[0]
2179
assert 'OME series is BinaryOnly' in caplog.text
2180
assert series.axes == 'CZYX'
2181
assert series.kind == 'imagej'
2182
assert_array_equal(series.asarray(), data)
2185
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2186
def test_issue_fei_sfeg_metadata():
2187
"""Test read FEI_SFEG metadata."""
2188
# https://github.com/cgohlke/tifffile/pull/141
2189
# FEI_SFEG tag value is a base64 encoded XML string with BOM header
2190
fname = private_file('issues/Helios-AutoSliceAndView.tif')
2191
with TiffFile(fname) as tif:
2192
fei = tif.fei_metadata
2193
assert fei is not None
2194
assert fei['User']['User'] == 'Supervisor'
2195
assert fei['System']['DisplayHeight'] == 0.324
2198
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2199
def test_issue_resolution():
2200
"""Test consistency of reading and writing resolution."""
2201
resolution = (4294967295 / 3904515723, 4294967295 / 1952257861) # 1.1, 2.2
2202
resolutionunit = RESUNIT.CENTIMETER
2204
with TempFileName('issue_resolution') as fname:
2206
fname, [[0]], resolution=resolution, resolutionunit=resolutionunit
2208
with TiffFile(fname) as tif:
2209
page = tif.pages.first
2210
assert tif.pages.first.tags['XResolution'].value == (
2214
assert tif.pages.first.tags['YResolution'].value == (
2218
assert tif.pages.first.tags['ResolutionUnit'].value == (
2222
assert page.resolution == resolution
2223
assert page.resolutionunit == resolutionunit
2225
assert page.get_resolution() == resolution
2226
assert page.get_resolution(resolutionunit) == resolution
2227
assert_array_almost_equal(
2228
page.get_resolution(RESUNIT.MICROMETER),
2229
(resolution[0] / 10000, resolution[1] / 10000),
2231
assert_array_almost_equal(
2232
page.get_resolution(RESUNIT.MICROMETER, 100),
2233
(resolution[0] / 10000, resolution[1] / 10000),
2235
assert_array_almost_equal(
2236
page.get_resolution('inch'),
2237
(resolution[0] * 2.54, resolution[1] * 2.54),
2239
assert_array_almost_equal(
2240
page.get_resolution(scale=111.111),
2241
(resolution[0] * scale, resolution[1] * scale),
2245
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2246
def test_issue_resolutionunit():
2247
"""Test write resolutionunit defaults."""
2248
# https://github.com/cgohlke/tifffile/issues/145
2250
with TempFileName('issue_resolutionunit_none') as fname:
2251
imwrite(fname, [[0]], resolution=None, resolutionunit=None)
2252
with TiffFile(fname) as tif:
2253
page = tif.pages.first
2254
assert tif.pages.first.tags['ResolutionUnit'].value == RESUNIT.NONE
2255
assert page.resolutionunit == RESUNIT.NONE
2256
assert page.resolution == (1, 1)
2258
with TempFileName('issue_resolutionunit_inch') as fname:
2259
imwrite(fname, [[0]], resolution=(1, 1), resolutionunit=None)
2260
with TiffFile(fname) as tif:
2261
page = tif.pages.first
2262
assert tif.pages.first.tags['ResolutionUnit'].value == RESUNIT.INCH
2263
assert page.resolutionunit == RESUNIT.INCH
2264
assert page.resolution == (1, 1)
2266
with TempFileName('issue_resolutionunit_imagej') as fname:
2268
fname, [[0]], dtype=numpy.float32, imagej=True, resolution=(1, 1)
2270
with TiffFile(fname) as tif:
2271
page = tif.pages.first
2272
assert tif.pages.first.tags['ResolutionUnit'].value == RESUNIT.NONE
2273
assert page.resolutionunit == RESUNIT.NONE
2274
assert page.resolution == (1, 1)
2277
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
2278
def test_issue_ome_jpeg_colorspace():
2279
"""Test colorspace of JPEG segments encoded by BioFormats."""
2280
# https://forum.image.sc/t/69862
2281
# JPEG encoded segments are stored as YCBCR but the
2282
# PhotometricInterpretation tag is RGB
2283
# CMU-1.svs exported by QuPath 0.3.2
2284
fname = private_file('ome/CMU-1.ome.tif')
2285
with TiffFile(fname) as tif:
2287
series = tif.series[0].levels[5]
2288
assert series.kind == 'ome'
2289
assert series.keyframe.is_jfif
2290
assert series.shape == (1028, 1437, 3)
2291
assert tuple(series.asarray()[800, 200]) == (207, 166, 198)
2294
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2295
def test_issue_imagej_compressed():
2296
"""Test read ImageJ hyperstack with compression."""
2297
# regression in tifffile 2022.7.28
2298
fname = private_file('imagej/imagej_compressed.tif')
2299
with TiffFile(fname) as tif:
2300
assert tif.is_imagej
2301
assert len(tif.pages) == 120
2302
series = tif.series[0]
2303
assert series.kind == 'imagej'
2304
assert series.axes == 'ZCYX'
2305
assert series.shape == (60, 2, 256, 256)
2306
assert series.sizes == {
2312
assert series.keyframe.compression == COMPRESSION.ADOBE_DEFLATE
2313
assert series.asarray()[59, 1, 55, 87] == 5643
2316
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
2317
def test_issue_jpeg_rgb():
2318
"""Test write JPEG compression in RGB mode."""
2319
# https://github.com/cgohlke/tifffile/issues/146
2320
# requires imagecodecs > 2022.7.31
2321
data = imread(public_file('tifffile/rgb.tif'))
2322
assert data.shape == (32, 31, 3)
2323
with TempFileName('issue_jpeg_rgb') as fname:
2330
compressionargs={'level': 95, 'outcolorspace': 'rgb'},
2332
with TiffFile(fname) as tif:
2333
page = tif.pages.first
2334
assert page.shape == data.shape
2335
assert page.photometric == PHOTOMETRIC.RGB
2336
assert page.compression == COMPRESSION.JPEG
2337
assert not page.is_jfif
2338
image = page.asarray()
2339
assert_array_equal(image, imagecodecs.imread(fname))
2342
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
2343
def test_issue_imread_out():
2344
"""Test imread supports out argument."""
2345
# https://github.com/cgohlke/tifffile/issues/147
2346
fname = public_file('tifffile/rgb.tif')
2347
image = imread(fname, out=None)
2348
assert isinstance(image, numpy.ndarray)
2349
data = imread(fname, out='memmap')
2350
assert isinstance(data, numpy.memmap)
2351
assert_array_equal(data, image)
2353
image = imread([fname, fname], out=None)
2354
assert isinstance(image, numpy.ndarray)
2355
assert_array_equal(image[1], data)
2359
chunkshape=(32, 31, 3),
2360
chunkdtype=numpy.uint8,
2364
assert isinstance(data, numpy.memmap)
2365
assert_array_equal(data, image)
2368
def test_issue_imagej_hyperstack_arg():
2369
"""Test write ImageJ with hyperstack argument."""
2370
# https://stackoverflow.com/questions/73279086
2371
with TempFileName('issue_imagej_hyperstack_arg') as fname:
2372
data = numpy.zeros((4, 3, 10, 11), dtype=numpy.uint8)
2377
metadata={'hyperstack': True, 'axes': 'TZYX'},
2379
with TiffFile(fname) as tif:
2380
assert tif.is_imagej
2381
assert 'hyperstack=true' in tif.pages.first.description
2382
assert tif.imagej_metadata is not None
2383
assert tif.imagej_metadata['hyperstack']
2384
assert tif.series[0].axes == 'TZYX'
2387
def test_issue_description_overwrite():
2388
"""Test user description is not overwritten if metadata is disabled."""
2389
data = numpy.zeros((5, 10, 11), dtype=numpy.uint8)
2394
storedshape=(5, 1, 1, 10, 11, 1),
2397
description = omexml.tostring()
2399
with TempFileName('issue_description_overwrite') as fname:
2400
with tifffile.TiffWriter(fname, ome=False) as tif:
2404
description=description,
2409
with TiffFile(fname) as tif:
2411
assert tif.pages.first.description == omexml.tostring()
2412
assert tif.series[0].kind == 'ome'
2413
assert tif.series[0].axes == 'ZYX'
2414
assert_array_equal(tif.asarray(), data)
2417
def test_issue_svs_description():
2418
"""Test svs_description_metadata function."""
2419
# https://github.com/cgohlke/tifffile/issues/149
2420
assert svs_description_metadata(
2421
'Aperio Image Library vFS90 01\r\n'
2422
'159712x44759 [0,100 153271x44659] (256x256) JPEG/RGB Q=30'
2424
'|StripeWidth = 992'
2425
'|ScanScope ID = SS1475'
2426
'|Filename = 12-0893-1'
2427
'|Title = Mag = 40X, compression quality =30'
2430
'|Time Zone = GMT-05:00'
2431
'|User = 8ce982e3-6ea2-4715-8af3-9874e823e6d9'
2435
'|LineCameraSkew = 0.001417'
2436
'|LineAreaXOffset = 0.014212'
2437
'|LineAreaYOffset = -0.004733'
2438
'|Focus Offset = 0.000000'
2439
'|DSR ID = 152.19.62.167'
2441
'|Exposure Time = 109'
2442
'|Exposure Scale = 0.000001'
2444
'|OriginalWidth = 159712'
2445
'|OriginalHeight = 44759'
2446
'|ICC Profile = ScanScope v1'
2449
'Aperio Image Library vFS90 01\r\n'
2450
'159712x44759 [0,100 153271x44659] (256x256) JPEG/RGB Q=30'
2454
'ScanScope ID': 'SS1475',
2455
'Filename': '12-0893-1',
2456
'Title': 'Mag = 40X, compression quality =30',
2459
'Time Zone': 'GMT-05:00',
2460
'User': '8ce982e3-6ea2-4715-8af3-9874e823e6d9',
2464
'LineCameraSkew': 0.001417,
2465
'LineAreaXOffset': 0.014212,
2466
'LineAreaYOffset': -0.004733,
2467
'Focus Offset': 0.0,
2468
'DSR ID': '152.19.62.167',
2470
'Exposure Time': 109,
2471
'Exposure Scale': 0.000001,
2473
'OriginalWidth': 159712,
2474
'OriginalHeight': 44759,
2475
'ICC Profile': 'ScanScope v1',
2478
assert svs_description_metadata(
2479
'Aperio Image Library v11.0.37\r\n60169x38406 (256x256) JPEG/RGB Q=70'
2480
'|Patient=CS-10-SI_HE'
2485
'|Copyright=Hamamatsu Photonics KK'
2487
'|Webslide Files=5329'
2490
'Aperio Image Library v11.0.37\r\n'
2491
'60169x38406 (256x256) JPEG/RGB Q=70'
2493
'Patient': 'CS-10-SI_HE',
2496
'Date': '10/12/2012',
2497
'Time': '04:55:13 PM',
2498
'Copyright': 'Hamamatsu Photonics KK',
2500
'Webslide Files': 5329,
2504
def test_issue_iterator_recursion():
2505
"""Test no RecursionError writing large number of tiled pages."""
2506
with TempFileName('issue_iterator_recursion') as fname:
2507
imwrite(fname, shape=(1024, 54, 64), dtype=numpy.uint8, tile=(32, 32))
2510
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
2511
def test_issue_predictor_floatx2():
2512
"""Test floatx2 predictor."""
2513
# https://github.com/cgohlke/tifffile/issues/167
2514
data = random_data(numpy.float32, (219, 302))
2515
with TempFileName('issue_predictor_floatx2') as fname:
2516
imwrite(fname, data, predictor=34894, compression=True)
2517
with TiffFile(fname) as tif:
2518
assert len(tif.pages) == 1
2519
assert len(tif.series) == 1
2520
page = tif.pages.first
2521
assert page.photometric == PHOTOMETRIC.MINISBLACK
2522
assert page.imagewidth == 302
2523
assert page.imagelength == 219
2524
assert page.samplesperpixel == 1
2525
assert page.predictor == 34894
2526
assert page.compression == 8
2527
image = page.asarray()
2528
assert_array_equal(data, image)
2532
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
2533
def test_issue_predictor_deltax2():
2534
"""Test deltax2 predictor."""
2535
# https://github.com/cgohlke/tifffile/issues/167
2536
data = random_data(numpy.uint8, (219, 302))
2537
with TempFileName('issue_predictor_deltax2') as fname:
2538
with pytest.raises(NotImplementedError):
2539
imwrite(fname, data, predictor=34892, compression=8)
2540
# with TiffFile(fname) as tif:
2541
# assert len(tif.pages) == 1
2542
# assert len(tif.series) == 1
2543
# page = tif.pages.first
2544
# assert page.photometric == MINISBLACK
2545
# assert page.imagewidth == 302
2546
# assert page.imagelength == 219
2547
# assert page.samplesperpixel == 1
2548
# assert page.predictor == 34892
2549
# assert page.compression == 8
2550
# image = page.asarray()
2551
# assert_array_equal(data, image)
2552
# assert__str__(tif)
2555
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
2556
@pytest.mark.parametrize('compression', ['none', 'packbits', 'zlib', 'lzw'])
2557
@pytest.mark.parametrize('predictor', ['none', 'horizontal'])
2558
@pytest.mark.parametrize('samples', [0, 1, 3])
2559
def test_issue_tile_generator(compression, predictor, samples):
2560
"""Test predictor and compression axes with tile generator."""
2561
# https://github.com/cgohlke/tifffile/issues/185
2563
if compression == 'none' and predictor != 'none':
2564
pytest.xfail('cannot use predictor without compression')
2567
(27, 23, samples) if samples else (27, 23, 1), numpy.uint8
2570
data[7:9, 11:13] = 13
2571
data[22:25, 19:22] = 11
2574
yield data[:16, :16]
2575
yield data[:16, 16:]
2576
yield data[16:, :16]
2577
yield data[16:, 16:]
2580
f'issue_tile_generator_{compression}_{predictor}_{samples}'
2585
shape=(27, 23, samples) if samples > 1 else (27, 23),
2588
compression=compression,
2589
predictor=predictor,
2591
assert_array_equal(imread(fname), data.squeeze())
2594
or not imagecodecs.TIFF.available
2595
or (compression == 'packbits' and predictor == 'horizontal')
2598
assert_array_equal(imagecodecs.imread(fname), data.squeeze())
2601
def test_issue_extratags_filter(caplog):
2602
"""Test filtering extratags."""
2603
# https://github.com/cgohlke/tifffile/pull/188
2604
with TempFileName('issue_extratags_filter') as fname:
2610
(322, 3, 1, 2, False), # TileWidth is filtered
2611
(34665, 13, 1, 0, False), # ExifIFD is filtered
2612
(270, 2, 0, 'second description', True), # filtered
2613
('FillOrder', 3, 1, 1, True), # by name should go through
2616
assert 'extratag 322' in caplog.text
2617
assert 'extratag 34665' in caplog.text
2618
with TiffFile(fname) as tif:
2619
tags = tif.pages.first.tags
2620
assert 322 not in tags
2621
assert 34665 not in tags
2622
assert tags.get(270, index=1) is None
2623
assert tags[266].value == 1
2627
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
2630
def test_issue_invalid_predictor(caplog):
2631
"""Test decoding JPEG compression with invalid predictor tag."""
2632
fname = private_file('issues/invalid_predictor.tiff')
2633
with TiffFile(fname) as tif:
2634
page = tif.pages.first
2635
assert page.predictor == 58240
2636
assert page.compression == 7
2637
data = page.asarray()
2638
assert 'ignoring predictor' in caplog.text
2639
assert data.shape == (1275, 1650, 4)
2642
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
2643
def test_issue_ome_missing_frames():
2644
"""Test read OME TIFF with missing pages at end."""
2645
# https://github.com/cgohlke/tifffile/issues/199
2646
fname = private_file('issues/stack_t24_y2048_x2448.tiff')
2647
with TiffFile(fname) as tif:
2649
assert tif.byteorder == '<'
2650
assert len(tif.pages) == 16
2651
assert len(tif.series) == 1
2652
# assert page properties
2653
page = tif.pages.first
2654
assert page.photometric == PHOTOMETRIC.MINISBLACK
2655
assert page.imagewidth == 2448
2656
assert page.imagelength == 2048
2657
assert page.bitspersample == 8
2658
assert not page.is_contiguous
2659
# assert series properties
2660
series = tif.series[0]
2661
assert len(series._pages) == 24
2662
assert len(series.pages) == 24
2663
assert series[16] is None
2664
assert series[23] is None
2665
assert series.shape == (24, 2048, 2448)
2666
assert series.dtype == numpy.uint8
2667
assert series.axes == 'TYX'
2668
assert series.kind == 'ome'
2669
data = series.asarray()
2670
assert_aszarr_method(tif, data)
2671
assert_aszarr_method(tif, data, chunkmode='page')
2675
@pytest.mark.skipif(not IS_WIN, reason=REASON)
2676
def test_issue_maxworkers():
2677
"""Test maxworkers defaults."""
2678
if 'TIFFFILE_NUM_THREADS' in os.environ:
2679
assert TIFF.MAXWORKERS == int(os.environ['TIFFFILE_NUM_THREADS'])
2681
assert TIFF.MAXWORKERS == max(1, os.cpu_count() // 2)
2683
if 'TIFFFILE_NUM_IOTHREADS' in os.environ:
2684
assert TIFF.MAXIOWORKERS == int(os.environ['TIFFFILE_NUM_IOTHREADS'])
2686
assert TIFF.MAXIOWORKERS == os.cpu_count() + 4
2689
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2690
def test_issue_logging_filter(caplog):
2691
"""Test raise an error by filtering logging messages."""
2692
# https://github.com/cgohlke/tifffile/issues/216
2695
def log_filter(record):
2696
if record.levelno == logging.ERROR:
2697
assert record.funcName == '__init__'
2698
assert 'invalid value offset' in record.msg
2699
raise ValueError(record.msg)
2702
fname = private_file('bad/Gel1.tif')
2704
logger().addFilter(log_filter)
2706
with pytest.raises(ValueError):
2709
logger().removeFilter(log_filter)
2711
assert 'invalid value offset' not in caplog.text
2712
imread(private_file(fname))
2713
assert 'invalid value offset' in caplog.text
2716
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2717
def test_issue_wrong_shape(caplog):
2718
"""Test rewritten file with wrong shape in metadata."""
2719
# https://github.com/Kitware/UPennContrast/issues/491
2720
fname = private_file('issues/2023_05_23_pw020_ctrl_well1.tif')
2721
with TiffFile(fname) as tif:
2722
assert tif.is_shaped
2723
page = tif.pages.first
2724
assert '"shape": [1, 1, 4, 1000, 1000]' in page.description
2725
assert '"axes": "ZTCYX"' in page.description
2726
assert page.shape == (1000, 1000, 4)
2727
series = tif.series[0]
2728
assert 'shaped series metadata does not match page' in caplog.text
2729
assert series.shape == (1000, 1000, 4) # != (1, 1, 4, 1000, 1000)
2730
assert series.axes == 'YXS' # != 'ZTCYX'
2731
assert_array_equal(page.asarray(), series.asarray())
2734
def test_issue_exclusive_creation():
2735
"""Test TiffWriter with exclusive creation mode 'x'."""
2736
# https://github.com/cgohlke/tifffile/pull/223
2737
with TempFileName('issue_exclusive_creation') as fname:
2738
if os.path.exists(fname):
2740
with FileHandle(fname, mode='x') as fh:
2741
assert fh._mode == 'xb'
2742
with TiffWriter(fh) as tif:
2743
tif.write(shape=(32, 32), dtype=numpy.uint8)
2744
with pytest.raises(FileExistsError):
2745
with FileHandle(fname, mode='x'):
2749
def test_issue_non_volumetric():
2750
"""Test writing non-volume data with volumetric tile."""
2751
# https://github.com/cgohlke/tifffile/pull/225
2752
data = random_data(numpy.uint8, (3, 13, 17))
2753
with TempFileName('issue_non_volumetric') as fname:
2754
with pytest.raises(ValueError):
2755
imwrite(fname, data[0], tile=(3, 16, 16))
2756
with pytest.raises(ValueError):
2757
imwrite(fname, data, photometric='rgb', tile=(3, 16, 16))
2759
# test some other invalid tiles
2760
with pytest.raises(ValueError):
2761
imwrite(fname, data, tile=(3, 3, 16, 16), photometric='minisblack')
2762
with pytest.raises(ValueError):
2763
imwrite(fname, data, tile=(16,), photometric='minisblack')
2764
with pytest.raises(ValueError):
2765
imwrite(fname, data, photometric='rgb', tile=(15, 16))
2766
with pytest.raises(ValueError):
2767
imwrite(fname, data, photometric='rgb', tile=(0, 16))
2769
# test some valid cases
2770
imwrite(fname, data, tile=(3, 16, 16), photometric='minisblack')
2771
with TiffFile(fname) as tif:
2772
page = tif.pages.first
2773
assert page.is_tiled
2774
assert page.is_volumetric
2775
assert page.shape == data.shape
2777
imwrite(fname, data, photometric='rgb', tile=(1, 16, 16))
2778
with TiffFile(fname) as tif:
2779
page = tif.pages.first
2780
assert page.is_tiled
2781
assert not page.is_volumetric
2782
assert page.shape == data.shape
2784
data = random_data(numpy.uint8, (3, 5, 13, 17))
2790
planarconfig='separate',
2793
with TiffFile(fname) as tif:
2794
assert len(tif.pages) == 1
2795
page = tif.pages.first
2796
assert page.is_tiled
2797
assert page.is_volumetric
2798
assert page.photometric == PHOTOMETRIC.RGB
2799
assert page.planarconfig == PLANARCONFIG.SEPARATE
2800
assert page.shape == data.shape
2802
data = random_data(numpy.uint8, (5, 13, 17, 3))
2808
planarconfig='contig',
2811
with TiffFile(fname) as tif:
2812
assert len(tif.pages) == 1
2813
page = tif.pages.first
2814
assert page.is_tiled
2815
assert page.is_volumetric
2816
assert page.photometric == PHOTOMETRIC.RGB
2817
assert page.planarconfig == PLANARCONFIG.CONTIG
2818
assert page.shape == data.shape
2820
data = random_data(numpy.uint8, (5, 13, 17))
2824
tile=(16, 16), # -> (1, 16, 16)
2825
photometric='miniswhite',
2829
with TiffFile(fname) as tif:
2830
assert len(tif.pages) == 1
2831
page = tif.pages.first
2832
assert page.is_tiled
2833
assert page.is_volumetric
2834
assert page.photometric == PHOTOMETRIC.MINISWHITE
2835
assert page.shape == data.shape
2838
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
2839
def test_issue_trucated_tileoffsets():
2840
"""Test reading truncated tile offsets and bytecounts."""
2841
# https://github.com/cgohlke/tifffile/issues/227
2842
data = random_data(numpy.uint8, (131, 128))
2843
with TempFileName('issue_trucated_tileoffsets') as fname:
2844
imwrite(fname, data, tile=(64, 64))
2845
with TiffFile(fname, mode='r+') as tif:
2846
# truncate TileOffsets and TileByteCounts
2847
tag = tif.pages[0].tags[324]
2848
assert tag.count == 6
2849
tag.overwrite(tag.value[:4])
2850
tag = tif.pages[0].tags[325]
2851
tag.overwrite(tag.value[:4])
2853
image = imread(fname)
2854
assert_raises(AssertionError, assert_array_equal, image, data)
2855
assert_array_equal(image[:128], data[:128])
2857
store = imread(fname, aszarr=True)
2858
za = zarr.open(store, mode='r')[:]
2860
assert_array_equal(za, image)
2863
@pytest.mark.parametrize('buffersize', [0, 1, 1234])
2864
@pytest.mark.parametrize('tile', [0, 1])
2865
def test_issue_buffersize(buffersize, tile):
2866
"""Test reading and writing with custom buffersize."""
2867
data = random_data(numpy.uint8, (5, 131, 133))
2868
with TempFileName(f'issue_buffersize_{buffersize}_{tile}') as fname:
2869
kwargs = {'tile': (32, 32)} if tile else {'rowsperstrip': 8}
2874
buffersize=buffersize,
2878
im = imread(fname, maxworkers=2, buffersize=buffersize)
2879
assert_array_equal(im, data)
2882
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2883
def test_issue_ideas(caplog):
2884
"""Test reading invalid TIFF produced by IDEAS."""
2885
# https://forum.image.sc/t/96103
2886
# NewSubfileType tag is of type bytes
2887
# FillOrder tag is zero
2888
fname = private_file('IDEAS/IDEAS_file.ome.tif')
2889
with TiffFile(fname) as tif:
2890
assert '0 is not a valid FILLORDER' in caplog.text
2891
assert 'invalid self.subfiletype=b' in caplog.text
2893
page = tif.pages.first
2894
assert page.tags['NewSubfileType'].value == b'\x02\x00'
2895
assert page.tags['FillOrder'].value == 0
2896
series = tif.series[0]
2897
assert series.shape == (37, 29)
2898
assert series.axes == 'YX'
2899
assert_array_equal(page.asarray(), series.asarray())
2902
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2903
def test_issue_nodata_invalid(caplog):
2904
"""Test read GeoTIFF with invalid nodata."""
2905
fname = private_file('GeoTIFF/nodata_corrupted.tiff')
2906
with TiffFile(fname) as tif:
2907
assert 'GDAL_NODATA tag raised ValueError' in caplog.text
2908
assert tif.byteorder == '<'
2909
assert len(tif.pages) == 1
2910
assert len(tif.series) == 1
2911
assert tif.is_geotiff
2913
# assert page properties
2914
page = tif.pages.first
2915
assert page.dtype == numpy.uint8
2916
assert page.nodata == 0
2917
assert page.tags['GDAL_NODATA'].value == '-99999999'
2918
# assert series properties
2919
series = tif.series[0]
2920
assert series.shape == (920, 1300)
2921
assert series.dtype == numpy.uint8
2922
assert series.axes == 'YX'
2923
assert series.kind == 'uniform'
2925
data = tif.asarray()
2926
assert isinstance(data, numpy.ndarray)
2927
assert data[500, 600] == 85
2928
assert data[0, 0] == 101
2929
assert_aszarr_method(tif, data)
2934
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
2935
def test_issue_tag_readfunc(caplog):
2936
"""Test allow tag reader functions to fail."""
2937
# file has an OlympusSIS tag, which is pointing to invalid structure
2938
fname = private_file('SIS/cirb_NOT_SIS.tif')
2939
with TiffFile(fname) as tif:
2940
# assert 'invalid OlympusSIS structure' in caplog.text
2941
assert tif.pages.first.tags[33560].value == (1382303888,)
2942
assert 'invalid OlympusSIS structure' in caplog.text
2943
assert tif.series[0].kind == 'generic'
2944
data = tif.asarray()
2945
assert data.shape == (800, 800, 4)
2946
assert data[166, 290, 2] == 255
2951
or not imagecodecs.JPEG8.available
2952
or not imagecodecs.JPEG2K.available
2953
or not imagecodecs.JPEGXL.available
2954
or imagecodecs.JPEG8.legacy,
2957
def test_issue_jpeg_bitspersample():
2958
"""Test write JPEG with many bitpersample."""
2959
# https://github.com/cgohlke/tifffile/pull/265
2961
data6 = random_data(numpy.uint8, (131, 128, 3)) >> 2
2962
data12 = random_data(numpy.uint16, (131, 128, 3)) >> 4
2963
jpeg12 = imagecodecs.jpeg_encode(data12, bitspersample=12, lossless=True)
2965
with TempFileName('issue_jpeg_bitspersample') as fname:
2966
with TiffWriter(fname) as tif:
2971
compressionargs={'lossless': True},
2978
compressionargs={'lossless': True, 'bitspersample': 12},
2992
compression='jpeg2000',
2993
compressionargs={'bitspersample': 12},
2998
compression='jpegxl',
2999
compressionargs={'bitspersample': 12},
3001
with pytest.raises(ValueError):
3008
with pytest.raises(ValueError):
3012
compression='jpeg2000',
3013
compressionargs={'bitspersample': 0},
3016
with TiffFile(fname) as tif:
3017
assert len(tif.pages) == 5
3018
assert tif.pages[0].bitspersample == 6
3019
assert tif.pages[1].bitspersample == 12
3020
assert tif.pages[2].bitspersample == 14
3021
assert tif.pages[3].bitspersample == 12
3022
assert tif.pages[4].bitspersample == 12
3023
assert_array_equal(tif.series[0].asarray(), data6)
3024
assert_array_equal(tif.series[1].asarray(), data12)
3025
assert_array_equal(tif.series[2].asarray(), data12)
3026
assert_array_equal(tif.series[3].asarray(), data12)
3027
assert_array_equal(tif.series[4].asarray(), data12)
3032
def test_issue_ometiff_modulo():
3033
"""Test writing OME-TIFF with modulo dimension."""
3034
# required for PhasorPy
3035
data = random_data(numpy.uint8, (3, 3, 31, 33))
3036
with TempFileName('issue_ometiff_modulo') as fname:
3037
with TiffWriter(fname, ome=True) as tif:
3039
data, photometric='minisblack', metadata={'axes': 'HTYX'}
3042
data, photometric='minisblack', metadata={'axes': 'QZYX'}
3044
with TiffFile(fname) as tif:
3045
series = tif.series[0]
3046
assert series.axes == 'HTYX'
3047
assert series.shape == (3, 3, 31, 33)
3048
series = tif.series[1]
3049
assert series.axes == 'QZYX'
3050
assert series.shape == (3, 3, 31, 33)
3053
def test_issue_ometiff_pixel():
3054
"""Test writing OME-TIFF three one pixel images."""
3055
# required for PhasorPy
3056
data = random_data(numpy.uint8, (3, 1, 1))
3057
with TempFileName('issue_ometiff_pixel') as fname:
3058
with TiffWriter(fname, ome=True) as tif:
3059
tif.write(data, photometric='minisblack', metadata={'axes': 'TYX'})
3060
with TiffFile(fname) as tif:
3061
series = tif.series[0]
3062
assert series.axes == 'TYX'
3063
assert series.shape == (3, 1, 1)
3066
class TestExceptions:
3067
"""Test various Exceptions and Warnings."""
3069
data = random_data(numpy.uint16, (5, 13, 17))
3071
@pytest.fixture(scope='class')
3073
with TempFileName('exceptions') as fname:
3076
def test_nofiles(self):
3078
with pytest.raises(ValueError):
3079
imread('*.exceptions')
3081
def test_memmap(self, fname):
3082
# not memory-mappable
3083
imwrite(fname, self.data, compression=8)
3084
with pytest.raises(ValueError):
3086
with pytest.raises(ValueError):
3087
memmap(fname, page=0)
3089
def test_dimensions(self, fname):
3090
# dimensions too large
3091
with pytest.raises(ValueError):
3092
imwrite(fname, shape=(4294967296, 32), dtype=numpy.uint8)
3094
def test_no_shape_dtype_empty(self, fname):
3095
# shape and dtype missing for empty array
3096
with pytest.raises(ValueError):
3099
def test_no_shape_dtype_iter(self, fname):
3100
# shape and dtype missing for iterator
3101
with pytest.raises(ValueError):
3102
imwrite(fname, iter(self.data))
3104
def test_no_shape_dtype(self, fname):
3105
# shape and dtype missing
3106
with TiffWriter(fname) as tif:
3107
with pytest.raises(ValueError):
3110
def test_no_shape(self, fname):
3112
with TiffWriter(fname) as tif:
3113
with pytest.raises(ValueError):
3114
tif.write(iter(self.data), dtype='u2')
3116
def test_no_dtype(self, fname):
3118
with TiffWriter(fname) as tif:
3119
with pytest.raises(ValueError):
3120
tif.write(iter(self.data), shape=(5, 13, 17))
3122
def test_mismatch_dtype(self, fname):
3124
with pytest.raises(ValueError):
3125
imwrite(fname, self.data, dtype='f4')
3127
def test_mismatch_shape(self, fname):
3129
with pytest.raises(ValueError):
3130
imwrite(fname, self.data, shape=(2, 13, 17))
3132
def test_byteorder(self, fname):
3134
with pytest.raises(ValueError):
3135
imwrite(fname, self.data, byteorder='?')
3137
def test_truncate_compression(self, fname):
3138
# truncate cannot be used with compression, packints, or tiles
3139
with pytest.raises(ValueError):
3140
imwrite(fname, self.data, compression=8, truncate=True)
3142
def test_truncate_ome(self, fname):
3143
# truncate cannot be used with ome-tiff
3144
with pytest.raises(ValueError):
3145
imwrite(fname, self.data, ome=True, truncate=True)
3147
def test_truncate_noshape(self, fname):
3148
# truncate cannot be used with shaped=False
3149
with pytest.raises(ValueError):
3150
imwrite(fname, self.data, shaped=False, truncate=True)
3152
def test_compression(self, fname):
3153
# invalid compression
3154
with pytest.raises(ValueError):
3155
with pytest.warns(DeprecationWarning):
3156
imwrite(fname, self.data, compression=(8, None, None, None))
3158
def test_predictor_dtype(self, fname):
3159
# cannot apply predictor to dtype complex
3160
with pytest.raises(ValueError):
3162
fname, self.data.astype('F'), predictor=True, compression=8
3165
def test_predictor_float(self, fname):
3166
# cannot apply horizontal predictor to float
3167
with pytest.raises(ValueError):
3168
imwrite(fname, self.data.astype('f'), predictor=2, compression=8)
3170
def test_predictor_uint(self, fname):
3171
# cannot apply float predictor to uint
3172
with pytest.raises(ValueError):
3173
imwrite(fname, self.data.astype('H'), predictor=3, compression=8)
3175
def test_predictor_wrong_compression(self, fname):
3176
# cannot apply predictor to with image compression schemes
3177
with pytest.raises(ValueError):
3178
imwrite(fname, self.data.astype('B'), predictor=2, compression=7)
3180
def test_predictor_no_compression(self, fname):
3181
# cannot apply predictor to without compression
3182
with pytest.raises(ValueError):
3183
imwrite(fname, self.data.astype('B'), predictor=2, compression=1)
3185
def test_ome_imagedepth(self, fname):
3186
# OME-TIFF does not support ImageDepth
3187
with pytest.raises(ValueError):
3188
imwrite(fname, self.data, ome=True, volumetric=True)
3190
def test_imagej_dtype(self, fname):
3191
# ImageJ does not support dtype
3192
with pytest.raises(ValueError):
3193
imwrite(fname, self.data.astype('f8'), imagej=True)
3195
def test_imagej_imagedepth(self, fname):
3196
# ImageJ does not support ImageDepth
3197
with pytest.raises(ValueError):
3198
imwrite(fname, self.data, imagej=True, volumetric=True)
3200
def test_imagej_float_rgb(self, fname):
3201
# ImageJ does not support float with rgb
3202
with pytest.raises(ValueError):
3205
self.data[..., :3].astype('f4'),
3210
def test_imagej_planar(self, fname):
3211
# ImageJ does not support planar
3212
with pytest.raises(ValueError):
3213
imwrite(fname, self.data, imagej=True, planarconfig='separate')
3215
def test_colormap_shape(self, fname):
3216
# invalid colormap shape
3217
with pytest.raises(ValueError):
3220
self.data.astype('u1'),
3221
photometric='palette',
3222
colormap=numpy.empty((3, 254), 'u2'),
3225
def test_colormap_dtype(self, fname):
3226
# invalid colormap dtype
3227
with pytest.raises(ValueError):
3230
self.data.astype('u1'),
3231
photometric='palette',
3232
colormap=numpy.empty((3, 255), 'i2'),
3235
def test_palette_dtype(self, fname):
3236
# invalid dtype for palette mode
3237
with pytest.raises(ValueError):
3240
self.data.astype('u4'),
3241
photometric='palette',
3242
colormap=numpy.empty((3, 255), 'u2'),
3245
def test_cfa_shape(self, fname):
3246
# invalid shape for CFA
3247
with pytest.raises(ValueError):
3248
imwrite(fname, self.data, photometric='cfa')
3250
def test_subfiletype_mask(self, fname):
3251
# invalid SubfileType MASK
3252
with pytest.raises(ValueError):
3253
imwrite(fname, self.data, subfiletype=0b100)
3255
def test_bitspersample_bilevel(self, fname):
3256
# invalid bitspersample for bilevel
3257
with pytest.raises(ValueError):
3258
imwrite(fname, self.data.astype('?'), bitspersample=2)
3260
def test_bitspersample_jpeg(self, fname):
3261
# invalid bitspersample for jpeg
3262
with pytest.raises(ValueError):
3263
imwrite(fname, self.data, compression='jpeg', bitspersample=17)
3265
def test_datetime(self, fname):
3267
with pytest.raises(ValueError):
3268
imwrite(fname, self.data, datetime='date')
3270
def test_rgb(self, fname):
3272
with pytest.raises(ValueError):
3273
imwrite(fname, self.data[:2], photometric='rgb')
3275
def test_extrasamples(self, fname):
3276
# invalid extrasamples
3277
with pytest.raises(ValueError):
3279
fname, self.data, photometric='rgb', extrasamples=(0, 1, 2)
3282
def test_subsampling(self, fname):
3283
# invalid subsampling
3284
with pytest.raises(ValueError):
3293
def test_compress_bilevel(self, fname):
3294
# cannot compress bilevel image
3295
with pytest.raises(NotImplementedError):
3296
imwrite(fname, self.data.astype('?'), compression='jpeg')
3298
def test_description_unicode(self, fname):
3299
# strings must be 7-bit ASCII
3300
with pytest.raises(ValueError):
3301
imwrite(fname, self.data, description='mu: \u03BC')
3303
def test_compression_contiguous(self, fname):
3304
# contiguous cannot be used with compression, tiles
3305
with TiffWriter(fname) as tif:
3306
tif.write(self.data[0])
3307
with pytest.raises(ValueError):
3308
tif.write(self.data[1], contiguous=True, compression=8)
3310
def test_imagej_contiguous(self, fname):
3311
# ImageJ format does not support non-contiguous series
3312
with TiffWriter(fname, imagej=True) as tif:
3313
tif.write(self.data[0])
3314
with pytest.raises(ValueError):
3315
tif.write(self.data[1], contiguous=False)
3317
def test_subifds_subifds(self, fname):
3318
# SubIFDs in SubIFDs are not supported
3319
with TiffWriter(fname) as tif:
3320
tif.write(self.data[0], subifds=1)
3321
with pytest.raises(ValueError):
3322
tif.write(self.data[1], subifds=1)
3324
def test_subifds_truncate(self, fname):
3325
# SubIFDs cannot be used with truncate
3326
with TiffWriter(fname) as tif:
3327
tif.write(self.data, subifds=1, truncate=True)
3328
with pytest.raises(ValueError):
3329
tif.write(self.data[:, ::2, ::2])
3331
def test_subifds_imwrite(self, fname):
3332
# imwrite cannot be used to write SubIFDs
3333
with pytest.raises(TypeError):
3334
imwrite(fname, self.data, subifds=1)
3336
def test_iter_bytes(self, fname):
3337
# iterator contains wrong number of bytes
3338
with TiffWriter(fname) as tif:
3339
with pytest.raises(ValueError):
3347
def test_iter_dtype(self, fname):
3348
# iterator contains wrong dtype
3349
with TiffWriter(fname) as tif:
3350
with pytest.raises(ValueError):
3358
with TiffWriter(fname) as tif:
3359
with pytest.raises(ValueError):
3368
def test_tiff_enums(self):
3369
# TIFF.COMPRESSION and others are deprecated
3370
with pytest.warns(DeprecationWarning):
3372
with pytest.warns(DeprecationWarning):
3374
with pytest.warns(DeprecationWarning):
3376
with pytest.warns(DeprecationWarning):
3378
with pytest.warns(DeprecationWarning):
3380
with pytest.warns(DeprecationWarning):
3382
with pytest.warns(DeprecationWarning):
3384
with pytest.warns(DeprecationWarning):
3387
# def test_extratags(self, fname):
3388
# # invalid dtype or count
3389
# with pytest.raises(ValueError):
3390
# imwrite(fname, data, extratags=[()])
3392
def test_container_binaryio(self, fname):
3393
# container cannot be binaryio
3394
with pytest.raises(ValueError):
3395
with FileHandle(fname, 'r+') as fh:
3396
imread(fh, container=fname)
3398
def test_imagej_colormap(self, fname):
3399
# invalid colormap shape
3400
with pytest.raises(ValueError):
3404
dtype=numpy.float32,
3409
def test_photometric(self, fname):
3411
with pytest.raises(ValueError):
3413
fname, shape=(31, 33, 2), dtype=numpy.uint8, photometric='rgb'
3416
def test_tile(self, fname):
3417
# invalid tile in iterator
3419
yield numpy.empty((32, 32), dtype=numpy.uint16)
3421
with pytest.raises(ValueError):
3430
with pytest.raises(ValueError):
3432
fname, tile(), shape=(31, 33), dtype=numpy.uint8, tile=(32, 32)
3435
def test_description(self, fname):
3436
# invalid description type
3437
with pytest.raises(ValueError):
3446
def test_omexml(self, fname):
3448
imwrite(fname, shape=(31, 33), dtype=numpy.uint8)
3449
with pytest.raises(ValueError):
3450
imread(fname, omexml='OME')
3452
def test_key(self, fname):
3454
imwrite(fname, shape=(31, 33), dtype=numpy.uint8)
3455
with pytest.raises(TypeError):
3456
imread(fname, key='1')
3457
with pytest.raises(TypeError):
3458
imread(fname, key='1', series=0)
3460
def test_filemode(self, fname):
3461
# invalid file open mode
3462
with pytest.raises(ValueError):
3463
imread(fname, mode='no')
3465
@pytest.mark.skipif(
3466
SKIP_CODECS or not imagecodecs.LERC.available, reason=REASON
3468
def test_lerc_compression(self, fname):
3469
# invalid LERC compression
3470
with pytest.raises(ValueError):
3476
compressionargs={'compression': 'jpeg'},
3479
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
3480
def test_sequence_imread_dtype(self):
3481
# dtype argument is deprecated
3482
files = public_file('tifffile/temp_C001T00*.tif')
3483
with pytest.warns(DeprecationWarning):
3484
stack = imread(files, dtype=numpy.float64)
3485
assert_array_equal(stack[0], imread(files[0]))
3487
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
3488
def test_filesequence_dtype(self):
3489
# dtype argument is deprecated
3490
files = public_file('tifffile/temp_C001T00*.tif')
3491
with pytest.warns(DeprecationWarning):
3492
TiffSequence(files).asarray(dtype=numpy.float64)
3493
with pytest.warns(DeprecationWarning):
3494
TiffSequence(files).asarray(dtype=numpy.float64)
3495
with pytest.warns(DeprecationWarning):
3496
TiffSequence(files).aszarr(dtype=numpy.float64)
3499
###############################################################################
3501
# Test specific functions and classes
3504
def test_class_tiffformat():
3505
"""Test TiffFormat class."""
3507
assert not tiff.is_bigtiff
3513
def test_class_filecache():
3514
"""Test FileCache class."""
3515
with TempFileName('class_filecache') as fname:
3516
cache = FileCache(3)
3518
with open(fname, 'wb') as fh:
3521
# create 6 handles, leaving only first one open
3524
fh = FileHandle(fname)
3532
assert len(cache) == 6
3533
for i, fh in enumerate(handles):
3534
assert not fh.closed
3535
assert cache.files[fh] == 1 if i else 2
3537
# close all files: only first file and recently used files are open
3540
assert len(cache) == 3
3541
for i, fh in enumerate(handles):
3542
assert fh.closed == (0 < i < 4)
3544
assert cache.files[fh] == 0 if i else 1
3546
# open all files, then clear cache: only first file is open
3550
assert len(cache) == 1
3551
assert handles[0] in cache.files
3552
for i, fh in enumerate(handles):
3553
assert fh.closed == (i > 0)
3555
# randomly open and close files
3557
fh = handles[random.randint(0, 5)]
3560
assert len(cache) <= 3
3561
assert fh in cache.files
3562
assert handles[0] in cache.files
3564
# randomly read from files
3566
fh = handles[random.randint(0, 5)]
3567
cache.read(fh, 0, 0)
3568
assert len(cache) <= 3
3569
assert fh in cache.files
3570
assert handles[0] in cache.files
3572
# clear cache: only first file is open
3574
assert len(cache) == 1
3575
assert handles[0] in cache.files
3576
for i, fh in enumerate(handles):
3577
assert fh.closed == (i > 0)
3579
# open and close all files twice
3583
assert len(cache) == 6
3584
for i, fh in enumerate(handles):
3585
assert not fh.closed
3586
assert cache.files[fh] == 2 if i else 3
3590
assert len(cache) == 6
3591
for i, fh in enumerate(handles):
3592
assert not fh.closed
3593
assert cache.files[fh] == 1 if i else 2
3597
assert len(cache) == 3
3598
for i, fh in enumerate(handles):
3599
assert fh.closed == (0 < i < 4)
3601
assert cache.files[fh] == 0 if i else 1
3608
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
3609
def test_class_tifftag_astuple():
3610
"""Test TiffTag.astuple method."""
3611
fname = private_file('imagej/IJMetadata.tif')
3612
with TiffFile(fname) as tif:
3613
tags = tif.pages.first.tags
3614
assert tags['BitsPerSample'].astuple() == (
3621
assert tags['ImageDescription'].astuple() == (
3625
b'ImageJ=1.52b\nimages=3\nchannels=3\nmode=composite\nloop=false'
3629
assert tags['IJMetadataByteCounts'].astuple() == (
3633
b'\x00\x00\x004\x00\x00\x07\xa8\x00\x00\x00\x06\x00\x00\x00\n\x00'
3634
b'\x00\x00\x08\x00\x00\x000\x00\x00\x03\x00\x00\x00\x03\x00\x00'
3635
b'\x00\x03\x00\x00\x00\x04\xa4\x00\x00\x00\xc0\x00\x00\x00\x80',
3638
assert tags['IJMetadata'].astuple()[:3] == (50839, 1, 5896)
3641
@pytest.mark.parametrize('bigtiff', [False, True])
3642
@pytest.mark.parametrize('byteorder', ['<', '>'])
3643
def test_class_tifftag_overwrite(bigtiff, byteorder):
3644
"""Test TiffTag.overwrite method."""
3645
data = numpy.ones((16, 16, 3), dtype=byteorder + 'i2')
3646
bt = '_bigtiff' if bigtiff else ''
3647
bo = 'be' if byteorder == '>' else 'le'
3649
with TempFileName(f'class_tifftag_overwrite_{bo}{bt}') as fname:
3654
photometric=PHOTOMETRIC.RGB,
3658
with TiffFile(fname, mode='r+') as tif:
3659
tags = tif.pages.first.tags
3662
t305 = tag.overwrite('inl')
3663
assert tag.valueoffset == t305.valueoffset
3664
valueoffset = tag.valueoffset
3667
t282 = tag.overwrite((2000, 1000))
3668
assert tag.valueoffset == t282.valueoffset
3669
# sampleformat, int -> uint
3671
t339 = tags[339].overwrite((1, 1, 1))
3672
assert tag.valueoffset == t339.valueoffset
3674
with TiffFile(fname) as tif:
3675
tags = tif.pages.first.tags
3677
assert tag.value == 'inl'
3678
assert tag.count == t305.count
3680
assert tag.value == (2000, 1000)
3681
assert tag.count == t282.count
3683
assert tag.value == (1, 1, 1)
3684
assert tag.count == t339.count
3686
# use bytes, specify dtype
3687
with TiffFile(fname, mode='r+') as tif:
3688
tags = tif.pages.first.tags
3691
fmt = byteorder + '2I'
3692
t282 = tag.overwrite(struct.pack(fmt, 2500, 1500), dtype=fmt)
3693
assert tag.valueoffset == t282.valueoffset
3695
with TiffFile(fname) as tif:
3696
tags = tif.pages.first.tags
3698
assert tag.value == (2500, 1500)
3699
assert tag.count == t282.count
3701
# inline -> separate
3702
with TiffFile(fname, mode='r+') as tif:
3703
tag = tif.pages.first.tags[305]
3704
t305 = tag.overwrite('separate')
3705
assert tag.valueoffset != t305.valueoffset
3707
# separate at end -> separate longer
3708
with TiffFile(fname, mode='r+') as tif:
3709
tag = tif.pages.first.tags[305]
3710
assert tag.value == 'separate'
3711
assert tag.valueoffset == t305.valueoffset
3712
t305 = tag.overwrite('separate longer')
3713
assert tag.valueoffset == t305.valueoffset # overwrite, not append
3715
# separate -> separate shorter
3716
with TiffFile(fname, mode='r+') as tif:
3717
tag = tif.pages.first.tags[305]
3718
assert tag.value == 'separate longer'
3719
assert tag.valueoffset == t305.valueoffset
3720
t305 = tag.overwrite('separate short')
3721
assert tag.valueoffset == t305.valueoffset
3723
# separate -> separate longer
3724
with TiffFile(fname, mode='r+') as tif:
3725
tag = tif.pages.first.tags[305]
3726
assert tag.value == 'separate short'
3727
assert tag.valueoffset == t305.valueoffset
3728
filesize = tif.filehandle.size
3729
t305 = tag.overwrite('separate longer')
3730
assert tag.valueoffset != t305.valueoffset
3731
assert t305.valueoffset == filesize # append to end
3733
# separate -> inline
3734
with TiffFile(fname, mode='r+') as tif:
3735
tag = tif.pages.first.tags[305]
3736
assert tag.value == 'separate longer'
3737
assert tag.valueoffset == t305.valueoffset
3738
t305 = tag.overwrite('inl')
3739
assert tag.valueoffset != t305.valueoffset
3740
assert t305.valueoffset == valueoffset
3743
with TiffFile(fname, mode='r+') as tif:
3744
tag = tif.pages.first.tags[305]
3745
assert tag.value == 'inl'
3746
assert tag.valueoffset == t305.valueoffset
3747
with pytest.raises(TypeError):
3748
t305 = tag.overwrite(tif, '')
3749
t305 = tag.overwrite('')
3750
assert tag.valueoffset == t305.valueoffset
3752
with TiffFile(fname) as tif:
3753
tag = tif.pages.first.tags[305]
3754
assert tag.value == ''
3755
assert tag.valueoffset == t305.valueoffset
3758
with TiffFile(fname, mode='r+') as tif:
3759
tags = tif.pages.first.tags
3762
t256 = tag.overwrite(tag.value, dtype=3)
3763
assert tag.valueoffset == t256.valueoffset
3765
with TiffFile(fname) as tif:
3766
tags = tif.pages.first.tags
3768
assert tag.value == 16
3769
assert tag.count == t256.count
3772
assert_valid_tiff(fname)
3779
or not imagecodecs.JPEG.available,
3782
def test_class_tifftag_overwrite_ndpi():
3783
"""Test TiffTag.overwrite method on 64-bit NDPI file."""
3784
fname = private_file('HamamatsuNDPI/103680x188160.ndpi')
3785
with TiffFile(fname, mode='r+') as tif:
3787
tags = tif.pages.first.tags
3789
# inline, old value 32-bit
3790
assert tags['ImageWidth'].value == 188160
3791
tags['ImageWidth'].overwrite(0)
3792
tags['ImageWidth'].overwrite(188160)
3794
# separate, smaller or same length
3795
assert tags['Model'].value == 'C13220'
3796
tags['Model'].overwrite('C13220')
3798
with pytest.raises(struct.error):
3799
# new offset > 32-bit
3800
tags['Model'].overwrite('C13220-')
3802
assert tags['StripByteCounts'].value == (4461521316,)
3803
with pytest.raises(ValueError):
3804
# old value > 32-bit
3805
tags['StripByteCounts'].overwrite(0)
3807
with TiffFile(fname, mode='r') as tif:
3809
tags = tif.pages.first.tags
3810
assert tags['ImageWidth'].value == 188160
3811
assert tags['Model'].value == 'C13220'
3812
assert tags['StripByteCounts'].value == (4461521316,)
3815
def test_class_tifftags():
3816
"""Test TiffTags interface."""
3817
data = random_data(numpy.uint8, (21, 31))
3819
with TempFileName('class_tifftags') as fname:
3820
imwrite(fname, data, description='test', software=False)
3822
with TiffFile(fname) as tif:
3823
tags = tif.pages.first.tags
3824
# assert len(tags) == 14
3826
assert 'ImageDescription' in tags
3827
assert tags[270].value == 'test'
3828
assert tags['ImageDescription'].value == 'test'
3829
assert tags.get(270).value == 'test'
3830
assert tags.get('ImageDescription').value == 'test'
3831
assert tags.get(270, index=0).value == 'test'
3832
assert tags.get('ImageDescription', index=0).value == 'test'
3833
assert tags.get(270, index=1).value.startswith('{')
3834
assert tags.get('ImageDescription', index=1).value.startswith('{')
3835
assert tags.get(270, index=2) is None
3836
assert tags.get('ImageDescription', index=2) is None
3837
assert tags.getall(270)[0].value == 'test'
3838
assert tags.getall(270)[1].value.startswith('{')
3839
assert tags.getall('ImageDescription')[0].value == 'test'
3840
assert tags.getall('ImageDescription')[1].value.startswith('{')
3841
assert tags.getall(0, default=1) == 1
3842
assert tags.getall('0', default=1) == 1
3843
assert tags.getall(None, default=1) == 1
3845
assert len(tags.getall(270)) == 2
3846
assert 305 not in tags
3847
assert 'Software' not in tags
3848
assert tags.get(305) is None
3849
assert tags.get('Software') is None
3850
with pytest.raises(KeyError):
3852
with pytest.raises(KeyError):
3853
tags['Software'].value
3854
assert len(tags.values()) == len(tags.items())
3855
assert len(tags.keys()) == len(tags.items()) - 1
3856
assert set(tags.keys()) == {i[0] for i in tags.items()}
3857
assert list(tags.values()) == [i[1] for i in tags.items()]
3858
assert list(tags.values()) == list(tags)
3862
assert 270 not in tags
3863
assert 'ImageDescription' not in tags
3864
with pytest.raises(KeyError):
3866
with pytest.raises(KeyError):
3867
del tags['ImageDescription']
3871
assert 'ImageDescription' in tags
3872
del tags['ImageDescription']
3873
assert 270 not in tags
3874
assert 'ImageDescription' not in tags
3878
assert 'ImageDescription' in tags
3880
assert 0 not in tags
3881
assert 'None' not in tags
3882
assert None not in tags
3883
assert 'TiffTags' in repr(tags)
3886
def test_class_tifftagregistry():
3887
"""Test TiffTagRegistry."""
3890
assert len(tags) == numtags
3891
assert tags[11] == 'ProcessingSoftware'
3892
assert tags['ProcessingSoftware'] == 11
3893
assert tags.getall(11) == ['ProcessingSoftware']
3894
assert tags.getall('ProcessingSoftware') == [11]
3895
tags.add(11, 'ProcessingSoftware')
3896
assert len(tags) == numtags
3898
# one code with two names
3899
assert 34853 in tags
3900
assert 'GPSTag' in tags
3901
assert 'OlympusSIS2' in tags
3902
assert tags[34853] == 'GPSTag'
3903
assert tags['GPSTag'] == 34853
3904
assert tags['OlympusSIS2'] == 34853
3905
assert tags.getall(34853) == ['GPSTag', 'OlympusSIS2']
3906
assert tags.getall('GPSTag') == [34853]
3909
assert len(tags) == numtags - 2
3910
assert 34853 not in tags
3911
assert 'GPSTag' not in tags
3912
assert 'OlympusSIS2' not in tags
3913
tags.add(34853, 'GPSTag')
3914
tags.add(34853, 'OlympusSIS2')
3915
assert 34853 in tags
3916
assert 'GPSTag' in tags
3917
assert 'OlympusSIS2' in tags
3920
assert "34853, 'GPSTag'" in info
3921
assert "34853, 'OlympusSIS2'" in info
3923
# two codes with same name
3924
assert 37387 in tags
3925
assert 41483 in tags
3926
assert 'FlashEnergy' in tags
3927
assert tags[37387] == 'FlashEnergy'
3928
assert tags[41483] == 'FlashEnergy'
3929
assert tags['FlashEnergy'] == 37387
3930
assert tags.getall('FlashEnergy') == [37387, 41483]
3931
assert tags.getall(37387) == ['FlashEnergy']
3932
assert tags.getall(41483) == ['FlashEnergy']
3934
del tags['FlashEnergy']
3935
assert len(tags) == numtags - 2
3936
assert 37387 not in tags
3937
assert 41483 not in tags
3938
assert 'FlashEnergy' not in tags
3939
tags.add(37387, 'FlashEnergy')
3940
tags.add(41483, 'FlashEnergy')
3941
assert 37387 in tags
3942
assert 41483 in tags
3943
assert 'FlashEnergy' in tags
3945
assert "37387, 'FlashEnergy'" in info
3946
assert "41483, 'FlashEnergy'" in info
3949
@pytest.mark.parametrize(
3950
'shape, storedshape, dtype, axes, error',
3952
# separate and contig
3953
((32, 32), (1, 2, 1, 32, 32, 2), numpy.uint8, None, ValueError),
3955
((32, 32, 32), (1, 1, 32, 32, 32, 1), numpy.uint8, None, OmeXmlError),
3957
((32, 32), (1, 1, 1, 32, 32, 1), numpy.float16, None, OmeXmlError),
3959
((0, 0), (1, 1, 1, 0, 0, 1), numpy.uint8, None, OmeXmlError),
3961
((32, 32), (1, 1, 1, 32, 32, 1), numpy.uint8, 'XZ', OmeXmlError),
3963
((1, 32, 32), (1, 1, 1, 32, 32, 1), numpy.uint8, 'KYX', OmeXmlError),
3965
((1, 32, 32), (1, 1, 1, 32, 32, 1), numpy.uint8, 'YYX', OmeXmlError),
3966
# more than 5 dimensions
3968
(1, 1, 1, 5, 32, 32),
3969
(5, 1, 1, 32, 32, 1),
3974
# more than 6 dimensions
3976
(1, 1, 1, 1, 32, 32, 3),
3977
(1, 1, 1, 32, 32, 3),
3982
# more than 8 dimensions
3984
(1, 1, 1, 1, 1, 1, 1, 32, 32),
3985
(1, 1, 1, 32, 32, 1),
3990
# more than 9 dimensions
3992
(1, 1, 1, 1, 1, 1, 1, 32, 32, 3),
3993
(1, 1, 1, 32, 32, 3),
3999
((1, 32, 32), (1, 1, 1, 32, 32, 1), numpy.uint8, 'YYX', OmeXmlError),
4000
# planecount mismatch
4001
((3, 32, 32), (1, 1, 1, 32, 32, 1), numpy.uint8, 'CYX', ValueError),
4002
# stored shape mismatch
4003
((3, 32, 32), (1, 2, 1, 32, 32, 1), numpy.uint8, 'SYX', ValueError),
4004
((32, 32, 3), (1, 1, 1, 32, 32, 2), numpy.uint8, 'YXS', ValueError),
4005
((3, 32, 32), (1, 3, 1, 31, 31, 1), numpy.uint8, 'SYX', ValueError),
4006
((32, 32, 3), (1, 1, 1, 31, 31, 3), numpy.uint8, 'YXS', ValueError),
4007
((32, 32), (1, 1, 1, 32, 31, 1), numpy.uint8, None, ValueError),
4008
# too many modulo dimensions
4010
(2, 3, 4, 5, 32, 32),
4011
(60, 1, 1, 32, 32, 1),
4018
def test_class_omexml_fail(shape, storedshape, dtype, axes, error):
4019
"""Test OmeXml class failures."""
4020
metadata = {'axes': axes} if axes else {}
4022
with pytest.raises(error):
4023
ox.addimage(dtype, shape, storedshape, **metadata)
4026
@pytest.mark.parametrize(
4027
'axes, autoaxes, shape, storedshape, dimorder',
4029
('YX', 'YX', (32, 32), (1, 1, 1, 32, 32, 1), 'XYCZT'),
4030
('YXS', 'YXS', (32, 32, 1), (1, 1, 1, 32, 32, 1), 'XYCZT'),
4031
('SYX', 'SYX', (1, 32, 32), (1, 1, 1, 32, 32, 1), 'XYCZT'),
4032
('YXS', 'YXS', (32, 32, 3), (1, 1, 1, 32, 32, 3), 'XYCZT'),
4033
('SYX', 'SYX', (3, 32, 32), (1, 3, 1, 32, 32, 1), 'XYCZT'),
4034
('CYX', 'CYX', (5, 32, 32), (5, 1, 1, 32, 32, 1), 'XYCZT'),
4035
('CYXS', 'CYXS', (5, 32, 32, 1), (5, 1, 1, 32, 32, 1), 'XYCZT'),
4036
('CSYX', 'ZCYX', (5, 1, 32, 32), (5, 1, 1, 32, 32, 1), 'XYCZT'), # !
4037
('CYXS', 'CYXS', (5, 32, 32, 3), (5, 1, 1, 32, 32, 3), 'XYCZT'),
4038
('CSYX', 'CSYX', (5, 3, 32, 32), (5, 3, 1, 32, 32, 1), 'XYCZT'),
4039
('TZCYX', 'TZCYX', (3, 4, 5, 32, 32), (60, 1, 1, 32, 32, 1), 'XYCZT'),
4043
(3, 4, 5, 32, 32, 1),
4044
(60, 1, 1, 32, 32, 1),
4050
(3, 4, 5, 1, 32, 32),
4051
(60, 1, 1, 32, 32, 1),
4057
(3, 4, 5, 32, 32, 3),
4058
(60, 1, 1, 32, 32, 3),
4061
('ZTCSYX', '', (3, 4, 5, 3, 32, 32), (60, 3, 1, 32, 32, 1), 'XYCTZ'),
4064
@pytest.mark.parametrize('metadata', ('axes', None))
4065
def test_class_omexml(axes, autoaxes, shape, storedshape, dimorder, metadata):
4066
"""Test OmeXml class."""
4068
if not metadata and dimorder != 'XYCZT':
4070
metadata = dict(axes=axes) if metadata else dict()
4072
omexml.addimage(dtype, shape, storedshape, **metadata)
4074
assert '\n ' in str(omexml)
4075
omexml = omexml.tostring()
4076
assert dimorder in omexml
4081
size = shape[autoaxes.index(ax)]
4085
size *= storedshape[1] * storedshape[-1]
4086
assert f'Size{ax}="{size}"' in omexml
4087
assert__repr__(omexml)
4088
assert_valid_omexml(omexml)
4091
@pytest.mark.parametrize(
4092
'axes, shape, storedshape, sizetzc, dimorder',
4094
('ZAYX', (3, 4, 32, 32), (12, 1, 1, 32, 32, 1), (1, 12, 1), 'XYCZT'),
4095
('AYX', (3, 32, 32), (3, 1, 1, 32, 32, 1), (3, 1, 1), 'XYCZT'),
4096
('APYX', (3, 4, 32, 32), (12, 1, 1, 32, 32, 1), (3, 4, 1), 'XYCZT'),
4097
('TAYX', (3, 4, 32, 32), (12, 1, 1, 32, 32, 1), (12, 1, 1), 'XYCZT'),
4101
(12, 1, 1, 32, 32, 3),
4108
(12, 3, 1, 32, 32, 1),
4115
(60, 1, 1, 32, 32, 1),
4122
(60, 1, 1, 32, 32, 1),
4129
(60, 1, 1, 32, 32, 1),
4136
(60, 1, 1, 32, 32, 1),
4143
(50, 1, 1, 200, 200, 1),
4149
(2, 3, 4, 5, 6, 7, 32, 32),
4150
(5040, 1, 1, 32, 32, 1),
4156
def test_class_omexml_modulo(axes, shape, storedshape, sizetzc, dimorder):
4157
"""Test OmeXml class with modulo dimensions."""
4160
omexml.addimage(dtype, shape, storedshape, axes=axes)
4161
assert '\n ' in str(omexml)
4162
omexml = omexml.tostring()
4163
assert dimorder in omexml
4164
for ax, size in zip('TZC', sizetzc):
4165
assert f'Size{ax}="{size}"' in omexml
4166
assert__repr__(omexml)
4167
assert_valid_omexml(omexml)
4170
def test_class_omexml_attributes():
4171
"""Test OmeXml class with attributes and elements."""
4172
from uuid import uuid1
4178
Creator=f'test_tifffile.py {tifffile.__version__}',
4182
Acquisitiondate='2011-09-16T10:45:48',
4183
Description='Image "Description" < & >\n{test}',
4184
TypeDescription={'Q': 'Phasor'},
4187
PhysicalSizeXUnit='nm',
4189
PhysicalSizeYUnit='\xb5m',
4191
PhysicalSizeZUnit='\xc5',
4193
TimeIncrementUnit='\xb5s',
4194
Channel=dict(Name='ChannelName'), # one channel with 3 samples
4195
Plane=dict(PositionZ=[0.0, 0.0, 2.0, 2.0, 4.0, 4.0]), # 6 TZ-planes
4196
CommentAnnotation='Tifffile test',
4197
BooleanAnnotation=True,
4198
LongAnnotation=[1, 2],
4199
DoubleAnnotation={'Description': 'A double', 'Value': 1.0},
4201
{'Description': 'description', 'key': '<str/>', 'key2': 1.0},
4202
{'Namespace': 'ns.org', 'key2': 1, 'key3': 2},
4206
omexml = OmeXml(**metadata)
4208
numpy.uint16, (2, 3, 32, 32, 3), (6, 1, 1, 32, 32, 3), **metadata
4210
xml = omexml.tostring()
4212
f'UUID="urn:uuid:{uuid}"',
4213
'SizeX="32" SizeY="32" SizeC="3" SizeZ="3" SizeT="2"',
4214
'Interleaved="true" SignificantBits="12"',
4215
'<Channel ID="Channel:0:0" SamplesPerPixel="3" Name="ChannelName">',
4216
'<Plane TheC="0" TheZ="2" TheT="1" PositionZ="4.0"/>',
4217
'<StructuredAnnotations><XMLAnnotation ID="Annotation:0" Namespace',
4218
'<ModuloAlongT Type="other" TypeDescription="Phasor" '
4219
'Start="0" End="1"/>',
4220
'<CommentAnnotation ID="Annotation:1">'
4221
'<Value>Tifffile test</Value></CommentAnnotation>',
4222
'<BooleanAnnotation ID="Annotation:2">'
4223
'<Value>true</Value></BooleanAnnotation>',
4224
'<LongAnnotation ID="Annotation:3"><Value>1</Value></LongAnnotation>'
4225
'<LongAnnotation ID="Annotation:4"><Value>2</Value>',
4226
'<DoubleAnnotation ID="Annotation:5">'
4227
'<Description>A double</Description>'
4228
'<Value>1.0</Value></DoubleAnnotation>',
4229
'<MapAnnotation ID="Annotation:6">'
4230
'<Description>description</Description>'
4231
'<Value><M K="key"><str/></M><M K="key2">1.0</M></Value>'
4233
'<MapAnnotation ID="Annotation:7" Namespace="ns.org">'
4234
'<Value><M K="key2">1</M><M K="key3">2</M></Value></MapAnnotation>',
4238
pytest.xfail('lxml bug?')
4239
assert__repr__(omexml)
4240
assert_valid_omexml(xml)
4241
assert '\n ' in str(omexml)
4243
with TempFileName('class_omexml_attributes') as fname:
4246
shape=(2, 3, 32, 32, 3),
4252
assert imread(fname).shape == (2, 3, 32, 32, 3)
4255
def test_class_omexml_datasets():
4256
"""Test OmeXml class with datasets."""
4257
args = numpy.uint8, (3, 7), (1, 1, 1, 3, 7, 1)
4258
kwargs = {'dtype': numpy.uint8, 'shape': (3, 7)}
4262
omexml.addimage(*args, CommentAnnotation='0')
4263
# first dataset explicit
4268
'Description': 'Dataset',
4269
'CommentAnnotation': '1',
4272
# first dataset implicit
4273
omexml.addimage(*args, CommentAnnotation='2')
4275
omexml.addimage(*args, Dataset=None, CommentAnnotation='3')
4276
# first dataset implicit
4277
omexml.addimage(*args, CommentAnnotation='4')
4278
# second dataset explicit
4279
omexml.addimage(*args, Dataset={'CommentAnnotation': '5'})
4281
xml = omexml.tostring()
4283
'<Dataset ID="Dataset:0" Name="First">'
4284
'<Description>Dataset</Description>'
4285
'<ImageRef ID="Image:1"/>'
4286
'<ImageRef ID="Image:2"/>'
4287
'<ImageRef ID="Image:4"/>'
4288
'<AnnotationRef ID="Annotation:1"/>'
4290
'<Dataset ID="Dataset:1">'
4291
'<ImageRef ID="Image:5"/>'
4292
'<AnnotationRef ID="Annotation:5"/>'
4294
'<AnnotationRef ID="Annotation:4"/></Image>'
4295
'<Image ID="Image:5" Name="Image5">',
4299
pytest.xfail('lxml bug?')
4300
assert__repr__(omexml)
4301
assert_valid_omexml(xml)
4302
assert '\n ' in str(omexml)
4304
with TempFileName('class_omexml_datasets') as fname:
4305
with TiffWriter(fname, ome=True) as tif:
4306
tif.write(**kwargs, metadata={'CommentAnnotation': '0'})
4312
'Description': 'Dataset',
4313
'CommentAnnotation': '1',
4317
tif.write(**kwargs, metadata={'CommentAnnotation': '2'})
4319
**kwargs, metadata={'Dataset': None, 'CommentAnnotation': '3'}
4321
tif.write(**kwargs, metadata={'CommentAnnotation': '4'})
4323
**kwargs, metadata={'Dataset': {'CommentAnnotation': '5'}}
4326
with TiffFile(fname) as tif:
4327
assert len(tif.series) == 6
4330
def test_class_omexml_multiimage():
4331
"""Test OmeXml class with multiple images."""
4332
omexml = OmeXml(description='multiimage')
4334
numpy.uint8, (32, 32, 3), (1, 1, 1, 32, 32, 3), name='preview'
4337
numpy.float32, (4, 256, 256), (4, 1, 1, 256, 256, 1), name='1'
4339
omexml.addimage('bool', (256, 256), (1, 1, 1, 256, 256, 1), name='mask')
4340
assert '\n ' in str(omexml)
4341
omexml = omexml.tostring()
4342
assert 'TiffData IFD="0" PlaneCount="1"' in omexml
4343
assert 'TiffData IFD="1" PlaneCount="4"' in omexml
4344
assert 'TiffData IFD="5" PlaneCount="1"' in omexml
4345
assert_valid_omexml(omexml)
4348
def test_class_timer(capsys):
4349
"""Test Timer class."""
4350
started = Timer.clock()
4351
with Timer('test_class_timer', started=started) as timer:
4352
assert timer.started == started
4353
captured = capsys.readouterr()
4354
assert captured.out == 'test_class_timer '
4355
duration = timer.stop()
4356
assert timer.duration == duration
4357
assert timer.stopped == started + duration
4358
timer.duration = 314159.265359
4359
assert__repr__(timer)
4360
captured = capsys.readouterr()
4361
assert captured.out == '3 days, 15:15:59.265359 s\n'
4364
def test_func_xml2dict():
4365
"""Test xml2dict function."""
4366
xml = """<?xml version="1.0" ?>
4367
<root attr="attribute">
4370
<float>-3.14</float>
4371
<floats>1.0, -2.0</floats>
4373
<string>Lorem, Ipsum</string>
4376
d = xml2dict(xml)['root']
4377
assert d['attr'] == 'attribute'
4378
assert d['int'] == -1
4379
assert d['ints'] == (-1, 2)
4380
assert d['float'] == -3.14
4381
assert d['floats'] == (1.0, -2.0)
4382
assert d['bool'] is True
4383
assert d['string'] == 'Lorem, Ipsum'
4385
d = xml2dict(xml, prefix=('a_', 'b_'), sep='')['root']
4386
assert d['ints'] == '-1,2'
4387
assert d['floats'] == '1.0, -2.0'
4390
def test_func_memmap():
4391
"""Test memmap function."""
4392
with TempFileName('func_memmap_new') as fname:
4397
dtype=numpy.float32,
4403
assert im.shape == (32, 16)
4404
assert im.dtype == numpy.float32
4406
im = memmap(fname, page=0, mode='r')
4407
assert im[31, 15] == 1.0
4409
im = memmap(fname, series=0, mode='c')
4410
assert im[31, 15] == 1.0
4418
photometric=PHOTOMETRIC.MINISBLACK,
4422
assert im.shape == (3, 64, 64)
4423
assert im.dtype == numpy.uint16
4425
im = memmap(fname, page=3, mode='r')
4426
assert im[63, 63] == 1
4428
im = memmap(fname, series=1, mode='c')
4429
assert im[2, 63, 63] == 1
4431
# can not memory-map compressed array
4432
with pytest.raises(ValueError):
4436
dtype=numpy.float32,
4438
compression=COMPRESSION.ADOBE_DEFLATE,
4442
@pytest.mark.skipif(IS_BE, reason=REASON)
4443
@pytest.mark.parametrize('byteorder', ['>', '<'])
4444
def test_func_memmap_byteorder(byteorder):
4445
"""Test non-native byteorder can be memory mapped."""
4446
bo = {'<': 'le', '>': 'be'}[byteorder]
4448
with TempFileName(f'func_memmap_byteorder_{bo}') as fname:
4449
if os.path.exists(fname):
4454
fname, shape=(16, 16), dtype=numpy.uint16, byteorder=byteorder
4456
assert im.dtype.byteorder == byteorder
4461
with TiffFile(fname) as tif:
4462
assert tif.byteorder == byteorder
4464
assert im.dtype.byteorder in {'<', '='} # native
4465
assert im[0, 0] == 253
4466
assert im[1, 1] == 257
4468
im = memmap(fname, mode='r')
4469
assert im.dtype.byteorder == '=' if byteorder == '<' else '>'
4470
assert im[0, 0] == 253
4471
assert im[1, 1] == 257
4475
def test_func_repeat_nd():
4476
"""Test repeat_nd function."""
4477
a = repeat_nd([[0, 1, 2], [3, 4, 5], [6, 7, 8]], (2, 3))
4481
[0, 0, 0, 1, 1, 1, 2, 2, 2],
4482
[0, 0, 0, 1, 1, 1, 2, 2, 2],
4483
[3, 3, 3, 4, 4, 4, 5, 5, 5],
4484
[3, 3, 3, 4, 4, 4, 5, 5, 5],
4485
[6, 6, 6, 7, 7, 7, 8, 8, 8],
4486
[6, 6, 6, 7, 7, 7, 8, 8, 8],
4491
def test_func_byteorder_isnative():
4492
"""Test byteorder_isnative function."""
4493
assert byteorder_isnative(sys.byteorder)
4494
assert byteorder_isnative('=')
4495
if sys.byteorder == 'little':
4496
assert byteorder_isnative('<')
4497
assert not byteorder_isnative('>')
4499
assert byteorder_isnative('>')
4500
assert not byteorder_isnative('<')
4503
def test_func_byteorder_compare():
4504
"""Test byteorder_isnative function."""
4505
assert byteorder_compare('<', '<')
4506
assert byteorder_compare('>', '>')
4507
assert byteorder_compare('=', '=')
4508
assert byteorder_compare('|', '|')
4509
assert byteorder_compare('>', '|')
4510
assert byteorder_compare('<', '|')
4511
assert byteorder_compare('|', '>')
4512
assert byteorder_compare('|', '<')
4513
assert byteorder_compare('=', '|')
4514
assert byteorder_compare('|', '=')
4515
if sys.byteorder == 'little':
4516
assert byteorder_compare('<', '=')
4518
assert byteorder_compare('>', '=')
4521
def test_func_reshape_nd():
4522
"""Test reshape_nd function."""
4523
assert reshape_nd(numpy.empty(0), 2).shape == (1, 0)
4524
assert reshape_nd(numpy.empty(1), 3).shape == (1, 1, 1)
4525
assert reshape_nd(numpy.empty((2, 3)), 3).shape == (1, 2, 3)
4526
assert reshape_nd(numpy.empty((2, 3, 4)), 3).shape == (2, 3, 4)
4528
assert reshape_nd((0,), 2) == (1, 0)
4529
assert reshape_nd((1,), 3) == (1, 1, 1)
4530
assert reshape_nd((2, 3), 3) == (1, 2, 3)
4531
assert reshape_nd((2, 3, 4), 3) == (2, 3, 4)
4534
def test_func_order_axes():
4535
axes = [(0, 2, 0), (1, 2, 0), (0, 2, 1), (1, 2, 1)]
4536
# first axis varies fastest, second axis is constant
4537
assert order_axes(axes, True) == (2, 0)
4538
assert order_axes(axes, False) == (1, 2, 0)
4541
def test_func_apply_colormap():
4542
"""Test apply_colormap function."""
4543
image = numpy.arange(256, dtype=numpy.uint8)
4544
colormap = numpy.vstack([image, image, image]).astype(numpy.uint16) * 256
4545
assert_array_equal(apply_colormap(image, colormap)[-1], colormap[:, -1])
4548
def test_func_parse_filenames():
4549
"""Test parse_filenames function."""
4551
def func(*args, **kwargs):
4552
labels, shape, indices, _ = parse_filenames(*args, **kwargs)
4553
return ''.join(labels), shape, indices
4555
files = ['c1t001.ext', 'c1t002.ext', 'c2t002.ext'] # 'c2t001.ext' missing
4557
p = r'(?P<a>\d).[!\d](?P<b>\d+)\.ext'
4558
assert func(files[:1], p) == ('ab', (1, 1), [(0, 0)]) # (1, 1)
4559
assert func(files[:2], p) == ('ab', (1, 2), [(0, 0), (0, 1)]) # (1, 1)
4560
assert func(files, p) == ('ab', (2, 2), [(0, 0), (0, 1), (1, 1)]) # (1, 1)
4562
p = r'(\d)[^\d](\d+)\.ext'
4563
assert func(files[:1], p) == ('QQ', (1, 1), [(0, 0)]) # (1, 1)
4564
assert func(files[:2], p) == ('QQ', (1, 2), [(0, 0), (0, 1)]) # (1, 1)
4565
assert func(files, p) == ('QQ', (2, 2), [(0, 0), (0, 1), (1, 1)]) # (1, 1)
4567
p = r'([^\d])(\d)([^\d])(\d+)\.ext'
4568
assert func(files[:1], p) == ('ct', (1, 1), [(0, 0)]) # (1, 1)
4569
assert func(files[:2], p) == ('ct', (1, 2), [(0, 0), (0, 1)]) # (1, 1)
4570
assert func(files, p) == ('ct', (2, 2), [(0, 0), (0, 1), (1, 1)]) # (1, 1)
4572
files = ['c0t001.ext', 'c0t002.ext', 'c2t002.ext'] # 'c2t001.ext' missing
4573
p = r'([^\d])(\d)[^\d](?P<b>\d+)\.ext'
4574
assert func(files[:1], p) == ('cb', (1, 1), [(0, 0)]) # (0, 1)
4575
assert func(files[:2], p) == ('cb', (1, 2), [(0, 0), (0, 1)]) # (0, 1)
4576
assert func(files, p) == ('cb', (3, 2), [(0, 0), (0, 1), (2, 1)]) # (0, 1)
4579
categories = {'p': {chr(i + 97): i for i in range(25)}}
4581
'BBBC006_v1_images_z_00/mcf-z-stacks-03212011_a01_s1_w1a57.tif',
4582
'BBBC006_v1_images_z_00/mcf-z-stacks-03212011_a03_s2_w1419.tif',
4583
'BBBC006_v1_images_z_00/mcf-z-stacks-03212011_p24_s2_w2283.tif',
4584
'BBBC006_v1_images_z_01/mcf-z-stacks-03212011_p24_s2_w11cf.tif',
4586
# don't match directory
4587
p = r'_(?P<p>[a-z])(?P<a>\d+)(?:_(s)(\d))(?:_(w)(\d))'
4588
assert func(files[:1], p, categories=categories) == (
4594
assert func(files[:2], p, categories=categories) == (
4597
[(0, 0, 0, 0), (0, 2, 1, 0)],
4601
p = r'(?:_(z)_(\d+)).*_(?P<p>[a-z])(?P<a>\d+)(?:_(s)(\d))(?:_(w)(\d))'
4602
assert func(files, p, categories=categories) == (
4614
p = r'(?:_(z)_(\d+)).*_(?P<p>[a-z])(?P<a>\d+)(?:_(s)(\d))(?:_(w)(\d))'
4616
files, p, axesorder=(2, 0, 1, 3, 4), categories=categories
4630
def test_func_reshape_axes():
4631
"""Test reshape_axes function."""
4632
assert reshape_axes('YXS', (219, 301, 1), (219, 301, 1)) == 'YXS'
4633
assert reshape_axes('YXS', (219, 301, 3), (219, 301, 3)) == 'YXS'
4634
assert reshape_axes('YXS', (219, 301, 1), (219, 301)) == 'YX'
4635
assert reshape_axes('YXS', (219, 301, 1), (219, 1, 1, 301, 1)) == 'YQQXS'
4636
assert reshape_axes('IYX', (12, 219, 301), (3, 4, 219, 301, 1)) == 'QQYXQ'
4638
reshape_axes('IYX', (12, 219, 301), (3, 4, 219, 1, 301, 1)) == 'QQYQXQ'
4641
reshape_axes('IYX', (12, 219, 301), (3, 2, 219, 2, 301, 1)) == 'QQQQXQ'
4643
with pytest.raises(ValueError):
4644
reshape_axes('IYX', (12, 219, 301), (3, 4, 219, 2, 301, 1))
4645
with pytest.raises(ValueError):
4646
reshape_axes('IYX', (12, 219, 301), (3, 4, 219, 301, 2))
4649
def test_func_julian_datetime():
4650
"""Test julian_datetime function."""
4651
assert julian_datetime(2451576, 54362783) == (
4652
datetime.datetime(2000, 2, 2, 15, 6, 2, 783)
4656
def test_func_excel_datetime():
4657
"""Test excel_datetime function."""
4658
assert excel_datetime(40237.029999999795) == (
4659
datetime.datetime(2010, 2, 28, 0, 43, 11, 999982)
4663
def test_func_natural_sorted():
4664
"""Test natural_sorted function."""
4665
assert natural_sorted(['f1', 'f2', 'f10']) == ['f1', 'f2', 'f10']
4668
def test_func_stripnull():
4669
"""Test stripnull function."""
4670
assert stripnull(b'string\x00') == b'string'
4671
assert stripnull('string\x00', null='\0') == 'string'
4673
stripnull(b'string\x00string\x00\x00', first=False)
4674
== b'string\x00string'
4677
stripnull('string\x00string\x00\x00', null='\0', first=False)
4678
== 'string\x00string'
4682
def test_func_stripascii():
4683
"""Test stripascii function."""
4684
assert stripascii(b'string\x00string\n\x01\x00') == b'string\x00string\n'
4685
assert stripascii(b'\x00') == b''
4688
def test_func_sequence():
4689
"""Test sequence function."""
4690
assert sequence(1) == (1,)
4691
assert sequence([1]) == [1]
4694
def test_func_product():
4695
"""Test product function."""
4696
assert product([2**8, 2**30]) == 274877906944
4697
assert product([]) == 1
4698
assert product(numpy.array([2**8, 2**30], numpy.int32)) == 274877906944
4701
def test_func_squeeze_axes():
4702
"""Test squeeze_axes function."""
4703
assert squeeze_axes((5, 1, 2, 1, 1), 'TZYXC') == (
4706
(True, False, True, True, False),
4708
assert squeeze_axes((1,), 'Y') == ((1,), 'Y', (True,))
4709
assert squeeze_axes((1,), 'Q') == ((1,), 'Q', (True,))
4710
assert squeeze_axes((1, 1), 'PQ') == ((1,), 'Q', (False, True))
4713
def test_func_transpose_axes():
4714
"""Test transpose_axes function."""
4715
assert transpose_axes(
4716
numpy.zeros((2, 3, 4, 5)), 'TYXC', asaxes='CTZYX'
4717
).shape == (5, 2, 1, 3, 4)
4720
def test_func_subresolution():
4721
"""Test subresolution function."""
4726
shape = (3, 256, 512, 1024, 4)
4731
shape = (3, 128, 256, 512, 4)
4733
assert subresolution(a, a) == 0
4734
assert subresolution(a, b) == 1
4735
assert subresolution(a, b, p=2, n=2) == 1
4736
assert subresolution(a, b, p=3) is None
4737
b.shape = (3, 86, 171, 342, 4)
4738
assert subresolution(a, b, p=3) == 1
4739
b.shape = (3, 128, 256, 512, 2)
4740
assert subresolution(a, b) is None
4741
b.shape = (3, 64, 256, 512, 4)
4742
assert subresolution(a, b) is None
4743
b.shape = (3, 128, 64, 512, 4)
4744
assert subresolution(a, b) is None
4745
b.shape = (3, 128, 256, 1024, 4)
4746
assert subresolution(a, b) is None
4747
b.shape = (3, 32, 64, 128, 4)
4748
assert subresolution(a, b) == 3
4751
@pytest.mark.skipif(IS_BE, reason=REASON)
4752
def test_func_unpack_rgb():
4753
"""Test unpack_rgb function."""
4754
data = struct.pack('BBBB', 0x21, 0x08, 0xFF, 0xFF)
4756
unpack_rgb(data, '<B', (5, 6, 5), False), [1, 1, 1, 31, 63, 31]
4759
unpack_rgb(data, '<B', (5, 6, 5)), [8, 4, 8, 255, 255, 255]
4762
unpack_rgb(data, '<B', (5, 5, 5)), [16, 8, 8, 255, 255, 255]
4766
def test_func_shaped_description():
4767
"""Test shaped_description function."""
4768
descr = shaped_description((256, 256, 3), axes='YXS')
4769
assert json.loads(descr) == {'shape': [256, 256, 3], 'axes': 'YXS'}
4772
def test_func_shaped_description_metadata():
4773
"""Test shaped_description_metadata function."""
4774
assert shaped_description_metadata('shape=(256, 256, 3)') == {
4775
'shape': (256, 256, 3)
4777
assert shaped_description_metadata(
4778
'{"shape": [256, 256, 3], "axes": "YXS"}'
4779
) == {'shape': [256, 256, 3], 'axes': 'YXS'}
4782
def test_func_imagej_shape():
4783
"""Test imagej_shape function."""
4785
((1, None), (1, 1, 1, 1, 1, 1)),
4786
((3, None), (1, 1, 1, 1, 3, 1)),
4787
((4, 3, None), (1, 1, 1, 4, 3, 1)),
4788
((4, 3, True), (1, 1, 1, 1, 4, 3)),
4789
((4, 4, None), (1, 1, 1, 4, 4, 1)),
4790
((4, 4, True), (1, 1, 1, 1, 4, 4)),
4791
((4, 3, 1, None), (1, 1, 1, 4, 3, 1)),
4792
((4, 3, 2, None), (1, 1, 4, 3, 2, 1)),
4793
((4, 3, 3, None), (1, 1, 1, 4, 3, 3)),
4794
((4, 3, 4, None), (1, 1, 1, 4, 3, 4)),
4795
((4, 3, 4, True), (1, 1, 1, 4, 3, 4)),
4796
((4, 3, 4, False), (1, 1, 4, 3, 4, 1)),
4797
((4, 3, 5, None), (1, 1, 4, 3, 5, 1)),
4798
((3, 2, 1, 5, 4, None), (1, 3, 2, 1, 5, 4)),
4799
((3, 2, 1, 4, 5, None), (3, 2, 1, 4, 5, 1)),
4800
((1, 2, 3, 4, 5, None), (1, 2, 3, 4, 5, 1)),
4801
((2, 3, 4, 5, 3, None), (1, 2, 3, 4, 5, 3)),
4802
((2, 3, 4, 5, 3, True), (1, 2, 3, 4, 5, 3)),
4803
((2, 3, 4, 5, 3, False), (2, 3, 4, 5, 3, 1)),
4804
((1, 2, 3, 4, 5, 4, None), (1, 2, 3, 4, 5, 4)),
4805
((6, 5, 4, 3, 2, 1, None), (6, 5, 4, 3, 2, 1)),
4807
assert imagej_shape(k[:-1], rgb=k[-1]) == v
4810
def test_func_imagej_description():
4811
"""Test imagej_description function."""
4813
'ImageJ=1.11a\nimages=510\nchannels=2\nslices=5\n'
4814
'frames=51\nhyperstack=true\nmode=grayscale\nloop=false\n'
4816
assert imagej_description((51, 5, 2, 196, 171)) == expected
4817
assert imagej_description((51, 5, 2, 196, 171), axes='TZCYX') == expected
4819
'ImageJ=1.11a\nimages=2\nslices=2\nhyperstack=true\nmode=grayscale\n'
4821
assert imagej_description((1, 2, 1, 196, 171)) == expected
4822
assert imagej_description((2, 196, 171), axes='ZYX') == expected
4823
expected = 'ImageJ=1.11a\nimages=1\nhyperstack=true\nmode=grayscale\n'
4824
assert imagej_description((196, 171)) == expected
4825
assert imagej_description((196, 171), axes='YX') == expected
4826
expected = 'ImageJ=1.11a\nimages=1\nhyperstack=true\n'
4827
assert imagej_description((196, 171, 3)) == expected
4828
assert imagej_description((196, 171, 3), axes='YXS') == expected
4830
with pytest.raises(ValueError):
4831
imagej_description((196, 171, 3), axes='TYXS')
4832
with pytest.raises(ValueError):
4833
imagej_description((196, 171, 2), axes='TYXS')
4834
with pytest.raises(ValueError):
4835
imagej_description((3, 196, 171, 3), axes='ZTYX')
4838
def test_func_imagej_description_metadata():
4839
"""Test imagej_description_metadata function."""
4841
'ImageJ=1.11a\nimages=510\nchannels=2\nslices=5\n'
4842
'frames=51\nhyperstack=true\nmode=grayscale\nloop=false\n'
4851
'mode': 'grayscale',
4854
assert imagej_description_metadata(imagej_str) == imagej_dict
4857
def test_func_pilatus_header_metadata():
4858
"""Test pilatus_description_metadata function."""
4860
# Detector: PILATUS 300K, 3-0101
4861
# 2011-07-22T17:33:22.529
4862
# Pixel_size 172e-6 m x 172e-6 m
4863
# Silicon sensor, thickness 0.000320 m
4864
# Exposure_time 0.0970000 s
4865
# Exposure_period 0.1000000 s
4867
# Count_cutoff 126367 counts
4868
# Threshold_setting: not set
4869
# Gain_setting: high gain (vrf = -0.150)
4870
# N_excluded_pixels = 19
4871
# Excluded_pixels: badpix_mask.tif
4873
# Trim_file: p300k0101_E8048_T4024_vrf_m0p15.bin
4874
# Beam_xy (243.12, 309.12) pixels
4875
# Image_path: /ramdisk/
4877
# Unknown 1 2 3 4 5""".strip().replace(
4880
attr = pilatus_description_metadata(header)
4881
assert attr['Detector'] == 'PILATUS 300K 3-0101'
4882
assert attr['Pixel_size'] == (0.000172, 0.000172)
4883
assert attr['Silicon'] == 0.000320
4884
# self.assertEqual(attr['Threshold_setting'], float('nan'))
4885
assert attr['Beam_xy'] == (243.12, 309.12)
4886
assert attr['Unknown'] == '1 2 3 4 5'
4889
def test_func_astrotiff_description_metadata(caplog):
4890
"""Test astrotiff_description_metadata function."""
4892
astrotiff_description_metadata(
4894
SIMPLE = T / file does conform to FITS standard
4895
COMMENT 1 First comment.
4897
STRING = 'a string' / string
4898
STRING1 = '' / null string
4899
STRING2 = ' ' / empty string
4900
STRING3 = ' string with / .' / comment with / . and leading whitespace
4901
STRING4 = 'string longer than 30 characters' / long string
4902
COMMENT 2 Second comment, longer than 30 characters.
4903
COMMENT 3 Third comment with /.
4908
FLOAT = 123.456789123456789 / Float
4909
FLOAT2 = 123. / Float
4910
FLOAT3 = -123.4564890000E-001 / Scientific
4911
CINT = (123, 45) / Complex integer
4912
CFLT = (23.23, -45.7) / Complex float
4913
JD = 2457388.4562152778 / Julian date cannot be represented as float ?
4914
UNIT = 123 / [unit] comment
4915
CUSTOM = '+12 34 56' / [+dd mm ss] custom unit
4918
INVALID1= None / invalid value
4919
INVALID2= ' / invalid string
4925
'SIMPLE:COMMENT': 'file does conform to FITS standard',
4926
'COMMENT:0': '1 First comment.',
4928
'UNDEF:COMMENT': 'undefined',
4929
'STRING': 'a string',
4930
'STRING:COMMENT': 'string',
4932
'STRING1:COMMENT': 'null string',
4934
'STRING2:COMMENT': 'empty string',
4935
'STRING3': ' string with / .',
4936
'STRING3:COMMENT': 'comment with / . and leading whitespace',
4937
'STRING4': 'string longer than 30 characters',
4938
'STRING4:COMMENT': 'long string',
4939
'COMMENT:1': '2 Second comment, longer than 30 characters.',
4940
'COMMENT:2': '3 Third comment with /.',
4943
'TRUE:COMMENT': 'True',
4945
'FALSE:COMMENT': 'False',
4947
'INT:COMMENT': 'Integer',
4948
'FLOAT': 123.45678912345679,
4949
'FLOAT:COMMENT': 'Float',
4951
'FLOAT2:COMMENT': 'Float',
4952
'FLOAT3': -12.3456489,
4953
'FLOAT3:COMMENT': 'Scientific',
4955
'CINT:COMMENT': 'Complex integer',
4956
'CFLT': (23.23, -45.7),
4957
'CFLT:COMMENT': 'Complex float',
4958
'JD': 2457388.456215278,
4959
'JD:COMMENT': 'Julian date cannot be represented as float ?',
4961
'UNIT:COMMENT': '[unit] comment',
4962
'UNIT:UNIT': 'unit',
4963
'CUSTOM': '+12 34 56',
4964
'CUSTOM:COMMENT': '[+dd mm ss] custom unit',
4965
'CUSTOM:UNIT': '+dd mm ss',
4970
assert 'DUPLICAT: duplicate key' in caplog.text
4971
assert 'INVALID1: invalid value' in caplog.text
4972
assert 'INVALID2: invalid string' in caplog.text
4975
def test_func_matlabstr2py():
4976
"""Test matlabstr2py function."""
4977
assert matlabstr2py('1') == 1
4978
assert matlabstr2py(
4979
"['x y z' true false; 1 2.0 -3e4; Inf Inf @class;[1;2;3][1 2] 3]"
4981
['x y z', True, False],
4983
[float('inf'), float('inf'), '@class'],
4984
[[[1], [2], [3]], [1, 2], 3],
4987
assert matlabstr2py(
4988
"SI.hChannels.channelType = {'stripe' 'stripe'}\n"
4989
"SI.hChannels.channelsActive = 2"
4990
)['SI.hChannels.channelType'] == ['stripe', 'stripe']
5005
String.Array = ['ab']
5009
Transform = [1 0 0;0 1 0;0 0 1]
5011
Zeros.Empty = zeros(1,0)
5013
Filename = C:\\Users\\scanimage.cfg
5016
StructObject = <nonscalar struct/object>
5022
assert p['Array'] == [1, 2]
5023
assert p['Array.2D'] == [[1], [2]]
5024
assert p['Array.Empty'] == []
5025
assert p['Cell'] == ['', '']
5026
assert p['Class'] == '@class'
5027
assert p['False'] is False
5028
assert p['Filename'] == 'C:\\Users\\scanimage.cfg'
5029
assert p['Float'] == 3.14
5030
assert p['Float.E'] == 3.14
5031
assert p['Float.Inf'] == float('inf')
5032
# self.assertEqual(p['Float.NaN'], float('nan')) # can't compare NaN
5033
assert p['Int'] == 10
5034
assert p['StructObject'] == '<nonscalar struct/object>'
5035
assert p['Ones'] == [[]]
5036
assert p['String'] == 'string'
5037
assert p['String.Array'] == 'ab'
5038
assert p['String.Empty'] == ''
5039
assert p['Transform'] == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
5040
assert p['True'] is True
5041
assert p['Unknown'] == 'unknown'
5042
assert p['Zeros'] == [[0.0]]
5043
assert p['Zeros.Empty'] == [[]]
5044
assert p['false'] is False
5045
assert p['true'] is True
5048
def test_func_strptime():
5049
"""Test strptime function."""
5050
now = datetime.datetime.now().replace(microsecond=0)
5051
assert strptime(now.isoformat()) == now
5052
assert strptime(now.strftime('%Y:%m:%d %H:%M:%S')) == now
5053
assert strptime(now.strftime('%Y%m%d %H:%M:%S.%f')) == now
5056
def test_func_hexdump():
5057
"""Test hexdump function."""
5058
# test hexdump function
5059
data = binascii.unhexlify(
5060
'49492a00080000000e00fe0004000100'
5061
'00000000000000010400010000000001'
5062
'00000101040001000000000100000201'
5063
'030001000000200000000301030001'
5066
assert hexdump(data[:16]) == (
5067
'49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 II*.............'
5070
assert hexdump(data, width=64, height=1) == (
5071
'49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 II*.............'
5074
assert hexdump(data) == (
5075
'00: 49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 '
5076
'II*.............\n'
5077
'10: 00 00 00 00 00 00 00 01 04 00 01 00 00 00 00 01 '
5078
'................\n'
5079
'20: 00 00 01 01 04 00 01 00 00 00 00 01 00 00 02 01 '
5080
'................\n'
5081
'30: 03 00 01 00 00 00 20 00 00 00 03 01 03 00 01 '
5085
assert hexdump(data, height=3, snipat=0.5) == (
5086
'00: 49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 '
5087
'II*.............\n'
5089
'30: 03 00 01 00 00 00 20 00 00 00 03 01 03 00 01 '
5093
assert hexdump(data, height=3, snipat=0) == (
5094
'10: 00 00 00 00 00 00 00 01 04 00 01 00 00 00 00 01 '
5095
'................\n'
5096
'20: 00 00 01 01 04 00 01 00 00 00 00 01 00 00 02 01 '
5097
'................\n'
5098
'30: 03 00 01 00 00 00 20 00 00 00 03 01 03 00 01 '
5102
assert hexdump(data, height=3, snipat=1) == (
5103
'00: 49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 '
5104
'II*.............\n'
5105
'10: 00 00 00 00 00 00 00 01 04 00 01 00 00 00 00 01 '
5106
'................\n'
5107
'20: 00 00 01 01 04 00 01 00 00 00 00 01 00 00 02 01 '
5112
def test_func_asbool():
5113
"""Test asbool function."""
5114
for true in ('TRUE', ' True ', 'true '):
5116
assert asbool(true.encode())
5117
for false in ('FALSE', ' False ', 'false '):
5118
assert not asbool(false)
5119
assert not asbool(false.encode())
5120
assert asbool('ON', ['on'], ['off'])
5121
assert asbool('ON', 'on', 'off')
5122
with pytest.raises(TypeError):
5123
assert asbool('Yes')
5124
with pytest.raises(TypeError):
5125
assert asbool('True', ['on'], ['off'])
5128
def test_func_snipstr():
5129
"""Test snipstr function."""
5131
assert snipstr('abc', 3, ellipsis='...') == 'abc'
5132
assert snipstr('abc', 3, ellipsis='....') == 'abc'
5133
assert snipstr('abcdefg', 4, ellipsis='') == 'abcd'
5134
assert snipstr('abcdefg', 4, ellipsis=None) == 'abc…'
5135
assert snipstr(b'abcdefg', 4, ellipsis=None) == b'a...'
5136
assert snipstr('abcdefghijklmnop', 8, ellipsis=None) == 'abcd…nop'
5137
assert snipstr(b'abcdefghijklmnop', 8, ellipsis=None) == b'abc...op'
5138
assert snipstr('abcdefghijklmnop', 9, ellipsis=None) == 'abcd…mnop'
5139
assert snipstr(b'abcdefghijklmnop', 9, ellipsis=None) == b'abc...nop'
5140
assert snipstr('abcdefghijklmnop', 8, ellipsis='..') == 'abc..nop'
5141
assert snipstr('abcdefghijklmnop', 8, ellipsis='....') == 'ab....op'
5142
assert snipstr('abcdefghijklmnop', 8, ellipsis='......') == 'ab......'
5144
assert snipstr('abc', 3, snipat=1, ellipsis='...') == 'abc'
5145
assert snipstr('abc', 3, snipat=1, ellipsis='....') == 'abc'
5146
assert snipstr('abcdefg', 4, snipat=1, ellipsis='') == 'abcd'
5147
assert snipstr('abcdefg', 4, snipat=1, ellipsis=None) == 'abc…'
5148
assert snipstr(b'abcdefg', 4, snipat=1, ellipsis=None) == b'a...'
5150
snipstr('abcdefghijklmnop', 8, snipat=1, ellipsis=None) == 'abcdefg…'
5153
snipstr(b'abcdefghijklmnop', 8, snipat=1, ellipsis=None) == b'abcde...'
5156
snipstr('abcdefghijklmnop', 9, snipat=1, ellipsis=None) == 'abcdefgh…'
5159
snipstr(b'abcdefghijklmnop', 9, snipat=1, ellipsis=None)
5163
snipstr('abcdefghijklmnop', 8, snipat=1, ellipsis='..') == 'abcdef..'
5166
snipstr('abcdefghijklmnop', 8, snipat=1, ellipsis='....') == 'abcd....'
5169
snipstr('abcdefghijklmnop', 8, snipat=1, ellipsis='......')
5173
assert snipstr('abc', 3, snipat=0, ellipsis='...') == 'abc'
5174
assert snipstr('abc', 3, snipat=0, ellipsis='....') == 'abc'
5175
assert snipstr('abcdefg', 4, snipat=0, ellipsis='') == 'defg'
5176
assert snipstr('abcdefg', 4, snipat=0, ellipsis=None) == '…efg'
5177
assert snipstr(b'abcdefg', 4, snipat=0, ellipsis=None) == b'...g'
5179
snipstr('abcdefghijklmnop', 8, snipat=0, ellipsis=None) == '…jklmnop'
5182
snipstr(b'abcdefghijklmnop', 8, snipat=0, ellipsis=None) == b'...lmnop'
5185
snipstr('abcdefghijklmnop', 9, snipat=0, ellipsis=None) == '…ijklmnop'
5188
snipstr(b'abcdefghijklmnop', 9, snipat=0, ellipsis=None)
5192
snipstr('abcdefghijklmnop', 8, snipat=0, ellipsis='..') == '..klmnop'
5195
snipstr('abcdefghijklmnop', 8, snipat=0, ellipsis='....') == '....mnop'
5198
snipstr('abcdefghijklmnop', 8, snipat=0, ellipsis='......')
5203
def test_func_pformat_printable_bytes():
5204
"""Test pformat function with printable bytes."""
5206
b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST'
5207
b'UVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
5210
assert pformat(value, height=1, width=60, linewidth=None) == (
5211
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX'
5215
pformat(value, height=8, width=60, linewidth=None)
5217
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX
5220
# YZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
5223
def test_func_pformat_printable_unicode():
5224
"""Test pformat function with printable unicode."""
5226
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST'
5227
'UVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
5230
assert pformat(value, height=1, width=60, linewidth=None) == (
5231
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX'
5235
pformat(value, height=8, width=60, linewidth=None)
5237
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX
5240
# YZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
5243
def test_func_pformat_hexdump():
5244
"""Test pformat function with unprintable bytes."""
5245
value = binascii.unhexlify(
5246
'49492a00080000000e00fe0004000100'
5247
'00000000000000010400010000000001'
5248
'00000101040001000000000100000201'
5249
'03000100000020000000030103000100'
5252
assert pformat(value, height=1, width=60, linewidth=None) == (
5253
'49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 II*............'
5257
pformat(value, height=8, width=70, linewidth=None)
5259
00: 49 49 2a 00 08 00 00 00 0e 00 fe 00 04 00 01 00 II*.............
5260
10: 00 00 00 00 00 00 00 01 04 00 01 00 00 00 00 01 ................
5261
20: 00 00 01 01 04 00 01 00 00 00 00 01 00 00 02 01 ................
5262
30: 03 00 01 00 00 00 20 00 00 00 03 01 03 00 01 00 ...... .........
5267
def test_func_pformat_dict():
5268
"""Test pformat function with dict."""
5270
'GTCitationGeoKey': 'WGS 84 / UTM zone 29N',
5271
'GTModelTypeGeoKey': 1,
5272
'GTRasterTypeGeoKey': 1,
5273
'KeyDirectoryVersion': 1,
5275
'KeyRevisionMinor': 2,
5276
'ModelTransformation': numpy.array(
5278
[6.00000e01, 0.00000e00, 0.00000e00, 6.00000e05],
5279
[0.00000e00, -6.00000e01, 0.00000e00, 5.90004e06],
5280
[0.00000e00, 0.00000e00, 0.00000e00, 0.00000e00],
5281
[0.00000e00, 0.00000e00, 0.00000e00, 1.00000e00],
5284
'PCSCitationGeoKey': 'WGS 84 / UTM zone 29N',
5285
'ProjectedCSTypeGeoKey': 32629,
5288
assert pformat(value, height=1, width=60, linewidth=None) == (
5289
"{'GTCitationGeoKey': 'WGS 84 / UTM zone 29N', 'GTModelTypeGe"
5292
assert pformat(value, height=8, width=60, linewidth=None) == (
5293
"""{'GTCitationGeoKey': 'WGS 84 / UTM zone 29N',
5294
'GTModelTypeGeoKey': 1,
5295
'GTRasterTypeGeoKey': 1,
5296
'KeyDirectoryVersion': 1,
5299
[ 0., 0., 0., 1.]]),
5300
'PCSCitationGeoKey': 'WGS 84 / UTM zone 29N',
5301
'ProjectedCSTypeGeoKey': 32629}"""
5305
def test_func_pformat_list():
5306
"""Test pformat function with list."""
5326
assert pformat(value, height=1, width=60, linewidth=None) == (
5327
'(60.0, 0.0, 0.0, 600000.0, 0.0, -60.0, 0.0, 5900040.0, 60.0,'
5330
assert pformat(value, height=8, width=60, linewidth=None) == (
5331
'(60.0, 0.0, 0.0, 600000.0, 0.0, -60.0, 0.0, 5900040.0, 60.0,\n'
5332
' 0.0, 0.0, 600000.0, 0.0, -60.0, 0.0, 5900040.0)'
5336
def test_func_pformat_numpy():
5337
"""Test pformat function with numpy array."""
5338
value = numpy.array(
5359
assert pformat(value, height=1, width=60, linewidth=None) == (
5360
'array([ 60., 0., 0., 600000., 0., -60., 0., 5900040., 60., 0'
5363
assert pformat(value, height=8, width=60, linewidth=None) == (
5364
"""array([ 60., 0., 0., 600000., 0.,
5365
-60., 0., 5900040., 60., 0.,
5366
0., 600000., 0., -60., 0.,
5371
@pytest.mark.skipif(not IS_WIN, reason='not reliable on Linux')
5372
def test_func_pformat_xml():
5373
"""Test pformat function with XML."""
5374
value = """<?xml version="1.0" encoding="ISO-8859-1" ?>
5375
<Dimap_Document name="band2.dim">
5377
<METADATA_FORMAT version="2.12.1">DIMAP</METADATA_FORMAT>
5378
<METADATA_PROFILE>BEAM-DATAMODEL-V1</METADATA_PROFILE>
5380
<Image_Interpretation>
5381
<Spectral_Band_Info>
5382
<BAND_INDEX>0</BAND_INDEX>
5383
</Spectral_Band_Info>
5384
</Image_Interpretation>
5387
assert pformat(value, height=1, width=60, linewidth=None) == (
5388
'<?xml version="1.0" encoding="ISO-8859-1" ?> <Dimap_Document'
5391
assert pformat(value, height=8, width=60, linewidth=None) == (
5392
"""<?xml version='1.0' encoding='ISO-8859-1'?>
5393
<Dimap_Document name="band2.dim">
5395
<METADATA_FORMAT version="2.12.1">DIMAP</METADATA_FORMAT>
5397
<BAND_INDEX>0</BAND_INDEX>
5398
</Spectral_Band_Info>
5399
</Image_Interpretation>
5404
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
5405
def test_func_lsm2bin():
5406
"""Test lsm2bin function."""
5407
# Convert LSM to BIN
5408
fname = private_file(
5409
'lsm/Twoareas_Zstacks54slices_3umintervals_5cycles.lsm'
5411
# fname = private_file(
5412
# 'LSM/fish01-wt-t01-10_ForTest-20zplanes10timepoints.lsm')
5413
lsm2bin(fname, '', verbose=True)
5416
def test_func_tiffcomment():
5417
"""Test tiffcomment function."""
5418
data = random_data(numpy.uint8, (33, 31, 3))
5419
with TempFileName('func_tiffcomment') as fname:
5420
comment = 'A comment'
5424
photometric=PHOTOMETRIC.RGB,
5425
description=comment,
5428
assert comment == tiffcomment(fname)
5429
comment = 'changed comment'
5430
tiffcomment(fname, comment)
5431
assert comment == tiffcomment(fname)
5432
assert_valid_tiff(fname)
5435
def test_func_create_output():
5436
"""Test create_output function."""
5438
dtype = numpy.uint16
5440
a = create_output(None, shape, dtype)
5441
assert_array_equal(a, numpy.zeros(shape, dtype))
5443
b = create_output(a, a.shape, a.dtype)
5446
a = create_output('memmap', shape, dtype)
5447
assert isinstance(a, numpy.memmap)
5450
a = create_output(f'memmap:{os.path.abspath(TEMP_DIR)}', shape, dtype)
5451
assert isinstance(a, numpy.memmap)
5454
with TempFileName('nopages') as fname:
5455
a = create_output(fname, shape, dtype)
5459
def test_func_reorient():
5460
"""Test reoirient func."""
5461
data = numpy.zeros((2, 3, 31, 33, 3), numpy.uint8)
5462
for orientation in range(1, 9):
5463
reorient(data, orientation) # TODO: assert result
5466
@pytest.mark.parametrize('key', [None, 0, 3, 'series'])
5467
@pytest.mark.parametrize('out', [None, 'empty', 'memmap', 'dir', 'name'])
5468
def test_func_create_output_asarray(out, key):
5469
"""Test create_output function in context of asarray."""
5470
data = random_data(numpy.uint16, (5, 219, 301))
5472
with TempFileName(f'func_out_{key}_{out}') as fname:
5473
imwrite(fname, data)
5475
with TiffFile(fname) as tif:
5476
tif.pages.useframes = True
5483
elif key == 'series':
5489
obj = tif.pages[key]
5492
assert isinstance(obj, TiffPage)
5494
assert isinstance(obj, TiffFrame)
5498
image = obj.asarray(out=None)
5499
assert_array_equal(dat, image)
5501
elif out == 'empty':
5503
image = numpy.empty_like(dat)
5504
obj.asarray(out=image)
5505
assert_array_equal(dat, image)
5507
elif out == 'memmap':
5508
# memmap in temp dir
5509
image = obj.asarray(out='memmap')
5510
assert isinstance(image, numpy.memmap)
5511
assert_array_equal(dat, image)
5514
# memmap in specified dir
5515
tempdir = os.path.dirname(fname)
5516
image = obj.asarray(out=f'memmap:{tempdir}')
5517
assert isinstance(image, numpy.memmap)
5518
assert_array_equal(dat, image)
5521
# memmap in specified file
5523
f'out_{key}_{out}', ext='.memmap'
5525
image = obj.asarray(out=fileout)
5526
assert isinstance(image, numpy.memmap)
5527
assert_array_equal(dat, image)
5531
def test_func_bitorder_decode():
5532
"""Test bitorder_decode function."""
5533
from tifffile._imagecodecs import bitorder_decode
5536
assert bitorder_decode(b'\x01\x64') == b'\x80&'
5537
assert bitorder_decode(b'\x01\x00\x9a\x02') == b'\x80\x00Y@'
5540
data = numpy.array([1, 666], dtype=numpy.uint16)
5541
reverse = numpy.array([128, 16473], dtype=numpy.uint16)
5543
assert_array_equal(bitorder_decode(data), reverse)
5544
# array view not supported
5547
[1, 666, 1431655765, 62],
5548
[2, 667, 2863311530, 32],
5549
[3, 668, 1431655765, 30],
5553
reverse = numpy.array(
5555
[1, 666, 1431655765, 62],
5556
[2, 16601, 1431655765, 32],
5557
[3, 16441, 2863311530, 30],
5561
# if int(numpy.__version__.split('.')[1]) < 23:
5562
# with pytest.raises(NotImplementedError):
5563
# bitorder_decode(data[1:, 1:3])
5565
assert_array_equal(bitorder_decode(data[1:, 1:3]), reverse[1:, 1:3])
5568
@pytest.mark.parametrize(
5570
['u1', 'u2', 'u4', 'u8', 'i1', 'i2', 'i4', 'i8', 'f4', 'f8', 'B'],
5572
@pytest.mark.parametrize('byteorder', ['>', '<'])
5573
def test_func_delta_codec(byteorder, kind):
5574
"""Test delta codec functions."""
5575
from tifffile._imagecodecs import delta_decode, delta_encode
5577
# if byteorder == '>' and numpy.dtype(kind).itemsize == 1:
5578
# pytest.skip('duplicate test')
5580
if kind[0] in 'iuB':
5581
low = numpy.iinfo(kind).min
5582
high = numpy.iinfo(kind).max
5583
data = numpy.random.randint(
5584
low, high, size=33 * 31 * 3, dtype=kind
5585
).reshape(33, 31, 3)
5588
if byteorder == '>':
5589
pytest.xfail('requires imagecodecs')
5590
low, high = -1e5, 1e5
5591
data = numpy.random.randint(
5592
low, high, size=33 * 31 * 3, dtype='i4'
5593
).reshape(33, 31, 3)
5594
data = data.astype(byteorder + kind)
5596
data[16, 14] = [0, 0, 0]
5597
data[16, 15] = [low, high, low]
5598
data[16, 16] = [high, low, high]
5599
data[16, 17] = [low, high, low]
5600
data[16, 18] = [high, low, high]
5601
data[16, 19] = [0, 0, 0]
5604
# data = data.reshape(-1)
5605
data = data.tobytes()
5606
assert delta_decode(delta_encode(data)) == data
5608
encoded = delta_encode(data, axis=-2)
5609
assert encoded.dtype.byteorder == data.dtype.byteorder
5610
assert_array_equal(data, delta_decode(encoded, axis=-2))
5613
encoded, imagecodecs.delta_encode(data, axis=-2)
5617
@pytest.mark.parametrize('length', [0, 2, 31 * 33 * 3])
5618
@pytest.mark.parametrize('codec', ['lzma', 'zlib'])
5619
def test_func_zlib_lzma_codecs(codec, length):
5620
"""Test zlib and lzma codec functions."""
5622
from tifffile._imagecodecs import zlib_decode, zlib_encode
5624
encode = zlib_encode
5625
decode = zlib_decode
5626
elif codec == 'lzma':
5627
from tifffile._imagecodecs import lzma_decode, lzma_encode
5629
encode = lzma_encode
5630
decode = lzma_decode
5633
data = numpy.random.randint(255, size=length, dtype=numpy.uint8)
5634
assert decode(encode(data)) == data.tobytes()
5637
assert decode(encode(data)) == data
5642
([0] * 1, b'\x00\x00'), # literal
5643
([0] * 2, b'\xff\x00'), # replicate
5644
([0] * 3, b'\xfe\x00'),
5645
([0] * 64, b'\xc1\x00'),
5646
([0] * 127, b'\x82\x00'),
5647
([0] * 128, b'\x81\x00'), # max replicate
5648
([0] * 129, b'\x81\x00\x00\x00'),
5649
([0] * 130, b'\x81\x00\xff\x00'),
5650
([0] * 128 * 3, b'\x81\x00' * 3),
5651
([255] * 1, b'\x00\xff'), # literal
5652
([255] * 2, b'\xff\xff'), # replicate
5653
([0, 1], b'\x01\x00\x01'),
5654
([0, 1, 2], b'\x02\x00\x01\x02'),
5655
([0, 1] * 32, b'\x3f' + b'\x00\x01' * 32),
5656
([0, 1] * 63 + [2], b'\x7e' + b'\x00\x01' * 63 + b'\x02'),
5657
([0, 1] * 64, b'\x7f' + b'\x00\x01' * 64), # max literal
5658
([0, 1] * 64 + [2], b'\x7f' + b'\x00\x01' * 64 + b'\x00\x02'),
5659
([0, 1] * 64 * 5, (b'\x7f' + b'\x00\x01' * 64) * 5),
5660
([0, 1, 1], b'\x00\x00\xff\x01'), # or b'\x02\x00\x01\x01'
5661
([0] + [1] * 128, b'\x00\x00\x81\x01'), # or b'\x01\x00\x01\x82\x01'
5662
([0] + [1] * 129, b'\x00\x00\x81\x01\x00\x01'), # b'\x01\x00\x01\x81\x01'
5663
([0, 1] * 64 + [2] * 2, b'\x7f' + b'\x00\x01' * 64 + b'\xff\x02'),
5664
([0, 1] * 64 + [2] * 128, b'\x7f' + b'\x00\x01' * 64 + b'\x81\x02'),
5665
([0, 0, 1], b'\x02\x00\x00\x01'), # or b'\xff\x00\x00\x01'
5666
([0, 0] + [1, 2] * 64, b'\xff\x00\x7f' + b'\x01\x02' * 64),
5667
([0] * 128 + [1], b'\x81\x00\x00\x01'),
5668
([0] * 128 + [1, 2] * 64, b'\x81\x00\x7f' + b'\x01\x02' * 64),
5670
b'\xaa\xaa\xaa\x80\x00\x2a\xaa\xaa\xaa\xaa\x80\x00'
5671
b'\x2a\x22\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa',
5672
b'\xfe\xaa\x02\x80\x00\x2a\xfd\xaa\x03\x80\x00\x2a\x22\xf7\xaa',
5677
@pytest.mark.parametrize('data', range(len(PACKBITS_DATA)))
5678
def test_func_packbits_decode(data):
5679
"""Test packbits_decode function."""
5680
from tifffile._imagecodecs import packbits_decode
5682
uncompressed, compressed = PACKBITS_DATA[data]
5683
assert packbits_decode(compressed) == bytes(uncompressed)
5686
def test_func_packints_decode():
5687
"""Test packints_decode function."""
5688
from tifffile._imagecodecs import packints_decode
5690
decoded = packints_decode(b'', 'B', 1)
5691
assert len(decoded) == 0
5692
decoded = packints_decode(b'a', 'B', 1)
5693
assert tuple(decoded) == (0, 1, 1, 0, 0, 0, 0, 1)
5694
with pytest.raises(NotImplementedError):
5695
decoded = packints_decode(b'ab', 'B', 2)
5696
assert tuple(decoded) == (1, 2, 0, 1, 1, 2, 0, 2)
5697
with pytest.raises(NotImplementedError):
5698
decoded = packints_decode(b'abcd', 'B', 3)
5699
assert tuple(decoded) == (3, 0, 2, 6, 1, 1, 4, 3, 3, 1)
5702
def test_func_check_shape():
5703
"""Test check_shape function."""
5704
assert check_shape((10, 10, 4), (10, 10, 4))
5705
assert check_shape((10, 10, 4), (1, 1, 10, 10, 4))
5706
assert not check_shape((4, 10, 10), (10, 10, 4))
5707
assert not check_shape((10, 10, 4), (4, 10, 10))
5708
assert not check_shape((10, 10, 4), (1, 1, 4, 10, 10))
5710
assert check_shape((0,), (0, 0))
5711
assert check_shape((0, 0), (0,))
5713
assert check_shape((4,), (4,))
5714
assert check_shape((1, 4), (4,))
5715
assert check_shape((1, 4), (4, 1))
5716
assert check_shape((4, 1), (4, 1))
5717
assert check_shape((4, 1), (1, 4, 1))
5718
assert check_shape((4, 5), (4, 5, 1))
5719
assert check_shape((4, 5), (4, 5, 1, 1))
5720
assert check_shape((4, 5), (1, 4, 5, 1))
5722
assert not check_shape((1,), (0, 0))
5723
assert not check_shape((1, 0), (1,))
5724
assert not check_shape((4, 1), (1,))
5725
assert not check_shape((4, 1), (2,))
5726
assert not check_shape((4, 1), (4,))
5727
assert not check_shape((4, 1), (2, 2))
5728
assert not check_shape((4, 1), (2, 1))
5729
assert not check_shape((3, 4, 5), (4, 5, 3))
5732
###############################################################################
5734
# Test FileHandle class
5736
FILEHANDLE_NAME = public_file('tifffile/test_FileHandle.bin')
5737
FILEHANDLE_SIZE = 7937381
5738
FILEHANDLE_OFFSET = 333
5739
FILEHANDLE_LENGTH = 7937381 - 666
5742
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5743
def create_filehandle_file():
5744
"""Write test_FileHandle.bin file."""
5747
# recarray start 2253
5753
with open(FILEHANDLE_NAME, 'wb') as fh:
5755
numpy.ones(999, dtype=numpy.uint8).tofile(fh)
5757
print('array start', fh.tell())
5758
numpy.arange(255, dtype=numpy.uint8).tofile(fh)
5759
print('array end', fh.tell())
5761
numpy.ones(999, dtype=numpy.uint8).tofile(fh)
5763
print('recarray start', fh.tell())
5765
(255, 3), dtype=[('x', numpy.float32), ('y', numpy.uint8)]
5768
a[:, i].x = numpy.arange(255, dtype=numpy.float32)
5769
a[:, i].y = numpy.arange(255, dtype=numpy.uint8)
5771
print('recarray end', fh.tell())
5773
numpy.ones(999, dtype=numpy.uint8).tofile(fh)
5775
print('tiff start', fh.tell())
5776
with open('data/public/tifffile/generic_series.tif', 'rb') as tif:
5777
fh.write(tif.read())
5778
print('tiff end', fh.tell())
5780
numpy.ones(999, dtype=numpy.uint8).tofile(fh)
5782
print('micromanager start', fh.tell())
5783
with open('data/public/tifffile/micromanager.tif', 'rb') as tif:
5784
fh.write(tif.read())
5785
print('micromanager end', fh.tell())
5787
numpy.ones(999, dtype=numpy.uint8).tofile(fh)
5790
def assert_filehandle(fh, offset=0):
5791
"""Assert filehandle can read test_FileHandle.bin."""
5793
assert not fh.closed
5794
assert fh.open() is None # open an open file
5797
assert fh.open() is None # open a closed file
5798
size = FILEHANDLE_SIZE - 2 * offset
5800
assert fh.size == size
5801
assert fh.tell() == 0
5802
assert fh.read(4) == b'\x01\x01\x01\x01'
5804
assert fh.tell() == pad - 4
5805
assert fh.read(4) == b'\x01\x01\x01\x01'
5806
fh.seek(-4, whence=1)
5807
assert fh.tell() == pad - 4
5808
assert fh.read(4) == b'\x01\x01\x01\x01'
5809
fh.seek(-pad, whence=2)
5810
assert fh.tell() == size - pad
5811
assert fh.read(4) == b'\x01\x01\x01\x01'
5813
fh.seek(pad, whence=0)
5814
assert fh.tell() == pad
5816
fh.read_array(numpy.uint8, 255), numpy.arange(255, dtype=numpy.uint8)
5819
fh.seek(999, whence=1)
5820
assert fh.tell() == 2253 - offset
5821
records = fh.read_record(
5822
[('x', numpy.float32), ('y', numpy.uint8)], (255, 3)
5824
assert_array_equal(records.y[:, 0], range(255))
5825
assert_array_equal(records.x, records.y)
5829
fh.memmap_array(numpy.uint8, 255, pad),
5830
numpy.arange(255, dtype=numpy.uint8),
5834
@pytest.mark.skipif(SKIP_HTTP, reason=REASON)
5835
def test_filehandle_seekable():
5836
"""Test FileHandle must be seekable."""
5837
from urllib.request import HTTPHandler, build_opener
5839
opener = build_opener(HTTPHandler())
5840
opener.addheaders = [('User-Agent', 'test_tifffile.py')]
5842
fh = opener.open(URL + 'test/test_http.tif')
5844
pytest.skip(URL + 'test/test_http.tif')
5846
with pytest.raises(ValueError):
5850
def test_filehandle_write_bytesio():
5851
"""Test write to FileHandle from BytesIO."""
5852
value = b'123456789'
5854
with FileHandle(buf) as fh:
5856
assert buf.getvalue() == value
5859
def test_filehandle_write_bytesio_offset():
5860
"""Test write to FileHandle from BytesIO with offset."""
5862
value = b'123456789'
5865
with FileHandle(buf) as fh:
5870
assert buf.read(len(value)) == value
5872
with FileHandle(buf, offset=len(pad), size=len(value)) as fh:
5873
assert fh.read(len(value)) == value
5876
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5877
def test_filehandle_filename():
5878
"""Test FileHandle from filename."""
5879
with FileHandle(FILEHANDLE_NAME) as fh:
5880
assert fh.name == 'test_FileHandle.bin'
5882
assert_filehandle(fh)
5885
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5886
def test_filehandle_filename_offset():
5887
"""Test FileHandle from filename with offset."""
5889
FILEHANDLE_NAME, offset=FILEHANDLE_OFFSET, size=FILEHANDLE_LENGTH
5891
assert fh.name == 'test_FileHandle.bin'
5893
assert_filehandle(fh, FILEHANDLE_OFFSET)
5896
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5897
def test_filehandle_bytesio():
5898
"""Test FileHandle from BytesIO."""
5899
with open(FILEHANDLE_NAME, 'rb') as fh:
5900
stream = BytesIO(fh.read())
5901
with FileHandle(stream) as fh:
5902
assert fh.name == 'Unnamed binary stream'
5903
assert not fh.is_file
5904
assert_filehandle(fh)
5907
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5908
def test_filehandle_bytesio_offset():
5909
"""Test FileHandle from BytesIO with offset."""
5910
with open(FILEHANDLE_NAME, 'rb') as fh:
5911
stream = BytesIO(fh.read())
5913
stream, offset=FILEHANDLE_OFFSET, size=FILEHANDLE_LENGTH
5915
assert fh.name == 'Unnamed binary stream'
5916
assert not fh.is_file
5917
assert_filehandle(fh, offset=FILEHANDLE_OFFSET)
5920
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5921
def test_filehandle_openfile():
5922
"""Test FileHandle from open file."""
5923
with open(FILEHANDLE_NAME, 'rb') as fhandle:
5924
with FileHandle(fhandle) as fh:
5925
assert fh.name == 'test_FileHandle.bin'
5927
assert_filehandle(fh)
5928
assert not fhandle.closed
5931
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5932
def test_filehandle_openfile_offset():
5933
"""Test FileHandle from open file with offset."""
5934
with open(FILEHANDLE_NAME, 'rb') as fhandle:
5936
fhandle, offset=FILEHANDLE_OFFSET, size=FILEHANDLE_LENGTH
5938
assert fh.name == 'test_FileHandle.bin'
5940
assert_filehandle(fh, offset=FILEHANDLE_OFFSET)
5941
assert not fhandle.closed
5944
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5945
def test_filehandle_filehandle():
5946
"""Test FileHandle from other FileHandle."""
5947
with FileHandle(FILEHANDLE_NAME, 'rb') as fhandle:
5948
with FileHandle(fhandle) as fh:
5949
assert fh.name == 'test_FileHandle.bin'
5951
assert_filehandle(fh)
5952
assert not fhandle.closed
5955
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5956
def test_filehandle_offset():
5957
"""Test FileHandle from other FileHandle with offset."""
5958
with FileHandle(FILEHANDLE_NAME, 'rb') as fhandle:
5960
fhandle, offset=FILEHANDLE_OFFSET, size=FILEHANDLE_LENGTH
5962
assert fh.name == 'test_FileHandle@333.bin'
5964
assert_filehandle(fh, offset=FILEHANDLE_OFFSET)
5965
assert not fhandle.closed
5968
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
5969
def test_filehandle_reopen():
5970
"""Test FileHandle close and open."""
5972
fh = FileHandle(FILEHANDLE_NAME)
5973
assert not fh.closed
5978
assert not fh.closed
5980
assert fh.name == 'test_FileHandle.bin'
5981
assert_filehandle(fh)
5986
@pytest.mark.skipif(SKIP_HTTP or not IS_CG, reason=REASON)
5987
def test_filehandle_unc_path():
5988
"""Test FileHandle from UNC path."""
5989
with FileHandle(r'\\localhost\test$\test_FileHandle.bin') as fh:
5990
assert fh.name == 'test_FileHandle.bin'
5991
assert fh.dirname == '\\\\localhost\\test$\\'
5992
assert_filehandle(fh)
5995
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
5996
def test_filehandle_fsspec_localfileopener():
5997
"""Test FileHandle from fsspec LocalFileOpener."""
5998
with fsspec.open(FILEHANDLE_NAME, 'rb') as fhandle:
5999
with FileHandle(fhandle) as fh:
6000
assert fh.name == 'test_FileHandle.bin'
6001
assert fh.is_file # fails with fsspec 2022.7
6002
assert_filehandle(fh)
6003
assert not fhandle.closed
6006
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
6007
def test_filehandle_fsspec_openfile():
6008
"""Test FileHandle from fsspec OpenFile."""
6009
fhandle = fsspec.open(FILEHANDLE_NAME, 'rb')
6010
with FileHandle(fhandle) as fh:
6011
assert fh.name == 'test_FileHandle.bin'
6013
assert_filehandle(fh)
6017
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_HTTP or SKIP_ZARR, reason=REASON)
6018
def test_filehandle_fsspec_http():
6019
"""Test FileHandle from HTTP via fsspec."""
6020
with fsspec.open(URL + 'test/test_FileHandle.bin', 'rb') as fhandle:
6021
with FileHandle(fhandle) as fh:
6022
assert fh.name == 'test_FileHandle.bin'
6023
assert not fh.is_file
6024
assert_filehandle(fh)
6025
assert not fhandle.closed
6028
def test_filehandle_exclusive_creation():
6029
"""Test FileHandle with exclusive creation mode 'x'."""
6030
# https://github.com/cgohlke/tifffile/issues/221
6031
with TempFileName('read_filehandle_exclusive', ext='.bin') as fname:
6032
if os.path.exists(fname):
6034
with FileHandle(fname, mode='x'):
6036
with pytest.raises(FileExistsError):
6037
with FileHandle(fname, mode='x'):
6041
###############################################################################
6043
# Test read specific files
6045
if SKIP_EXTENDED or SKIP_PRIVATE:
6050
public_file('graphicsmagick.org/be/*.tif')
6051
+ public_file('graphicsmagick.org/le/*.tif')
6052
+ public_file('graphicsmagick.org/bigtiff-be/*.tif')
6053
+ public_file('graphicsmagick.org/bigtiff-le/*.tif')
6056
'-'.join(f.split(os.path.sep)[-2:])
6057
.replace('-tiger', '')
6058
.replace('.tif', '')
6059
for f in TIGER_FILES
6063
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS or SKIP_EXTENDED, reason=REASON)
6064
@pytest.mark.parametrize('fname', TIGER_FILES, ids=TIGER_IDS)
6065
def test_read_tigers(fname):
6066
"""Test tiger images from GraphicsMagick."""
6067
# ftp://ftp.graphicsmagick.org/pub/tiff-samples
6068
with TiffFile(fname) as tif:
6069
byteorder = {'le': '<', 'be': '>'}[os.path.split(fname)[0][-2:]]
6070
databits = int(fname.rsplit('.tif')[0][-2:])
6072
# assert file properties
6073
assert_file_flags(tif)
6074
assert tif.byteorder == byteorder
6075
assert tif.is_bigtiff == ('bigtiff' in fname)
6076
assert len(tif.pages) == 1
6078
# assert page properties
6079
page = tif.pages.first
6080
assert_page_flags(page)
6081
assert page.tags['DocumentName'].value == os.path.basename(fname)
6082
assert page.imagewidth == 73
6083
assert page.imagelength == 76
6084
assert page.bitspersample == databits
6085
assert (page.photometric == PHOTOMETRIC.RGB) == ('rgb' in fname)
6086
assert (page.photometric == PHOTOMETRIC.PALETTE) == (
6089
assert page.is_tiled == ('tile' in fname)
6090
assert (page.planarconfig == PLANARCONFIG.CONTIG) == (
6091
'planar' not in fname
6093
if 'minisblack' in fname:
6094
assert page.photometric == PHOTOMETRIC.MINISBLACK
6096
# float24 not supported
6097
# if 'float' in fname and databits == 24:
6098
# with pytest.raises(ValueError):
6099
# data = tif.asarray()
6102
# assert data shapes
6103
data = tif.asarray()
6104
assert isinstance(data, numpy.ndarray)
6105
assert data.flags['C_CONTIGUOUS']
6106
# if 'palette' in fname:
6107
# shape = (76, 73, 3)
6109
if 'planar' in fname:
6113
elif 'separated' in fname:
6114
if 'planar' in fname:
6120
assert data.shape == shape
6123
if 'float' in fname:
6125
dtype = numpy.float32
6127
dtype = f'float{databits}'
6128
# elif 'palette' in fname:
6129
# dtype = numpy.uint16
6134
elif databits <= 16:
6135
dtype = numpy.uint16
6136
elif databits <= 32:
6137
dtype = numpy.uint32
6138
elif databits <= 64:
6139
dtype = numpy.uint64
6140
assert data.dtype == dtype
6142
assert_decode_method(page, data)
6143
assert_aszarr_method(page, data)
6147
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
6148
def test_read_exif_paint():
6149
"""Test read EXIF tags."""
6150
fname = private_file('exif/paint.tif')
6151
with TiffFile(fname) as tif:
6152
exif = tif.pages.first.tags['ExifTag'].value
6153
assert exif['ColorSpace'] == 65535
6154
assert exif['ExifVersion'] == '0230'
6155
assert exif['UserComment'] == 'paint'
6156
assert tif.fstat.st_size == 4234366
6157
assert_aszarr_method(tif)
6161
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6162
def test_read_hopper_2bit():
6163
"""Test read 2-bit, fillorder=lsb2msb."""
6164
# https://github.com/python-pillow/Pillow/pull/1789
6165
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper2.tif')
6166
with TiffFile(fname) as tif:
6167
assert tif.byteorder == '<'
6168
assert len(tif.pages) == 1
6169
assert len(tif.series) == 1
6170
# assert page properties
6171
page = tif.pages.first
6172
assert page.photometric == PHOTOMETRIC.MINISBLACK
6173
assert not page.is_contiguous
6174
assert page.compression == COMPRESSION.NONE
6175
assert page.imagewidth == 128
6176
assert page.imagelength == 128
6177
assert page.bitspersample == 2
6178
assert page.samplesperpixel == 1
6179
# assert series properties
6180
series = tif.series[0]
6181
assert series.shape == (128, 128)
6182
assert series.dtype == numpy.uint8
6183
assert series.axes == 'YX'
6184
assert series.kind == 'uniform'
6185
assert series.dataoffset is None
6187
data = tif.asarray()
6188
assert isinstance(data, numpy.ndarray)
6189
assert data.shape == (128, 128)
6190
assert data[50, 63] == 3
6191
assert_aszarr_method(tif, data)
6194
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper2R.tif')
6195
with TiffFile(fname) as tif:
6196
page = tif.pages.first
6197
assert page.photometric == PHOTOMETRIC.MINISBLACK
6198
assert page.fillorder == FILLORDER.LSB2MSB
6199
assert_array_equal(tif.asarray(), data)
6200
assert_aszarr_method(tif)
6203
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper2I.tif')
6204
with TiffFile(fname) as tif:
6205
page = tif.pages.first
6206
assert page.photometric == PHOTOMETRIC.MINISWHITE
6207
assert_array_equal(tif.asarray(), 3 - data)
6208
assert_aszarr_method(tif)
6210
# inverted and reversed
6211
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper2IR.tif')
6212
with TiffFile(fname) as tif:
6213
page = tif.pages.first
6214
assert page.photometric == PHOTOMETRIC.MINISWHITE
6215
assert_array_equal(tif.asarray(), 3 - data)
6216
assert_aszarr_method(tif)
6220
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6221
def test_read_hopper_4bit():
6222
"""Test read 4-bit, fillorder=lsb2msb."""
6223
# https://github.com/python-pillow/Pillow/pull/1789
6224
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper4.tif')
6225
with TiffFile(fname) as tif:
6226
assert tif.byteorder == '<'
6227
assert len(tif.pages) == 1
6228
assert len(tif.series) == 1
6229
# assert page properties
6230
page = tif.pages.first
6231
assert page.photometric == PHOTOMETRIC.MINISBLACK
6232
assert not page.is_contiguous
6233
assert page.compression == COMPRESSION.NONE
6234
assert page.imagewidth == 128
6235
assert page.imagelength == 128
6236
assert page.bitspersample == 4
6237
assert page.samplesperpixel == 1
6238
# assert series properties
6239
series = tif.series[0]
6240
assert series.shape == (128, 128)
6241
assert series.dtype == numpy.uint8
6242
assert series.axes == 'YX'
6243
assert series.kind == 'uniform'
6244
assert series.dataoffset is None
6246
data = tif.asarray()
6247
assert isinstance(data, numpy.ndarray)
6248
assert data.shape == (128, 128)
6249
assert data[50, 63] == 13
6251
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper4R.tif')
6252
with TiffFile(fname) as tif:
6253
page = tif.pages.first
6254
assert page.photometric == PHOTOMETRIC.MINISBLACK
6255
assert page.fillorder == FILLORDER.LSB2MSB
6256
assert_array_equal(tif.asarray(), data)
6259
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper4I.tif')
6260
with TiffFile(fname) as tif:
6261
page = tif.pages.first
6262
assert page.photometric == PHOTOMETRIC.MINISWHITE
6263
assert_array_equal(tif.asarray(), 15 - data)
6265
# inverted and reversed
6266
fname = public_file('pillow/tiff_gray_2_4_bpp/hopper4IR.tif')
6267
with TiffFile(fname) as tif:
6268
page = tif.pages.first
6269
assert page.photometric == PHOTOMETRIC.MINISWHITE
6270
assert_array_equal(tif.asarray(), 15 - data)
6274
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
6275
def test_read_lsb2msb():
6276
"""Test read fillorder=lsb2msb, 2 series."""
6277
# http://lists.openmicroscopy.org.uk/pipermail/ome-users
6278
# /2015-September/005635.html
6279
fname = private_file('test_lsb2msb.tif')
6280
with TiffFile(fname) as tif:
6281
assert tif.byteorder == '<'
6282
assert len(tif.pages) == 2
6283
assert len(tif.series) == 2
6284
# assert page properties
6285
page = tif.pages.first
6286
assert page.is_contiguous
6287
assert page.compression == COMPRESSION.NONE
6288
assert page.imagewidth == 7100
6289
assert page.imagelength == 4700
6290
assert page.bitspersample == 16
6291
assert page.samplesperpixel == 3
6293
assert page.is_contiguous
6294
assert page.compression == COMPRESSION.NONE
6295
assert page.imagewidth == 7100
6296
assert page.imagelength == 4700
6297
assert page.bitspersample == 16
6298
assert page.samplesperpixel == 1
6299
# assert series properties
6300
series = tif.series[0]
6301
assert series.shape == (4700, 7100, 3)
6302
assert series.dtype == numpy.uint16
6303
assert series.axes == 'YXS'
6304
assert series.dataoffset is None
6305
series = tif.series[1]
6306
assert series.shape == (4700, 7100)
6307
assert series.dtype == numpy.uint16
6308
assert series.axes == 'YX'
6309
assert series.kind == 'generic'
6310
assert series.dataoffset is None
6312
data = tif.asarray(series=0)
6313
assert isinstance(data, numpy.ndarray)
6314
assert data.shape == (4700, 7100, 3)
6315
assert data[2350, 3550, 1] == 60457
6316
assert_aszarr_method(tif, data, series=0)
6317
data = tif.asarray(series=1)
6318
assert isinstance(data, numpy.ndarray)
6319
assert data.flags['C_CONTIGUOUS']
6320
assert data.shape == (4700, 7100)
6321
assert data[2350, 3550] == 56341
6322
assert_aszarr_method(tif, data, series=1)
6326
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6327
def test_read_gimp_u2():
6328
"""Test read uint16 with horizontal predictor by GIMP."""
6329
fname = public_file('tifffile/gimp_u2.tiff')
6330
with TiffFile(fname) as tif:
6331
assert len(tif.pages) == 1
6332
page = tif.pages.first
6333
assert page.compression == COMPRESSION.ADOBE_DEFLATE
6334
assert page.photometric == PHOTOMETRIC.RGB
6335
assert page.predictor == PREDICTOR.HORIZONTAL
6336
assert page.imagewidth == 333
6337
assert page.imagelength == 231
6338
assert page.samplesperpixel == 3
6339
image = tif.asarray()
6340
assert image.flags['C_CONTIGUOUS']
6341
assert tuple(image[110, 110]) == (23308, 17303, 41160)
6342
assert_aszarr_method(tif, image)
6346
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6347
def test_read_gimp_f4():
6348
"""Test read float32 with horizontal predictor by GIMP."""
6349
fname = public_file('tifffile/gimp_f4.tiff')
6350
with TiffFile(fname) as tif:
6351
assert len(tif.pages) == 1
6352
page = tif.pages.first
6353
assert page.compression == COMPRESSION.ADOBE_DEFLATE
6354
assert page.photometric == PHOTOMETRIC.RGB
6355
assert page.predictor == PREDICTOR.HORIZONTAL
6356
assert page.imagewidth == 333
6357
assert page.imagelength == 231
6358
assert page.samplesperpixel == 3
6359
image = tif.asarray()
6360
assert image.flags['C_CONTIGUOUS']
6361
assert_array_almost_equal(
6362
image[110, 110], (0.35565534, 0.26402164, 0.6280674)
6364
assert_aszarr_method(tif, image)
6368
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6369
def test_read_gimp_f2():
6370
"""Test read float16 with horizontal predictor by GIMP."""
6371
fname = public_file('tifffile/gimp_f2.tiff')
6372
with TiffFile(fname) as tif:
6373
assert len(tif.pages) == 1
6374
page = tif.pages.first
6375
assert page.compression == COMPRESSION.ADOBE_DEFLATE
6376
assert page.photometric == PHOTOMETRIC.RGB
6377
assert page.predictor == PREDICTOR.HORIZONTAL
6378
assert page.imagewidth == 333
6379
assert page.imagelength == 231
6380
assert page.samplesperpixel == 3
6381
image = tif.asarray()
6382
assert image.flags['C_CONTIGUOUS']
6383
assert_array_almost_equal(
6384
image[110, 110].astype(numpy.float64),
6385
(0.35571289, 0.26391602, 0.62792969),
6387
assert_aszarr_method(tif, image)
6392
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG8.available,
6395
def test_read_dng_jpeglossy():
6396
"""Test read JPEG_LOSSY in DNG."""
6397
fname = private_file('DNG/Adobe DNG Converter.dng')
6398
with TiffFile(fname) as tif:
6399
assert len(tif.pages) == 1
6400
assert len(tif.series) == 6
6401
for series in tif.series:
6402
image = series.asarray()
6403
assert_aszarr_method(series, image)
6408
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.LJPEG.available,
6411
def test_read_dng_ljpeg():
6412
"""Test read 14-bit CFA LJPEG in DNG."""
6413
fname = private_file('DNG/uint14_ljpeg_cfa.dng')
6414
with TiffFile(fname) as tif:
6415
assert len(tif.pages) == 1
6416
assert len(tif.series) == 3
6417
page = tif.pages.first.pages[0]
6418
assert page.compression == COMPRESSION.JPEG
6419
assert page.photometric == PHOTOMETRIC.CFA
6420
assert page.imagewidth == 7392
6421
assert page.imagelength == 4950
6422
assert page.bitspersample == 14
6423
assert page.samplesperpixel == 1
6424
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
6425
assert page.tags['CFAPattern'].value == b'\0\1\1\2'
6426
assert page.tags['CFALayout'].value == 1
6427
image = page.asarray()
6428
assert image.shape == (4950, 7392)
6429
assert image.dtype == numpy.uint16
6430
assert image[1024, 1024] == 3425
6435
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.LJPEG.available,
6438
def test_read_dng_linearraw():
6439
"""Test read 12-bit LinearRAW LJPEG in DNG."""
6440
fname = private_file('DNG/LinearRaw.dng')
6441
with TiffFile(fname) as tif:
6442
assert len(tif.pages) == 1
6443
assert len(tif.series) == 2
6444
page = tif.pages.first.pages[0]
6445
assert page.compression == COMPRESSION.JPEG
6446
assert page.photometric == PHOTOMETRIC.LINEAR_RAW
6447
assert page.imagewidth == 4032
6448
assert page.imagelength == 3024
6449
assert page.bitspersample == 12
6450
assert page.samplesperpixel == 3
6451
assert page.tile == (378, 504)
6452
image = page.asarray()
6453
assert image.shape == (3024, 4032, 3)
6454
assert image.dtype == numpy.uint16
6455
assert tuple(image[740, 3660]) == (1474, 3090, 1655)
6459
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
6460
@pytest.mark.parametrize('fp', ['fp16', 'fp24', 'fp32'])
6461
def test_read_dng_floatpredx2(fp):
6462
"""Test read FLOATINGPOINTX2 predictor in DNG."""
6463
# <https://raw.pixls.us/data/Canon/EOS%205D%20Mark%20III/>
6464
fname = private_file(f'DNG/fpx2/hdrmerge-bayer-{fp}-w-pred-deflate.dng')
6465
with TiffFile(fname) as tif:
6466
assert len(tif.pages) == 1
6467
assert len(tif.series) == 3
6468
page = tif.pages.first.pages[0]
6469
assert page.compression == COMPRESSION.ADOBE_DEFLATE
6470
assert page.photometric == PHOTOMETRIC.CFA
6471
assert page.predictor == 34894
6472
assert page.imagewidth == 5920
6473
assert page.imagelength == 3950
6474
assert page.sampleformat == SAMPLEFORMAT.IEEEFP
6475
assert page.bitspersample == int(fp[2:])
6476
assert page.samplesperpixel == 1
6478
with pytest.raises(NotImplementedError):
6479
image = page.asarray()
6481
image = page.asarray()
6482
assert_aszarr_method(page, image)
6487
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEGXL.available,
6490
def test_read_dng_jpegxl():
6491
"""Test read JPEGXL in DNG."""
6492
fname = private_file('DNG/20240125_204051_1.dng')
6493
with TiffFile(fname) as tif:
6494
assert len(tif.pages) == 1
6495
assert len(tif.series) == 6
6497
page = tif.pages.first.pages[0]
6498
assert not page.is_reduced
6499
assert page.compression == COMPRESSION.JPEGXL_DNG
6500
assert page.photometric == PHOTOMETRIC.LINEAR_RAW
6501
assert page.imagewidth == 5712
6502
assert page.imagelength == 4284
6503
assert page.bitspersample == 16
6504
assert page.samplesperpixel == 3
6505
image = page.asarray()
6506
assert image.shape == (4284, 5712, 3)
6507
assert image.dtype == numpy.uint16
6508
assert image[1024, 1024, 1] == 36
6510
page = tif.pages.first.pages[1]
6511
assert page.is_reduced
6512
assert page.compression == COMPRESSION.JPEGXL_DNG
6513
assert page.photometric == PHOTOMETRIC.RGB
6514
assert page.imagewidth == 1024
6515
assert page.imagelength == 768
6516
assert page.bitspersample == 8
6517
assert page.samplesperpixel == 3
6518
image = page.asarray()
6519
assert image.shape == (768, 1024, 3)
6520
assert image.dtype == numpy.uint8
6521
assert image[512, 512, 1] in {47, 48}
6522
assert page.tags['JXLDistance'].value == 2.0
6523
assert page.tags['JXLEffort'].value == 7
6524
assert page.tags['JXLDecodeSpeed'].value == 4
6528
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
6529
@pytest.mark.parametrize('fname', ['sample1.orf', 'sample1.rw2'])
6530
def test_read_rawformats(fname, caplog):
6531
"""Test parse unsupported RAW formats."""
6532
fname = private_file(f'RAWformats/{fname}')
6533
with TiffFile(fname) as tif:
6534
assert 'RAW format' in caplog.text
6538
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
6539
def test_read_iss_vista():
6540
"""Test read bogus imagedepth tag by ISS Vista."""
6541
fname = private_file('iss/10um_beads_14stacks_ch1.tif')
6542
with TiffFile(fname) as tif:
6543
assert tif.byteorder == '<'
6544
assert len(tif.pages) == 14
6545
assert len(tif.series) == 1
6546
# assert page properties
6547
page = tif.pages.first
6548
assert not page.is_reduced
6549
assert not page.is_tiled
6550
assert page.compression == COMPRESSION.NONE
6551
assert page.imagewidth == 256
6552
assert page.imagelength == 256
6553
assert page.tags['ImageDepth'].value == 14 # bogus
6554
assert page.bitspersample == 16
6555
assert page.samplesperpixel == 1
6556
# assert series properties
6557
series = tif.series[0]
6558
assert series.shape == (14, 256, 256)
6559
assert series.dtype == numpy.int16
6560
assert series.axes == 'IYX' # ZYX
6561
assert series.kind == 'uniform'
6562
assert isinstance(series.pages[3], TiffFrame)
6563
assert_aszarr_method(series)
6567
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
6568
def test_read_vips():
6569
"""Test read 347x641 RGB, bigtiff, pyramid, tiled, produced by VIPS."""
6570
fname = private_file('vips.tif')
6571
with TiffFile(fname) as tif:
6572
assert tif.byteorder == '<'
6573
assert len(tif.pages) == 4
6574
assert len(tif.series) == 1
6575
# assert page properties
6576
page = tif.pages.first
6577
assert not page.is_reduced
6578
assert page.is_tiled
6579
assert page.compression == COMPRESSION.ADOBE_DEFLATE
6580
assert page.imagewidth == 641
6581
assert page.imagelength == 347
6582
assert page.bitspersample == 8
6583
assert page.samplesperpixel == 3
6584
# assert series properties
6585
series = tif.series[0]
6586
assert series.is_pyramidal
6587
assert len(series.levels) == 4
6588
assert series.shape == (347, 641, 3)
6589
assert series.dtype == numpy.uint8
6590
assert series.axes == 'YXS'
6591
assert series.kind == 'generic'
6593
series = series.levels[3]
6594
page = series.pages[0]
6595
assert page.is_reduced
6596
assert page.is_tiled
6597
assert series.shape == (43, 80, 3)
6598
assert series.dtype == numpy.uint8
6599
assert series.axes == 'YXS'
6601
data = tif.asarray(series=0)
6602
assert isinstance(data, numpy.ndarray)
6603
assert data.flags['C_CONTIGUOUS']
6604
assert data.shape == (347, 641, 3)
6605
assert data.dtype == numpy.uint8
6606
assert tuple(data[132, 361]) == (114, 233, 58)
6607
assert_aszarr_method(tif, data, series=0, level=0)
6611
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6612
def test_read_volumetric():
6613
"""Test read 128x128x128, float32, tiled SGI."""
6614
fname = public_file('tifffile/sgi_depth.tif')
6615
with TiffFile(fname) as tif:
6616
assert tif.byteorder == '<'
6617
assert len(tif.pages) == 1
6618
assert len(tif.series) == 1
6619
# assert page properties
6620
page = tif.pages.first
6621
assert page.is_volumetric
6622
assert page.planarconfig == PLANARCONFIG.CONTIG
6623
assert page.is_tiled
6624
assert page.is_contiguous
6625
assert page.compression == COMPRESSION.NONE
6626
assert page.imagewidth == 128
6627
assert page.imagelength == 128
6628
assert page.imagedepth == 128
6629
assert page.tilewidth == 128
6630
assert page.tilelength == 128
6631
assert page.tiledepth == 1
6632
assert page.tile == (128, 128)
6633
assert page.bitspersample == 32
6634
assert page.samplesperpixel == 1
6635
assert page.tags['Software'].value == (
6636
'MFL MeVis File Format Library, TIFF Module'
6638
# assert series properties
6639
series = tif.series[0]
6640
assert series.shape == (128, 128, 128)
6641
assert series.dtype == numpy.float32
6642
assert series.axes == 'ZYX'
6643
assert series.kind == 'uniform'
6645
data = tif.asarray()
6646
assert isinstance(data, numpy.ndarray)
6647
assert data.flags['C_CONTIGUOUS']
6648
assert data.shape == (128, 128, 128)
6649
assert data.dtype == numpy.float32
6650
assert data[64, 64, 64] == 0.0
6651
assert_decode_method(page)
6652
assert_aszarr_method(tif, data)
6656
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6657
def test_read_oxford():
6658
"""Test read 601x81, uint8, LZW."""
6659
fname = public_file('juicypixels/oxford.tif')
6660
with TiffFile(fname) as tif:
6661
assert tif.byteorder == '>'
6662
assert len(tif.pages) == 1
6663
assert len(tif.series) == 1
6664
# assert page properties
6665
page = tif.pages.first
6666
assert page.planarconfig == PLANARCONFIG.SEPARATE
6667
assert page.photometric == PHOTOMETRIC.RGB
6668
assert page.compression == COMPRESSION.LZW
6669
assert page.imagewidth == 601
6670
assert page.imagelength == 81
6671
assert page.bitspersample == 8
6672
assert page.samplesperpixel == 3
6673
# assert series properties
6674
series = tif.series[0]
6675
assert series.shape == (3, 81, 601)
6676
assert series.dtype == numpy.uint8
6677
assert series.axes == 'SYX'
6678
assert series.kind == 'uniform'
6680
data = tif.asarray()
6681
assert isinstance(data, numpy.ndarray)
6682
assert data.flags['C_CONTIGUOUS']
6683
assert data.shape == (3, 81, 601)
6684
assert data.dtype == numpy.uint8
6685
assert data[1, 24, 49] == 191
6686
assert_aszarr_method(tif, data)
6690
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6691
def test_read_cramps():
6692
"""Test 800x607 uint8, PackBits."""
6693
fname = public_file('juicypixels/cramps.tif')
6694
with TiffFile(fname) as tif:
6695
assert tif.byteorder == '>'
6696
assert len(tif.pages) == 1
6697
assert len(tif.series) == 1
6698
# assert page properties
6699
page = tif.pages.first
6700
assert page.compression == COMPRESSION.PACKBITS
6701
assert page.photometric == PHOTOMETRIC.MINISWHITE
6702
assert page.imagewidth == 800
6703
assert page.imagelength == 607
6704
assert page.bitspersample == 8
6705
assert page.samplesperpixel == 1
6706
# assert series properties
6707
series = tif.series[0]
6708
assert series.shape == (607, 800)
6709
assert series.dtype == numpy.uint8
6710
assert series.axes == 'YX'
6711
assert series.kind == 'uniform'
6713
data = tif.asarray()
6714
assert isinstance(data, numpy.ndarray)
6715
assert data.flags['C_CONTIGUOUS']
6716
assert data.shape == (607, 800)
6717
assert data.dtype == numpy.uint8
6718
assert data[273, 426] == 34
6719
assert_aszarr_method(tif, data)
6723
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6724
def test_read_cramps_tile():
6725
"""Test read 800x607 uint8, raw, volumetric, tiled."""
6726
fname = public_file('juicypixels/cramps-tile.tif')
6727
with TiffFile(fname) as tif:
6728
assert tif.byteorder == '>'
6729
assert len(tif.pages) == 1
6730
assert len(tif.series) == 1
6731
# assert page properties
6732
page = tif.pages.first
6733
assert page.is_tiled
6734
assert not page.is_volumetric
6735
assert page.compression == COMPRESSION.NONE
6736
assert page.photometric == PHOTOMETRIC.MINISWHITE
6737
assert page.imagewidth == 800
6738
assert page.imagelength == 607
6739
assert page.imagedepth == 1
6740
assert page.tilewidth == 256
6741
assert page.tilelength == 256
6742
assert page.tiledepth == 1
6743
assert page.bitspersample == 8
6744
assert page.samplesperpixel == 1
6745
# assert series properties
6746
series = tif.series[0]
6747
assert series.shape == (607, 800)
6748
assert series.dtype == numpy.uint8
6749
assert series.axes == 'YX'
6750
assert series.kind == 'uniform'
6752
data = tif.asarray()
6753
assert isinstance(data, numpy.ndarray)
6754
assert data.flags['C_CONTIGUOUS']
6755
assert data.shape == (607, 800)
6756
assert data.dtype == numpy.uint8
6757
assert data[273, 426] == 34
6758
assert_aszarr_method(tif, data)
6762
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6763
def test_read_jello():
6764
"""Test read 256x192x3, uint16, palette, PackBits."""
6765
fname = public_file('juicypixels/jello.tif')
6766
with TiffFile(fname) as tif:
6767
assert tif.byteorder == '>'
6768
assert len(tif.pages) == 1
6769
assert len(tif.series) == 1
6770
# assert page properties
6771
page = tif.pages.first
6772
assert page.photometric == PHOTOMETRIC.PALETTE
6773
assert page.planarconfig == PLANARCONFIG.CONTIG
6774
assert page.compression == COMPRESSION.PACKBITS
6775
assert page.imagewidth == 256
6776
assert page.imagelength == 192
6777
assert page.bitspersample == 8
6778
assert page.samplesperpixel == 1
6779
# assert series properties
6780
series = tif.series[0]
6781
assert series.shape == (192, 256)
6782
assert series.dtype == numpy.uint8
6783
assert series.axes == 'YX'
6784
assert series.kind == 'uniform'
6786
data = page.asrgb(uint8=False)
6787
assert isinstance(data, numpy.ndarray)
6788
assert data.flags['C_CONTIGUOUS']
6789
assert data.shape == (192, 256, 3)
6790
assert data.dtype == numpy.uint16
6791
assert tuple(data[100, 140, :]) == (48895, 65279, 48895)
6795
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6796
def test_read_quad_lzw():
6797
"""Test read 384x512 RGB uint8 old style LZW."""
6798
fname = public_file('libtiff/quad-lzw-compat.tiff')
6799
with TiffFile(fname) as tif:
6800
assert tif.byteorder == '>'
6801
assert len(tif.pages) == 1
6802
assert len(tif.series) == 1
6803
# assert page properties
6804
page = tif.pages.first
6805
assert not page.is_tiled
6806
assert page.photometric == PHOTOMETRIC.RGB
6807
assert page.compression == COMPRESSION.LZW
6808
assert page.imagewidth == 512
6809
assert page.imagelength == 384
6810
assert page.bitspersample == 8
6811
assert page.samplesperpixel == 3
6812
# assert series properties
6813
series = tif.series[0]
6814
assert series.shape == (384, 512, 3)
6815
assert series.dtype == numpy.uint8
6816
assert series.axes == 'YXS'
6817
assert series.kind == 'uniform'
6819
data = tif.asarray()
6820
assert isinstance(data, numpy.ndarray)
6821
assert data.flags['C_CONTIGUOUS']
6822
assert data.shape == (384, 512, 3)
6823
assert data.dtype == numpy.uint8
6824
assert tuple(data[309, 460, :]) == (0, 163, 187)
6825
assert_aszarr_method(tif, data)
6828
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
6829
def test_read_quad_lzw_le():
6830
"""Test read 384x512 RGB uint8 LZW."""
6831
fname = private_file('quad-lzw_le.tif')
6832
with TiffFile(fname) as tif:
6833
assert tif.byteorder == '<'
6834
assert len(tif.pages) == 1
6835
assert len(tif.series) == 1
6836
# assert page properties
6837
page = tif.pages.first
6838
assert page.photometric == PHOTOMETRIC.RGB
6839
assert not page.is_tiled
6840
assert page.compression == COMPRESSION.LZW
6841
assert page.imagewidth == 512
6842
assert page.imagelength == 384
6843
assert page.bitspersample == 8
6844
assert page.samplesperpixel == 3
6845
# assert series properties
6846
series = tif.series[0]
6847
assert series.shape == (384, 512, 3)
6848
assert series.dtype == numpy.uint8
6849
assert series.axes == 'YXS'
6850
assert series.kind == 'uniform'
6852
data = tif.asarray()
6853
assert isinstance(data, numpy.ndarray)
6854
assert data.flags['C_CONTIGUOUS']
6855
assert data.shape == (384, 512, 3)
6856
assert data.dtype == numpy.uint8
6857
assert tuple(data[309, 460, :]) == (0, 163, 187)
6858
assert_aszarr_method(tif, data)
6859
assert_decode_method(page)
6862
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6863
def test_read_quad_tile():
6864
"""Test read 384x512 RGB uint8 LZW tiled."""
6865
# Strips and tiles defined in same page
6866
fname = public_file('juicypixels/quad-tile.tif')
6867
with TiffFile(fname) as tif:
6869
assert tif.byteorder == '>'
6870
assert len(tif.pages) == 1
6871
assert len(tif.series) == 1
6872
# assert page properties
6873
page = tif.pages.first
6874
assert page.photometric == PHOTOMETRIC.RGB
6875
assert page.is_tiled
6876
assert page.compression == COMPRESSION.LZW
6877
assert page.imagewidth == 512
6878
assert page.imagelength == 384
6879
assert page.imagedepth == 1
6880
assert page.tilewidth == 128
6881
assert page.tilelength == 128
6882
assert page.tiledepth == 1
6883
assert page.bitspersample == 8
6884
assert page.samplesperpixel == 3
6885
# assert series properties
6886
series = tif.series[0]
6887
assert series.shape == (384, 512, 3)
6888
assert series.dtype == numpy.uint8
6889
assert series.axes == 'YXS'
6890
assert series.kind == 'uniform'
6892
data = tif.asarray()
6893
# assert 'invalid tile data (49153,) (1, 128, 128, 3)' in caplog.text
6894
assert isinstance(data, numpy.ndarray)
6895
assert data.flags['C_CONTIGUOUS']
6896
assert data.shape == (384, 512, 3)
6897
assert data.dtype == numpy.uint8
6898
assert tuple(data[309, 460, :]) == (0, 163, 187)
6899
assert_aszarr_method(tif, data)
6902
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
6903
def test_read_strike():
6904
"""Test read 256x200 RGBA uint8 LZW."""
6905
fname = public_file('juicypixels/strike.tif')
6906
with TiffFile(fname) as tif:
6908
assert tif.byteorder == '>'
6909
assert len(tif.pages) == 1
6910
assert len(tif.series) == 1
6911
# assert page properties
6912
page = tif.pages.first
6913
assert page.photometric == PHOTOMETRIC.RGB
6914
assert page.compression == COMPRESSION.LZW
6915
assert page.imagewidth == 256
6916
assert page.imagelength == 200
6917
assert page.bitspersample == 8
6918
assert page.samplesperpixel == 4
6919
assert page.extrasamples[0] == EXTRASAMPLE.ASSOCALPHA
6920
# assert series properties
6921
series = tif.series[0]
6922
assert series.shape == (200, 256, 4)
6923
assert series.dtype == numpy.uint8
6924
assert series.axes == 'YXS'
6925
assert series.kind == 'uniform'
6927
data = tif.asarray()
6928
assert isinstance(data, numpy.ndarray)
6929
assert data.flags['C_CONTIGUOUS']
6930
assert data.shape == (200, 256, 4)
6931
assert data.dtype == numpy.uint8
6932
assert tuple(data[65, 139, :]) == (43, 34, 17, 91)
6933
assert_aszarr_method(tif, data)
6934
assert_decode_method(page)
6938
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6939
def test_read_incomplete_tile_contig():
6940
"""Test read PackBits compressed incomplete tile, contig RGB."""
6941
fname = public_file('GDAL/contig_tiled.tif')
6942
with TiffFile(fname) as tif:
6943
assert tif.byteorder == '>'
6944
assert len(tif.pages) == 1
6945
assert len(tif.series) == 1
6946
# assert page properties
6947
page = tif.pages.first
6948
assert page.photometric == PHOTOMETRIC.RGB
6949
assert page.planarconfig == PLANARCONFIG.CONTIG
6950
assert page.compression == COMPRESSION.PACKBITS
6951
assert page.imagewidth == 35
6952
assert page.imagelength == 37
6953
assert page.bitspersample == 8
6954
assert page.samplesperpixel == 3
6955
# assert series properties
6956
series = tif.series[0]
6957
assert series.shape == (37, 35, 3)
6958
assert series.dtype == numpy.uint8
6959
assert series.axes == 'YXS'
6960
assert series.kind == 'uniform'
6962
data = page.asarray()
6963
assert data.flags['C_CONTIGUOUS']
6964
assert data.shape == (37, 35, 3)
6965
assert data.dtype == numpy.uint8
6966
assert tuple(data[19, 31]) == (50, 50, 50)
6967
assert tuple(data[36, 34]) == (70, 70, 70)
6968
assert_aszarr_method(page, data)
6969
assert_decode_method(page)
6973
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
6974
def test_read_incomplete_tile_separate():
6975
"""Test read PackBits compressed incomplete tile, separate RGB."""
6976
fname = public_file('GDAL/separate_tiled.tif')
6977
with TiffFile(fname) as tif:
6978
assert tif.byteorder == '>'
6979
assert len(tif.pages) == 1
6980
assert len(tif.series) == 1
6981
# assert page properties
6982
page = tif.pages.first
6983
assert page.photometric == PHOTOMETRIC.RGB
6984
assert page.planarconfig == PLANARCONFIG.SEPARATE
6985
assert page.compression == COMPRESSION.PACKBITS
6986
assert page.imagewidth == 35
6987
assert page.imagelength == 37
6988
assert page.bitspersample == 8
6989
assert page.samplesperpixel == 3
6990
# assert series properties
6991
series = tif.series[0]
6992
assert series.shape == (3, 37, 35)
6993
assert series.dtype == numpy.uint8
6994
assert series.axes == 'SYX'
6995
assert series.kind == 'uniform'
6997
data = page.asarray()
6998
assert data.flags['C_CONTIGUOUS']
6999
assert data.shape == (3, 37, 35)
7000
assert data.dtype == numpy.uint8
7001
assert tuple(data[:, 19, 31]) == (50, 50, 50)
7002
assert tuple(data[:, 36, 34]) == (70, 70, 70)
7003
assert_aszarr_method(page, data)
7004
assert_decode_method(page)
7008
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
7009
def test_read_django():
7010
"""Test read 3x480x320, uint16, palette, raw."""
7011
fname = private_file('django.tiff')
7012
with TiffFile(fname) as tif:
7013
assert tif.byteorder == '<'
7014
assert len(tif.pages) == 1
7015
assert len(tif.series) == 1
7016
# assert page properties
7017
page = tif.pages.first
7018
assert page.photometric == PHOTOMETRIC.PALETTE
7019
assert page.planarconfig == PLANARCONFIG.CONTIG
7020
assert page.compression == COMPRESSION.NONE
7021
assert page.imagewidth == 320
7022
assert page.imagelength == 480
7023
assert page.bitspersample == 8
7024
assert page.samplesperpixel == 1
7025
# assert series properties
7026
series = tif.series[0]
7027
assert series.shape == (480, 320)
7028
assert series.dtype == numpy.uint8
7029
assert series.axes == 'YX'
7030
assert series.kind == 'uniform'
7032
data = page.asrgb(uint8=False)
7033
assert isinstance(data, numpy.ndarray)
7034
assert data.flags['C_CONTIGUOUS']
7035
assert data.shape == (480, 320, 3)
7036
assert data.dtype == numpy.uint16
7037
assert tuple(data[64, 64, :]) == (65535, 52171, 63222)
7041
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
7042
def test_read_pygame_icon():
7043
"""Test read 128x128 RGBA uint8 PackBits."""
7044
fname = private_file('pygame_icon.tiff')
7045
with TiffFile(fname) as tif:
7046
assert tif.byteorder == '>'
7047
assert len(tif.pages) == 1
7048
assert len(tif.series) == 1
7049
# assert page properties
7050
page = tif.pages.first
7051
assert page.photometric == PHOTOMETRIC.RGB
7052
assert page.compression == COMPRESSION.PACKBITS
7053
assert page.imagewidth == 128
7054
assert page.imagelength == 128
7055
assert page.bitspersample == 8
7056
assert page.samplesperpixel == 4
7057
assert page.extrasamples[0] == EXTRASAMPLE.UNASSALPHA # ?
7058
assert page.tags['Software'].value == 'QuickTime 5.0.5'
7059
assert page.tags['HostComputer'].value == 'MacOS 10.1.2'
7060
assert page.tags['DateTime'].value == '2001:12:21 04:34:56'
7061
assert page.datetime == datetime.datetime(2001, 12, 21, 4, 34, 56)
7062
# assert series properties
7063
series = tif.series[0]
7064
assert series.shape == (128, 128, 4)
7065
assert series.dtype == numpy.uint8
7066
assert series.axes == 'YXS'
7067
assert series.kind == 'uniform'
7069
data = tif.asarray()
7070
assert isinstance(data, numpy.ndarray)
7071
assert data.flags['C_CONTIGUOUS']
7072
assert data.shape == (128, 128, 4)
7073
assert data.dtype == numpy.uint8
7074
assert tuple(data[22, 112, :]) == (100, 99, 98, 132)
7075
assert_aszarr_method(tif, data)
7079
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
7080
def test_read_rgba_wo_extra_samples():
7081
"""Test read 1065x785 RGBA uint8."""
7082
fname = private_file('rgba_wo_extra_samples.tif')
7083
with TiffFile(fname) as tif:
7084
assert tif.byteorder == '<'
7085
assert len(tif.pages) == 1
7086
assert len(tif.series) == 1
7087
# assert page properties
7088
page = tif.pages.first
7089
assert page.photometric == PHOTOMETRIC.RGB
7090
assert page.compression == COMPRESSION.LZW
7091
assert page.imagewidth == 1065
7092
assert page.imagelength == 785
7093
assert page.bitspersample == 8
7094
assert page.samplesperpixel == 4
7095
# with self.assertRaises(AttributeError):
7097
# assert series properties
7098
series = tif.series[0]
7099
assert series.shape == (785, 1065, 4)
7100
assert series.dtype == numpy.uint8
7101
assert series.axes == 'YXS'
7102
assert series.kind == 'uniform'
7104
data = tif.asarray()
7105
assert isinstance(data, numpy.ndarray)
7106
assert data.flags['C_CONTIGUOUS']
7107
assert data.shape == (785, 1065, 4)
7108
assert data.dtype == numpy.uint8
7109
assert tuple(data[560, 412, :]) == (60, 92, 74, 255)
7110
assert_aszarr_method(tif, data)
7111
assert_decode_method(page)
7115
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
7116
def test_read_rgb565():
7117
"""Test read 64x64 RGB uint8 5,6,5 bitspersample."""
7118
fname = private_file('rgb565.tif')
7119
with TiffFile(fname) as tif:
7120
assert tif.byteorder == '<'
7121
assert len(tif.pages) == 1
7122
assert len(tif.series) == 1
7123
# assert page properties
7124
page = tif.pages.first
7125
assert page.photometric == PHOTOMETRIC.RGB
7126
assert page.compression == COMPRESSION.NONE
7127
assert page.imagewidth == 64
7128
assert page.imagelength == 64
7129
assert page.bitspersample == (5, 6, 5)
7130
assert page.samplesperpixel == 3
7131
# assert series properties
7132
series = tif.series[0]
7133
assert series.shape == (64, 64, 3)
7134
assert series.dtype == numpy.uint8
7135
assert series.axes == 'YXS'
7136
assert series.kind == 'uniform'
7138
data = tif.asarray()
7139
assert isinstance(data, numpy.ndarray)
7140
assert data.flags['C_CONTIGUOUS']
7141
assert data.shape == (64, 64, 3)
7142
assert data.dtype == numpy.uint8
7143
assert tuple(data[56, 32, :]) == (239, 243, 247)
7144
assert_aszarr_method(tif, data)
7145
assert_decode_method(page)
7149
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
7150
def test_read_generic_series():
7151
"""Test read 4 series in 6 pages."""
7152
fname = public_file('tifffile/generic_series.tif')
7153
with TiffFile(fname) as tif:
7154
assert tif.byteorder == '<'
7155
assert len(tif.pages) == 6
7156
assert len(tif.series) == 4
7157
# assert series 0 properties
7158
series = tif.series[0]
7159
assert series.shape == (3, 20, 20)
7160
assert series.dtype == numpy.uint8
7161
assert series.axes == 'IYX'
7162
assert series.kind == 'generic'
7163
page = series.pages[0]
7164
assert page.compression == COMPRESSION.LZW
7165
assert page.imagewidth == 20
7166
assert page.imagelength == 20
7167
assert page.bitspersample == 8
7168
assert page.samplesperpixel == 1
7169
data = tif.asarray(series=0)
7170
assert data.flags['C_CONTIGUOUS']
7171
assert data.shape == (3, 20, 20)
7172
assert data.dtype == numpy.uint8
7173
assert tuple(data[:, 9, 9]) == (19, 90, 206)
7174
assert_aszarr_method(tif, data, series=0)
7175
# assert series 1 properties
7176
series = tif.series[1]
7177
assert series.shape == (10, 10, 3)
7178
assert series.dtype == numpy.float32
7179
assert series.axes == 'YXS'
7180
assert series.kind == 'generic'
7181
page = series.pages[0]
7182
assert page.photometric == PHOTOMETRIC.RGB
7183
assert page.compression == COMPRESSION.LZW
7184
assert page.imagewidth == 10
7185
assert page.imagelength == 10
7186
assert page.bitspersample == 32
7187
assert page.samplesperpixel == 3
7188
data = tif.asarray(series=1)
7189
assert isinstance(data, numpy.ndarray)
7190
assert data.flags['C_CONTIGUOUS']
7191
assert data.shape == (10, 10, 3)
7192
assert data.dtype == numpy.float32
7193
assert round(abs(data[9, 9, 1] - 214.5733642578125), 7) == 0
7194
assert_aszarr_method(tif, data, series=1)
7195
# assert series 2 properties
7196
series = tif.series[2]
7197
assert series.shape == (20, 20, 3)
7198
assert series.dtype == numpy.uint8
7199
assert series.axes == 'YXS'
7200
assert series.kind == 'generic'
7201
page = series.pages[0]
7202
assert page.photometric == PHOTOMETRIC.RGB
7203
assert page.compression == COMPRESSION.LZW
7204
assert page.imagewidth == 20
7205
assert page.imagelength == 20
7206
assert page.bitspersample == 8
7207
assert page.samplesperpixel == 3
7208
data = tif.asarray(series=2)
7209
assert isinstance(data, numpy.ndarray)
7210
assert data.flags['C_CONTIGUOUS']
7211
assert data.shape == (20, 20, 3)
7212
assert data.dtype == numpy.uint8
7213
assert tuple(data[9, 9, :]) == (19, 90, 206)
7214
assert_aszarr_method(tif, data, series=2)
7215
# assert series 3 properties
7216
series = tif.series[3]
7217
assert series.shape == (10, 10)
7218
assert series.dtype == numpy.float32
7219
assert series.axes == 'YX'
7220
assert series.kind == 'generic'
7221
page = series.pages[0]
7222
assert page.compression == COMPRESSION.LZW
7223
assert page.imagewidth == 10
7224
assert page.imagelength == 10
7225
assert page.bitspersample == 32
7226
assert page.samplesperpixel == 1
7227
data = tif.asarray(series=3)
7228
assert isinstance(data, numpy.ndarray)
7229
assert data.flags['C_CONTIGUOUS']
7230
assert data.shape == (10, 10)
7231
assert data.dtype == numpy.float32
7232
assert round(abs(data[9, 9] - 223.1648712158203), 7) == 0
7233
assert_aszarr_method(tif, data, series=3)
7237
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
7238
def test_read_freeimage():
7239
"""Test read 3 series in 3 pages RGB LZW."""
7240
fname = private_file('freeimage.tif')
7241
with TiffFile(fname) as tif:
7242
assert tif.byteorder == '<'
7243
assert len(tif.pages) == 3
7244
assert len(tif.series) == 3
7245
for i, shape in enumerate(((100, 600), (379, 574), (689, 636))):
7246
series = tif.series[i]
7247
shape = shape + (3,)
7248
assert series.shape == shape
7249
assert series.dtype == numpy.uint8
7250
assert series.axes == 'YXS'
7251
assert series.kind == 'generic'
7252
page = series.pages[0]
7253
assert page.photometric == PHOTOMETRIC.RGB
7254
assert page.compression == COMPRESSION.LZW
7255
assert page.imagewidth == shape[1]
7256
assert page.imagelength == shape[0]
7257
assert page.bitspersample == 8
7258
assert page.samplesperpixel == 3
7259
data = tif.asarray(series=i)
7260
assert isinstance(data, numpy.ndarray)
7261
assert data.flags['C_CONTIGUOUS']
7262
assert data.shape == shape
7263
assert data.dtype == numpy.uint8
7264
assert_aszarr_method(tif, data, series=i)
7268
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
7269
def test_read_leadtools():
7270
"""Test read LeadTools 11-pages with different compression."""
7271
# https://www.leadtools.com/support/forum/posts/t10960-
7272
fname = private_file('LeadTools/MultipleFormats.tif')
7273
with TiffFile(fname) as tif:
7274
assert tif.byteorder == '<'
7275
assert len(tif.pages) == 11
7276
assert len(tif.series) == 11
7278
# 1- Uncompressed bilevel
7279
page = tif.pages.first
7280
assert page.photometric == PHOTOMETRIC.MINISBLACK
7281
assert page.compression == COMPRESSION.NONE
7282
assert page.imagewidth == 600
7283
assert page.imagelength == 75
7284
assert page.bitspersample == 1
7285
assert page.samplesperpixel == 1
7286
data = page.asarray()
7287
assert data.shape == (75, 600)
7288
assert data.dtype == numpy.bool_
7289
# 2- Uncompressed CMYK
7291
assert page.photometric == PHOTOMETRIC.SEPARATED
7292
assert page.compression == COMPRESSION.NONE
7293
assert page.imagewidth == 600
7294
assert page.imagelength == 75
7295
assert page.bitspersample == 8
7296
assert page.samplesperpixel == 4
7297
data = page.asarray()
7298
assert data.shape == (75, 600, 4)
7299
assert data.dtype == numpy.uint8
7300
# 3- JPEG 2000 compression
7302
assert page.photometric == PHOTOMETRIC.RGB
7303
assert page.compression == COMPRESSION.JPEG2000
7304
assert page.imagewidth == 600
7305
assert page.imagelength == 75
7306
assert page.bitspersample == 8
7307
assert page.samplesperpixel == 3
7308
data = page.asarray()
7309
assert data.shape == (75, 600, 3)
7310
assert data.dtype == numpy.uint8
7311
# 4- JPEG 4:1:1 compression
7313
assert page.photometric == PHOTOMETRIC.YCBCR
7314
assert page.compression == COMPRESSION.JPEG
7315
assert page.imagewidth == 600
7316
assert page.imagelength == 75
7317
assert page.bitspersample == 8
7318
assert page.samplesperpixel == 3
7319
assert page.tags['YCbCrSubSampling'].value == (2, 2)
7320
data = page.asarray()
7321
assert data.shape == (75, 600, 3)
7322
assert data.dtype == numpy.uint8
7323
# 5- JBIG compression
7325
assert page.photometric == PHOTOMETRIC.MINISBLACK
7326
assert page.compression == COMPRESSION.JBIG
7327
assert page.imagewidth == 600
7328
assert page.imagelength == 75
7329
assert page.bitspersample == 1
7330
assert page.samplesperpixel == 1
7331
with pytest.raises(ValueError):
7332
data = page.asarray()
7333
# 6- RLE Packbits compression
7335
assert page.photometric == PHOTOMETRIC.RGB
7336
assert page.compression == COMPRESSION.PACKBITS
7337
assert page.imagewidth == 600
7338
assert page.imagelength == 75
7339
assert page.bitspersample == 8
7340
assert page.samplesperpixel == 3
7341
data = page.asarray()
7342
assert data.shape == (75, 600, 3)
7343
assert data.dtype == numpy.uint8
7344
# 7- CMYK with RLE Packbits compression
7346
assert page.photometric == PHOTOMETRIC.SEPARATED
7347
assert page.compression == COMPRESSION.PACKBITS
7348
assert page.imagewidth == 600
7349
assert page.imagelength == 75
7350
assert page.bitspersample == 8
7351
assert page.samplesperpixel == 4
7352
data = page.asarray()
7353
assert data.shape == (75, 600, 4)
7354
assert data.dtype == numpy.uint8
7355
# 8- YCC with RLE Packbits compression
7357
assert page.photometric == PHOTOMETRIC.YCBCR
7358
assert page.compression == COMPRESSION.PACKBITS
7359
assert page.imagewidth == 600
7360
assert page.imagelength == 75
7361
assert page.bitspersample == 8
7362
assert page.samplesperpixel == 3
7363
assert page.tags['YCbCrSubSampling'].value == (2, 1)
7364
with pytest.raises(NotImplementedError):
7365
data = page.asarray()
7366
# 9- LZW compression
7368
assert page.photometric == PHOTOMETRIC.MINISBLACK
7369
assert page.compression == COMPRESSION.LZW
7370
assert page.imagewidth == 600
7371
assert page.imagelength == 75
7372
assert page.bitspersample == 1
7373
assert page.samplesperpixel == 1
7374
data = page.asarray()
7375
assert data.shape == (75, 600)
7376
assert data.dtype == numpy.bool_
7377
# 10- CCITT Group 4 compression
7379
assert page.photometric == PHOTOMETRIC.MINISWHITE
7380
assert page.compression == COMPRESSION.CCITT_T6
7381
assert page.imagewidth == 600
7382
assert page.imagelength == 75
7383
assert page.bitspersample == 1
7384
assert page.samplesperpixel == 1
7385
with pytest.raises(ValueError):
7386
data = page.asarray()
7387
# 11- CCITT Group 3 2-D compression
7388
page = tif.pages[10]
7389
assert page.photometric == PHOTOMETRIC.MINISWHITE
7390
assert page.compression == COMPRESSION.CCITT_T4
7391
assert page.imagewidth == 600
7392
assert page.imagelength == 75
7393
assert page.bitspersample == 1
7394
assert page.samplesperpixel == 1
7395
with pytest.raises(ValueError):
7396
data = page.asarray()
7399
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
7400
def test_read_12bit():
7401
"""Test read 12 bit images."""
7402
fname = private_file('12bit.tif')
7403
with TiffFile(fname) as tif:
7404
assert tif.byteorder == '<'
7405
assert len(tif.pages) == 1000
7406
assert len(tif.series) == 1
7407
# assert page properties
7408
page = tif.pages.first
7409
assert not page.is_contiguous
7410
assert page.compression == COMPRESSION.NONE
7411
assert page.imagewidth == 1024
7412
assert page.imagelength == 304
7413
assert page.bitspersample == 12
7414
assert page.samplesperpixel == 1
7415
# assert series properties
7416
series = tif.series[0]
7417
assert series.shape == (1000, 304, 1024)
7418
assert series.dtype == numpy.uint16
7419
assert series.axes == 'IYX'
7420
assert series.kind == 'uniform'
7422
data = tif.asarray(478)
7423
assert isinstance(data, numpy.ndarray)
7424
assert data.flags['C_CONTIGUOUS']
7425
assert data.shape == (304, 1024)
7426
assert data.dtype == numpy.uint16
7427
assert round(abs(data[138, 475] - 40), 7) == 0
7428
assert_aszarr_method(tif, data, key=478)
7429
assert__str__(tif, 0)
7432
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
7433
def test_read_lzw_12bit_table():
7434
"""Test read lzw-full-12-bit-table.tif.
7436
Also test RowsPerStrip > ImageLength.
7439
fname = public_file('twelvemonkeys/tiff/lzw-full-12-bit-table.tif')
7440
with TiffFile(fname) as tif:
7441
assert len(tif.series) == 1
7442
assert len(tif.pages) == 1
7443
page = tif.pages.first
7444
assert page.photometric == PHOTOMETRIC.MINISBLACK
7445
assert page.imagewidth == 874
7446
assert page.imagelength == 1240
7447
assert page.bitspersample == 8
7448
assert page.samplesperpixel == 1
7449
assert page.rowsperstrip == 1240
7450
assert page.tags['RowsPerStrip'].value == 4294967295
7452
image = page.asarray()
7453
assert image.flags['C_CONTIGUOUS']
7454
assert image[434, 588] == 88
7455
assert image[400, 600] == 255
7456
assert_aszarr_method(page, image)
7460
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS or SKIP_LARGE, reason=REASON)
7461
def test_read_lzw_large_buffer():
7462
"""Test read LZW compression which requires large buffer."""
7463
# https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC-App
7465
fname = private_file('lzw/lzw_large_buffer.tiff')
7466
with TiffFile(fname) as tif:
7467
assert len(tif.pages) == 1
7468
page = tif.pages.first
7469
assert page.compression == COMPRESSION.LZW
7470
assert page.imagewidth == 5104
7471
assert page.imagelength == 8400
7472
assert page.bitspersample == 8
7473
assert page.samplesperpixel == 4
7475
image = page.asarray()
7476
assert image.shape == (8400, 5104, 4)
7477
assert image.dtype == numpy.uint8
7478
image = tif.asarray()
7479
assert image.shape == (8400, 5104, 4)
7480
assert image.dtype == numpy.uint8
7481
assert image[4200, 2550, 0] == 0
7482
assert image[4200, 2550, 3] == 255
7483
assert_aszarr_method(tif, image)
7487
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
7488
def test_read_lzw_ycbcr_subsampling():
7489
"""Test fail LZW compression with subsampling."""
7490
fname = private_file('lzw/lzw_ycbcr_subsampling.tif')
7491
with TiffFile(fname) as tif:
7492
assert len(tif.pages) == 1
7493
page = tif.pages.first
7494
assert page.compression == COMPRESSION.LZW
7495
assert page.photometric == PHOTOMETRIC.YCBCR
7496
assert page.planarconfig == PLANARCONFIG.CONTIG
7497
assert page.imagewidth == 39
7498
assert page.imagelength == 39
7499
assert page.bitspersample == 8
7500
assert page.samplesperpixel == 3
7502
with pytest.raises(NotImplementedError):
7507
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
7508
def test_read_ycbcr_subsampling():
7509
"""Test fail YCBCR with subsampling."""
7510
fname = private_file('ycbcr_subsampling.tif')
7511
with TiffFile(fname) as tif:
7512
assert len(tif.pages) == 2
7513
page = tif.pages.first
7514
assert page.compression == COMPRESSION.NONE
7515
assert page.photometric == PHOTOMETRIC.YCBCR
7516
assert page.planarconfig == PLANARCONFIG.CONTIG
7517
assert page.imagewidth == 640
7518
assert page.imagelength == 480
7519
assert page.bitspersample == 8
7520
assert page.samplesperpixel == 3
7522
with pytest.raises(NotImplementedError):
7528
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
7531
def test_read_jpeg_baboon():
7532
"""Test JPEG compression."""
7533
fname = private_file('baboon.tiff')
7534
with TiffFile(fname) as tif:
7535
assert tif.byteorder == '<'
7536
assert len(tif.pages) == 1
7537
assert len(tif.series) == 1
7538
# assert page properties
7539
page = tif.pages.first
7540
assert 'JPEGTables' in page.tags
7541
assert not page.is_reduced
7542
assert not page.is_tiled
7543
assert page.compression == COMPRESSION.JPEG
7544
assert page.imagewidth == 512
7545
assert page.imagelength == 512
7546
assert page.bitspersample == 8
7547
# assert series properties
7548
series = tif.series[0]
7549
assert series.shape == (512, 512, 3)
7550
assert series.dtype == numpy.uint8
7551
assert series.axes == 'YXS'
7552
assert series.kind == 'uniform'
7554
# with pytest.raises((ValueError, NotImplementedError)):
7555
image = tif.asarray()
7556
assert image.flags['C_CONTIGUOUS']
7557
assert_aszarr_method(tif, image)
7562
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
7565
def test_read_jpeg_ycbcr():
7566
"""Test read YCBCR JPEG is returned as RGB."""
7567
fname = private_file('jpeg/jpeg_ycbcr.tiff')
7568
with TiffFile(fname) as tif:
7569
assert len(tif.pages) == 1
7570
page = tif.pages.first
7571
assert page.compression == COMPRESSION.JPEG
7572
assert page.photometric == PHOTOMETRIC.YCBCR
7573
assert page.planarconfig == PLANARCONFIG.CONTIG
7574
assert page.imagewidth == 128
7575
assert page.imagelength == 80
7576
assert page.bitspersample == 8
7577
assert page.samplesperpixel == 3
7579
image = tif.asarray()
7580
assert image.flags['C_CONTIGUOUS']
7581
assert image.shape == (80, 128, 3)
7582
assert image.dtype == numpy.uint8
7583
assert tuple(image[50, 50, :]) == (177, 149, 210)
7584
# YCBCR (164, 154, 137)
7585
assert_aszarr_method(tif, image)
7586
assert_decode_method(page)
7591
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
7594
@pytest.mark.parametrize(
7595
'fname', ['tiff_tiled_cmyk_jpeg.tif', 'tiff_strip_cmyk_jpeg.tif']
7597
def test_read_jpeg_cmyk(fname):
7598
"""Test read JPEG compressed CMYK image."""
7599
with TiffFile(private_file(f'pillow/{fname}')) as tif:
7600
assert len(tif.pages) == 1
7601
page = tif.pages.first
7602
assert page.compression == COMPRESSION.JPEG
7603
assert page.photometric == PHOTOMETRIC.SEPARATED
7604
assert page.shape == (100, 100, 4)
7605
assert page.dtype == numpy.uint8
7606
data = page.asarray()
7607
assert data.shape == (100, 100, 4)
7608
assert data.dtype == numpy.uint8
7609
assert tuple(data[46, 49]) == (79, 230, 222, 77)
7610
assert_aszarr_method(tif, data)
7611
# assert_decode_method(page)
7616
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG8.available,
7619
def test_read_jpeg12_mandril():
7620
"""Test read JPEG 12-bit compression."""
7622
fname = private_file('jpeg/jpeg12_mandril.tif')
7623
with TiffFile(fname) as tif:
7624
assert len(tif.pages) == 1
7625
page = tif.pages.first
7626
assert page.compression == COMPRESSION.JPEG
7627
assert page.photometric == PHOTOMETRIC.YCBCR
7628
assert page.imagewidth == 512
7629
assert page.imagelength == 480
7630
assert page.bitspersample == 12
7631
assert page.samplesperpixel == 3
7633
image = tif.asarray()
7634
assert image.flags['C_CONTIGUOUS']
7635
assert image.shape == (480, 512, 3)
7636
assert image.dtype == numpy.uint16
7637
assert tuple(image[128, 128, :]) == (1685, 1859, 1376)
7638
# YCBCR (1752, 1836, 2000)
7639
assert_aszarr_method(tif, image)
7647
or not imagecodecs.JPEG.available,
7650
def test_read_jpeg_lsb2msb():
7651
"""Test read huge tiled, JPEG compressed, with lsb2msb specified.
7653
Also test JPEG with RGB photometric.
7656
fname = private_file('large/jpeg_lsb2msb.tif')
7657
with TiffFile(fname) as tif:
7658
assert len(tif.pages) == 1
7659
page = tif.pages.first
7660
assert page.compression == COMPRESSION.JPEG
7661
assert page.photometric == PHOTOMETRIC.RGB
7662
assert not page.is_jfif
7663
assert page.imagewidth == 49128
7664
assert page.imagelength == 59683
7665
assert page.bitspersample == 8
7666
assert page.samplesperpixel == 3
7668
image = tif.asarray()
7669
assert image.flags['C_CONTIGUOUS']
7670
assert image.shape == (59683, 49128, 3)
7671
assert image.dtype == numpy.uint8
7672
assert tuple(image[38520, 43767, :]) == (255, 255, 255)
7673
assert tuple(image[47866, 30076, :]) == (52, 39, 23)
7680
or not imagecodecs.JPEG.available
7681
or not imagecodecs.JPEG2K.available,
7684
def test_read_aperio_j2k():
7685
"""Test read SVS slide with J2K compression."""
7686
fname = private_file('slides/CMU-1-JP2K-33005.tif')
7687
with TiffFile(fname) as tif:
7689
assert len(tif.pages) == 6
7690
page = tif.pages.first
7691
assert page.compression == COMPRESSION.APERIO_JP2000_RGB
7692
assert page.photometric == PHOTOMETRIC.RGB
7693
assert page.planarconfig == PLANARCONFIG.CONTIG
7694
assert page.shape == (32893, 46000, 3)
7695
assert page.dtype == numpy.uint8
7697
assert page.compression == COMPRESSION.JPEG
7698
assert page.photometric == PHOTOMETRIC.RGB
7699
assert page.planarconfig == PLANARCONFIG.CONTIG
7700
assert page.shape == (732, 1024, 3)
7701
assert page.dtype == numpy.uint8
7703
assert page.compression == COMPRESSION.APERIO_JP2000_RGB
7704
assert page.photometric == PHOTOMETRIC.RGB
7705
assert page.planarconfig == PLANARCONFIG.CONTIG
7706
assert page.shape == (8223, 11500, 3)
7707
assert page.dtype == numpy.uint8
7709
assert page.compression == COMPRESSION.APERIO_JP2000_RGB
7710
assert page.photometric == PHOTOMETRIC.RGB
7711
assert page.planarconfig == PLANARCONFIG.CONTIG
7712
assert page.shape == (2055, 2875, 3)
7713
assert page.dtype == numpy.uint8
7715
assert page.is_reduced
7716
assert page.compression == COMPRESSION.LZW
7717
assert page.photometric == PHOTOMETRIC.RGB
7718
assert page.planarconfig == PLANARCONFIG.CONTIG
7719
assert page.shape == (463, 387, 3)
7720
assert page.dtype == numpy.uint8
7722
assert page.is_reduced
7723
assert page.compression == COMPRESSION.JPEG
7724
assert page.photometric == PHOTOMETRIC.RGB
7725
assert page.planarconfig == PLANARCONFIG.CONTIG
7726
assert page.shape == (431, 1280, 3)
7727
assert page.dtype == numpy.uint8
7729
image = tif.pages[3].asarray()
7730
assert image.flags['C_CONTIGUOUS']
7731
assert image.shape == (2055, 2875, 3)
7732
assert image.dtype == numpy.uint8
7733
assert image[512, 1024, 0] == 246
7734
assert image[512, 1024, 1] == 245
7735
assert image[512, 1024, 2] == 245
7737
assert_decode_method(tif.pages[3], image)
7741
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
7742
def test_read_lzma():
7743
"""Test read LZMA compression."""
7744
# 512x512, uint8, lzma compression
7745
fname = private_file('lzma.tif')
7746
with TiffFile(fname) as tif:
7747
assert tif.byteorder == '<'
7748
assert len(tif.pages) == 1
7749
assert len(tif.series) == 1
7750
# assert page properties
7751
page = tif.pages.first
7752
assert page.compression == COMPRESSION.LZMA
7753
assert page.photometric == PHOTOMETRIC.MINISBLACK
7754
assert page.imagewidth == 512
7755
assert page.imagelength == 512
7756
assert page.bitspersample == 8
7757
assert page.samplesperpixel == 1
7758
# assert series properties
7759
series = tif.series[0]
7760
assert series.shape == (512, 512)
7761
assert series.dtype == numpy.uint8
7762
assert series.axes == 'YX'
7763
assert series.kind == 'shaped'
7765
data = tif.asarray()
7766
assert data.flags['C_CONTIGUOUS']
7767
assert isinstance(data, numpy.ndarray)
7768
assert data.shape == (512, 512)
7769
assert data.dtype == numpy.uint8
7770
assert data[273, 426] == 151
7771
assert_aszarr_method(tif, data)
7776
SKIP_PUBLIC or SKIP_CODECS or not imagecodecs.WEBP.available, reason=REASON
7778
def test_read_webp():
7779
"""Test read WebP compression."""
7780
fname = public_file('GDAL/tif_webp.tif')
7781
with TiffFile(fname) as tif:
7782
assert len(tif.pages) == 1
7783
page = tif.pages.first
7784
assert page.compression == COMPRESSION.WEBP
7785
assert page.photometric == PHOTOMETRIC.RGB
7786
assert page.planarconfig == PLANARCONFIG.CONTIG
7787
assert page.imagewidth == 50
7788
assert page.imagelength == 50
7789
assert page.bitspersample == 8
7790
assert page.samplesperpixel == 3
7792
image = tif.asarray()
7793
assert image.flags['C_CONTIGUOUS']
7794
assert image.shape == (50, 50, 3)
7795
assert image.dtype == numpy.uint8
7796
assert image[25, 25, 0] == 92
7797
assert image[25, 25, 1] == 122
7798
assert image[25, 25, 2] == 37
7799
assert_aszarr_method(tif, image)
7804
SKIP_PUBLIC or SKIP_CODECS or not imagecodecs.LERC.available, reason=REASON
7806
def test_read_lerc():
7807
"""Test read LERC compression."""
7808
if not hasattr(imagecodecs, 'LERC'):
7809
pytest.skip('LERC codec missing')
7811
fname = public_file('imagecodecs/rgb.u2.lerc.tif')
7812
with TiffFile(fname) as tif:
7813
assert len(tif.pages) == 1
7814
page = tif.pages.first
7815
assert page.compression == COMPRESSION.LERC
7816
assert page.photometric == PHOTOMETRIC.RGB
7817
assert page.planarconfig == PLANARCONFIG.CONTIG
7818
assert page.imagewidth == 31
7819
assert page.imagelength == 32
7820
assert page.bitspersample == 16
7821
assert page.samplesperpixel == 3
7823
image = tif.asarray()
7824
assert image.flags['C_CONTIGUOUS']
7825
assert image.shape == (32, 31, 3)
7826
assert image.dtype == numpy.uint16
7827
assert tuple(image[25, 25]) == (3265, 1558, 2811)
7828
assert_aszarr_method(tif, image)
7833
SKIP_PUBLIC or SKIP_CODECS or not imagecodecs.ZSTD.available, reason=REASON
7835
def test_read_zstd():
7836
"""Test read ZStd compression."""
7837
fname = public_file('GDAL/byte_zstd.tif')
7838
with TiffFile(fname) as tif:
7839
assert len(tif.pages) == 1
7840
page = tif.pages.first
7841
assert page.compression == COMPRESSION.ZSTD
7842
assert page.photometric == PHOTOMETRIC.MINISBLACK
7843
assert page.planarconfig == PLANARCONFIG.CONTIG
7844
assert page.imagewidth == 20
7845
assert page.imagelength == 20
7846
assert page.bitspersample == 8
7847
assert page.samplesperpixel == 1
7849
image = tif.asarray() # fails with imagecodecs <= 2018.11.8
7850
assert image.flags['C_CONTIGUOUS']
7851
assert image.shape == (20, 20)
7852
assert image.dtype == numpy.uint8
7853
assert image[18, 1] == 247
7854
assert_aszarr_method(tif, image)
7858
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
7859
def test_read_jetraw():
7860
"""Test read Jetraw compression."""
7862
have_jetraw = imagecodecs.JETRAW.available
7863
except AttributeError:
7864
# requires imagecodecs > 2022.22.2
7867
fname = private_file('jetraw/16ms-1.p.tif')
7868
with TiffFile(fname) as tif:
7869
assert len(tif.pages) == 1
7870
page = tif.pages.first
7871
assert page.compression == COMPRESSION.JETRAW
7872
assert page.photometric == PHOTOMETRIC.MINISBLACK
7873
assert page.planarconfig == PLANARCONFIG.CONTIG
7874
assert page.imagewidth == 2304
7875
assert page.imagelength == 2304
7876
assert page.bitspersample == 16
7877
assert page.samplesperpixel == 1
7881
pytest.skip('Jetraw codec not available')
7882
image = tif.asarray()
7883
assert image[1490, 1830] == 36554
7884
assert_aszarr_method(tif, image)
7887
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
7888
def test_read_pixtiff():
7889
"""Test read PIXTIFF compression."""
7890
# https://github.com/haraldk/TwelveMonkeys/issues/307
7892
fname = private_file('PIXTIFF/pixtiff_1bpp.tif')
7893
with TiffFile(fname) as tif:
7894
page = tif.pages.first
7895
assert page.compression == COMPRESSION.PIXTIFF
7896
assert page.photometric == PHOTOMETRIC.MINISBLACK
7897
assert page.imagewidth == 801
7898
assert page.imagelength == 1313
7899
assert page.bitspersample == 1
7900
assert page.samplesperpixel == 1
7902
image = tif.asarray()
7903
assert image.dtype == numpy.bool_
7904
assert image.shape == (1313, 801)
7905
assert not image[1000, 700]
7907
fname = private_file('PIXTIFF/pixtiff_4bpp.tif')
7908
with TiffFile(fname) as tif:
7909
page = tif.pages.first
7910
assert page.compression == COMPRESSION.PIXTIFF
7911
assert page.photometric == PHOTOMETRIC.MINISBLACK
7912
assert page.imagewidth == 801
7913
assert page.imagelength == 1313
7914
assert page.bitspersample == 4
7915
assert page.samplesperpixel == 1
7917
image = tif.asarray()
7918
assert image.dtype == numpy.uint8
7919
assert image.shape == (1313, 801)
7920
assert image[1000, 700] == 6
7922
fname = private_file('PIXTIFF/pixtiff_8bpp_rgb.tif')
7923
with TiffFile(fname) as tif:
7924
page = tif.pages.first
7925
assert page.compression == COMPRESSION.PIXTIFF
7926
assert page.photometric == PHOTOMETRIC.RGB
7927
assert page.imagewidth == 801
7928
assert page.imagelength == 1313
7929
assert page.bitspersample == 8
7930
assert page.samplesperpixel == 3
7932
image = tif.asarray()
7933
assert image.dtype == numpy.uint8
7934
assert image.shape == (1313, 801, 3)
7935
assert tuple(image[1000, 700]) == (89, 70, 80)
7939
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.LJPEG.available,
7943
"""Test read JPEG compressed CFA image in SubIFD."""
7944
fname = private_file('DNG/IMG_0793.DNG')
7945
with TiffFile(fname) as tif:
7946
assert len(tif.pages) == 1
7947
assert len(tif.series) == 2
7948
page = tif.pages.first
7949
assert page.index == 0
7950
assert page.shape == (640, 852, 3)
7951
assert page.bitspersample == 8
7952
data = page.asarray()
7953
assert_aszarr_method(tif, data)
7954
page = tif.pages.first.pages[0]
7955
assert page.is_tiled
7956
assert page.treeindex == (0, 0)
7957
assert page.compression == COMPRESSION.JPEG
7958
assert page.photometric == PHOTOMETRIC.CFA
7959
assert page.shape == (3024, 4032)
7960
assert page.bitspersample == 16
7961
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
7962
assert page.tags['CFAPattern'].value == b'\x00\x01\x01\x02'
7963
data = page.asarray()
7964
assert_aszarr_method(tif.series[1], data)
7969
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.LJPEG.available,
7973
"""Test read 14-bit uncompressed and JPEG compressed CFA image."""
7974
fname = private_file('DNG/cinemadng/M14-1451_000085_cDNG_uncompressed.dng')
7975
with TiffFile(fname) as tif:
7976
assert len(tif.pages) == 1
7977
page = tif.pages.first
7978
assert page.compression == 1
7979
assert page.photometric == PHOTOMETRIC.CFA
7980
assert page.imagewidth == 960
7981
assert page.imagelength == 540
7982
assert page.bitspersample == 14
7983
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
7984
assert page.tags['CFAPattern'].value == b'\x00\x01\x01\x02'
7985
data = page.asarray()
7986
assert_aszarr_method(tif, data)
7988
fname = private_file('DNG/cinemadng/M14-1451_000085_cDNG_compressed.dng')
7989
with TiffFile(fname) as tif:
7990
assert len(tif.pages) == 1
7991
page = tif.pages.first
7992
assert page.compression == COMPRESSION.JPEG
7993
assert page.photometric == PHOTOMETRIC.CFA
7994
assert page.imagewidth == 960
7995
assert page.imagelength == 540
7996
assert page.bitspersample == 14
7997
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
7998
assert page.tags['CFAPattern'].value == b'\x00\x01\x01\x02'
7999
image = page.asarray()
8000
assert_array_equal(image, data)
8001
assert_aszarr_method(tif, data)
8004
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
8005
def test_read_lena_be_f16_contig():
8006
"""Test read big endian float16 horizontal differencing."""
8007
fname = private_file('PS/lena_be_f16_contig.tif')
8008
with TiffFile(fname) as tif:
8009
assert tif.byteorder == '>'
8010
assert len(tif.pages) == 1
8011
assert len(tif.series) == 1
8012
# assert page properties
8013
page = tif.pages.first
8014
assert not page.is_reduced
8015
assert not page.is_tiled
8016
assert page.compression == COMPRESSION.NONE
8017
assert page.imagewidth == 512
8018
assert page.imagelength == 512
8019
assert page.bitspersample == 16
8020
assert page.samplesperpixel == 3
8021
# assert series properties
8022
series = tif.series[0]
8023
assert series.shape == (512, 512, 3)
8024
assert series.dtype == numpy.float16
8025
assert series.axes == 'YXS'
8026
assert series.kind == 'imagej'
8028
data = tif.asarray(series=0)
8029
assert isinstance(data, numpy.ndarray)
8030
assert data.flags['C_CONTIGUOUS']
8031
assert data.shape == (512, 512, 3)
8032
assert data.dtype == numpy.float16
8033
assert_array_almost_equal(data[256, 256], (0.4563, 0.052856, 0.064819))
8034
assert_aszarr_method(tif, data, series=0)
8035
assert_decode_method(page)
8039
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
8040
def test_read_lena_be_f16_lzw_planar():
8041
"""Test read big endian, float16, LZW, horizontal differencing."""
8042
fname = private_file('PS/lena_be_f16_lzw_planar.tif')
8043
with TiffFile(fname, is_imagej=False) as tif:
8044
assert tif.byteorder == '>'
8045
assert len(tif.pages) == 1
8046
assert len(tif.series) == 1
8047
assert not tif.is_imagej
8048
# assert page properties
8049
page = tif.pages.first
8050
assert not page.is_reduced
8051
assert not page.is_tiled
8052
assert page.compression == COMPRESSION.LZW
8053
assert page.imagewidth == 512
8054
assert page.imagelength == 512
8055
assert page.bitspersample == 16
8056
assert page.samplesperpixel == 3
8057
# assert series properties
8058
series = tif.series[0]
8059
assert series.shape == (3, 512, 512)
8060
assert series.dtype == numpy.float16
8061
assert series.axes == 'SYX'
8062
assert series.kind == 'uniform'
8064
data = tif.asarray(series=0)
8065
assert isinstance(data, numpy.ndarray)
8066
assert data.flags['C_CONTIGUOUS']
8067
assert data.shape == (3, 512, 512)
8068
assert data.dtype == numpy.float16
8069
assert_array_almost_equal(
8070
data[:, 256, 256], (0.4563, 0.052856, 0.064819)
8072
assert_aszarr_method(tif, data, series=0)
8073
assert_decode_method(page)
8077
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
8078
def test_read_lena_be_f32_deflate_contig():
8079
"""Test read big endian, float32 horizontal differencing, deflate."""
8080
fname = private_file('PS/lena_be_f32_deflate_contig.tif')
8081
with TiffFile(fname, is_imagej=False) as tif:
8082
assert tif.byteorder == '>'
8083
assert len(tif.pages) == 1
8084
assert len(tif.series) == 1
8085
assert not tif.is_imagej
8086
# assert page properties
8087
page = tif.pages.first
8088
assert not page.is_reduced
8089
assert not page.is_tiled
8090
assert page.compression == COMPRESSION.ADOBE_DEFLATE
8091
assert page.imagewidth == 512
8092
assert page.imagelength == 512
8093
assert page.bitspersample == 32
8094
assert page.samplesperpixel == 3
8095
# assert series properties
8096
series = tif.series[0]
8097
assert series.shape == (512, 512, 3)
8098
assert series.dtype == numpy.float32
8099
assert series.axes == 'YXS'
8100
assert series.kind == 'uniform'
8102
data = tif.asarray(series=0)
8103
assert isinstance(data, numpy.ndarray)
8104
assert data.flags['C_CONTIGUOUS']
8105
assert data.shape == (512, 512, 3)
8106
assert data.dtype == numpy.float32
8107
assert_array_almost_equal(
8108
data[256, 256], (0.456386, 0.052867, 0.064795)
8110
assert_aszarr_method(tif, data, series=0)
8114
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
8115
def test_read_lena_le_f32_lzw_planar():
8116
"""Test read little endian, LZW, float32 horizontal differencing."""
8117
fname = private_file('PS/lena_le_f32_lzw_planar.tif')
8118
with TiffFile(fname, is_imagej=False) as tif:
8119
assert tif.byteorder == '<'
8120
assert len(tif.pages) == 1
8121
assert len(tif.series) == 1
8122
assert not tif.is_imagej
8123
# assert page properties
8124
page = tif.pages.first
8125
assert not page.is_reduced
8126
assert not page.is_tiled
8127
assert page.compression == COMPRESSION.LZW
8128
assert page.imagewidth == 512
8129
assert page.imagelength == 512
8130
assert page.bitspersample == 32
8131
assert page.samplesperpixel == 3
8132
# assert series properties
8133
series = tif.series[0]
8134
assert series.shape == (3, 512, 512)
8135
assert series.dtype == numpy.float32
8136
assert series.axes == 'SYX'
8137
assert series.kind == 'uniform'
8139
data = tif.asarray(series=0)
8140
assert isinstance(data, numpy.ndarray)
8141
assert data.flags['C_CONTIGUOUS']
8142
assert data.shape == (3, 512, 512)
8143
assert data.dtype == numpy.float32
8144
assert_array_almost_equal(
8145
data[:, 256, 256], (0.456386, 0.052867, 0.064795)
8147
assert_aszarr_method(tif, data, series=0)
8151
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
8152
def test_read_lena_be_rgb48():
8153
"""Test read RGB48."""
8154
fname = private_file('PS/lena_be_rgb48.tif')
8155
with TiffFile(fname) as tif:
8156
assert tif.byteorder == '>'
8157
assert len(tif.pages) == 1
8158
assert len(tif.series) == 1
8159
# assert page properties
8160
page = tif.pages.first
8161
assert not page.is_reduced
8162
assert not page.is_tiled
8163
assert page.compression == COMPRESSION.NONE
8164
assert page.imagewidth == 512
8165
assert page.imagelength == 512
8166
assert page.bitspersample == 16
8167
assert page.samplesperpixel == 3
8168
# assert series properties
8169
series = tif.series[0]
8170
assert series.shape == (512, 512, 3)
8171
assert series.dtype == numpy.uint16
8172
assert series.axes == 'YXS'
8173
assert series.kind == 'imagej'
8175
data = tif.asarray(series=0)
8176
assert isinstance(data, numpy.ndarray)
8177
assert data.flags['C_CONTIGUOUS']
8178
assert data.shape == (512, 512, 3)
8179
assert data.dtype == numpy.uint16
8180
assert_array_equal(data[256, 256], (46259, 16706, 18504))
8181
assert_aszarr_method(tif, data, series=0)
8185
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE or IS_PYPY, reason=REASON)
8186
def test_read_huge_ps5_memmap():
8187
"""Test read 30000x30000 float32 contiguous."""
8188
# TODO: segfault on pypy3.7-v7.3.5rc2-win64
8189
fname = private_file('large/huge_ps5.tif')
8190
with TiffFile(fname) as tif:
8191
assert tif.byteorder == '<'
8192
assert len(tif.pages) == 1
8193
assert len(tif.series) == 1
8194
# assert page properties
8195
page = tif.pages.first
8196
assert page.dataoffsets[0] == 21890
8197
assert page.nbytes == 3600000000
8198
assert not page.is_memmappable # data not aligned!
8199
assert page.compression == COMPRESSION.NONE
8200
assert page.imagewidth == 30000
8201
assert page.imagelength == 30000
8202
assert page.bitspersample == 32
8203
assert page.samplesperpixel == 1
8204
# assert series properties
8205
series = tif.series[0]
8206
assert series.shape == (30000, 30000)
8207
assert series.dtype == numpy.float32
8208
assert series.axes == 'YX'
8209
assert series.kind == 'uniform'
8211
data = tif.asarray(out='memmap') # memmap in a temp file
8212
assert isinstance(data, numpy.memmap)
8213
assert data.flags['C_CONTIGUOUS']
8214
assert data.shape == (30000, 30000)
8215
assert data.dtype == numpy.float32
8216
assert data[6597, 8135] == 0.008780896663665771
8217
assert_aszarr_method(tif, data)
8219
assert not tif.filehandle.closed
8223
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
8224
def test_read_movie():
8225
"""Test read 30000 pages, uint16."""
8226
fname = public_file('tifffile/movie.tif')
8227
with TiffFile(fname) as tif:
8228
assert tif.byteorder == '<'
8229
assert len(tif.pages) == 30000
8230
assert len(tif.series) == 1
8231
assert tif.is_uniform
8232
# assert series properties
8233
series = tif.series[0]
8234
assert series.shape == (30000, 64, 64)
8235
assert series.dtype == numpy.uint16
8236
assert series.axes == 'IYX'
8237
assert series.kind == 'uniform'
8238
# assert page properties
8239
page = tif.pages[-1]
8241
assert isinstance(page, TiffFrame)
8243
assert isinstance(page, TiffPage)
8244
assert page.shape == (64, 64)
8245
page = tif.pages[-3]
8247
assert isinstance(page, TiffFrame)
8249
assert isinstance(page, TiffPage)
8251
data = tif.pages[29999].asarray() # last frame
8252
assert isinstance(data, numpy.ndarray)
8253
assert data.flags['C_CONTIGUOUS']
8254
assert data.shape == (64, 64)
8255
assert data.dtype == numpy.uint16
8256
assert data[32, 32] == 460
8258
# read selected pages
8259
# https://github.com/blink1073/tifffile/issues/51
8260
data = tif.asarray(key=[31, 999, 29999])
8261
assert data.flags['C_CONTIGUOUS']
8262
assert data.shape == (3, 64, 64)
8263
assert data[2, 32, 32] == 460
8265
assert__str__(tif, 0)
8268
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
8269
def test_read_movie_memmap():
8270
"""Test read 30000 pages memory-mapped."""
8271
fname = public_file('tifffile/movie.tif')
8272
with TiffFile(fname) as tif:
8274
data = tif.asarray(out='memmap')
8275
assert isinstance(data, numpy.memmap)
8276
assert data.flags['C_CONTIGUOUS']
8277
assert data.shape == (30000, 64, 64)
8278
assert data.dtype == numpy.dtype('<u2')
8279
assert data[29999, 32, 32] == 460
8281
assert not tif.filehandle.closed
8282
assert__str__(tif, 0)
8285
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
8286
def test_read_100000_pages_movie():
8287
"""Test read 100000x64x64 big endian in memory."""
8288
fname = public_file('tifffile/100000_pages.tif')
8289
with TiffFile(fname, _useframes=True) as tif:
8290
assert tif.is_imagej
8291
assert tif.byteorder == '>'
8292
assert len(tif.pages) == 100000
8293
assert len(tif.series) == 1
8294
# assert series properties
8295
series = tif.series[0]
8296
assert series.shape == (100000, 64, 64)
8297
assert series.dtype == numpy.uint16
8298
assert series.axes == 'TYX'
8299
assert series.kind == 'imagej'
8300
# assert page properties
8301
frame = tif.pages[100]
8302
assert isinstance(frame, TiffFrame) # uniform=True
8303
assert frame.shape == (64, 64)
8304
frame = tif.pages.first
8305
assert frame.imagewidth == 64
8306
assert frame.imagelength == 64
8307
assert frame.bitspersample == 16
8308
assert frame.compression == 1
8309
assert frame.shape == (64, 64)
8310
assert frame.shaped == (1, 1, 64, 64, 1)
8311
assert frame.ndim == 2
8312
assert frame.size == 4096
8313
assert frame.nbytes == 8192
8314
assert frame.axes == 'YX'
8315
assert frame._nextifd() == 819200206
8316
assert frame.is_final
8317
assert frame.is_contiguous
8318
assert frame.is_memmappable
8321
assert frame.aszarr()
8322
# assert ImageJ tags
8323
ijmeta = tif.imagej_metadata
8324
assert ijmeta is not None
8325
assert ijmeta['ImageJ'] == '1.48g'
8326
assert round(abs(ijmeta['max'] - 119.0), 7) == 0
8327
assert round(abs(ijmeta['min'] - 86.0), 7) == 0
8329
data = tif.asarray()
8330
assert data.flags['C_CONTIGUOUS']
8331
assert data.shape == (100000, 64, 64)
8332
assert data.dtype == numpy.uint16
8333
assert round(abs(data[7310, 25, 25] - 100), 7) == 0
8334
# too slow: assert_aszarr_method(tif, data)
8336
assert__str__(tif, 0)
8339
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
8340
def test_read_chart_bl():
8341
"""Test read 13228x18710, 1 bit, no bitspersample tag."""
8342
fname = public_file('tifffile/chart_bl.tif')
8343
with TiffFile(fname) as tif:
8344
assert tif.byteorder == '<'
8345
assert len(tif.pages) == 1
8346
assert len(tif.series) == 1
8347
# assert page properties
8348
page = tif.pages.first
8349
assert page.compression == COMPRESSION.NONE
8350
assert page.imagewidth == 13228
8351
assert page.imagelength == 18710
8352
assert page.bitspersample == 1
8353
assert page.samplesperpixel == 1
8354
assert page.rowsperstrip == 18710
8355
# assert series properties
8356
series = tif.series[0]
8357
assert series.shape == (18710, 13228)
8358
assert series.dtype == numpy.bool_
8359
assert series.axes == 'YX'
8360
assert series.kind == 'uniform'
8362
data = tif.asarray()
8363
assert isinstance(data, numpy.ndarray)
8364
assert data.flags['C_CONTIGUOUS']
8365
assert data.shape == (18710, 13228)
8366
assert data.dtype == numpy.bool_
8367
assert data[0, 0] is numpy.bool_(True)
8368
assert data[5000, 5000] is numpy.bool_(False)
8370
assert_aszarr_method(tif, data)
8374
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
8375
def test_read_srtm_20_13():
8376
"""Test read 6000x6000 int16 GDAL."""
8377
fname = private_file('large/srtm_20_13.tif')
8378
with TiffFile(fname) as tif:
8379
assert tif.byteorder == '<'
8380
assert len(tif.pages) == 1
8381
assert len(tif.series) == 1
8382
# assert page properties
8383
page = tif.pages.first
8384
assert page.is_contiguous
8385
assert page.compression == COMPRESSION.NONE
8386
assert page.imagewidth == 6000
8387
assert page.imagelength == 6000
8388
assert page.bitspersample == 16
8389
assert page.samplesperpixel == 1
8390
assert page.nodata == -32768
8391
assert page.tags['GDAL_NODATA'].value == '-32768'
8392
assert page.tags['GeoAsciiParamsTag'].value == 'WGS 84|'
8393
# assert series properties
8394
series = tif.series[0]
8395
assert series.shape == (6000, 6000)
8396
assert series.dtype == numpy.int16
8397
assert series.axes == 'YX'
8398
assert series.kind == 'uniform'
8400
data = tif.asarray()
8401
assert isinstance(data, numpy.ndarray)
8402
assert data.flags['C_CONTIGUOUS']
8403
assert data.shape == (6000, 6000)
8404
assert data.dtype == numpy.int16
8405
assert data[5199, 5107] == 1019
8406
assert data[0, 0] == -32768
8407
assert_aszarr_method(tif, data)
8412
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS or SKIP_LARGE, reason=REASON)
8413
def test_read_gel_scan():
8414
"""Test read 6976x4992x3 uint8 LZW."""
8415
fname = private_file('large/gel_1-scan2.tif')
8416
with TiffFile(fname) as tif:
8417
assert tif.byteorder == '<'
8418
assert len(tif.pages) == 1
8419
assert len(tif.series) == 1
8420
# assert page properties
8421
page = tif.pages.first
8422
assert page.photometric == PHOTOMETRIC.RGB
8423
assert page.compression == COMPRESSION.LZW
8424
assert page.imagewidth == 4992
8425
assert page.imagelength == 6976
8426
assert page.bitspersample == 8
8427
assert page.samplesperpixel == 3
8428
# assert series properties
8429
series = tif.series[0]
8430
assert series.shape == (6976, 4992, 3)
8431
assert series.dtype == numpy.uint8
8432
assert series.axes == 'YXS'
8433
assert series.kind == 'uniform'
8435
data = tif.asarray()
8436
assert isinstance(data, numpy.ndarray)
8437
assert data.flags['C_CONTIGUOUS']
8438
assert data.shape == (6976, 4992, 3)
8439
assert data.dtype == numpy.uint8
8440
assert tuple(data[2229, 1080, :]) == (164, 164, 164)
8441
assert_aszarr_method(tif, data)
8446
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
8447
def test_read_caspian():
8448
"""Test read 3x220x279 float64, RGB, deflate, GDAL."""
8449
fname = public_file('juicypixels/caspian.tif')
8450
with TiffFile(fname) as tif:
8451
assert tif.byteorder == '<'
8452
assert len(tif.pages) == 1
8453
assert len(tif.series) == 1
8454
# assert page properties
8455
page = tif.pages.first
8456
assert page.photometric == PHOTOMETRIC.RGB
8457
assert page.planarconfig == PLANARCONFIG.SEPARATE
8458
assert page.compression == COMPRESSION.DEFLATE
8459
assert page.imagewidth == 279
8460
assert page.imagelength == 220
8461
assert page.bitspersample == 64
8462
assert page.samplesperpixel == 3
8463
assert page.tags['GDAL_METADATA'].value.startswith('<GDALMetadata>')
8464
# assert series properties
8465
series = tif.series[0]
8466
assert series.shape == (3, 220, 279)
8467
assert series.dtype == numpy.float64
8468
assert series.axes == 'SYX'
8469
assert series.kind == 'uniform'
8471
data = tif.asarray()
8472
assert isinstance(data, numpy.ndarray)
8473
assert data.flags['C_CONTIGUOUS']
8474
assert data.shape == (3, 220, 279)
8475
assert data.dtype == numpy.float64
8476
assert round(abs(data[2, 100, 140] - 353.0), 7) == 0
8477
assert_aszarr_method(tif, data)
8481
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
8482
def test_read_subifds_array():
8483
"""Test read SubIFDs."""
8484
fname = public_file('Tiff-Library-4J/IFD struct/SubIFDs array E.tif')
8485
with TiffFile(fname) as tif:
8486
assert len(tif.pages) == 1
8488
# make sure no pyramid was detected
8489
assert len(tif.series) == 5
8490
assert tif.series[0].shape == (1500, 2000, 3)
8491
assert tif.series[1].shape == (1200, 1600, 3)
8492
assert tif.series[2].shape == (900, 1200, 3)
8493
assert tif.series[3].shape == (600, 800, 3)
8494
assert tif.series[4].shape == (300, 400, 3)
8496
page = tif.pages.first
8497
assert page.photometric == PHOTOMETRIC.RGB
8498
assert page.imagewidth == 2000
8499
assert page.imagelength == 1500
8500
assert page.bitspersample == 8
8501
assert page.samplesperpixel == 3
8502
assert page.tags['SubIFDs'].value == (
8509
assert len(page.pages) == 4
8510
page = tif.pages.first.pages[0]
8511
assert page.photometric == PHOTOMETRIC.RGB
8512
assert page.imagewidth == 1600
8513
assert page.imagelength == 1200
8514
assert_aszarr_method(page)
8515
page = tif.pages.first.pages[1]
8516
assert page.photometric == PHOTOMETRIC.RGB
8517
assert page.imagewidth == 1200
8518
assert page.imagelength == 900
8519
assert_aszarr_method(page)
8520
page = tif.pages.first.pages[2]
8521
assert page.photometric == PHOTOMETRIC.RGB
8522
assert page.imagewidth == 800
8523
assert page.imagelength == 600
8524
assert_aszarr_method(page)
8525
page = tif.pages.first.pages[3]
8526
assert page.photometric == PHOTOMETRIC.RGB
8527
assert page.imagewidth == 400
8528
assert page.imagelength == 300
8529
assert_aszarr_method(page)
8531
image = page.asarray()
8532
assert image.flags['C_CONTIGUOUS']
8533
assert image.shape == (300, 400, 3)
8534
assert image.dtype == numpy.uint8
8535
assert tuple(image[124, 292]) == (236, 109, 95)
8539
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
8540
def test_read_subifd4():
8541
"""Test read BigTIFFSubIFD4."""
8542
fname = public_file('twelvemonkeys/bigtiff/BigTIFFSubIFD4.tif')
8543
with TiffFile(fname) as tif:
8544
assert len(tif.series) == 1
8545
assert len(tif.pages) == 2
8546
page = tif.pages.first
8547
assert page.photometric == PHOTOMETRIC.RGB
8548
assert page.imagewidth == 64
8549
assert page.imagelength == 64
8550
assert page.bitspersample == 8
8551
assert page.samplesperpixel == 3
8552
assert page.tags['SubIFDs'].value == (3088,)
8554
page = page.pages[0]
8555
assert page.photometric == PHOTOMETRIC.RGB
8556
assert page.imagewidth == 32
8557
assert page.imagelength == 32
8558
assert page.bitspersample == 8
8559
assert page.samplesperpixel == 3
8561
image = page.asarray()
8562
assert image.flags['C_CONTIGUOUS']
8563
assert image.shape == (32, 32, 3)
8564
assert image.dtype == numpy.uint8
8565
assert image[15, 15, 0] == 255
8566
assert image[16, 16, 2] == 0
8567
assert_aszarr_method(page)
8571
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
8572
def test_read_subifd8():
8573
"""Test read BigTIFFSubIFD8."""
8574
fname = public_file('twelvemonkeys/bigtiff/BigTIFFSubIFD8.tif')
8575
with TiffFile(fname) as tif:
8576
assert len(tif.series) == 1
8577
assert len(tif.pages) == 2
8578
page = tif.pages.first
8579
assert page.photometric == PHOTOMETRIC.RGB
8580
assert page.imagewidth == 64
8581
assert page.imagelength == 64
8582
assert page.bitspersample == 8
8583
assert page.samplesperpixel == 3
8584
assert page.tags['SubIFDs'].value == (3088,)
8586
page = page.pages[0]
8587
assert page.photometric == PHOTOMETRIC.RGB
8588
assert page.imagewidth == 32
8589
assert page.imagelength == 32
8590
assert page.bitspersample == 8
8591
assert page.samplesperpixel == 3
8593
image = page.asarray()
8594
assert image.flags['C_CONTIGUOUS']
8595
assert image.shape == (32, 32, 3)
8596
assert image.dtype == numpy.uint8
8597
assert image[15, 15, 0] == 255
8598
assert image[16, 16, 2] == 0
8599
assert_aszarr_method(page)
8604
SKIP_CODECS or not imagecodecs.JPEG.available, reason=REASON
8606
def test_read_tiles():
8607
"""Test iteration over tiles, manually and via page.segments."""
8608
data = numpy.arange(600 * 500 * 3, dtype=numpy.uint8).reshape(
8611
with TempFileName('read_tiles') as fname:
8612
with TiffWriter(fname) as tif:
8615
photometric=PHOTOMETRIC.RGB,
8616
compression=COMPRESSION.JPEG,
8619
tif.write(data, **options)
8621
data[::2, ::2], subfiletype=FILETYPE.REDUCEDIMAGE, **options
8623
with TiffFile(fname) as tif:
8625
for page in tif.pages:
8626
segments = page.segments()
8627
jpegtables = page.tags.get('JPEGTables', None)
8628
if jpegtables is not None:
8629
jpegtables = jpegtables.value
8630
for index, (offset, bytecount) in enumerate(
8631
zip(page.dataoffsets, page.databytecounts)
8634
data = fh.read(bytecount)
8635
tile, indices, shape = page.decode(
8636
data, index, jpegtables=jpegtables
8638
assert_array_equal(tile, next(segments)[0])
8641
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
8642
def test_read_lsm_mosaic():
8643
"""Test read LSM: PTZCYX (Mosaic mode), two areas, 32 samples, >4 GB."""
8644
# LSM files are little endian with two series, one of which is reduced RGB
8645
# Tags may be unordered or contain bogus values
8646
fname = private_file(
8647
'lsm/Twoareas_Zstacks54slices_3umintervals_5cycles.lsm'
8649
with TiffFile(fname) as tif:
8651
assert tif.byteorder == '<'
8652
assert len(tif.pages) == 1080
8653
assert len(tif.series) == 2
8654
# assert page properties
8655
page = tif.pages.first
8657
assert page.is_contiguous
8658
assert page.compression == COMPRESSION.NONE
8659
assert page.imagewidth == 512
8660
assert page.imagelength == 512
8661
assert page.bitspersample == 16
8662
assert page.samplesperpixel == 32
8663
# assert strip offsets are corrected
8664
page = tif.pages[-2]
8665
assert page.dataoffsets[0] == 9070895981
8666
# assert series properties
8667
series = tif.series[0]
8668
assert series.shape == (2, 5, 54, 32, 512, 512)
8669
assert series.dtype == numpy.uint16
8670
assert series.axes == 'PTZCYX'
8671
assert series.kind == 'lsm'
8673
series = tif.series[1]
8674
assert series.shape == (2, 5, 54, 3, 128, 128)
8675
assert series.dtype == numpy.uint8
8676
assert series.axes == 'PTZSYX'
8677
assert series.kind == 'lsm'
8678
# assert lsm_info tags
8679
tags = tif.lsm_metadata
8680
assert tags['DimensionX'] == 512
8681
assert tags['DimensionY'] == 512
8682
assert tags['DimensionZ'] == 54
8683
assert tags['DimensionTime'] == 5
8684
assert tags['DimensionChannels'] == 32
8685
# assert lsm_scan_info tags
8686
tags = tif.lsm_metadata['ScanInformation']
8687
assert tags['ScanMode'] == 'Stack'
8688
assert tags['User'] == 'lfdguest1'
8689
# very slow: assert_aszarr_method(tif)
8690
assert__str__(tif, 0)
8693
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
8694
def test_read_lsm_carpet():
8695
"""Test read LSM: TYX (time series x-y), 72000 pages."""
8696
# reads very slowly, ensure colormap is not applied
8697
fname = private_file('lsm/Cardarelli_carpet_3.lsm')
8698
with TiffFile(fname) as tif:
8700
assert tif.byteorder == '<'
8701
assert len(tif.pages) == 72000
8702
assert len(tif.series) == 2
8703
# assert page properties
8704
page = tif.pages.first
8706
assert 'ColorMap' in page.tags
8707
assert page.photometric == PHOTOMETRIC.PALETTE
8708
assert page.compression == COMPRESSION.NONE
8709
assert page.imagewidth == 32
8710
assert page.imagelength == 10
8711
assert page.bitspersample == 8
8712
assert page.samplesperpixel == 1
8713
# assert series properties
8714
series = tif.series[0]
8715
assert series.dtype == numpy.uint8
8716
assert series.shape == (36000, 10, 32)
8717
assert series.axes == 'TYX'
8718
assert series.kind == 'lsm'
8719
assert series.get_shape(False) == (36000, 1, 10, 32)
8720
assert series.get_axes(False) == 'TCYX'
8722
series = tif.series[1]
8723
assert series.dtype == numpy.uint8
8724
assert series.shape == (36000, 3, 40, 128)
8725
assert series.axes == 'TSYX'
8726
assert series.get_shape(False) == (36000, 3, 40, 128)
8727
assert series.get_axes(False) == 'TSYX'
8728
assert series.kind == 'lsm'
8729
# assert lsm_info tags
8730
tags = tif.lsm_metadata
8731
assert tags['DimensionX'] == 32
8732
assert tags['DimensionY'] == 10
8733
assert tags['DimensionZ'] == 1
8734
assert tags['DimensionTime'] == 36000
8735
assert tags['DimensionChannels'] == 1
8736
# assert lsm_scan_info tags
8737
tags = tif.lsm_metadata['ScanInformation']
8738
assert tags['ScanMode'] == 'Plane'
8739
assert tags['User'] == 'LSM User'
8740
# assert_aszarr_method(tif)
8741
assert__str__(tif, 0)
8744
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
8745
def test_read_lsm_sfcs():
8746
"""Test read LSM linescan: TX (time series y), 1 page."""
8747
# second page/series is corrupted: ImageLength=128 but StripByteCounts=1
8749
fname = private_file('lsm/sFCS_780_2069Hz_3p94us.lsm')
8750
with TiffFile(fname) as tif:
8752
assert tif.byteorder == '<'
8753
assert len(tif.pages) == 2
8754
assert len(tif.series) == 2
8755
# assert page properties
8756
page = tif.pages.first
8758
assert 'ColorMap' in page.tags
8759
assert page.photometric == PHOTOMETRIC.PALETTE
8760
assert page.compression == COMPRESSION.NONE
8761
assert page.imagewidth == 52
8762
assert page.imagelength == 100000
8763
assert page.bitspersample == 16
8764
assert page.samplesperpixel == 1
8765
# assert series properties
8766
series = tif.series[0]
8767
assert series.dtype == numpy.uint16
8768
assert series.shape == (100000, 52)
8769
assert series.axes == 'TX'
8770
assert series.kind == 'lsm'
8771
assert series.get_shape(False) == (1, 1, 1, 100000, 52)
8772
assert series.get_axes(False) == 'MPCTX'
8773
data = series.asarray()
8774
assert data.shape == (100000, 52)
8775
assert data.dtype == numpy.uint16
8776
assert data[1000].sum() == 4
8779
series = tif.series[1]
8780
assert series.dtype == numpy.uint8
8781
assert series.shape == (3, 128, 1)
8782
assert series.axes == 'SYX'
8783
assert series.get_shape(False) == (3, 128, 1)
8784
assert series.get_axes(False) == 'SYX'
8785
assert series.kind == 'lsm'
8786
with pytest.raises(TiffFileError):
8787
# strip cannot be reshaped from (1,) to (1, 128, 1, 1)
8789
# assert lsm_info tags
8790
tags = tif.lsm_metadata
8791
assert tags['DimensionX'] == 52
8792
assert tags['DimensionY'] == 1
8793
assert tags['DimensionZ'] == 1
8794
assert tags['DimensionTime'] == 100000
8795
assert tags['DimensionChannels'] == 1
8796
# assert lsm_scan_info tags
8797
tags = tif.lsm_metadata['ScanInformation']
8798
assert tags['ScanMode'] == 'Line'
8799
assert tags['User'] == 'LSM User'
8800
# assert_aszarr_method(tif)
8801
assert__str__(tif, 0)
8804
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
8805
def test_read_lsm_line_2channel():
8806
"""Test read LSM point scan with 2 channels: CTX, 1 page."""
8807
# https://github.com/cgohlke/tifffile/issues/269
8808
# second page/series is corrupted: ImageLength=128 but StripByteCounts=1
8810
fname = private_file('lsm/issue269.lsm')
8811
with TiffFile(fname) as tif:
8813
assert tif.byteorder == '<'
8814
assert len(tif.pages) == 2
8815
assert len(tif.series) == 2
8816
# assert page properties
8817
page = tif.pages.first
8819
assert 'ColorMap' not in page.tags
8820
assert page.photometric == PHOTOMETRIC.RGB
8821
assert page.compression == COMPRESSION.NONE
8822
assert page.imagewidth == 512
8823
assert page.imagelength == 70000
8824
assert page.bitspersample == 8
8825
assert page.samplesperpixel == 2
8826
# assert series properties
8827
series = tif.series[0]
8828
assert series.dtype == numpy.uint8
8829
assert series.shape == (2, 70000, 512)
8830
assert series.axes == 'CTX'
8831
assert series.kind == 'lsm'
8832
assert series.get_axes(False) == 'MPCTX'
8833
assert series.get_shape(False) == (1, 1, 2, 70000, 512)
8834
data = series.asarray()
8835
assert data.shape == (2, 70000, 512)
8836
assert data.dtype == numpy.uint8
8837
assert data[0, 1000].sum() == 13241
8840
series = tif.series[1]
8841
assert series.dtype == numpy.uint8
8842
assert series.shape == (3, 128, 1)
8843
assert series.axes == 'SYX'
8844
assert series.get_shape(False) == (3, 128, 1)
8845
assert series.get_axes(False) == 'SYX'
8846
assert series.kind == 'lsm'
8847
with pytest.raises(TiffFileError):
8848
# strip cannot be reshaped from (1,) to (1, 128, 1, 1)
8850
# assert lsm_info tags
8851
tags = tif.lsm_metadata
8852
assert tags['DimensionX'] == 512
8853
assert tags['DimensionY'] == 1
8854
assert tags['DimensionZ'] == 1
8855
assert tags['DimensionTime'] == 70000
8856
assert tags['DimensionChannels'] == 2
8857
# assert lsm_scan_info tags
8858
tags = tif.lsm_metadata['ScanInformation']
8859
assert tags['ScanMode'] == 'Line'
8860
assert tags['User'] == 'LSMUser'
8861
assert_aszarr_method(tif)
8862
assert__str__(tif, 0)
8865
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
8866
def test_read_lsm_take1():
8867
"""Test read LSM: TZCYX (Plane mode), single image, uint8."""
8868
fname = private_file('lsm/take1.lsm')
8869
with TiffFile(fname) as tif:
8871
assert tif.byteorder == '<'
8872
assert len(tif.pages) == 2
8873
assert len(tif.series) == 2
8874
# assert page properties
8875
page = tif.pages.first
8877
assert page.is_contiguous
8878
assert page.compression == COMPRESSION.NONE
8879
assert page.imagewidth == 512
8880
assert page.imagelength == 512
8881
assert page.bitspersample == 8
8882
assert page.samplesperpixel == 1
8884
assert page.is_reduced
8885
assert page.photometric == PHOTOMETRIC.RGB
8886
assert page.planarconfig == PLANARCONFIG.SEPARATE
8887
assert page.compression == COMPRESSION.NONE
8888
assert page.imagewidth == 128
8889
assert page.imagelength == 128
8890
assert page.samplesperpixel == 3
8891
assert page.bitspersample == 8
8892
# assert series properties
8893
series = tif.series[0]
8894
assert series.dtype == numpy.uint8
8895
assert series.shape == (512, 512)
8896
assert series.axes == 'YX'
8897
assert series.kind == 'lsm'
8898
assert series.get_shape(False) == (1, 1, 512, 512)
8899
assert series.get_axes(False) == 'ZCYX'
8901
series = tif.series[1]
8902
assert series.shape == (3, 128, 128)
8903
assert series.dtype == numpy.uint8
8904
assert series.axes == 'SYX'
8905
assert series.kind == 'lsm'
8907
data = tif.asarray()
8908
assert isinstance(data, numpy.ndarray)
8909
assert data.flags['C_CONTIGUOUS']
8910
assert data.shape == (512, 512)
8911
assert data.dtype == numpy.uint8
8912
assert data[256, 256] == 101
8914
data = tif.asarray(series=1)
8915
assert isinstance(data, numpy.ndarray)
8916
assert data.shape == (3, 128, 128)
8917
assert data.dtype == numpy.uint8
8918
assert tuple(data[..., 64, 64]) == (89, 89, 89)
8919
# assert lsm_info tags
8920
tags = tif.lsm_metadata
8921
assert tags['DimensionX'] == 512
8922
assert tags['DimensionY'] == 512
8923
assert tags['DimensionZ'] == 1
8924
assert tags['DimensionTime'] == 1
8925
assert tags['DimensionChannels'] == 1
8926
# assert lsm_scan_info tags
8927
tags = tif.lsm_metadata['ScanInformation']
8928
assert tags['ScanMode'] == 'Plane'
8929
assert tags['User'] == 'LSM User'
8930
assert len(tags['Tracks']) == 1
8931
assert len(tags['Tracks'][0]['DataChannels']) == 1
8932
track = tags['Tracks'][0]
8933
assert track['DataChannels'][0]['Name'] == 'Ch1'
8934
assert track['DataChannels'][0]['BitsPerSample'] == 8
8935
assert len(track['IlluminationChannels']) == 1
8936
assert track['IlluminationChannels'][0]['Name'] == '561'
8937
assert track['IlluminationChannels'][0]['Wavelength'] == 561.0
8938
assert_aszarr_method(tif)
8939
assert_aszarr_method(tif, series=1)
8943
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
8944
def test_read_lsm_2chzt():
8945
"""Test read LSM: ZCYX (Stack mode) uint8."""
8946
fname = public_file('scif.io/2chZT.lsm')
8947
with TiffFile(fname) as tif:
8949
assert tif.byteorder == '<'
8950
assert len(tif.pages) == 798
8951
assert len(tif.series) == 2
8952
# assert page properties
8953
page = tif.pages.first
8955
assert page.is_contiguous
8956
assert page.photometric == PHOTOMETRIC.RGB
8957
assert page.tags['StripOffsets'].value[2] == 242632 # bogus offset
8958
assert page.tags['StripByteCounts'].value[2] == 0 # no strip data
8959
assert page.compression == COMPRESSION.NONE
8960
assert page.imagewidth == 400
8961
assert page.imagelength == 300
8962
assert page.bitspersample == 8
8963
assert page.samplesperpixel == 2
8966
assert page.is_reduced
8967
assert page.photometric == PHOTOMETRIC.RGB
8968
assert page.planarconfig == PLANARCONFIG.SEPARATE
8969
assert page.is_contiguous
8970
assert page.compression == COMPRESSION.NONE
8971
assert page.imagewidth == 128
8972
assert page.imagelength == 96
8973
assert page.samplesperpixel == 3
8974
assert page.bitspersample == 8
8975
# assert series properties
8976
series = tif.series[0]
8977
assert series.shape == (19, 21, 2, 300, 400)
8978
assert series.dtype == numpy.uint8
8979
assert series.axes == 'TZCYX'
8980
assert series.kind == 'lsm'
8982
series = tif.series[1]
8983
assert series.shape == (19, 21, 3, 96, 128)
8984
assert series.dtype == numpy.uint8
8985
assert series.axes == 'TZSYX'
8986
assert series.kind == 'lsm'
8988
data = tif.asarray(out='memmap')
8989
assert isinstance(data, numpy.memmap)
8990
assert data.flags['C_CONTIGUOUS']
8991
assert data.shape == (19, 21, 2, 300, 400)
8992
assert data.dtype == numpy.uint8
8993
assert data[18, 20, 1, 199, 299] == 39
8995
data = tif.asarray(series=1)
8996
assert isinstance(data, numpy.ndarray)
8997
assert data.shape == (19, 21, 3, 96, 128)
8998
assert data.dtype == numpy.uint8
8999
assert tuple(data[18, 20, :, 64, 96]) == (22, 22, 0)
9001
# assert lsm_info tags
9002
tags = tif.lsm_metadata
9003
assert tags['DimensionX'] == 400
9004
assert tags['DimensionY'] == 300
9005
assert tags['DimensionZ'] == 21
9006
assert tags['DimensionTime'] == 19
9007
assert tags['DimensionChannels'] == 2
9008
# assert lsm_scan_info tags
9009
tags = tif.lsm_metadata['ScanInformation']
9010
assert tags['ScanMode'] == 'Stack'
9011
assert tags['User'] == 'zjfhe'
9012
assert len(tags['Tracks']) == 3
9013
assert len(tags['Tracks'][0]['DataChannels']) == 1
9014
track = tags['Tracks'][0]
9015
assert track['DataChannels'][0]['Name'] == 'Ch3'
9016
assert track['DataChannels'][0]['BitsPerSample'] == 8
9017
assert len(track['IlluminationChannels']) == 6
9018
assert track['IlluminationChannels'][5]['Name'] == '488'
9019
assert track['IlluminationChannels'][5]['Wavelength'] == 488.0
9020
assert_aszarr_method(tif)
9021
assert_aszarr_method(tif, series=1)
9022
assert__str__(tif, 0)
9025
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9026
def test_read_lsm_unbounderror():
9027
"""Test read LSM: MZSYX (196, 2, 33, 512, 512)."""
9028
# file is > 4GB with no time axis
9029
fname = private_file('lsm/48h-CM-C-2.lsm')
9030
with TiffFile(fname) as tif:
9032
assert tif.byteorder == '<'
9033
assert len(tif.pages) == 784
9034
assert len(tif.series) == 2
9035
# assert page properties
9036
page = tif.pages.first
9038
assert page.is_contiguous
9039
assert page.photometric == PHOTOMETRIC.RGB
9040
assert page.planarconfig == PLANARCONFIG.SEPARATE
9041
assert page.imagewidth == 512
9042
assert page.imagelength == 512
9043
assert page.bitspersample == 16
9044
assert page.samplesperpixel == 33
9046
assert page.is_reduced
9047
assert page.photometric == PHOTOMETRIC.RGB
9048
assert page.planarconfig == PLANARCONFIG.SEPARATE
9049
assert page.compression == COMPRESSION.NONE
9050
assert page.imagewidth == 128
9051
assert page.imagelength == 128
9052
assert page.samplesperpixel == 3
9053
assert page.bitspersample == 8
9054
# assert series properties
9055
series = tif.series[0]
9056
assert series.shape == (196, 2, 33, 512, 512)
9057
assert series.dtype == numpy.uint16
9058
assert series.axes == 'MZCYX'
9059
assert series.get_axes(False) == 'MPZCYX'
9060
assert series.get_shape(False) == (196, 1, 2, 33, 512, 512)
9061
assert series.kind == 'lsm'
9063
series = tif.series[1]
9064
assert series.shape == (196, 2, 3, 128, 128)
9065
assert series.dtype == numpy.uint8
9066
assert series.axes == 'MZSYX'
9067
assert series.get_axes(False) == 'MPZSYX'
9068
assert series.get_shape(False) == (196, 1, 2, 3, 128, 128)
9069
assert series.kind == 'lsm'
9071
data = tif.asarray()
9072
assert isinstance(data, numpy.ndarray)
9073
assert data.flags['C_CONTIGUOUS']
9074
assert data.shape == (196, 2, 33, 512, 512)
9075
assert data.dtype == numpy.uint16
9076
assert data[195, 1, 32, 511, 511] == 22088
9077
# assert_aszarr_method(tif, data)
9079
data = tif.asarray(series=1)
9080
assert isinstance(data, numpy.ndarray)
9081
assert data.shape == (196, 2, 3, 128, 128)
9082
assert data.dtype == numpy.uint8
9083
assert tuple(data[195, 1, :, 127, 127]) == (0, 61, 52)
9084
# assert_aszarr_method(tif, series=1)
9085
# assert lsm_info tags
9086
tags = tif.lsm_metadata
9087
assert tags['DimensionX'] == 512
9088
assert tags['DimensionY'] == 512
9089
assert tags['DimensionZ'] == 2
9090
assert tags['DimensionTime'] == 1
9091
assert tags['DimensionChannels'] == 33
9092
# assert lsm_scan_info tags
9093
tags = tif.lsm_metadata['ScanInformation']
9094
assert tags['ScanMode'] == 'Stack'
9095
assert tags['User'] == 'lfdguest1'
9099
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9100
def test_read_lsm_incomplete(caplog):
9101
"""Test read LSM: MZSYX (196, 2, 33, 512, 512)."""
9102
# file is ~18 GB incompletely written, dataoffsets zeroed
9103
fname = private_file('lsm/NTERT_NM-50_x2.lsm')
9105
with TiffFile(fname) as tif:
9106
assert 'LSM file incompletely written' in caplog.text
9108
assert tif.byteorder == '<'
9109
assert len(tif.pages) == 2450
9110
assert len(tif.series) == 2
9111
# assert page properties
9112
page = tif.pages.first
9114
assert page.is_contiguous
9115
assert page.photometric == PHOTOMETRIC.RGB
9116
assert page.planarconfig == PLANARCONFIG.SEPARATE
9117
assert page.imagewidth == 512
9118
assert page.imagelength == 512
9119
assert page.bitspersample == 16
9120
assert page.samplesperpixel == 33
9122
assert page.is_reduced
9123
assert page.photometric == PHOTOMETRIC.RGB
9124
assert page.planarconfig == PLANARCONFIG.SEPARATE
9125
assert page.compression == COMPRESSION.NONE
9126
assert page.imagewidth == 128
9127
assert page.imagelength == 128
9128
assert page.samplesperpixel == 3
9129
assert page.bitspersample == 8
9130
# assert series properties
9131
series = tif.series[0]
9132
assert series.pages[-1].dataoffsets[0] == 0
9133
assert series.shape == (25, 49, 33, 512, 512)
9134
assert series.dtype == numpy.uint16
9135
assert series.axes == 'MTCYX'
9136
assert series.get_axes(False) == 'MPTCYX'
9137
assert series.get_shape(False) == (25, 1, 49, 33, 512, 512)
9138
assert series.kind == 'lsm'
9140
series = tif.series[1]
9141
assert series.shape == (25, 49, 3, 128, 128)
9142
assert series.get_shape(False) == (25, 1, 49, 3, 128, 128)
9143
assert series.dtype == numpy.uint8
9144
assert series.axes == 'MTSYX'
9145
assert series.get_axes(False) == 'MPTSYX'
9146
assert series.kind == 'lsm'
9148
data = tif.asarray()
9149
assert isinstance(data, numpy.ndarray)
9150
assert data.flags['C_CONTIGUOUS']
9151
assert data.shape == (25, 49, 33, 512, 512)
9152
assert data.dtype == numpy.uint16
9153
assert data[24, 45, 32, 511, 511] == 14648
9154
# assert_aszarr_method(tif, data)
9156
data = tif.asarray(series=1)
9157
assert isinstance(data, numpy.ndarray)
9158
assert data.shape == (25, 49, 3, 128, 128)
9159
assert data.dtype == numpy.uint8
9160
assert numpy.sum(data[24, 45]) == 0
9161
# assert_aszarr_method(tif, series=1)
9162
# assert lsm_info tags
9163
tags = tif.lsm_metadata
9164
assert tags['DimensionX'] == 512
9165
assert tags['DimensionY'] == 512
9166
assert tags['DimensionZ'] == 1
9167
assert tags['DimensionTime'] == 49
9168
assert tags['DimensionChannels'] == 33
9169
# assert lsm_scan_info tags
9170
tags = tif.lsm_metadata['ScanInformation']
9171
assert tags['ScanMode'] == 'Plane'
9172
assert tags['User'] == 'lfdguest1'
9176
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
9177
def test_read_lsm_earpax2isl11():
9178
"""Test read LSM: ZCYX (19, 3, 512, 512) uint8, RGB, LZW."""
9179
fname = private_file('lsm/earpax2isl11.lzw.lsm')
9180
with TiffFile(fname) as tif:
9182
assert tif.byteorder == '<'
9183
assert len(tif.pages) == 38
9184
assert len(tif.series) == 2
9185
# assert page properties
9186
page = tif.pages.first
9188
assert not page.is_contiguous
9189
assert page.photometric == PHOTOMETRIC.RGB
9190
assert page.compression == COMPRESSION.LZW
9191
assert page.imagewidth == 512
9192
assert page.imagelength == 512
9193
assert page.bitspersample == 8
9194
assert page.samplesperpixel == 3
9195
# assert corrected strip_byte_counts
9196
assert page.tags['StripByteCounts'].value == (262144, 262144, 262144)
9197
assert page.databytecounts == (131514, 192933, 167874)
9199
assert page.is_reduced
9200
assert page.photometric == PHOTOMETRIC.RGB
9201
assert page.planarconfig == PLANARCONFIG.SEPARATE
9202
assert page.compression == COMPRESSION.NONE
9203
assert page.imagewidth == 128
9204
assert page.imagelength == 128
9205
assert page.samplesperpixel == 3
9206
assert page.bitspersample == 8
9207
# assert series properties
9208
series = tif.series[0]
9209
assert series.shape == (19, 3, 512, 512)
9210
assert series.dtype == numpy.uint8
9211
assert series.axes == 'ZCYX'
9212
assert series.get_axes(False) == 'ZCYX'
9213
assert series.get_shape(False) == (19, 3, 512, 512)
9214
assert series.kind == 'lsm'
9216
series = tif.series[1]
9217
assert series.shape == (19, 3, 128, 128)
9218
assert series.get_shape(False) == (19, 3, 128, 128)
9219
assert series.dtype == numpy.uint8
9220
assert series.axes == 'ZSYX'
9221
assert series.get_axes(False) == 'ZSYX'
9222
assert series.kind == 'lsm'
9224
data = tif.asarray()
9225
assert isinstance(data, numpy.ndarray)
9226
assert data.flags['C_CONTIGUOUS']
9227
assert data.shape == (19, 3, 512, 512)
9228
assert data.dtype == numpy.uint8
9229
assert tuple(data[18, :, 200, 320]) == (17, 22, 21)
9230
assert_aszarr_method(tif, data)
9232
data = tif.asarray(series=1)
9233
assert isinstance(data, numpy.ndarray)
9234
assert data.shape == (19, 3, 128, 128)
9235
assert data.dtype == numpy.uint8
9236
assert tuple(data[18, :, 64, 64]) == (25, 5, 33)
9237
assert_aszarr_method(tif, series=1)
9238
# assert lsm_info tags
9239
tags = tif.lsm_metadata
9240
assert tags['DimensionX'] == 512
9241
assert tags['DimensionY'] == 512
9242
assert tags['DimensionZ'] == 19
9243
assert tags['DimensionTime'] == 1
9244
assert tags['DimensionChannels'] == 3
9245
# assert lsm_scan_info tags
9246
tags = tif.lsm_metadata['ScanInformation']
9247
assert tags['ScanMode'] == 'Stack'
9248
assert tags['User'] == 'megason'
9252
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS or SKIP_LARGE, reason=REASON)
9253
def test_read_lsm_mb231paxgfp_060214():
9254
"""Test read LSM with many LZW compressed pages."""
9255
# TZCYX (Stack mode), (60, 31, 2, 512, 512), 3720
9256
fname = public_file('tifffile/MB231paxgfp_060214.lzw.lsm')
9257
with TiffFile(fname) as tif:
9259
assert tif.byteorder == '<'
9260
assert len(tif.pages) == 3720
9261
assert len(tif.series) == 2
9262
# assert page properties
9263
page = tif.pages.first
9265
assert not page.is_contiguous
9266
assert page.compression == COMPRESSION.LZW
9267
assert page.imagewidth == 512
9268
assert page.imagelength == 512
9269
assert page.bitspersample == 16
9270
assert page.samplesperpixel == 2
9272
assert page.is_reduced
9273
assert page.photometric == PHOTOMETRIC.RGB
9274
assert page.planarconfig == PLANARCONFIG.SEPARATE
9275
assert page.compression == COMPRESSION.NONE
9276
assert page.imagewidth == 128
9277
assert page.imagelength == 128
9278
assert page.samplesperpixel == 3
9279
assert page.bitspersample == 8
9280
# assert series properties
9281
series = tif.series[0]
9282
assert series.dtype == numpy.uint16
9283
assert series.shape == (60, 31, 2, 512, 512)
9284
assert series.get_shape(False) == (60, 31, 2, 512, 512)
9285
assert series.axes == 'TZCYX'
9286
assert series.get_axes(False) == 'TZCYX'
9287
assert series.kind == 'lsm'
9289
series = tif.series[1]
9290
assert series.dtype == numpy.uint8
9291
assert series.shape == (60, 31, 3, 128, 128)
9292
assert series.axes == 'TZSYX'
9293
assert series.kind == 'lsm'
9295
data = tif.asarray(out='memmap', maxworkers=None)
9296
assert isinstance(data, numpy.memmap)
9297
assert data.flags['C_CONTIGUOUS']
9298
assert data.shape == (60, 31, 2, 512, 512)
9299
assert data.dtype == numpy.dtype('<u2')
9300
assert data[59, 30, 1, 256, 256] == 222
9302
# assert lsm_info tags
9303
tags = tif.lsm_metadata
9304
assert tags['DimensionX'] == 512
9305
assert tags['DimensionY'] == 512
9306
assert tags['DimensionZ'] == 31
9307
assert tags['DimensionTime'] == 60
9308
assert tags['DimensionChannels'] == 2
9309
# assert some lsm_scan_info tags
9310
tags = tif.lsm_metadata['ScanInformation']
9311
assert tags['ScanMode'] == 'Stack'
9312
assert tags['User'] == 'lfdguest1'
9313
assert__str__(tif, 0)
9316
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
9317
def test_read_lsm_lzw_no_eoi():
9318
"""Test read LSM with LZW compressed strip without EOI."""
9319
# The first LZW compressed strip in page 834 has no EOI
9320
# such that too much data is returned from the decoder and
9321
# the data of the 2nd channel was getting corrupted
9322
fname = public_file('tifffile/MB231paxgfp_060214.lzw.lsm')
9323
with TiffFile(fname) as tif:
9325
assert tif.byteorder == '<'
9326
assert len(tif.pages) == 3720
9327
assert len(tif.series) == 2
9328
# assert page properties
9329
page = tif.pages.first
9330
assert not page.is_contiguous
9331
assert page.photometric == PHOTOMETRIC.RGB
9332
assert page.compression == COMPRESSION.LZW
9333
assert page.imagewidth == 512
9334
assert page.imagelength == 512
9335
assert page.bitspersample == 16
9336
assert page.samplesperpixel == 2
9337
page = tif.pages[834]
9338
assert isinstance(page, TiffFrame)
9339
assert page.dataoffsets == (344655101, 345109987)
9340
assert page.databytecounts == (454886, 326318)
9341
# assert second channel is not corrupted
9342
data = page.asarray()
9343
assert tuple(data[:, 0, 0]) == (288, 238)
9344
assert__str__(tif, 0)
9347
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9348
def test_stk_nonstack():
9349
"""Test read MetaMorph STK with single plane."""
9350
# https://github.com/cgohlke/tifffile/pull/217
9351
fname = private_file('stk/test_w1491-Fast_s1_t1.tif')
9352
with TiffFile(fname) as tif:
9354
assert tif.byteorder == '<'
9355
assert len(tif.pages) == 1
9356
assert len(tif.series) == 1
9357
# assert page properties
9358
page = tif.pages.first
9359
assert page.is_contiguous
9360
assert page.compression == COMPRESSION.NONE
9361
assert page.imagewidth == 24
9362
assert page.imagelength == 24
9363
assert page.bitspersample == 16
9364
assert page.samplesperpixel == 1
9365
assert page.tags['Software'].value == 'MetaMorph 7.8.3.0'
9366
assert page.tags['DateTime'].value == '2023:08:07 15:01:32'
9367
assert page.datetime == datetime.datetime(2023, 8, 7, 15, 1, 32)
9368
assert page.description.startswith('Exposure: 150 ms')
9369
meta = stk_description_metadata(page.description)
9370
assert meta[0]['Exposure'] == '150 ms'
9372
tags = tif.stk_metadata
9373
assert 'ZDistance' not in tags
9374
assert 'Wavelengths' not in tags
9375
assert tags['Name'] == '491_Fast'
9376
assert tags['NumberPlanes'] == 1
9377
assert ''.join(tags['StageLabel']) == 'position_a'
9378
assert len(tags['AbsoluteZ']) == 1
9379
assert tags['AbsoluteZ'][0] == 4294085.491
9380
assert tuple(tags['StagePosition'][0]) == (16204.6, 444.7)
9381
assert tuple(tags['CameraChipOffset'][0]) == (192.0, 219.0)
9382
assert tags['PlaneDescriptions'][0].startswith('Exposure: 150 ms')
9383
# assert series properties
9384
series = tif.series[0]
9385
assert not series.is_truncated
9386
assert series.shape == (24, 24)
9387
assert series.dtype == numpy.uint16
9388
assert series.axes == 'YX'
9389
assert series.kind == 'stk'
9391
data = tif.asarray()
9392
assert isinstance(data, numpy.ndarray)
9393
assert data.shape == (24, 24)
9394
assert data.dtype == numpy.uint16
9395
assert data[9, 11] == 3453
9396
assert_aszarr_method(tif, data)
9397
assert_decode_method(page)
9401
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9402
def test_read_stk_zseries():
9403
"""Test read MetaMorph STK z-series."""
9404
fname = private_file('stk/zseries.stk')
9405
with TiffFile(fname) as tif:
9407
assert tif.byteorder == '<'
9408
assert len(tif.pages) == 1
9409
assert len(tif.series) == 1
9410
# assert page properties
9411
page = tif.pages.first
9412
assert page.is_contiguous
9413
assert page.compression == COMPRESSION.NONE
9414
assert page.imagewidth == 320
9415
assert page.imagelength == 256
9416
assert page.bitspersample == 16
9417
assert page.samplesperpixel == 1
9418
assert page.tags['Software'].value == 'MetaMorph'
9419
assert page.tags['DateTime'].value == '2000:01:02 15:06:33'
9420
assert page.datetime == datetime.datetime(2000, 1, 2, 15, 6, 33)
9421
assert page.description.startswith('Acquired from MV-1500')
9422
meta = stk_description_metadata(page.description)
9423
assert meta[0]['Exposure'] == '2 ms'
9425
tags = tif.stk_metadata
9426
assert tags['Name'] == 'Z Series'
9427
assert tags['NumberPlanes'] == 11
9428
assert ''.join(tags['StageLabel']) == ''
9429
assert tags['ZDistance'][10] == 2.5
9430
assert len(tags['Wavelengths']) == 11
9431
assert tags['Wavelengths'][10] == 490.0
9432
assert len(tags['AbsoluteZ']) == 11
9433
assert tags['AbsoluteZ'][10] == 150.0
9434
assert tuple(tags['StagePosition'][10]) == (0.0, 0.0)
9435
assert tuple(tags['CameraChipOffset'][10]) == (0.0, 0.0)
9436
assert tags['PlaneDescriptions'][0].startswith('Acquired from MV-1500')
9437
assert str(tags['DatetimeCreated'][0]) == (
9438
'2000-02-02T15:06:02.000783000'
9440
# assert series properties
9441
series = tif.series[0]
9442
assert series.is_truncated
9443
assert series.shape == (11, 256, 320)
9444
assert series.dtype == numpy.uint16
9445
assert series.axes == 'ZYX'
9446
assert series.kind == 'stk'
9448
data = tif.asarray()
9449
assert isinstance(data, numpy.ndarray)
9450
assert data.shape == (11, 256, 320)
9451
assert data.dtype == numpy.uint16
9452
assert data[8, 159, 255] == 1156
9453
assert_aszarr_method(tif, data)
9454
assert_decode_method(page)
9458
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9459
def test_read_stk_zser24():
9460
"""Test read MetaMorph STK RGB z-series."""
9461
fname = private_file('stk/zser24.stk')
9462
with TiffFile(fname) as tif:
9464
assert tif.byteorder == '<'
9465
assert len(tif.pages) == 1
9466
assert len(tif.series) == 1
9467
# assert page properties
9468
page = tif.pages.first
9469
assert page.is_contiguous
9470
assert page.photometric == PHOTOMETRIC.RGB
9471
assert page.compression == COMPRESSION.NONE
9472
assert page.imagewidth == 160
9473
assert page.imagelength == 128
9474
assert page.bitspersample == 8
9475
assert page.samplesperpixel == 3
9476
assert page.tags['Software'].value == 'MetaMorph'
9477
assert page.tags['DateTime'].value == '2000:01:02 15:11:23'
9479
tags = tif.stk_metadata
9480
assert tags['Name'] == 'Color Encoded'
9481
assert tags['NumberPlanes'] == 11
9482
assert ''.join(tags['StageLabel']) == ''
9483
assert tags['ZDistance'][10] == 2.5
9484
assert len(tags['Wavelengths']) == 11
9485
assert tags['Wavelengths'][10] == 510.0
9486
assert len(tags['AbsoluteZ']) == 11
9487
assert tags['AbsoluteZ'][10] == 150.0
9488
assert tuple(tags['StagePosition'][10]) == (0.0, 0.0)
9489
assert tuple(tags['CameraChipOffset'][10]) == (320.0, 256.0)
9490
assert str(tags['DatetimeCreated'][0]) == (
9491
'2000-02-02T15:10:34.000264000'
9493
# assert series properties
9494
series = tif.series[0]
9495
assert series.is_truncated
9496
assert series.shape == (11, 128, 160, 3)
9497
assert series.dtype == numpy.uint8
9498
assert series.axes == 'ZYXS'
9499
assert series.kind == 'stk'
9501
data = tif.asarray()
9502
assert isinstance(data, numpy.ndarray)
9503
assert data.shape == (11, 128, 160, 3)
9504
assert data.dtype == numpy.uint8
9505
assert tuple(data[8, 100, 135]) == (70, 63, 0)
9506
assert_aszarr_method(tif, data)
9507
assert_decode_method(page)
9511
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9512
def test_read_stk_diatoms3d():
9513
"""Test read MetaMorph STK time-series."""
9514
fname = private_file('stk/diatoms3d.stk')
9515
with TiffFile(fname) as tif:
9517
assert tif.byteorder == '<'
9518
assert len(tif.pages) == 1
9519
assert len(tif.series) == 1
9520
# assert page properties
9521
page = tif.pages.first
9522
assert page.is_contiguous
9523
assert page.compression == COMPRESSION.NONE
9524
assert page.imagewidth == 196
9525
assert page.imagelength == 191
9526
assert page.bitspersample == 8
9527
assert page.samplesperpixel == 1
9528
assert page.tags['Software'].value == 'MetaMorph'
9529
assert page.tags['DateTime'].value == '2000:01:04 14:57:22'
9531
tags = tif.stk_metadata
9532
assert tags['Name'] == 'diatoms3d'
9533
assert tags['NumberPlanes'] == 10
9534
assert ''.join(tags['StageLabel']) == ''
9535
assert tags['ZDistance'][9] == 3.54545
9536
assert len(tags['Wavelengths']) == 10
9537
assert tags['Wavelengths'][9] == 440.0
9538
assert len(tags['AbsoluteZ']) == 10
9539
assert tags['AbsoluteZ'][9] == 12898.15
9540
assert tuple(tags['StagePosition'][9]) == (0.0, 0.0)
9541
assert tuple(tags['CameraChipOffset'][9]) == (206.0, 148.0)
9542
assert tags['PlaneDescriptions'][0].startswith(
9543
'Acquired from Flashbus.'
9545
assert str(tags['DatetimeCreated'][0]) == (
9546
'2000-02-04T14:38:37.000738000'
9548
# assert series properties
9549
series = tif.series[0]
9550
assert series.shape == (10, 191, 196)
9551
assert series.dtype == numpy.uint8
9552
assert series.axes == 'ZYX'
9553
assert series.kind == 'stk'
9555
data = tif.asarray()
9556
assert isinstance(data, numpy.ndarray)
9557
assert data.shape == (10, 191, 196)
9558
assert data.dtype == numpy.uint8
9559
assert data[8, 100, 135] == 223
9560
assert_aszarr_method(tif, data)
9561
assert_decode_method(page)
9565
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9566
def test_read_stk_greenbeads():
9567
"""Test read MetaMorph STK time-series, but time_created is corrupt (?)."""
9568
# 8bit palette is present but should not be applied
9569
fname = private_file('stk/GreenBeads.stk')
9570
with TiffFile(fname) as tif:
9572
assert tif.byteorder == '<'
9573
assert len(tif.pages) == 1
9574
assert len(tif.series) == 1
9575
# assert page properties
9576
page = tif.pages.first
9577
assert page.is_contiguous
9578
assert page.photometric == PHOTOMETRIC.PALETTE
9579
assert page.compression == COMPRESSION.NONE
9580
assert page.imagewidth == 298
9581
assert page.imagelength == 322
9582
assert page.bitspersample == 8
9583
assert page.samplesperpixel == 1
9584
assert page.tags['Software'].value == 'MetaMorph 7.5.3.0'
9585
assert page.tags['DateTime'].value == '2008:05:09 17:35:32'
9587
tags = tif.stk_metadata
9588
assert tags['Name'] == 'Green'
9589
assert tags['NumberPlanes'] == 79
9590
assert tags['ZDistance'][1] == 0.0
9591
assert len(tags['Wavelengths']) == 79
9592
assert tuple(tags['CameraChipOffset'][0]) == (0.0, 0.0)
9593
assert str(tags['DatetimeModified'][0]) == (
9594
'2008-05-09T17:35:33.000274000'
9596
# assert tags['AbsoluteZ'][78] == 1.1672684733218932
9597
assert 'AbsoluteZ' not in tags
9598
# assert series properties
9599
series = tif.series[0]
9600
assert series.shape == (79, 322, 298)
9601
assert series.dtype == numpy.uint8
9602
assert series.axes == 'IYX' # corrupt time_created
9603
assert series.kind == 'stk'
9605
data = tif.asarray()
9606
assert isinstance(data, numpy.ndarray)
9607
assert data.shape == (79, 322, 298)
9608
assert data.dtype == numpy.uint8
9609
assert data[43, 180, 102] == 205
9610
assert_aszarr_method(tif, data)
9614
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
9615
def test_read_stk_10xcalib():
9616
"""Test read MetaMorph STK two planes, not Z or T series."""
9617
fname = private_file('stk/10xcalib.stk')
9618
with TiffFile(fname) as tif:
9620
assert tif.byteorder == '<'
9621
assert len(tif.pages) == 1
9622
assert len(tif.series) == 1
9623
# assert page properties
9624
page = tif.pages.first
9625
assert page.is_contiguous
9626
assert page.photometric != PHOTOMETRIC.PALETTE
9627
assert page.compression == COMPRESSION.NONE
9628
assert page.imagewidth == 640
9629
assert page.imagelength == 480
9630
assert page.bitspersample == 8
9631
assert page.samplesperpixel == 1
9632
assert page.tags['Software'].value == 'MetaMorph'
9633
assert page.tags['DateTime'].value == '2000:03:28 09:24:37'
9635
tags = tif.stk_metadata
9636
assert tags['Name'] == '10xcalib'
9637
assert tags['NumberPlanes'] == 2
9638
assert tuple(tags['Wavelengths']) == (440.0, 440.0)
9639
assert tags['XCalibration'] == 1.24975007
9640
assert tags['YCalibration'] == 1.24975007
9641
# assert series properties
9642
series = tif.series[0]
9643
assert series.shape == (2, 480, 640)
9644
assert series.dtype == numpy.uint8
9645
assert series.axes == 'IYX'
9646
assert series.kind == 'stk'
9648
data = tif.asarray()
9649
assert isinstance(data, numpy.ndarray)
9650
assert data.shape == (2, 480, 640)
9651
assert data.dtype == numpy.uint8
9652
assert data[1, 339, 579] == 56
9653
assert_aszarr_method(tif, data)
9657
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
9658
def test_read_stk_112508h100():
9659
"""Test read MetaMorph STK large time-series."""
9660
fname = private_file('stk/112508h100.stk')
9661
with TiffFile(fname) as tif:
9663
assert tif.byteorder == '<'
9664
assert len(tif.pages) == 1
9665
assert len(tif.series) == 1
9666
# assert page properties
9667
page = tif.pages.first
9668
assert page.is_contiguous
9669
assert page.photometric != PHOTOMETRIC.PALETTE
9670
assert page.compression == COMPRESSION.NONE
9671
assert page.imagewidth == 512
9672
assert page.imagelength == 128
9673
assert page.bitspersample == 16
9674
assert page.samplesperpixel == 1
9675
assert page.tags['Software'].value == 'MetaMorph 7.5.3.0'
9676
assert page.tags['DateTime'].value == '2008:11:25 18:59:20'
9678
tags = tif.stk_metadata
9679
assert tags['Name'] == 'Photometrics'
9680
assert tags['NumberPlanes'] == 2048
9681
assert len(tags['PlaneDescriptions']) == 2048
9682
assert tags['PlaneDescriptions'][0].startswith(
9683
'Acquired from Photometrics\r\n'
9685
assert tags['CalibrationUnits'] == 'pixel'
9686
# assert series properties
9687
series = tif.series[0]
9688
assert series.shape == (2048, 128, 512)
9689
assert series.dtype == numpy.uint16
9690
assert series.axes == 'TYX'
9691
assert series.kind == 'stk'
9693
data = tif.asarray()
9694
assert isinstance(data, numpy.ndarray)
9695
assert data.shape == (2048, 128, 512)
9696
assert data.dtype == numpy.uint16
9697
assert data[2047, 64, 128] == 7132
9698
assert_aszarr_method(tif, data)
9702
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
9703
def test_read_stk_noname():
9704
"""Test read MetaMorph STK with no name in metadata."""
9705
# https://forum.image.sc/t/metamorph-stack-issue-with-ome-metadata-
9706
# bioformats-and-omero/48416
9707
fname = private_file('stk/60x_2well_diffexpos1_w1sdcGFP_s1_t1.stk')
9708
with TiffFile(fname) as tif:
9710
assert tif.byteorder == '<'
9711
assert len(tif.pages) == 1
9712
assert len(tif.series) == 1
9713
# assert page properties
9714
page = tif.pages.first
9715
assert page.is_contiguous
9716
assert page.photometric == PHOTOMETRIC.MINISBLACK
9717
assert page.compression == COMPRESSION.NONE
9718
assert page.imagewidth == 1148
9719
assert page.imagelength == 1112
9720
assert page.bitspersample == 16
9721
assert page.samplesperpixel == 1
9722
assert page.tags['Software'].value == 'VisiView 4.5.0'
9723
assert page.tags['DateTime'].value == '2021:01:27 13:29:51'
9725
tags = tif.stk_metadata
9726
assert 'Name' not in tags
9727
assert tags['NumberPlanes'] == 5
9728
assert len(tags['PlaneDescriptions']) == 5
9729
assert tags['PlaneDescriptions'][0].startswith('Exposure: 50 ms\r\n')
9730
# assert series properties
9731
series = tif.series[0]
9732
assert series.shape == (5, 1112, 1148)
9733
assert series.dtype == numpy.uint16
9734
assert series.axes == 'ZYX'
9735
assert series.kind == 'stk'
9737
data = tif.asarray()
9738
assert isinstance(data, numpy.ndarray)
9739
assert data.shape == (5, 1112, 1148)
9740
assert data.dtype == numpy.uint16
9741
assert data[4, 64, 128] == 98
9742
assert_aszarr_method(tif, data)
9747
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
9750
def test_read_ndpi_cmu1():
9751
"""Test read Hamamatsu NDPI slide, JPEG."""
9752
fname = private_file('HamamatsuNDPI/CMU-1.ndpi')
9753
with TiffFile(fname) as tif:
9755
assert len(tif.pages) == 5
9756
assert len(tif.series) == 2
9757
for page in tif.pages:
9758
assert page.ndpi_tags['Model'] == 'NanoZoomer'
9760
page = tif.pages.first
9762
assert page.photometric == PHOTOMETRIC.YCBCR
9763
assert page.compression == COMPRESSION.JPEG
9764
assert page.shape == (38144, 51200, 3)
9765
assert page.ndpi_tags['Magnification'] == 20.0
9769
assert page.photometric == PHOTOMETRIC.YCBCR
9770
assert page.compression == COMPRESSION.JPEG
9771
assert page.shape == (408, 1191, 3)
9772
assert page.ndpi_tags['Magnification'] == -1.0
9773
assert page.asarray()[226, 629, 0] == 167
9774
assert_aszarr_method(page)
9782
or not imagecodecs.JPEG.available,
9785
def test_read_ndpi_cmu2():
9786
"""Test read Hamamatsu NDPI slide, JPEG."""
9787
# JPEG stream too large to be opened with unpatched libjpeg
9788
fname = private_file('HamamatsuNDPI/CMU-2.ndpi')
9789
with TiffFile(fname) as tif:
9791
assert len(tif.pages) == 6
9792
assert len(tif.series) == 2
9793
for page in tif.pages:
9794
assert page.ndpi_tags['Model'] == 'NanoZoomer'
9796
page = tif.pages.first
9798
assert page.photometric == PHOTOMETRIC.YCBCR
9799
assert page.compression == COMPRESSION.JPEG
9800
assert page.shape == (33792, 79872, 3)
9801
assert page.ndpi_tags['Magnification'] == 20.0
9802
# with pytest.raises(RuntimeError):
9804
data = page.asarray()
9805
assert data.shape == (33792, 79872, 3)
9806
assert data.dtype == numpy.uint8
9810
assert page.photometric == PHOTOMETRIC.YCBCR
9811
assert page.compression == COMPRESSION.JPEG
9812
assert page.shape == (408, 1191, 3)
9813
assert page.ndpi_tags['Magnification'] == -1.0
9814
assert page.asarray()[226, 629, 0] == 181
9815
assert_aszarr_method(page)
9823
or not imagecodecs.JPEG.available,
9826
def test_read_ndpi_4gb():
9827
"""Test read > 4 GB Hamamatsu NDPI slide, JPEG 103680x188160."""
9828
fname = private_file('HamamatsuNDPI/103680x188160.ndpi')
9829
with TiffFile(fname) as tif:
9831
assert len(tif.pages) == 8
9832
assert len(tif.series) == 3
9833
for page in tif.pages:
9834
assert page.ndpi_tags['Model'] == 'C13220'
9836
page = tif.pages.first
9837
assert page.offset == 4466602683
9839
assert page.databytecounts[0] == 5105 # not 4461521316
9840
assert page.photometric == PHOTOMETRIC.YCBCR
9841
assert page.compression == COMPRESSION.JPEG
9842
assert page.shape == (103680, 188160, 3)
9844
page.tags['ImageLength'].offset - page.tags['ImageWidth'].offset
9847
assert page.tags['ImageWidth'].offset == 4466602685
9848
assert page.tags['ImageWidth'].valueoffset == 4466602693
9849
assert page.tags['ImageLength'].offset == 4466602697
9850
assert page.tags['ImageLength'].valueoffset == 4466602705
9851
assert page.tags['ReferenceBlackWhite'].offset == 4466602889
9852
assert page.tags['ReferenceBlackWhite'].valueoffset == 1003
9853
assert page.ndpi_tags['Magnification'] == 40.0
9854
assert page.ndpi_tags['McuStarts'][-1] == 4461516507 # corrected
9855
with pytest.raises(ValueError):
9856
page.tags['StripByteCounts'].astuple()
9858
# data = page.asarray() # 55 GB
9859
with page.aszarr() as store:
9860
data = zarr.open(store, mode='r')
9861
assert data[38061, 121978].tolist() == [220, 167, 187]
9865
assert page.photometric == PHOTOMETRIC.MINISBLACK
9866
assert page.compression == COMPRESSION.NONE
9867
assert page.shape == (200, 600)
9868
assert page.ndpi_tags['Magnification'] == -2.0
9869
# assert page.asarray()[226, 629, 0] == 167
9871
series = tif.series[0]
9872
assert series.kind == 'ndpi'
9873
assert series.name == 'S10533009'
9874
assert series.shape == (103680, 188160, 3)
9875
assert series.is_pyramidal
9876
assert len(series.levels) == 6
9877
assert len(series.pages) == 1
9879
assert series.levels[1].shape == (51840, 94080, 3)
9880
assert series.levels[2].shape == (25920, 47040, 3)
9881
assert series.levels[3].shape == (12960, 23520, 3)
9882
assert series.levels[4].shape == (6480, 11760, 3)
9883
assert series.levels[5].shape == (3240, 5880, 3)
9884
data = series.levels[5].asarray()
9885
assert tuple(data[1000, 1000]) == (222, 165, 200)
9886
with pytest.raises(ValueError):
9887
page.tags['StripOffsets'].astuple()
9888
# cannot decode base levels since JPEG compressed size > 2 GB
9889
# series.levels[0].asarray()
9890
assert_aszarr_method(series.levels[5], data)
9895
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEGXR.available,
9898
def test_read_ndpi_jpegxr():
9899
"""Test read Hamamatsu NDPI slide with JPEG XR compression."""
9900
# https://downloads.openmicroscopy.org/images/Hamamatsu-NDPI/hamamatsu/
9901
fname = private_file('HamamatsuNDPI/DM0014 - 2020-04-02 10.25.21.ndpi')
9902
with TiffFile(fname) as tif:
9904
assert len(tif.pages) == 6
9905
assert len(tif.series) == 3
9906
for page in tif.pages:
9907
assert page.ndpi_tags['Model'] == 'C13210'
9909
for page in tif.pages[:4]:
9910
# check that all levels are corrected
9913
page.tags['PhotometricInterpretation'].value
9914
== PHOTOMETRIC.YCBCR
9916
assert page.tags['BitsPerSample'].value == (8, 8, 8)
9917
assert page.samplesperpixel == 1 # not 3
9918
assert page.bitspersample == 16 # not 8
9919
assert page.photometric == PHOTOMETRIC.MINISBLACK # not YCBCR
9920
assert page.compression == COMPRESSION.JPEGXR_NDPI
9923
page = tif.pages.first
9924
assert page.shape == (34944, 69888) # not (34944, 69888, 3)
9925
assert page.databytecounts[0] == 632009
9926
assert page.ndpi_tags['CaptureMode'] == 17
9927
assert page.ndpi_tags['Magnification'] == 20.0
9929
with page.aszarr() as store:
9930
data = zarr.open(store, mode='r')
9931
assert data[28061, 41978] == 6717
9935
assert page.photometric == PHOTOMETRIC.MINISBLACK
9936
assert page.compression == COMPRESSION.NONE
9937
assert page.shape == (192, 566)
9938
assert page.ndpi_tags['Magnification'] == -2.0
9940
series = tif.series[0]
9941
assert series.kind == 'ndpi'
9942
assert series.name == 'DM0014'
9943
assert series.shape == (34944, 69888)
9944
assert series.is_pyramidal
9945
assert len(series.levels) == 4
9946
assert len(series.pages) == 1
9948
assert series.levels[1].shape == (17472, 34944)
9949
assert series.levels[2].shape == (8736, 17472)
9950
assert series.levels[3].shape == (4368, 8736)
9951
data = series.levels[3].asarray()
9952
assert data[1000, 1000] == 1095
9953
assert_aszarr_method(series.levels[3], data)
9961
or not imagecodecs.JPEG.available,
9964
def test_read_ndpi_databytecounts():
9965
"""Test read Hamamatsu NDPI slide databytecounts do not overflow."""
9966
# https://forum.image.sc/t/some-ndpi-files-not-opening-in-qupath-v0-4-1
9967
fname = private_file('HamamatsuNDPI/doesnt_work.ndpi')
9968
with TiffFile(fname) as tif:
9970
assert len(tif.pages) == 23
9971
assert len(tif.series) == 3
9973
series = tif.series[0]
9974
assert series.kind == 'ndpi'
9975
assert series.name == 'Baseline'
9976
assert series.shape == (3, 60928, 155648, 3)
9977
assert series.is_pyramidal
9978
assert len(series.levels) == 7
9979
assert len(series.pages) == 3
9981
assert series.levels[1].shape == (3, 30464, 77824, 3)
9982
assert series.levels[2].shape == (3, 15232, 38912, 3)
9983
assert series.levels[3].shape == (3, 7616, 19456, 3)
9984
assert series.levels[4].shape == (3, 3808, 9728, 3)
9985
assert series.levels[5].shape == (3, 1904, 4864, 3)
9986
assert series.levels[6].shape == (3, 952, 2432, 3)
9987
# 3rd z-slice in base layer
9988
page = series.pages[2]
9989
assert page.index == 14
9990
assert page.shape == (60928, 155648, 3)
9991
assert page.dataoffsets[-1] == 4718518695
9992
assert page.databytecounts[-1] == 4338
9993
assert page.ndpi_tags['Magnification'] == 40.0
9994
assert page.ndpi_tags['FocusTime'] == 13
9995
assert page.ndpi_tags['ScannerSerialNumber'] == '680057'
9996
assert tuple(page.asarray()[60000, 150000]) == (216, 221, 217)
10000
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
10003
def test_read_ndpi_layers():
10004
"""Test read Hamamatsu NDPI slide with 5 layers."""
10005
fname = private_file('HamamatsuNDPI/hamamatsu_5-layers.ndpi')
10006
with TiffFile(fname) as tif:
10008
assert len(tif.pages) == 37
10009
assert len(tif.series) == 3
10010
for page in tif.pages:
10011
assert page.ndpi_tags['Model'] == 'C10730-12'
10013
for page in tif.pages[:4]:
10014
assert page.is_ndpi
10016
page.tags['PhotometricInterpretation'].value
10017
== PHOTOMETRIC.YCBCR
10019
assert page.tags['BitsPerSample'].value == (8, 8, 8)
10020
assert page.samplesperpixel == 3
10021
assert page.bitspersample == 8
10022
assert page.photometric == PHOTOMETRIC.YCBCR
10023
assert page.compression == COMPRESSION.JPEG
10026
page = tif.pages.first
10027
assert page.shape == (12032, 11520, 3)
10028
assert page.databytecounts[0] == 1634
10029
assert page.ndpi_tags['CaptureMode'] == 0
10030
assert page.ndpi_tags['Magnification'] == 20.0
10032
with page.aszarr() as store:
10033
data = zarr.open(store, mode='r')
10034
assert list(data[10000, 10000]) == [232, 215, 225]
10036
page = tif.pages[-1]
10037
assert page.is_ndpi
10038
assert page.photometric == PHOTOMETRIC.MINISBLACK
10039
assert page.compression == COMPRESSION.NONE
10040
assert page.shape == (196, 575)
10041
assert page.ndpi_tags['Magnification'] == -2.0
10043
series = tif.series[0]
10044
assert series.kind == 'ndpi'
10045
assert series.name == 'Baseline'
10046
assert series.shape == (7, 12032, 11520, 3)
10047
assert series.is_pyramidal
10048
assert len(series.levels) == 5
10049
assert len(series.pages) == 7
10051
assert series.levels[1].shape == (7, 6016, 5760, 3)
10052
assert series.levels[2].shape == (7, 3008, 2880, 3)
10053
assert series.levels[3].shape == (7, 1504, 1440, 3)
10054
assert series.levels[4].shape == (7, 752, 720, 3)
10055
data = series.levels[3].asarray()
10056
assert_array_equal(
10057
data[:, 1000, 1000],
10068
assert_aszarr_method(series.levels[3], data)
10072
@pytest.mark.skipif(
10073
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
10076
def test_read_svs_cmu1():
10077
"""Test read Aperio SVS slide, JPEG and LZW."""
10078
fname = private_file('AperioSVS/CMU-1.svs')
10079
with TiffFile(fname) as tif:
10081
assert not tif.is_scanimage
10082
assert len(tif.pages) == 6
10083
assert len(tif.series) == 4
10084
for page in tif.pages:
10085
svs_description_metadata(page.description)
10087
page = tif.pages.first
10089
assert not page.is_jfif
10090
assert page.is_subsampled
10091
assert page.photometric == PHOTOMETRIC.RGB
10092
assert page.is_tiled
10093
assert page.compression == COMPRESSION.JPEG
10094
assert page.shape == (32914, 46000, 3)
10095
metadata = svs_description_metadata(page.description)
10096
assert metadata['Header'].startswith('Aperio Image Library')
10097
assert metadata['Originalheight'] == 33014
10099
page = tif.pages[4]
10101
assert page.is_reduced
10102
assert page.photometric == PHOTOMETRIC.RGB
10103
assert page.compression == COMPRESSION.LZW
10104
assert page.shape == (463, 387, 3)
10105
metadata = svs_description_metadata(page.description)
10106
assert 'label 387x463' in metadata['Header']
10107
assert_aszarr_method(page)
10111
@pytest.mark.skipif(
10112
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG2K.available,
10115
def test_read_svs_jp2k_33003_1():
10116
"""Test read Aperio SVS slide, JP2000 and LZW."""
10117
fname = private_file('AperioSVS/JP2K-33003-1.svs')
10118
with TiffFile(fname) as tif:
10120
assert not tif.is_scanimage
10121
assert len(tif.pages) == 6
10122
assert len(tif.series) == 4
10123
for page in tif.pages:
10124
svs_description_metadata(page.description)
10126
page = tif.pages.first
10128
assert not page.is_subsampled
10129
assert page.photometric == PHOTOMETRIC.RGB
10130
assert page.is_tiled
10131
assert page.compression == COMPRESSION.APERIO_JP2000_YCBC
10132
assert page.shape == (17497, 15374, 3)
10133
metadata = svs_description_metadata(page.description)
10134
assert metadata['Header'].startswith('Aperio Image Library')
10135
assert metadata['Originalheight'] == 17597
10137
page = tif.pages[4]
10139
assert page.is_reduced
10140
assert page.photometric == PHOTOMETRIC.RGB
10141
assert page.compression == COMPRESSION.LZW
10142
assert page.shape == (422, 415, 3)
10143
metadata = svs_description_metadata(page.description)
10144
assert 'label 415x422' in metadata['Header']
10145
assert_aszarr_method(page)
10149
@pytest.mark.skipif(
10150
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
10153
def test_read_bif(caplog):
10154
"""Test read Ventana BIF slide."""
10155
fname = private_file('VentanaBIF/OS-2.bif')
10156
with TiffFile(fname) as tif:
10158
assert len(tif.pages) == 12
10159
assert len(tif.series) == 3
10161
page = tif.pages.first
10163
assert page.photometric == PHOTOMETRIC.YCBCR
10164
assert page.is_tiled
10165
assert page.compression == COMPRESSION.JPEG
10166
assert page.shape == (3008, 1008, 3)
10168
series = tif.series
10169
assert 'not stiched' in caplog.text
10171
series = tif.series[0]
10172
assert series.kind == 'bif'
10173
assert series.name == 'Baseline'
10174
assert len(series.levels) == 10
10175
assert series.shape == (82960, 128000, 3)
10176
assert series.dtype == numpy.uint8
10178
page = series.pages[0]
10180
assert page.is_tiled
10181
assert page.photometric == PHOTOMETRIC.YCBCR
10182
assert page.compression == COMPRESSION.JPEG
10183
assert page.shape == (82960, 128000, 3)
10184
assert page.description == 'level=0 mag=40 quality=90'
10186
page = series.levels[5].pages[0]
10187
assert not page.is_bif
10188
assert page.is_tiled
10189
assert page.photometric == PHOTOMETRIC.YCBCR
10190
assert page.compression == COMPRESSION.JPEG
10191
assert page.shape == (2600, 4000, 3)
10192
assert page.description == 'level=5 mag=1.25 quality=90'
10194
assert_aszarr_method(page)
10198
@pytest.mark.skipif(
10202
or not imagecodecs.JPEG.available,
10205
def test_read_scn_collection():
10206
"""Test read Leica SCN slide, JPEG."""
10207
# collection of 43 CZYX images
10208
# https://forum.image.sc/t/43585
10209
fname = private_file(
10210
'LeicaSCN/19-3-12_b5992c2e-5b6e-46f2-bf9b-d5872bdebdc1.SCN'
10212
with TiffFile(fname) as tif:
10214
assert tif.is_bigtiff
10215
assert len(tif.pages) == 5358
10216
assert len(tif.series) == 46
10218
page = tif.pages.first
10220
assert page.is_tiled
10221
assert page.photometric == PHOTOMETRIC.YCBCR
10222
assert page.compression == COMPRESSION.JPEG
10223
assert page.shape == (12990, 5741, 3)
10224
metadata = tif.scn_metadata
10225
assert metadata.startswith('<?xml version="1.0" encoding="utf-8"?>')
10226
for series in tif.series[2:]:
10227
assert series.kind == 'scn'
10228
assert series.axes == 'CZYX'
10229
assert series.shape[:2] == (4, 8)
10230
assert len(series.levels) in {2, 3, 4, 5}
10231
assert len(series.pages) == 32
10233
series = tif.series[2]
10234
assert series.shape == (4, 8, 946, 993)
10235
assert_aszarr_method(series)
10239
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10240
def test_read_scanimage_metadata():
10241
"""Test read ScanImage metadata."""
10242
fname = private_file('ScanImage/TS_UnitTestImage_BigTIFF.tif')
10243
with open(fname, 'rb') as fh:
10244
frame_data, roi_data, version = read_scanimage_metadata(fh)
10245
assert version == 3
10246
assert frame_data['SI.hChannels.channelType'] == ['stripe', 'stripe']
10247
assert roi_data['RoiGroups']['imagingRoiGroup']['ver'] == 1
10250
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10251
def test_read_scanimage_2021():
10252
"""Test read ScanImage metadata."""
10253
# https://github.com/cgohlke/tifffile/issues/46
10254
fname = private_file('ScanImage/ScanImage2021_3frames.tif')
10255
with open(fname, 'rb') as fh:
10256
frame_data, roi_data, version = read_scanimage_metadata(fh)
10257
assert frame_data['SI.hChannels.channelType'] == [
10263
assert version == 4
10264
assert roi_data['RoiGroups']['imagingRoiGroup']['ver'] == 1
10266
with TiffFile(fname) as tif:
10267
assert tif.is_scanimage
10268
assert len(tif.pages) == 3
10269
assert len(tif.series) == 1
10270
assert tif.series[0].shape == (3, 256, 256)
10271
assert tif.series[0].axes == 'TYX'
10272
# non-varying scanimage_metadata
10273
assert tif.scanimage_metadata['version'] == 4
10274
assert 'FrameData' in tif.scanimage_metadata
10275
assert 'RoiGroups' in tif.scanimage_metadata
10276
# assert page properties
10277
page = tif.pages.first
10278
assert page.is_scanimage
10279
assert page.is_contiguous
10280
assert page.compression == COMPRESSION.NONE
10281
assert page.imagewidth == 256
10282
assert page.imagelength == 256
10283
assert page.bitspersample == 16
10284
assert page.samplesperpixel == 1
10286
metadata = scanimage_description_metadata(page.description)
10287
assert metadata['epoch'] == [2021, 3, 1, 17, 31, 28.047]
10288
assert_aszarr_method(tif)
10292
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10293
def test_read_scanimage_no_framedata():
10294
"""Test read ScanImage no FrameData."""
10295
fname = private_file('ScanImage/PSF001_ScanImage36.tif')
10296
with TiffFile(fname) as tif:
10297
assert tif.is_scanimage
10298
assert len(tif.pages) == 100
10299
assert len(tif.series) == 1
10300
# no non-tiff scanimage_metadata
10301
assert not tif.scanimage_metadata
10302
# assert page properties
10303
page = tif.pages.first
10304
assert page.is_scanimage
10305
assert page.is_contiguous
10306
assert page.compression == COMPRESSION.NONE
10307
assert page.imagewidth == 256
10308
assert page.imagelength == 256
10309
assert page.bitspersample == 16
10310
assert page.samplesperpixel == 1
10312
metadata = scanimage_description_metadata(page.description)
10313
assert metadata['state.software.version'] == 3.6
10314
assert_aszarr_method(tif)
10318
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
10319
def test_read_scanimage_2gb():
10320
"""Test read ScanImage non-BigTIFF > 2 GB.
10322
https://github.com/MouseLand/suite2p/issues/149
10325
fname = private_file('ScanImage/M161209TH_01__001.tif')
10326
with TiffFile(fname) as tif:
10327
assert tif.is_scanimage
10328
assert len(tif.pages) == 5980
10329
assert len(tif.series) == 1
10330
assert tif.series[0].kind == 'scanimage'
10331
# no non-tiff scanimage_metadata
10332
assert 'version' not in tif.scanimage_metadata
10333
assert 'FrameData' not in tif.scanimage_metadata
10334
assert 'RoiGroups' not in tif.scanimage_metadata
10335
# assert page properties
10336
page = tif.pages.first
10337
assert isinstance(page, TiffPage)
10338
assert not page.is_frame
10339
assert not page.is_virtual
10340
assert not page.is_subifd
10341
assert page.is_scanimage
10342
assert page.is_contiguous
10343
assert page.compression == COMPRESSION.NONE
10344
assert page.imagewidth == 512
10345
assert page.imagelength == 512
10346
assert page.bitspersample == 16
10347
assert page.samplesperpixel == 1
10348
# using virtual frames
10349
frame = tif.pages[-1]
10350
assert isinstance(frame, TiffFrame)
10351
assert frame.is_frame
10352
assert frame.is_virtual
10353
assert not frame.is_subifd
10354
assert frame.offset <= 0
10355
assert frame.index == 5979
10356
assert frame.dataoffsets[0] == 3163182856
10357
assert frame.databytecounts[0] == 8192 # 524288
10358
assert len(frame.dataoffsets) == 64
10359
assert len(frame.databytecounts) == 64
10361
metadata = scanimage_description_metadata(page.description)
10362
assert metadata['scanimage.SI5.VERSION_MAJOR'] == 5
10364
data = tif.asarray()
10365
assert data[5979, 256, 256] == 71
10366
data = frame.asarray()
10367
assert data[256, 256] == 71
10368
assert_aszarr_method(tif)
10372
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10373
def test_read_scanimage_bigtiff():
10374
"""Test read ScanImage BigTIFF."""
10375
# https://github.com/cgohlke/tifffile/issues/29
10376
fname = private_file('ScanImage/area1__00001.tif')
10377
with TiffFile(fname) as tif:
10378
assert tif.is_scanimage
10379
assert len(tif.pages) == 162
10380
assert len(tif.series) == 1
10381
assert tif.series[0].kind == 'scanimage'
10382
# assert page properties
10383
page = tif.pages.first
10384
assert page.is_scanimage
10385
assert page.is_contiguous
10386
assert page.compression == COMPRESSION.NONE
10387
assert page.imagewidth == 512
10388
assert page.imagelength == 512
10389
assert page.bitspersample == 16
10390
assert page.samplesperpixel == 1
10391
# metadata in description, software, artist tags
10392
metadata = scanimage_description_metadata(page.description)
10393
assert metadata['frameNumbers'] == 1
10394
metadata = scanimage_description_metadata(page.tags['Software'].value)
10395
assert metadata['SI.TIFF_FORMAT_VERSION'] == 3
10396
metadata = scanimage_artist_metadata(page.tags['Artist'].value)
10397
assert metadata['RoiGroups']['imagingRoiGroup']['ver'] == 1
10398
metadata = tif.scanimage_metadata
10399
assert metadata['version'] == 3
10400
assert metadata['FrameData']['SI.TIFF_FORMAT_VERSION'] == 3
10401
assert metadata['RoiGroups']['imagingRoiGroup']['ver'] == 1
10402
assert 'Description' not in metadata
10403
# assert page offsets are correct
10404
assert tif.pages[-1].offset == 84527590 # not 84526526 (calculated)
10406
assert_aszarr_method(tif)
10410
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10411
def test_read_ome_single_channel():
10412
"""Test read OME image."""
10413
# 2D (single image)
10414
# OME-TIFF reference images from
10415
# https://www.openmicroscopy.org/site/support/ome-model/ome-tiff
10416
fname = public_file('OME/bioformats-artificial/single-channel.ome.tif')
10417
with TiffFile(fname) as tif:
10419
assert tif.byteorder == '>'
10420
assert len(tif.pages) == 1
10421
assert len(tif.series) == 1
10422
# assert page properties
10423
page = tif.pages.first
10424
assert page.is_contiguous
10425
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10426
assert page.compression == COMPRESSION.NONE
10427
assert page.imagewidth == 439
10428
assert page.imagelength == 167
10429
assert page.bitspersample == 8
10430
assert page.samplesperpixel == 1
10431
# assert series properties
10432
series = tif.series[0]
10433
assert not series.is_multifile
10434
assert series.dtype == numpy.int8
10435
assert series.shape == (167, 439)
10436
assert series.axes == 'YX'
10437
assert series.kind == 'ome'
10438
assert series.get_shape(False) == (1, 1, 1, 167, 439, 1)
10439
assert series.get_axes(False) == 'TCZYXS'
10441
data = tif.asarray()
10442
assert isinstance(data, numpy.ndarray)
10443
assert data.shape == (167, 439)
10444
assert data.dtype == numpy.int8
10445
assert data[158, 428] == 91
10446
assert_aszarr_method(tif, data)
10450
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10451
def test_read_ome_multi_channel():
10452
"""Test read OME multi channel image."""
10454
fname = public_file('OME/bioformats-artificial/multi-channel.ome.tiff')
10455
with TiffFile(fname) as tif:
10457
assert tif.byteorder == '>'
10458
assert len(tif.pages) == 3
10459
assert len(tif.series) == 1
10460
# assert page properties
10461
page = tif.pages.first
10462
assert page.is_contiguous
10463
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10464
assert page.compression == COMPRESSION.NONE
10465
assert page.imagewidth == 439
10466
assert page.imagelength == 167
10467
assert page.bitspersample == 8
10468
assert page.samplesperpixel == 1
10469
# assert series properties
10470
series = tif.series[0]
10471
assert series.shape == (3, 167, 439)
10472
assert series.dtype == numpy.int8
10473
assert series.axes == 'CYX'
10474
assert series.kind == 'ome'
10475
assert series.get_shape(False) == (1, 3, 1, 167, 439, 1)
10476
assert series.get_axes(False) == 'TCZYXS'
10477
assert not series.is_multifile
10479
data = tif.asarray()
10480
assert isinstance(data, numpy.ndarray)
10481
assert data.shape == (3, 167, 439)
10482
assert data.dtype == numpy.int8
10483
assert data[2, 158, 428] == 91
10484
assert_aszarr_method(tif, data)
10486
data = tif.asarray(squeeze=False)
10487
assert_aszarr_method(tif, data, squeeze=False)
10491
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10492
def test_read_ome_z_series():
10493
"""Test read OME volume."""
10494
# 3D (5 focal planes)
10495
fname = public_file('OME/bioformats-artificial/z-series.ome.tif')
10496
with TiffFile(fname) as tif:
10498
assert tif.byteorder == '>'
10499
assert len(tif.pages) == 5
10500
assert len(tif.series) == 1
10501
# assert page properties
10502
page = tif.pages.first
10503
assert page.is_contiguous
10504
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10505
assert page.compression == COMPRESSION.NONE
10506
assert page.imagewidth == 439
10507
assert page.imagelength == 167
10508
assert page.bitspersample == 8
10509
assert page.samplesperpixel == 1
10510
# assert series properties
10511
series = tif.series[0]
10512
assert series.shape == (5, 167, 439)
10513
assert series.dtype == numpy.int8
10514
assert series.axes == 'ZYX'
10515
assert series.kind == 'ome'
10516
assert series.get_shape(False) == (1, 1, 5, 167, 439, 1)
10517
assert series.get_axes(False) == 'TCZYXS'
10518
assert not series.is_multifile
10520
data = tif.asarray()
10521
assert isinstance(data, numpy.ndarray)
10522
assert data.shape == (5, 167, 439)
10523
assert data.dtype == numpy.int8
10524
assert data[4, 158, 428] == 91
10525
assert_aszarr_method(tif, data)
10529
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10530
def test_read_ome_multi_channel_z_series():
10531
"""Test read OME multi-channel volume."""
10532
# 3D (5 focal planes, 3 channels)
10533
fname = public_file(
10534
'OME/bioformats-artificial/multi-channel-z-series.ome.tiff'
10536
with TiffFile(fname) as tif:
10538
assert tif.byteorder == '>'
10539
assert len(tif.pages) == 15
10540
assert len(tif.series) == 1
10541
# assert page properties
10542
page = tif.pages.first
10543
assert page.is_contiguous
10544
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10545
assert page.compression == COMPRESSION.NONE
10546
assert page.imagewidth == 439
10547
assert page.imagelength == 167
10548
assert page.bitspersample == 8
10549
assert page.samplesperpixel == 1
10550
# assert series properties
10551
series = tif.series[0]
10552
assert series.shape == (3, 5, 167, 439)
10553
assert series.dtype == numpy.int8
10554
assert series.axes == 'CZYX'
10555
assert series.kind == 'ome'
10556
assert series.get_shape(False) == (1, 3, 5, 167, 439, 1)
10557
assert series.get_axes(False) == 'TCZYXS'
10558
assert not series.is_multifile
10560
data = tif.asarray()
10561
assert isinstance(data, numpy.ndarray)
10562
assert data.shape == (3, 5, 167, 439)
10563
assert data.dtype == numpy.int8
10564
assert data[2, 4, 158, 428] == 91
10565
assert_aszarr_method(tif, data)
10569
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10570
def test_read_ome_time_series():
10571
"""Test read OME time-series of images."""
10572
# 3D (7 time points)
10573
fname = public_file('OME/bioformats-artificial/time-series.ome.tiff')
10574
with TiffFile(fname) as tif:
10576
assert tif.byteorder == '>'
10577
assert len(tif.pages) == 7
10578
assert len(tif.series) == 1
10579
# assert page properties
10580
page = tif.pages.first
10581
assert page.is_contiguous
10582
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10583
assert page.compression == COMPRESSION.NONE
10584
assert page.imagewidth == 439
10585
assert page.imagelength == 167
10586
assert page.bitspersample == 8
10587
assert page.samplesperpixel == 1
10588
# assert series properties
10589
series = tif.series[0]
10590
assert series.shape == (7, 167, 439)
10591
assert series.dtype == numpy.int8
10592
assert series.axes == 'TYX'
10593
assert series.kind == 'ome'
10594
assert series.get_shape(False) == (7, 1, 1, 167, 439, 1)
10595
assert series.get_axes(False) == 'TCZYXS'
10596
assert not series.is_multifile
10598
data = tif.asarray()
10599
assert isinstance(data, numpy.ndarray)
10600
assert data.shape == (7, 167, 439)
10601
assert data.dtype == numpy.int8
10602
assert data[6, 158, 428] == 91
10603
assert_aszarr_method(tif, data)
10607
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10608
def test_read_ome_multi_channel_time_series():
10609
"""Test read OME time-series of multi-channel images."""
10610
# 3D (7 time points, 3 channels)
10611
fname = public_file(
10612
'OME/bioformats-artificial/multi-channel-time-series.ome.tiff'
10614
with TiffFile(fname) as tif:
10616
assert tif.byteorder == '>'
10617
assert len(tif.pages) == 21
10618
assert len(tif.series) == 1
10619
# assert page properties
10620
page = tif.pages.first
10621
assert page.is_contiguous
10622
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10623
assert page.compression == COMPRESSION.NONE
10624
assert page.imagewidth == 439
10625
assert page.imagelength == 167
10626
assert page.bitspersample == 8
10627
assert page.samplesperpixel == 1
10628
# assert series properties
10629
series = tif.series[0]
10630
assert series.shape == (7, 3, 167, 439)
10631
assert series.dtype == numpy.int8
10632
assert series.axes == 'TCYX'
10633
assert series.kind == 'ome'
10634
assert series.get_shape(False) == (7, 3, 1, 167, 439, 1)
10635
assert series.get_axes(False) == 'TCZYXS'
10636
assert not series.is_multifile
10638
data = tif.asarray()
10639
assert isinstance(data, numpy.ndarray)
10640
assert data.shape == (7, 3, 167, 439)
10641
assert data.dtype == numpy.int8
10642
assert data[6, 2, 158, 428] == 91
10643
assert_aszarr_method(tif, data)
10645
data = tif.asarray(squeeze=False)
10646
assert_aszarr_method(tif, data, squeeze=False)
10650
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10651
def test_read_ome_4d_series():
10652
"""Test read OME time-series of volumes."""
10653
# 4D (7 time points, 5 focal planes)
10654
fname = public_file('OME/bioformats-artificial/4D-series.ome.tiff')
10655
with TiffFile(fname) as tif:
10657
assert tif.byteorder == '>'
10658
assert len(tif.pages) == 35
10659
assert len(tif.series) == 1
10660
# assert page properties
10661
page = tif.pages.first
10662
assert page.is_contiguous
10663
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10664
assert page.compression == COMPRESSION.NONE
10665
assert page.imagewidth == 439
10666
assert page.imagelength == 167
10667
assert page.bitspersample == 8
10668
assert page.samplesperpixel == 1
10669
# assert series properties
10670
series = tif.series[0]
10671
assert series.shape == (7, 5, 167, 439)
10672
assert series.dtype == numpy.int8
10673
assert series.axes == 'TZYX'
10674
assert series.kind == 'ome'
10675
assert not series.is_multifile
10677
data = tif.asarray()
10678
assert isinstance(data, numpy.ndarray)
10679
assert data.shape == (7, 5, 167, 439)
10680
assert data.dtype == numpy.int8
10681
assert data[6, 4, 158, 428] == 91
10682
assert_aszarr_method(tif, data)
10686
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10687
def test_read_ome_multi_channel_4d_series():
10688
"""Test read OME time-series of multi-channel volumes."""
10689
# 4D (7 time points, 5 focal planes, 3 channels)
10690
fname = public_file(
10691
'OME/bioformats-artificial/multi-channel-4D-series.ome.tiff'
10693
with TiffFile(fname) as tif:
10695
assert tif.byteorder == '>'
10696
assert len(tif.pages) == 105
10697
assert len(tif.series) == 1
10698
# assert page properties
10699
page = tif.pages.first
10700
assert page.is_contiguous
10701
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10702
assert page.compression == COMPRESSION.NONE
10703
assert page.imagewidth == 439
10704
assert page.imagelength == 167
10705
assert page.bitspersample == 8
10706
assert page.samplesperpixel == 1
10707
# assert series properties
10708
series = tif.series[0]
10709
assert series.shape == (7, 3, 5, 167, 439)
10710
assert series.dtype == numpy.int8
10711
assert series.axes == 'TCZYX'
10712
assert series.kind == 'ome'
10713
assert series.get_shape(False) == (7, 3, 5, 167, 439, 1)
10714
assert series.get_axes(False) == 'TCZYXS'
10715
assert not series.is_multifile
10717
data = tif.asarray()
10718
assert isinstance(data, numpy.ndarray)
10719
assert data.shape == (7, 3, 5, 167, 439)
10720
assert data.dtype == numpy.int8
10721
assert data[6, 0, 4, 158, 428] == 91
10722
assert_aszarr_method(tif, data)
10724
data = tif.asarray(squeeze=False)
10725
assert_aszarr_method(tif, data, squeeze=False)
10729
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10730
def test_read_ome_modulo_flim():
10731
"""Test read OME modulo FLIM."""
10732
fname = public_file('OME/modulo/FLIM-ModuloAlongC.ome.tiff')
10733
with TiffFile(fname) as tif:
10735
assert tif.byteorder == '>'
10736
assert len(tif.pages) == 16
10737
assert len(tif.series) == 1
10738
# assert page properties
10739
page = tif.pages.first
10740
assert page.is_contiguous
10741
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10742
assert page.compression == COMPRESSION.NONE
10743
assert page.imagewidth == 180
10744
assert page.imagelength == 150
10745
assert page.bitspersample == 8
10746
assert page.samplesperpixel == 1
10747
# assert series properties
10748
series = tif.series[0]
10749
assert series.shape == (2, 8, 150, 180)
10750
assert series.dtype == numpy.int8
10751
assert series.axes == 'CHYX'
10752
assert series.kind == 'ome'
10753
assert series.get_shape(False) == (1, 2, 8, 1, 150, 180, 1)
10754
assert series.get_axes(False) == 'TCHZYXS'
10755
assert not series.is_multifile
10757
data = tif.asarray()
10758
assert isinstance(data, numpy.ndarray)
10759
assert data.shape == (2, 8, 150, 180)
10760
assert data.dtype == numpy.int8
10761
assert data[1, 7, 143, 172] == 92
10762
assert_aszarr_method(tif, data)
10764
data = tif.asarray(squeeze=False)
10765
assert_aszarr_method(tif, data, squeeze=False)
10769
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10770
def test_read_ome_modulo_flim_tcspc():
10771
"""Test read OME modulo FLIM TSCPC."""
10772
# Two channels each recorded at two timepoints and eight histogram bins
10773
fname = public_file('OME/modulo/FLIM-ModuloAlongT-TSCPC.ome.tiff')
10774
with TiffFile(fname) as tif:
10776
assert tif.byteorder == '<'
10777
assert len(tif.pages) == 32
10778
assert len(tif.series) == 1
10779
# assert page properties
10780
page = tif.pages.first
10781
assert page.is_contiguous
10782
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
10783
assert page.compression == COMPRESSION.NONE
10784
assert page.imagewidth == 180
10785
assert page.imagelength == 200
10786
assert page.bitspersample == 8
10787
assert page.samplesperpixel == 1
10788
# assert series properties
10789
series = tif.series[0]
10790
assert series.shape == (2, 8, 2, 200, 180)
10791
assert series.dtype == numpy.int8
10792
assert series.axes == 'THCYX'
10793
assert series.kind == 'ome'
10794
assert not series.is_multifile
10796
data = tif.asarray()
10797
assert isinstance(data, numpy.ndarray)
10798
assert data.shape == (2, 8, 2, 200, 180)
10799
assert data.dtype == numpy.int8
10800
assert data[1, 7, 1, 190, 161] == 92
10801
assert_aszarr_method(tif, data)
10805
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10806
def test_read_ome_modulo_spim():
10807
"""Test read OME modulo SPIM."""
10808
# 2x2 tile of planes each recorded at 4 angles
10809
fname = public_file('OME/modulo/SPIM-ModuloAlongZ.ome.tiff')
10810
with TiffFile(fname) as tif:
10812
assert tif.byteorder == '<'
10813
assert len(tif.pages) == 192
10814
assert len(tif.series) == 1
10815
# assert page properties
10816
page = tif.pages.first
10817
assert page.is_contiguous
10818
assert page.tags['Software'].value == 'OME Bio-Formats 5.2.0-SNAPSHOT'
10819
assert page.compression == COMPRESSION.NONE
10820
assert page.imagewidth == 160
10821
assert page.imagelength == 220
10822
assert page.bitspersample == 8
10823
assert page.samplesperpixel == 1
10824
# assert series properties
10825
series = tif.series[0]
10826
assert series.shape == (3, 4, 2, 4, 2, 220, 160)
10827
assert series.dtype == numpy.uint8
10828
assert series.axes == 'TRZACYX'
10829
assert series.kind == 'ome'
10830
assert not series.is_multifile
10832
data = tif.asarray()
10833
assert isinstance(data, numpy.ndarray)
10834
assert data.shape == (3, 4, 2, 4, 2, 220, 160)
10835
assert data.dtype == numpy.uint8
10836
assert data[2, 3, 1, 3, 1, 210, 151] == 92
10837
assert_aszarr_method(tif, data)
10841
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10842
def test_read_ome_modulo_lambda():
10843
"""Test read OME modulo LAMBDA."""
10844
# Excitation of 5 wavelength [big-lambda] each recorded at 10 emission
10845
# wavelength ranges [lambda].
10846
fname = public_file('OME/modulo/LAMBDA-ModuloAlongZ-ModuloAlongT.ome.tiff')
10847
with TiffFile(fname) as tif:
10849
assert tif.byteorder == '<'
10850
assert len(tif.pages) == 50
10851
assert len(tif.series) == 1
10852
# assert page properties
10853
page = tif.pages.first
10854
assert page.is_contiguous
10855
assert page.tags['Software'].value == 'OME Bio-Formats 5.2.0-SNAPSHOT'
10856
assert page.compression == COMPRESSION.NONE
10857
assert page.imagewidth == 200
10858
assert page.imagelength == 200
10859
assert page.bitspersample == 8
10860
assert page.samplesperpixel == 1
10861
# assert series properties
10862
series = tif.series[0]
10863
assert series.shape == (10, 5, 200, 200)
10864
assert series.dtype == numpy.uint8
10865
assert series.axes == 'EPYX'
10866
assert series.kind == 'ome'
10867
assert not series.is_multifile
10869
data = tif.asarray()
10870
assert isinstance(data, numpy.ndarray)
10871
assert data.shape == (10, 5, 200, 200)
10872
assert data.dtype == numpy.uint8
10873
assert data[9, 4, 190, 192] == 92
10874
assert_aszarr_method(tif, data)
10878
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
10879
def test_read_ome_multiimage_pixels():
10880
"""Test read OME with three image series."""
10881
fname = public_file('OME/bioformats-artificial/multi-image-pixels.ome.tif')
10882
with TiffFile(fname) as tif:
10884
assert tif.byteorder == '>'
10885
assert len(tif.pages) == 86
10886
assert len(tif.series) == 3
10887
# assert page properties
10888
for i, axes, shape in (
10889
(0, 'CTYX', (2, 7, 555, 431)),
10890
(1, 'TZYX', (6, 2, 461, 348)),
10891
(2, 'TZCYX', (4, 5, 3, 239, 517)),
10893
series = tif.series[i]
10894
assert series.kind == 'ome'
10895
page = series.pages[0]
10896
assert page.is_contiguous
10897
assert page.tags['Software'].value == 'LOCI Bio-Formats'
10898
assert page.compression == COMPRESSION.NONE
10899
assert page.imagewidth == shape[-1]
10900
assert page.imagelength == shape[-2]
10901
assert page.bitspersample == 8
10902
assert page.samplesperpixel == 1
10903
# assert series properties
10904
assert series.shape == shape
10905
assert series.dtype == numpy.uint8
10906
assert series.axes == axes
10907
assert not series.is_multifile
10909
data = tif.asarray(series=i)
10910
assert isinstance(data, numpy.ndarray)
10911
assert data.shape == shape
10912
assert data.dtype == numpy.uint8
10913
assert_aszarr_method(series, data)
10917
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10918
def test_read_ome_multiimage_nouuid():
10919
"""Test read single-file, multi-image OME without UUID."""
10920
fname = private_file(
10921
'OMETIFF.jl/singles/181003_multi_pos_time_course_1_MMStack.ome.tif'
10923
with TiffFile(fname, is_mmstack=False) as tif:
10925
assert tif.byteorder == '<'
10926
assert len(tif.pages) == 20
10927
assert len(tif.series) == 2
10928
# assert page properties
10930
series = tif.series[i]
10931
page = series.pages[0]
10932
assert page.is_imagej == (i == 0)
10933
assert page.is_ome == (i == 0)
10934
assert page.is_micromanager
10935
assert page.is_contiguous
10936
assert page.compression == COMPRESSION.NONE
10937
assert page.imagewidth == 256
10938
assert page.imagelength == 256
10939
assert page.bitspersample == 16
10940
assert page.samplesperpixel == 1
10941
# assert series properties
10942
assert series.shape == (10, 256, 256)
10943
assert series.dtype == numpy.uint16
10944
assert series.axes == 'TYX'
10945
assert series.kind == 'ome'
10946
assert not series.is_multifile
10948
data = tif.asarray(series=i)
10949
assert_array_equal(
10950
data, imread(fname, series=i, is_micromanager=False)
10952
assert isinstance(data, numpy.ndarray)
10953
assert data.shape == (10, 256, 256)
10954
assert data.dtype == numpy.uint16
10955
assert data[5, 128, 128] == (18661, 16235)[i]
10956
assert_aszarr_method(series, data)
10960
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
10961
def test_read_ome_zen_2chzt():
10962
"""Test read OME time-series of two-channel volumes by ZEN 2011."""
10963
fname = private_file('OME/zen_2chzt.ome.tiff')
10964
with TiffFile(fname) as tif:
10966
assert tif.byteorder == '<'
10967
assert len(tif.pages) == 798
10968
assert len(tif.series) == 1
10969
# assert page properties
10970
page = tif.pages.first
10971
assert page.is_contiguous
10972
assert page.tags['Software'].value == 'ZEN 2011 (blue edition)'
10973
assert page.compression == COMPRESSION.NONE
10974
assert page.imagewidth == 400
10975
assert page.imagelength == 300
10976
assert page.bitspersample == 8
10977
assert page.samplesperpixel == 1
10978
# assert series properties
10979
series = tif.series[0]
10980
assert series.shape == (2, 19, 21, 300, 400)
10981
assert series.dtype == numpy.uint8
10982
assert series.axes == 'CTZYX'
10983
assert series.kind == 'ome'
10984
assert not series.is_multifile
10986
data = tif.asarray()
10987
assert isinstance(data, numpy.ndarray)
10988
assert data.shape == (2, 19, 21, 300, 400)
10989
assert data.dtype == numpy.uint8
10990
assert data[1, 10, 10, 100, 245] == 78
10991
assert_aszarr_method(tif, data)
10992
assert__str__(tif, 0)
10995
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
10996
def test_read_ome_multifile():
10997
"""Test read OME CTZYX series in 86 files."""
10998
# (2, 43, 10, 512, 512) CTZYX uint8 in 86 files, 10 pages each
10999
fname = public_file('OME/tubhiswt-4D/tubhiswt_C0_TP10.ome.tif')
11000
with TiffFile(fname) as tif:
11002
assert tif.byteorder == '<'
11003
assert len(tif.pages) == 10
11004
assert len(tif.series) == 1
11005
# assert page properties
11006
page = tif.pages.first
11007
assert page.is_contiguous
11008
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11009
assert page.compression == COMPRESSION.NONE
11010
assert page.imagewidth == 512
11011
assert page.imagelength == 512
11012
assert page.bitspersample == 8
11013
assert page.samplesperpixel == 1
11014
# assert series properties
11015
series = tif.series[0]
11016
assert series.shape == (2, 43, 10, 512, 512)
11017
assert series.dtype == numpy.uint8
11018
assert series.axes == 'CTZYX'
11019
assert series.kind == 'ome'
11020
assert series.is_multifile
11021
# assert other files are closed after TiffFile._series_ome
11022
for page in tif.series[0].pages:
11023
assert bool(page.parent.filehandle._fh) == (page.parent == tif)
11025
data = tif.asarray(out='memmap')
11026
assert isinstance(data, numpy.memmap)
11027
assert data.shape == (2, 43, 10, 512, 512)
11028
assert data.dtype == numpy.uint8
11029
assert data[1, 42, 9, 426, 272] == 123
11030
# assert other files are still closed after TiffFile.asarray
11031
for page in tif.series[0].pages:
11032
assert bool(page.parent.filehandle._fh) == (page.parent == tif)
11033
assert tif.filehandle._fh
11036
assert_aszarr_method(tif, data)
11037
assert_aszarr_method(tif, data, chunkmode='page')
11039
# assert other files are still closed after ZarrStore.close
11040
for page in tif.series[0].pages:
11041
assert bool(page.parent.filehandle._fh) == (page.parent == tif)
11043
# assert all files stay open
11044
# with TiffFile(fname) as tif:
11045
# for page in tif.series[0].pages:
11046
# self.assertTrue(page.parent.filehandle._fh)
11047
# data = tif.asarray(out='memmap')
11048
# for page in tif.series[0].pages:
11049
# self.assertTrue(page.parent.filehandle._fh)
11052
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
11053
def test_read_ome_multifile_missing(caplog):
11054
"""Test read OME referencing missing files."""
11055
# (2, 43, 10, 512, 512) CTZYX uint8, 85 files missing
11056
fname = private_file('OME/tubhiswt_C0_TP34.ome.tif')
11057
with TiffFile(fname) as tif:
11059
assert tif.byteorder == '<'
11060
assert len(tif.pages) == 10
11061
assert len(tif.series) == 1
11062
assert 'failed to read' in caplog.text
11063
# assert page properties
11064
page = tif.pages.first
11065
TiffPage._str(page, 4)
11066
assert page.is_contiguous
11067
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11068
assert page.compression == COMPRESSION.NONE
11069
assert page.imagewidth == 512
11070
assert page.imagelength == 512
11071
assert page.bitspersample == 8
11072
assert page.samplesperpixel == 1
11073
page = tif.pages[-1]
11074
TiffPage._str(page, 4)
11075
assert page.shape == (512, 512)
11076
# assert series properties
11077
series = tif.series[0]
11078
assert series.shape == (2, 43, 10, 512, 512)
11079
assert series.dtype == numpy.uint8
11080
assert series.axes == 'CTZYX'
11081
assert series.kind == 'ome'
11082
assert series.is_multifile
11084
data = tif.asarray(out='memmap')
11085
assert isinstance(data, numpy.memmap)
11086
assert data.shape == (2, 43, 10, 512, 512)
11087
assert data.dtype == numpy.uint8
11088
assert data[0, 34, 4, 303, 206] == 82
11089
assert data[1, 25, 2, 425, 272] == 196
11090
assert_aszarr_method(tif, data)
11091
assert_aszarr_method(tif, data, chunkmode='page')
11096
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
11097
def test_read_ome_multifile_binaryio(caplog):
11098
"""Test read OME multifile series with BinaryIO."""
11099
# (2, 43, 10, 512, 512) CTZYX uint8, 85 files missing
11100
fname = private_file('OME/tubhiswt_C0_TP34.ome.tif')
11101
with open(fname, 'rb') as fh:
11102
bytesio = BytesIO(fh.read())
11103
with TiffFile(bytesio) as tif:
11105
assert tif.byteorder == '<'
11106
assert len(tif.pages) == 10
11107
assert len(tif.series) == 1
11108
assert 'failed to read' in caplog.text
11109
# assert page properties
11110
page = tif.pages.first
11111
TiffPage._str(page, 4)
11112
assert page.is_contiguous
11113
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11114
assert page.compression == COMPRESSION.NONE
11115
assert page.imagewidth == 512
11116
assert page.imagelength == 512
11117
assert page.bitspersample == 8
11118
assert page.samplesperpixel == 1
11119
page = tif.pages[-1]
11120
TiffPage._str(page, 4)
11121
assert page.shape == (512, 512)
11122
# assert series properties
11123
series = tif.series[0]
11124
assert series.shape == (2, 43, 10, 512, 512)
11125
assert series.dtype == numpy.uint8
11126
assert series.axes == 'CTZYX'
11127
assert series.kind == 'ome'
11128
assert not series.is_multifile
11130
data = tif.asarray()
11131
assert data.shape == (2, 43, 10, 512, 512)
11132
assert data.dtype == numpy.uint8
11133
assert data[0, 34, 4, 303, 206] == 82
11134
assert data[1, 25, 2, 425, 272] == 0
11135
assert_aszarr_method(tif, data)
11140
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11141
def test_read_ome_companion(caplog):
11142
"""Test read multifile OME-TIFF using companion file."""
11143
fname = private_file('OME/companion/multifile-Z2.ome.tiff')
11144
with TiffFile(fname) as tif:
11146
with caplog.at_level(logging.DEBUG):
11147
assert tif.series[0].kind == 'generic'
11148
assert 'OME series is BinaryOnly' in caplog.text
11151
private_file('OME/companion/multifile.companion.ome'), encoding='utf-8'
11154
with TiffFile(fname, omexml=omexml) as tif:
11156
series = tif.series[0]
11157
assert series.kind == 'ome'
11158
image = series.asarray()
11160
fname = private_file('OME/companion/multifile-Z1.ome.tiff')
11161
image2 = imread(fname)
11162
assert_array_equal(image, image2)
11165
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11166
def test_read_ome_rgb():
11167
"""Test read OME RGB image."""
11168
# https://github.com/openmicroscopy/bioformats/pull/1986
11169
fname = private_file('OME/test_rgb.ome.tif')
11170
with TiffFile(fname) as tif:
11172
assert tif.byteorder == '<'
11173
assert len(tif.pages) == 1
11174
assert len(tif.series) == 1
11175
# assert page properties
11176
page = tif.pages.first
11177
assert page.is_contiguous
11178
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11179
assert page.compression == COMPRESSION.NONE
11180
assert page.imagewidth == 1280
11181
assert page.imagelength == 720
11182
assert page.bitspersample == 8
11183
assert page.samplesperpixel == 3
11184
# assert series properties
11185
series = tif.series[0]
11186
assert series.shape == (3, 720, 1280)
11187
assert series.dtype == numpy.uint8
11188
assert series.axes == 'SYX'
11189
assert series.kind == 'ome'
11190
assert series.dataoffset == 17524
11191
assert not series.is_multifile
11193
data = tif.asarray()
11194
assert data.shape == (3, 720, 1280)
11195
assert data.dtype == numpy.uint8
11196
assert data[1, 158, 428] == 253
11197
assert_aszarr_method(tif, data)
11198
assert_aszarr_method(tif, data, chunkmode='page')
11202
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
11203
def test_read_ome_samplesperpixel():
11204
"""Test read OME image stack with SamplesPerPixel>1."""
11205
# Reported by Grzegorz Bokota on 2019.1.30
11206
fname = private_file('OME/test_samplesperpixel.ome.tif')
11207
with TiffFile(fname) as tif:
11209
assert tif.byteorder == '>'
11210
assert len(tif.pages) == 6
11211
assert len(tif.series) == 1
11212
# assert page properties
11213
page = tif.pages.first
11214
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11215
assert page.compression == COMPRESSION.LZW
11216
assert page.imagewidth == 1024
11217
assert page.imagelength == 1024
11218
assert page.bitspersample == 8
11219
assert page.samplesperpixel == 3
11220
# assert series properties
11221
series = tif.series[0]
11222
assert series.shape == (6, 3, 1024, 1024)
11223
assert series.dtype == numpy.uint8
11224
assert series.axes == 'ZSYX'
11225
assert series.kind == 'ome'
11226
assert not series.is_multifile
11228
data = tif.asarray()
11229
assert data.shape == (6, 3, 1024, 1024)
11230
assert data.dtype == numpy.uint8
11231
assert tuple(data[5, :, 191, 449]) == (253, 0, 28)
11232
assert_aszarr_method(tif, data)
11233
assert_aszarr_method(tif, data, chunkmode='page')
11237
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11238
def test_read_ome_float_modulo_attributes():
11239
"""Test read OME with floating point modulo attributes."""
11240
# reported by Start Berg. File by Lorenz Maier.
11241
fname = private_file('OME/float_modulo_attributes.ome.tiff')
11242
with TiffFile(fname) as tif:
11244
assert tif.byteorder == '>'
11245
assert len(tif.pages) == 2
11246
assert len(tif.series) == 1
11247
# assert page properties
11248
page = tif.pages.first
11249
assert page.is_contiguous
11250
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11251
assert page.compression == COMPRESSION.NONE
11252
assert page.imagewidth == 512
11253
assert page.imagelength == 512
11254
assert page.bitspersample == 16
11255
assert page.samplesperpixel == 1
11256
# assert series properties
11257
series = tif.series[0]
11258
assert series.shape == (2, 512, 512)
11259
assert series.dtype == numpy.uint16
11260
assert series.axes == 'QYX'
11261
assert series.kind == 'ome'
11262
assert not series.is_multifile
11264
data = tif.asarray()
11265
assert isinstance(data, numpy.ndarray)
11266
assert data.shape == (2, 512, 512)
11267
assert data.dtype == numpy.uint16
11268
assert data[1, 158, 428] == 51
11269
assert_aszarr_method(tif, data)
11270
assert_aszarr_method(tif, data, chunkmode='page')
11274
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11275
def test_read_ome_cropped(caplog):
11276
"""Test read bad OME by ImageJ cropping."""
11277
# ImageJ produces invalid ome-xml when cropping
11278
# http://lists.openmicroscopy.org.uk/pipermail/ome-devel/2013-December
11280
# Reported by Hadrien Mary on Dec 11, 2013
11281
fname = private_file('ome/cropped.ome.tif')
11282
with TiffFile(fname) as tif:
11284
assert tif.byteorder == '<'
11285
assert len(tif.pages) == 100
11286
assert len(tif.series) == 1
11287
assert 'invalid TiffData index' in caplog.text
11288
# assert page properties
11289
page = tif.pages.first
11290
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11291
assert page.imagewidth == 324
11292
assert page.imagelength == 249
11293
assert page.bitspersample == 16
11294
# assert series properties
11295
series = tif.series[0]
11296
assert series.shape == (5, 10, 2, 249, 324)
11297
assert series.dtype == numpy.uint16
11298
assert series.axes == 'TZCYX'
11299
assert series.kind == 'ome'
11300
assert not series.is_multifile
11302
data = tif.asarray()
11303
assert data.shape == (5, 10, 2, 249, 324)
11304
assert data.dtype == numpy.uint16
11305
assert data[4, 9, 1, 175, 123] == 9605
11306
assert_aszarr_method(tif, data)
11307
assert_aszarr_method(tif, data, chunkmode='page')
11312
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS or SKIP_LARGE, reason=REASON)
11313
def test_read_ome_corrupted_page(caplog):
11314
"""Test read OME with corrupted but not referenced page."""
11315
# https://forum.image.sc/t/qupath-0-2-0-not-able-to-open-ome-tiff/23821/3
11316
fname = private_file('ome/2019_02_19__7760_s1.ome.tiff')
11317
with TiffFile(fname) as tif:
11319
assert tif.is_bigtiff
11320
assert tif.byteorder == '<'
11321
assert len(tif.pages) == 5
11322
assert len(tif.series) == 1
11323
assert 'missing required tags' in caplog.text
11324
# assert page properties
11325
page = tif.pages.first
11326
assert page.imagewidth == 7506
11327
assert page.imagelength == 7506
11328
assert page.bitspersample == 16
11329
# assert series properties
11330
series = tif.series[0]
11331
assert series.shape == (4, 7506, 7506)
11332
assert series.dtype == numpy.uint16
11333
assert series.axes == 'CYX'
11334
assert series.kind == 'ome'
11335
assert not series.is_multifile
11337
data = tif.asarray()
11338
assert data.shape == (4, 7506, 7506)
11339
assert data.dtype == numpy.uint16
11340
assert tuple(data[:, 2684, 2684]) == (496, 657, 7106, 469)
11341
assert_aszarr_method(tif, data)
11342
assert_aszarr_method(tif, data, chunkmode='page')
11347
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11348
def test_read_ome_nikon():
11349
"""Test read bad OME by Nikon."""
11350
# OME-XML references only first image
11351
# received from E. Gratton
11352
fname = private_file('OME/Nikon-cell011.ome.tif')
11353
with TiffFile(fname) as tif:
11355
assert tif.byteorder == '<'
11356
assert len(tif.pages) == 1000
11357
assert len(tif.series) == 1
11358
# assert 'index out of range' in caplog.text
11359
# assert page properties
11360
page = tif.pages.first
11361
assert page.photometric != PHOTOMETRIC.RGB
11362
assert page.imagewidth == 1982
11363
assert page.imagelength == 1726
11364
assert page.bitspersample == 16
11365
assert page.is_contiguous
11367
page.tags['ImageLength'].offset - page.tags['ImageWidth'].offset
11370
assert page.tags['ImageWidth'].offset == 6856262146
11371
assert page.tags['ImageWidth'].valueoffset == 6856262158
11372
assert page.tags['ImageLength'].offset == 6856262166
11373
assert page.tags['ImageLength'].valueoffset == 6856262178
11374
assert page.tags['StripByteCounts'].offset == 6856262366
11375
assert page.tags['StripByteCounts'].valueoffset == 6856262534
11376
# assert series properties
11377
series = tif.series[0]
11378
assert len(series._pages) == 1
11379
assert len(series.pages) == 1
11380
assert series.dataoffset == 16 # contiguous
11381
assert series.shape == (1726, 1982)
11382
assert series.dtype == numpy.uint16
11383
assert series.axes == 'YX'
11384
assert series.kind == 'ome'
11387
with TiffFile(fname, is_ome=False) as tif:
11388
assert not tif.is_ome
11389
# assert series properties
11390
series = tif.series[0]
11391
assert len(series.pages) == 1000
11392
assert series.dataoffset is None # not contiguous
11393
assert series.shape == (1000, 1726, 1982)
11394
assert series.dtype == numpy.uint16
11395
assert series.axes == 'IYX'
11396
assert series.kind == 'uniform'
11400
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11401
def test_read_ome_shape_mismatch(caplog):
11402
"""Test read OME with page shape mismatch."""
11403
# TCX (20000, 2, 500) is stored in 2 pages of (20000, 500)
11404
# probably exported by ZEN Software
11405
fname = private_file('OME/Image 7.ome_h00.tiff')
11406
with TiffFile(fname) as tif:
11408
assert tif.byteorder == '<'
11409
assert len(tif.pages) == 2
11410
assert len(tif.series) == 2
11411
assert 'cannot handle discontiguous storage' in caplog.text
11412
# assert page properties
11413
page = tif.pages.first
11414
assert page.is_contiguous
11415
assert page.photometric == PHOTOMETRIC.MINISBLACK
11416
assert page.imagewidth == 500
11417
assert page.imagelength == 20000
11418
assert page.bitspersample == 16
11419
assert page.samplesperpixel == 1
11420
page = tif.pages[1]
11421
assert page.is_contiguous
11422
assert page.photometric == PHOTOMETRIC.PALETTE
11423
assert page.imagewidth == 500
11424
assert page.imagelength == 20000
11425
assert page.bitspersample == 8
11426
assert page.samplesperpixel == 1
11427
# assert series properties
11428
series = tif.series[0]
11429
assert series.shape == (20000, 500)
11430
assert series.dtype == numpy.uint16
11431
assert series.axes == 'YX'
11432
assert series.dataoffset == 8
11433
assert series.kind == 'generic'
11436
@pytest.mark.skipif(
11437
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG2K.available,
11440
def test_read_ome_jpeg2000_be():
11441
"""Test read JPEG2000 compressed big-endian OME-TIFF."""
11442
fname = private_file('OME/mitosis.jpeg2000.ome.tif')
11443
with TiffFile(fname) as tif:
11445
assert tif.byteorder == '>'
11446
assert len(tif.pages) == 510
11447
assert len(tif.series) == 1
11448
# assert page properties
11449
page = tif.pages.first
11450
assert not page.is_contiguous
11451
assert page.tags['Software'].value[:15] == 'OME Bio-Formats'
11452
assert page.compression == COMPRESSION.APERIO_JP2000_YCBC
11453
assert page.imagewidth == 171
11454
assert page.imagelength == 196
11455
assert page.bitspersample == 16
11456
assert page.samplesperpixel == 1
11457
# assert series properties
11458
series = tif.series[0]
11459
assert series.shape == (51, 5, 2, 196, 171)
11460
assert series.dtype == numpy.uint16
11461
assert series.axes == 'TZCYX'
11462
assert series.kind == 'ome'
11464
data = page.asarray()
11465
assert isinstance(data, numpy.ndarray)
11466
assert data.shape == (196, 171)
11467
assert data.dtype == numpy.uint16
11468
assert data[0, 0] == 1904
11469
assert_aszarr_method(page, data)
11470
assert_aszarr_method(page, data, chunkmode='page')
11474
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
11475
def test_read_ome_samplesperpixel_mismatch(caplog):
11476
"""Test read OME with SamplesPerPixel mismatch: OME=1, TIFF=4."""
11477
# https://forum.image.sc/t/ilastik-refuses-to-load-image-file/48541/1
11478
fname = private_file('OME/MismatchSamplesPerPixel.ome.tif')
11479
with TiffFile(fname) as tif:
11481
assert tif.byteorder == '<'
11482
assert len(tif.pages) == 1
11483
assert len(tif.series) == 1
11484
# assert page properties
11485
page = tif.pages.first
11486
assert page.photometric == PHOTOMETRIC.RGB
11487
assert page.compression == COMPRESSION.LZW
11488
assert page.imagewidth == 2080
11489
assert page.imagelength == 1552
11490
assert page.bitspersample == 8
11491
assert page.samplesperpixel == 4
11492
# assert series properties
11493
series = tif.series[0]
11494
assert 'cannot handle discontiguous storage' in caplog.text
11495
assert series.shape == (1552, 2080, 4)
11496
assert series.dtype == numpy.uint8
11497
assert series.axes == 'YXS'
11498
assert series.kind == 'generic' # ome series failed
11499
assert not series.is_multifile
11501
data = tif.asarray()
11502
assert data.shape == (1552, 2080, 4)
11503
assert_aszarr_method(tif, data)
11507
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
11508
@pytest.mark.parametrize('chunkmode', [0, 2])
11509
def test_read_ome_multiscale(chunkmode):
11510
"""Test read pyramidal OME file."""
11511
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
11512
with TiffFile(fname) as tif:
11514
assert tif.byteorder == '<'
11515
assert len(tif.pages) == 1025
11516
assert len(tif.series) == 2
11517
# assert page properties
11518
page = tif.pages.first
11519
assert page.photometric == PHOTOMETRIC.MINISBLACK
11520
assert page.compression == COMPRESSION.ADOBE_DEFLATE
11521
assert page.imagewidth == 256
11522
assert page.imagelength == 256
11523
assert page.bitspersample == 8
11524
assert page.samplesperpixel == 1
11525
# assert series properties
11526
series = tif.series[0]
11527
assert series.kind == 'ome'
11528
assert series.shape == (16, 32, 2, 256, 256)
11529
assert series.dtype == numpy.uint8
11530
assert series.axes == 'TZCYX'
11531
assert series.is_pyramidal
11532
assert not series.is_multifile
11533
series = tif.series[1]
11534
assert series.kind == 'ome'
11535
assert series.shape == (128, 128, 3)
11536
assert series.dtype == numpy.uint8
11537
assert series.axes == 'YXS'
11538
assert not series.is_pyramidal
11539
assert not series.is_multifile
11541
data = tif.asarray()
11542
assert data.shape == (16, 32, 2, 256, 256)
11543
assert_aszarr_method(tif, data, chunkmode=chunkmode)
11547
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11548
def test_read_andor_light_sheet_512p():
11549
"""Test read Andor."""
11550
# 12113x13453, uint16
11551
fname = private_file('andor/light sheet 512px.tif')
11552
with TiffFile(fname) as tif:
11553
assert tif.byteorder == '<'
11554
assert len(tif.pages) == 100
11555
assert len(tif.series) == 1
11556
assert tif.is_andor
11557
# assert page properties
11558
page = tif.pages.first
11559
assert page.is_andor
11560
assert page.is_contiguous
11561
assert page.compression == COMPRESSION.NONE
11562
assert page.imagewidth == 512
11563
assert page.imagelength == 512
11564
assert page.bitspersample == 16
11565
assert page.samplesperpixel == 1
11567
t = page.andor_tags
11568
assert t['SoftwareVersion'] == '4.23.30014.0'
11569
assert t['Frames'] == 100.0
11570
# assert series properties
11571
series = tif.series[0]
11572
assert series.shape == (100, 512, 512)
11573
assert series.dtype == numpy.uint16
11574
assert series.axes == 'IYX'
11575
assert series.kind == 'uniform'
11576
assert isinstance(series.pages[2], TiffFrame)
11578
data = tif.asarray()
11579
assert data.shape == (100, 512, 512)
11580
assert data.dtype == numpy.uint16
11581
assert round(abs(data[50, 256, 256] - 703), 7) == 0
11582
assert_aszarr_method(tif, data)
11583
assert_aszarr_method(tif, data, chunkmode='page')
11584
assert__str__(tif, 0)
11587
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11588
def test_read_nih_morph():
11589
"""Test read NIH."""
11591
fname = private_file('nihimage/morph.tiff')
11592
with TiffFile(fname) as tif:
11594
assert tif.byteorder == '>'
11595
assert len(tif.pages) == 1
11596
assert len(tif.series) == 1
11597
# assert page properties
11598
page = tif.pages.first
11599
assert page.imagewidth == 388
11600
assert page.imagelength == 252
11601
assert page.bitspersample == 8
11602
# assert series properties
11603
series = tif.series[0]
11604
assert series.kind == 'nih'
11605
assert series.shape == (252, 388)
11606
assert series.dtype == numpy.uint8
11607
assert series.axes == 'YX'
11609
tags = tif.nih_metadata
11610
assert tags['FileID'] == 'IPICIMAG'
11611
assert tags['PixelsPerLine'] == 388
11612
assert tags['nLines'] == 252
11613
assert tags['ForegroundIndex'] == 255
11615
data = tif.asarray()
11616
assert isinstance(data, numpy.ndarray)
11617
assert data.shape == (252, 388)
11618
assert data.dtype == numpy.uint8
11619
assert data[195, 144] == 41
11620
assert_aszarr_method(tif, data)
11621
assert_aszarr_method(tif, data, chunkmode='page')
11625
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11626
def test_read_nih_silver_lake():
11627
"""Test read NIH palette."""
11628
# 259x187 16 bit palette
11629
fname = private_file('nihimage/silver lake.tiff')
11630
with TiffFile(fname) as tif:
11632
assert tif.byteorder == '>'
11633
assert len(tif.pages) == 1
11634
assert len(tif.series) == 1
11635
# assert page properties
11636
page = tif.pages.first
11637
assert page.is_contiguous
11638
assert page.photometric == PHOTOMETRIC.PALETTE
11639
assert page.imagewidth == 259
11640
assert page.imagelength == 187
11641
assert page.bitspersample == 8
11642
# assert series properties
11643
series = tif.series[0]
11644
assert series.kind == 'nih'
11645
assert series.shape == (187, 259)
11646
assert series.dtype == numpy.uint8
11647
assert series.axes == 'YX'
11649
tags = tif.nih_metadata
11650
assert tags['FileID'] == 'IPICIMAG'
11651
assert tags['PixelsPerLine'] == 259
11652
assert tags['nLines'] == 187
11653
assert tags['ForegroundIndex'] == 109
11655
data = page.asrgb()
11656
assert isinstance(data, numpy.ndarray)
11657
assert data.shape == (187, 259, 3)
11658
assert data.dtype == numpy.uint16
11659
assert tuple(data[86, 102, :]) == (26214, 39321, 39321)
11663
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11664
def test_read_nih_scala_media():
11665
"""Test read multi-page NIH."""
11667
fname = private_file('nihimage/scala-media.tif')
11668
with TiffFile(fname) as tif:
11670
assert tif.byteorder == '>'
11671
assert len(tif.pages) == 36
11672
assert len(tif.series) == 1
11673
# assert page properties
11674
page = tif.pages.first
11675
assert page.is_contiguous
11676
assert page.photometric == PHOTOMETRIC.PALETTE
11677
assert page.imagewidth == 84
11678
assert page.imagelength == 54
11679
assert page.bitspersample == 8
11680
# assert series properties
11681
series = tif.series[0]
11682
assert series.kind == 'nih'
11683
assert series.shape == (36, 54, 84)
11684
assert series.dtype == numpy.uint8
11685
assert series.axes == 'IYX'
11687
tags = tif.nih_metadata
11688
assert tags['Version'] == 160
11689
assert tags['nLines'] == 54
11691
data = tif.asarray()
11692
assert isinstance(data, numpy.ndarray)
11693
assert data.shape == (36, 54, 84)
11694
assert data.dtype == numpy.uint8
11695
assert data[35, 35, 65] == 171
11696
assert_aszarr_method(tif, data)
11697
assert_aszarr_method(tif, data, chunkmode='page')
11701
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
11702
def test_read_imagej_rrggbb():
11703
"""Test read planar RGB ImageJ file created by Bio-Formats."""
11704
fname = public_file('tifffile/rrggbb.ij.tif')
11705
with TiffFile(fname) as tif:
11706
assert tif.is_imagej
11707
assert tif.byteorder == '<'
11708
assert len(tif.pages) == 1
11709
assert len(tif.series) == 1
11710
# assert page properties
11711
page = tif.pages.first
11712
assert page.photometric == PHOTOMETRIC.RGB
11713
assert page.compression == COMPRESSION.LZW
11714
assert page.imagewidth == 31
11715
assert page.imagelength == 32
11716
assert page.bitspersample == 16
11717
# assert series properties
11718
series = tif.series[0]
11719
assert series.kind == 'imagej'
11720
assert series.dtype == numpy.uint16
11721
assert series.shape == (3, 32, 31)
11722
assert series.axes == 'CYX'
11723
assert series.get_shape(False) == (1, 1, 3, 32, 31, 1)
11724
assert series.get_axes(False) == 'TZCYXS'
11725
assert len(series._pages) == 1
11726
assert len(series.pages) == 1
11727
# assert ImageJ tags
11728
ijmeta = tif.imagej_metadata
11729
assert ijmeta is not None
11730
assert ijmeta['ImageJ'] == ''
11731
assert ijmeta['images'] == 3
11732
assert ijmeta['channels'] == 3
11733
assert ijmeta['slices'] == 1
11734
assert ijmeta['frames'] == 1
11735
assert ijmeta['hyperstack']
11737
data = tif.asarray()
11738
assert isinstance(data, numpy.ndarray)
11739
assert data.shape == (3, 32, 31)
11740
assert data.dtype == numpy.uint16
11741
assert tuple(data[:, 15, 15]) == (812, 1755, 648)
11742
assert_decode_method(page)
11743
assert_aszarr_method(series, data)
11744
assert_aszarr_method(series, data, chunkmode='page')
11746
data = tif.asarray(squeeze=False)
11747
assert data.shape == (1, 1, 3, 32, 31, 1)
11748
assert_aszarr_method(series, data, squeeze=False)
11749
assert__str__(tif, 0)
11752
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11753
def test_read_imagej_focal1():
11754
"""Test read ImageJ 205x434x425 uint8."""
11755
fname = private_file('imagej/focal1.tif')
11756
with TiffFile(fname) as tif:
11757
assert tif.is_imagej
11758
assert tif.byteorder == '>'
11759
assert len(tif.pages) == 205
11760
assert len(tif.series) == 1
11761
# assert page properties
11762
page = tif.pages.first
11763
assert page.photometric != PHOTOMETRIC.RGB
11764
assert page.imagewidth == 425
11765
assert page.imagelength == 434
11766
assert page.bitspersample == 8
11767
assert page.is_contiguous
11768
# assert series properties
11769
series = tif.series[0]
11770
assert series.kind == 'imagej'
11771
assert series.dataoffset == 768
11772
assert series.shape == (205, 434, 425)
11773
assert series.dtype == numpy.uint8
11774
assert series.axes == 'IYX'
11775
assert series.get_shape(False) == (205, 1, 1, 1, 434, 425, 1)
11776
assert series.get_axes(False) == 'ITZCYXS'
11777
assert len(series._pages) == 1
11778
assert len(series.pages) == 205
11779
# assert ImageJ tags
11780
ijmeta = tif.imagej_metadata
11781
assert ijmeta is not None
11782
assert ijmeta['ImageJ'] == '1.34k'
11783
assert ijmeta['images'] == 205
11785
data = tif.asarray()
11786
assert isinstance(data, numpy.ndarray)
11787
assert data.shape == (205, 434, 425)
11788
assert data.dtype == numpy.uint8
11789
assert data[102, 216, 212] == 120
11790
assert_aszarr_method(series, data)
11791
assert_aszarr_method(series, data, chunkmode='page')
11792
assert__str__(tif, 0)
11795
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11796
def test_read_imagej_hela_cells():
11797
"""Test read ImageJ 512x672 RGB uint16."""
11798
fname = private_file('imagej/hela-cells.tif')
11799
with TiffFile(fname) as tif:
11800
assert tif.is_imagej
11801
assert tif.byteorder == '>'
11802
assert len(tif.pages) == 1
11803
assert len(tif.series) == 1
11804
# assert page properties
11805
page = tif.pages.first
11806
assert page.photometric == PHOTOMETRIC.RGB
11807
assert page.imagewidth == 672
11808
assert page.imagelength == 512
11809
assert page.bitspersample == 16
11810
assert page.is_contiguous
11811
# assert series properties
11812
series = tif.series[0]
11813
assert series.kind == 'imagej'
11814
assert series.shape == (512, 672, 3)
11815
assert series.dtype == numpy.uint16
11816
assert series.axes == 'YXS'
11817
assert series.get_shape(False) == (1, 1, 1, 512, 672, 3)
11818
assert series.get_axes(False) == 'TZCYXS'
11819
# assert ImageJ tags
11820
ijmeta = tif.imagej_metadata
11821
assert ijmeta is not None
11822
assert ijmeta['ImageJ'] == '1.46i'
11823
assert ijmeta['channels'] == 3
11825
data = tif.asarray()
11826
assert isinstance(data, numpy.ndarray)
11827
assert data.shape == (512, 672, 3)
11828
assert data.dtype == numpy.uint16
11829
assert tuple(data[255, 336]) == (440, 378, 298)
11830
assert_aszarr_method(series, data)
11831
assert_aszarr_method(series, data, chunkmode='page')
11833
data = tif.asarray(squeeze=False)
11834
assert data.shape == (1, 1, 1, 512, 672, 3)
11835
assert_aszarr_method(series, data, squeeze=False)
11839
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11840
def test_read_imagej_flybrain():
11841
"""Test read ImageJ 57x256x256 RGB."""
11842
fname = private_file('imagej/flybrain.tif')
11843
with TiffFile(fname) as tif:
11844
assert tif.is_imagej
11845
assert tif.byteorder == '>'
11846
assert len(tif.pages) == 57
11847
assert len(tif.series) == 1 # hyperstack
11848
# assert page properties
11849
page = tif.pages.first
11850
assert page.photometric == PHOTOMETRIC.RGB
11851
assert page.imagewidth == 256
11852
assert page.imagelength == 256
11853
assert page.bitspersample == 8
11854
# assert series properties
11855
series = tif.series[0]
11856
assert series.kind == 'imagej'
11857
assert series.shape == (57, 256, 256, 3)
11858
assert series.dtype == numpy.uint8
11859
assert series.axes == 'ZYXS'
11860
assert series.get_shape(False) == (1, 57, 1, 256, 256, 3)
11861
assert series.get_axes(False) == 'TZCYXS'
11862
# assert ImageJ tags
11863
ijmeta = tif.imagej_metadata
11864
assert ijmeta is not None
11865
assert ijmeta['ImageJ'] == '1.43d'
11866
assert ijmeta['slices'] == 57
11868
data = tif.asarray()
11869
assert isinstance(data, numpy.ndarray)
11870
assert data.shape == (57, 256, 256, 3)
11871
assert data.dtype == numpy.uint8
11872
assert tuple(data[18, 108, 97]) == (165, 157, 0)
11873
assert_aszarr_method(series, data)
11874
assert_aszarr_method(series, data, chunkmode='page')
11876
data = tif.asarray(squeeze=False)
11877
assert data.shape == (1, 57, 1, 256, 256, 3)
11878
assert_aszarr_method(series, data, squeeze=False)
11882
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11883
def test_read_imagej_confocal_series():
11884
"""Test read ImageJ 25x2x400x400 ZCYX."""
11885
fname = private_file('imagej/confocal-series.tif')
11886
with TiffFile(fname) as tif:
11887
assert tif.is_imagej
11888
assert tif.byteorder == '>'
11889
assert len(tif.pages) == 50
11890
assert len(tif.series) == 1 # hyperstack
11891
# assert page properties
11892
page = tif.pages.first
11893
assert page.imagewidth == 400
11894
assert page.imagelength == 400
11895
assert page.bitspersample == 8
11896
assert page.is_contiguous
11897
# assert series properties
11898
series = tif.series[0]
11899
assert series.kind == 'imagej'
11900
assert series.shape == (25, 2, 400, 400)
11901
assert series.dtype == numpy.uint8
11902
assert series.axes == 'ZCYX'
11903
assert len(series._pages) == 1
11904
assert len(series.pages) == 50
11905
# assert ImageJ tags
11906
ijmeta = tif.imagej_metadata
11907
assert ijmeta is not None
11908
assert ijmeta['ImageJ'] == '1.43d'
11909
assert ijmeta['images'] == len(tif.pages)
11910
assert ijmeta['channels'] == 2
11911
assert ijmeta['slices'] == 25
11912
assert ijmeta['hyperstack']
11914
data = tif.asarray()
11915
assert isinstance(data, numpy.ndarray)
11916
assert data.shape == (25, 2, 400, 400)
11917
assert data.dtype == numpy.uint8
11918
assert tuple(data[12, :, 100, 300]) == (6, 66)
11919
# assert only two pages are loaded
11920
with pytest.warns(DeprecationWarning):
11921
assert isinstance(tif.pages.pages[0], TiffPage)
11922
assert isinstance(tif.pages._pages[0], TiffPage)
11923
if tif.pages.cache:
11924
assert isinstance(tif.pages._pages[1], TiffFrame)
11926
assert tif.pages._pages[1] == 8000911
11927
assert tif.pages._pages[2] == 8001073
11928
assert tif.pages._pages[-1] == 8008687
11929
assert_aszarr_method(series, data)
11930
assert_aszarr_method(series, data, chunkmode='page')
11932
data = tif.asarray(squeeze=False)
11933
assert data.shape == (1, 25, 2, 400, 400, 1)
11934
assert_aszarr_method(series, data, squeeze=False)
11938
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11939
def test_read_imagej_graphite():
11940
"""Test read ImageJ 1024x593 float32."""
11941
fname = private_file('imagej/graphite1-1024.tif')
11942
with TiffFile(fname) as tif:
11943
assert tif.is_imagej
11944
assert tif.byteorder == '>'
11945
assert len(tif.pages) == 1
11946
assert len(tif.series) == 1
11947
# assert page properties
11948
page = tif.pages.first
11949
assert page.imagewidth == 1024
11950
assert page.imagelength == 593
11951
assert page.bitspersample == 32
11952
assert page.is_contiguous
11953
# assert series properties
11954
series = tif.series[0]
11955
assert series.kind == 'imagej'
11956
assert len(series._pages) == 1
11957
assert len(series.pages) == 1
11958
assert series.shape == (593, 1024)
11959
assert series.dtype == numpy.float32
11960
assert series.axes == 'YX'
11961
# assert ImageJ tags
11962
ijmeta = tif.imagej_metadata
11963
assert ijmeta is not None
11964
assert ijmeta['ImageJ'] == '1.47t'
11965
assert round(abs(ijmeta['max'] - 1686.10949707), 7) == 0
11966
assert round(abs(ijmeta['min'] - 852.08605957), 7) == 0
11968
data = tif.asarray()
11969
assert isinstance(data, numpy.ndarray)
11970
assert data.shape == (593, 1024)
11971
assert data.dtype == numpy.float32
11972
assert round(abs(data[443, 656] - 2203.040771484375), 7) == 0
11973
assert_aszarr_method(series, data)
11975
data = tif.asarray(squeeze=False)
11976
assert data.shape == (1, 1, 1, 593, 1024, 1)
11977
assert_aszarr_method(series, data, squeeze=False)
11981
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
11982
def test_read_imagej_bat_cochlea_volume():
11983
"""Test read ImageJ 114 images, no frames, slices, channels specified."""
11984
fname = private_file('imagej/bat-cochlea-volume.tif')
11985
with TiffFile(fname) as tif:
11986
assert tif.is_imagej
11987
assert tif.byteorder == '>'
11988
assert len(tif.pages) == 114
11989
assert len(tif.series) == 1
11990
# assert page properties
11991
page = tif.pages.first
11992
assert page.photometric != PHOTOMETRIC.RGB
11993
assert page.imagewidth == 121
11994
assert page.imagelength == 154
11995
assert page.bitspersample == 8
11996
assert page.is_contiguous
11997
# assert series properties
11998
series = tif.series[0]
11999
assert series.kind == 'imagej'
12000
assert len(series._pages) == 1
12001
assert len(series.pages) == 114
12002
assert series.shape == (114, 154, 121)
12003
assert series.dtype == numpy.uint8
12004
assert series.axes == 'IYX'
12005
# assert ImageJ tags
12006
ijmeta = tif.imagej_metadata
12007
assert ijmeta is not None
12008
assert ijmeta['ImageJ'] == '1.20n'
12009
assert ijmeta['images'] == 114
12011
data = tif.asarray()
12012
assert isinstance(data, numpy.ndarray)
12013
assert data.shape == (114, 154, 121)
12014
assert data.dtype == numpy.uint8
12015
assert data[113, 97, 61] == 255
12016
assert_aszarr_method(series, data)
12018
data = tif.asarray(squeeze=False)
12019
assert data.shape == (114, 1, 1, 1, 154, 121, 1)
12020
assert_aszarr_method(series, data, squeeze=False)
12024
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12025
def test_read_imagej_first_instar_brain():
12026
"""Test read ImageJ 56x256x256x3 ZYXS."""
12027
fname = private_file('imagej/first-instar-brain.tif')
12028
with TiffFile(fname) as tif:
12029
assert tif.is_imagej
12030
assert tif.byteorder == '>'
12031
assert len(tif.pages) == 56
12032
assert len(tif.series) == 1
12033
# assert page properties
12034
page = tif.pages.first
12035
assert page.photometric == PHOTOMETRIC.RGB
12036
assert page.imagewidth == 256
12037
assert page.imagelength == 256
12038
assert page.bitspersample == 8
12039
assert page.is_contiguous
12040
# assert series properties
12041
series = tif.series[0]
12042
assert series.kind == 'imagej'
12043
assert len(series._pages) == 1
12044
assert len(series.pages) == 56
12045
assert series.shape == (56, 256, 256, 3)
12046
assert series.dtype == numpy.uint8
12047
assert series.axes == 'ZYXS'
12048
# assert ImageJ tags
12049
ijmeta = tif.imagej_metadata
12050
assert ijmeta is not None
12051
assert ijmeta['ImageJ'] == '1.44j'
12052
assert ijmeta['images'] == 56
12053
assert ijmeta['slices'] == 56
12055
data = tif.asarray()
12056
assert isinstance(data, numpy.ndarray)
12057
assert data.shape == (56, 256, 256, 3)
12058
assert data.dtype == numpy.uint8
12059
assert tuple(data[55, 151, 112]) == (209, 8, 58)
12060
assert_aszarr_method(series, data)
12064
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12065
def test_read_imagej_fluorescentcells():
12066
"""Test read ImageJ three channels."""
12067
fname = private_file('imagej/FluorescentCells.tif')
12068
with TiffFile(fname) as tif:
12069
assert tif.is_imagej
12070
assert tif.byteorder == '>'
12071
assert len(tif.pages) == 3
12072
assert len(tif.series) == 1
12073
# assert page properties
12074
page = tif.pages.first
12075
assert page.photometric == PHOTOMETRIC.PALETTE
12076
assert page.imagewidth == 512
12077
assert page.imagelength == 512
12078
assert page.bitspersample == 8
12079
assert page.is_contiguous
12080
# assert series properties
12081
series = tif.series[0]
12082
assert series.kind == 'imagej'
12083
assert series.shape == (3, 512, 512)
12084
assert series.dtype == numpy.uint8
12085
assert series.axes == 'CYX'
12086
# assert ImageJ tags
12087
ijmeta = tif.imagej_metadata
12088
assert ijmeta is not None
12089
assert ijmeta['ImageJ'] == '1.40c'
12090
assert ijmeta['images'] == 3
12091
assert ijmeta['channels'] == 3
12093
data = tif.asarray()
12094
assert isinstance(data, numpy.ndarray)
12095
assert data.shape == (3, 512, 512)
12096
assert data.dtype == numpy.uint8
12097
assert tuple(data[:, 256, 256]) == (57, 120, 13)
12098
assert_aszarr_method(series, data)
12102
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_LARGE, reason=REASON)
12103
def test_read_imagej_100000_pages():
12104
"""Test read ImageJ with 100000 pages."""
12106
# file is big endian, memory mapped
12107
fname = public_file('tifffile/100000_pages.tif')
12108
with TiffFile(fname) as tif:
12109
assert tif.is_imagej
12110
assert tif.byteorder == '>'
12111
assert len(tif.pages) == 100000
12112
assert len(tif.series) == 1
12113
# assert page properties
12114
page = tif.pages.first
12115
assert page.imagewidth == 64
12116
assert page.imagelength == 64
12117
assert page.bitspersample == 16
12118
assert page.is_contiguous
12119
# assert series properties
12120
series = tif.series[0]
12121
assert series.kind == 'imagej'
12122
assert len(series._pages) == 1
12123
assert len(series.pages) == 100000
12124
assert series.shape == (100000, 64, 64)
12125
assert series.dtype == numpy.uint16
12126
assert series.axes == 'TYX'
12127
# assert ImageJ tags
12128
ijmeta = tif.imagej_metadata
12129
assert ijmeta is not None
12130
assert ijmeta['ImageJ'] == '1.48g'
12131
assert round(abs(ijmeta['max'] - 119.0), 7) == 0
12132
assert round(abs(ijmeta['min'] - 86.0), 7) == 0
12134
data = tif.asarray(out='memmap')
12135
assert isinstance(data, numpy.memmap)
12136
assert data.shape == (100000, 64, 64)
12137
assert data.dtype == numpy.dtype('>u2')
12138
assert round(abs(data[7310, 25, 25] - 100), 7) == 0
12139
# too slow: assert_aszarr_method(series, data)
12140
assert__str__(tif, 0)
12144
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12145
def test_read_imagej_invalid_metadata(caplog):
12146
"""Test read bad ImageJ metadata."""
12147
# file contains 1 page but metadata claims 3500 images
12148
# memory map big endian data
12149
fname = private_file('sima/0.tif')
12150
with TiffFile(fname) as tif:
12151
assert tif.is_imagej
12152
assert tif.byteorder == '>'
12153
assert len(tif.pages) == 1
12154
assert len(tif.series) == 1
12155
assert 'ImageJ series metadata invalid or corrupted' in caplog.text
12156
# assert page properties
12157
page = tif.pages.first
12158
assert page.photometric != PHOTOMETRIC.RGB
12159
assert page.imagewidth == 173
12160
assert page.imagelength == 173
12161
assert page.bitspersample == 16
12162
assert page.is_contiguous
12163
# assert series properties
12164
series = tif.series[0]
12165
assert series.kind == 'generic' # imagej series failed
12166
assert series.dataoffset == 8 # 8
12167
assert series.shape == (173, 173)
12168
assert series.dtype == numpy.uint16
12169
assert series.axes == 'YX'
12170
# assert ImageJ tags
12171
ijmeta = tif.imagej_metadata
12172
assert ijmeta is not None
12173
assert ijmeta['ImageJ'] == '1.49i'
12174
assert ijmeta['images'] == 3500
12176
data = tif.asarray(out='memmap')
12177
assert isinstance(data, numpy.memmap)
12178
assert data.shape == (173, 173)
12179
assert data.dtype == numpy.dtype('>u2')
12180
assert data[94, 34] == 1257
12181
assert_aszarr_method(series, data)
12182
assert_aszarr_method(series, data, chunkmode='page')
12187
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12188
def test_read_imagej_invalid_hyperstack():
12189
"""Test read bad ImageJ hyperstack."""
12190
# file claims to be a hyperstack but is not stored as such
12191
# produced by OME writer
12192
# reported by Taras Golota on 10/27/2016
12193
fname = private_file('imagej/X0.ome.CTZ.perm.tif')
12194
with TiffFile(fname) as tif:
12195
assert tif.is_imagej
12196
assert tif.byteorder == '<'
12197
assert len(tif.pages) == 48 # not a hyperstack
12198
assert len(tif.series) == 1
12199
# assert page properties
12200
page = tif.pages.first
12201
assert page.photometric != PHOTOMETRIC.RGB
12202
assert page.imagewidth == 1392
12203
assert page.imagelength == 1040
12204
assert page.bitspersample == 16
12205
assert page.is_contiguous
12206
# assert series properties
12207
series = tif.series[0]
12208
assert series.kind == 'imagej'
12209
assert series.dataoffset is None # not contiguous
12210
assert series.shape == (2, 4, 6, 1040, 1392)
12211
assert series.dtype == numpy.uint16
12212
assert series.axes == 'TZCYX'
12213
# assert ImageJ tags
12214
ijmeta = tif.imagej_metadata
12215
assert ijmeta is not None
12216
assert ijmeta['hyperstack']
12217
assert ijmeta['images'] == 48
12221
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12222
def test_read_scifio():
12223
"""Test read SCIFIO file using ImageJ metadata."""
12224
# https://github.com/AllenCellModeling/aicsimageio/issues/436
12226
fname = private_file('scifio/2MF1P2_glia.tif')
12227
with TiffFile(fname) as tif:
12228
assert tif.is_imagej
12229
assert tif.byteorder == '>'
12230
assert len(tif.pages) == 343 # not a hyperstack
12231
assert len(tif.series) == 1
12232
# assert page properties
12233
page = tif.pages.first
12234
assert page.photometric == PHOTOMETRIC.MINISBLACK
12235
assert page.imagewidth == 1024
12236
assert page.imagelength == 1024
12237
assert page.bitspersample == 8
12238
assert page.is_contiguous
12239
# assert series properties
12240
series = tif.series[0]
12241
assert series.kind == 'imagej'
12242
assert series.dataoffset is None # not contiguous
12243
assert series.shape == (343, 1024, 1024)
12244
assert series.dtype == numpy.uint8
12245
assert series.axes == 'IYX'
12246
assert isinstance(series.pages[2], TiffFrame)
12247
# assert ImageJ tags
12248
ijmeta = tif.imagej_metadata
12249
assert ijmeta is not None
12250
assert ijmeta['SCIFIO'] == '0.42.0'
12251
assert ijmeta['hyperstack']
12252
assert ijmeta['images'] == 343
12254
# data = series.asarray()
12255
# assert data[192, 740, 420] == 2
12256
# assert_aszarr_method(series, data)
12260
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12261
def test_read_fluoview_lsp1_v_laser():
12262
"""Test read FluoView CTYX."""
12263
# raises 'UnicodeWarning: Unicode equal comparison failed' on Python 2
12264
fname = private_file('fluoview/lsp1-V-laser0.3-1.tif')
12265
with TiffFile(fname) as tif:
12266
assert tif.byteorder == '<'
12267
assert len(tif.pages) == 100
12268
assert len(tif.series) == 1
12269
assert tif.is_fluoview
12270
# assert page properties
12271
page = tif.pages.first
12272
assert page.is_fluoview
12273
assert page.is_contiguous
12274
assert page.compression == COMPRESSION.NONE
12275
assert page.imagewidth == 256
12276
assert page.imagelength == 256
12277
assert page.bitspersample == 16
12278
assert page.samplesperpixel == 1
12280
m = fluoview_description_metadata(page.description)
12281
assert m['Version Info']['FLUOVIEW Version'] == (
12282
'FV10-ASW ,ValidBitColunt=12'
12284
assert tuple(m['LUT Ch1'][255]) == (255, 255, 255)
12285
mm = tif.fluoview_metadata
12286
assert mm['ImageName'] == 'lsp1-V-laser0.3-1.oib'
12287
# assert series properties
12288
series = tif.series[0]
12289
assert series.shape == (2, 50, 256, 256)
12290
assert series.dtype == numpy.uint16
12291
assert series.axes == 'CTYX'
12293
data = tif.asarray()
12294
assert data.shape == (2, 50, 256, 256)
12295
assert data.dtype == numpy.uint16
12296
assert round(abs(data[1, 36, 128, 128] - 824), 7) == 0
12297
assert_aszarr_method(series, data)
12298
assert_aszarr_method(series, data, chunkmode='page')
12302
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
12303
def test_read_fluoview_120816_bf_f0000():
12304
"""Test read FluoView TZYX."""
12305
fname = private_file('fluoview/120816_bf_f0000.tif')
12306
with TiffFile(fname) as tif:
12307
assert tif.byteorder == '<'
12308
assert len(tif.pages) == 864
12309
assert len(tif.series) == 1
12310
assert tif.is_fluoview
12311
# assert page properties
12312
page = tif.pages.first
12313
assert page.is_fluoview
12314
assert page.is_contiguous
12315
assert page.compression == COMPRESSION.NONE
12316
assert page.imagewidth == 1024
12317
assert page.imagelength == 1024
12318
assert page.bitspersample == 16
12319
assert page.samplesperpixel == 1
12321
m = fluoview_description_metadata(page.description)
12322
assert m['Environment']['User'] == 'admin'
12323
assert m['Region Info (Fields) Field']['Width'] == 1331.2
12324
m = tif.fluoview_metadata
12325
assert m['ImageName'] == '120816_bf'
12326
# assert series properties
12327
series = tif.series[0]
12328
assert series.shape == (144, 6, 1024, 1024)
12329
assert series.dtype == numpy.uint16
12330
assert series.axes == 'TZYX'
12332
data = tif.asarray()
12333
assert data.shape == (144, 6, 1024, 1024)
12334
assert data.dtype == numpy.uint16
12335
assert round(abs(data[1, 2, 128, 128] - 8317), 7) == 0
12336
# too slow: assert_aszarr_method(series, data)
12340
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
12341
def test_read_metaseries():
12342
"""Test read MetaSeries 1040x1392 uint16, LZW."""
12343
# Strips do not contain an EOI code as required by the TIFF spec.
12344
fname = private_file('metaseries/metaseries.tif')
12345
with TiffFile(fname) as tif:
12346
assert tif.byteorder == '<'
12347
assert len(tif.pages) == 1
12348
assert len(tif.series) == 1
12349
# assert page properties
12350
page = tif.pages.first
12351
assert page.imagewidth == 1392
12352
assert page.imagelength == 1040
12353
assert page.bitspersample == 16
12355
assert page.description.startswith('<MetaData>')
12356
# assert series properties
12357
series = tif.series[0]
12358
assert series.shape == (1040, 1392)
12359
assert series.dtype == numpy.uint16
12360
assert series.axes == 'YX'
12361
assert series.kind == 'uniform'
12363
data = tif.asarray()
12364
assert data.shape == (1040, 1392)
12365
assert data.dtype == numpy.uint16
12366
assert data[256, 256] == 1917
12367
assert_aszarr_method(series, data)
12368
assert_aszarr_method(series, data, chunkmode='page')
12372
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12373
def test_read_metaseries_g4d7r():
12374
"""Test read Metamorph/Metaseries."""
12375
# 12113x13453, uint16
12378
fname = private_file('metaseries/g4d7r.tif')
12379
with TiffFile(fname) as tif:
12380
assert tif.byteorder == '<'
12381
assert len(tif.pages) == 1
12382
assert len(tif.series) == 1
12383
assert tif.is_metaseries
12384
# assert page properties
12385
page = tif.pages.first
12386
assert page.is_metaseries
12387
assert page.is_contiguous
12388
assert page.compression == COMPRESSION.NONE
12389
assert page.imagewidth == 13453
12390
assert page.imagelength == 12113
12391
assert page.bitspersample == 16
12392
assert page.samplesperpixel == 1
12394
m = metaseries_description_metadata(page.description)
12395
assert m['ApplicationVersion'] == '7.8.6.0'
12396
assert m['PlaneInfo']['pixel-size-x'] == 13453
12397
assert m['SetInfo']['number-of-planes'] == 1
12398
assert m['PlaneInfo']['modification-time-local'] == datetime.datetime(
12399
2014, 10, 28, 16, 17, 16, 620000
12401
assert m['PlaneInfo']['plane-guid'] == uuid.UUID(
12402
'213d9ee7-b38f-4598-9601-6474bf9d0c81'
12404
# assert series properties
12405
series = tif.series[0]
12406
assert series.shape == (12113, 13453)
12407
assert series.dtype == numpy.uint16
12408
assert series.axes == 'YX'
12409
assert series.kind == 'uniform'
12411
data = tif.asarray(out='memmap')
12412
assert isinstance(data, numpy.memmap)
12413
assert data.shape == (12113, 13453)
12414
assert data.dtype == numpy.dtype('<u2')
12415
assert round(abs(data[512, 2856] - 4095), 7) == 0
12417
assert_aszarr_method(series, data)
12418
assert_aszarr_method(series, data, chunkmode='page')
12422
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12423
def test_read_mdgel_rat():
12424
"""Test read Molecular Dynamics GEL."""
12425
# Second page does not contain data, only private tags
12426
fname = private_file('mdgel/rat.gel')
12427
with TiffFile(fname) as tif:
12428
assert tif.byteorder == '<'
12429
assert len(tif.pages) == 2
12430
assert len(tif.series) == 1
12431
# assert page properties
12432
page = tif.pages.first
12433
assert page.is_contiguous
12434
assert page.compression == COMPRESSION.NONE
12435
assert page.imagewidth == 1528
12436
assert page.imagelength == 413
12437
assert page.bitspersample == 16
12438
assert page.samplesperpixel == 1
12439
assert page.tags['Software'].value == (
12440
'ImageQuant Software Release Version 2.0'
12442
assert page.tags['PageName'].value == r'C:\DATA\RAT.GEL'
12444
# assert 2nd page properties
12445
page = tif.pages[1]
12446
assert page.is_mdgel
12447
assert page.imagewidth == 0
12448
assert page.imagelength == 0
12449
assert page.bitspersample == 1
12450
assert page.samplesperpixel == 1
12451
assert page.tags['MDFileTag'].value == 2
12452
assert page.tags['MDScalePixel'].value == (1, 21025)
12453
assert len(page.tags['MDColorTable'].value) == 17
12454
md = tif.mdgel_metadata
12455
assert md['SampleInfo'] == 'Rat slices from Dr. Schweitzer'
12456
assert md['PrepDate'] == '12 July 90'
12457
assert md['PrepTime'] == '40hr'
12458
assert md['FileUnits'] == 'Counts'
12460
# assert series properties
12461
series = tif.series[0]
12462
assert series.shape == (413, 1528)
12463
assert series.dtype == numpy.float32
12464
assert series.axes == 'YX'
12465
assert series.kind == 'mdgel'
12467
data = series.asarray()
12468
assert isinstance(data, numpy.ndarray)
12469
assert data.shape == (413, 1528)
12470
assert data.dtype == numpy.float32
12471
assert round(abs(data[260, 740] - 399.1728515625), 7) == 0
12472
assert_aszarr_method(series, data)
12473
assert_aszarr_method(series, data, chunkmode='page')
12477
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12478
def test_read_mediacy_imagepro():
12479
"""Test read Media Cybernetics SEQ."""
12480
# TZYX, uint16, OME multifile TIFF
12481
fname = private_file('mediacy/imagepro.tif')
12482
with TiffFile(fname) as tif:
12483
assert tif.byteorder == '<'
12484
assert len(tif.pages) == 1
12485
assert len(tif.series) == 1
12486
# assert page properties
12487
page = tif.pages.first
12488
assert page.is_mediacy
12489
assert page.is_contiguous
12490
assert page.compression == COMPRESSION.NONE
12491
assert page.imagewidth == 201
12492
assert page.imagelength == 201
12493
assert page.bitspersample == 8
12494
assert page.samplesperpixel == 1
12495
assert page.tags['Software'].value == 'Image-Pro Plus'
12496
assert page.tags['MC_Id'].value[:-1] == b'MC TIFF 4.0'
12497
# assert series properties
12498
series = tif.series[0]
12499
assert series.shape == (201, 201)
12500
assert series.dtype == numpy.uint8
12501
assert series.axes == 'YX'
12502
assert series.kind == 'uniform'
12504
data = tif.asarray()
12505
assert data.shape == (201, 201)
12506
assert data.dtype == numpy.uint8
12507
assert round(abs(data[120, 34] - 4), 7) == 0
12508
assert_aszarr_method(series, data)
12509
assert_aszarr_method(series, data, chunkmode='page')
12513
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12514
def test_read_pilatus_100k():
12515
"""Test read Pilatus."""
12516
fname = private_file('TvxPilatus/Pilatus100K_scan030_033.tiff')
12517
with TiffFile(fname) as tif:
12518
assert tif.byteorder == '<'
12519
assert len(tif.pages) == 1
12520
assert tif.is_pilatus
12521
# assert page properties
12522
page = tif.pages.first
12523
assert page.imagewidth == 487
12524
assert page.imagelength == 195
12525
assert page.bitspersample == 32
12526
assert page.samplesperpixel == 1
12528
assert page.tags['Model'].value == (
12529
'PILATUS 100K, S/N 1-0230, Cornell University'
12531
attr = pilatus_description_metadata(page.description)
12532
assert attr['Tau'] == 1.991e-07
12533
assert attr['Silicon'] == 0.000320
12534
assert_aszarr_method(page)
12535
assert_aszarr_method(page, chunkmode='page')
12539
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12540
def test_read_pilatus_gibuf2():
12541
"""Test read Pilatus."""
12542
fname = private_file('TvxPilatus/GIbuf2_A9_18_001_0009.tiff')
12543
with TiffFile(fname) as tif:
12544
assert tif.byteorder == '<'
12545
assert len(tif.pages) == 1
12546
assert tif.is_pilatus
12547
# assert page properties
12548
page = tif.pages.first
12549
assert page.imagewidth == 487
12550
assert page.imagelength == 195
12551
assert page.bitspersample == 32
12552
assert page.samplesperpixel == 1
12554
assert page.tags['Model'].value == 'PILATUS 100K-S, S/N 1-0299,'
12555
attr = pilatus_description_metadata(page.description)
12556
assert attr['Filter_transmission'] == 1.0
12557
assert attr['Silicon'] == 0.000320
12558
assert_aszarr_method(page)
12562
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12563
def test_read_epics_attrib():
12564
"""Test read EPICS."""
12565
fname = private_file('epics/attrib.tif')
12566
with TiffFile(fname) as tif:
12567
assert tif.is_epics
12568
assert tif.byteorder == '<'
12569
assert len(tif.pages) == 1
12570
assert len(tif.series) == 1
12571
# assert series properties
12572
series = tif.series[0]
12573
assert series.shape == (2048, 2048)
12574
assert series.dtype == numpy.uint16
12575
assert series.axes == 'YX'
12576
assert series.kind == 'uniform'
12577
# assert page properties
12578
page = tif.pages.first
12579
assert page.shape == (2048, 2048)
12580
assert page.imagewidth == 2048
12581
assert page.imagelength == 2048
12582
assert page.bitspersample == 16
12583
assert page.is_contiguous
12584
# assert EPICS tags
12585
tags = tif.epics_metadata
12586
assert tags['timeStamp'] == 802117891.5714135
12587
assert tags['uniqueID'] == 15
12588
assert tags['Focus'] == 0.6778
12589
assert epics_datetime(
12590
tags['epicsTSSec'], tags['epicsTSNsec']
12591
) == datetime.datetime(2015, 6, 2, 11, 31, 56, 103746)
12592
assert_aszarr_method(page)
12593
assert_aszarr_method(page, chunkmode='page')
12597
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12598
def test_read_tvips_tietz_16bit():
12599
"""Test read TVIPS metadata."""
12600
# file provided by Marco Oster on 10/26/2016
12601
fname = private_file('tvips/test_tietz_16bit.tif')
12602
with TiffFile(fname) as tif:
12603
assert tif.is_tvips
12604
tvips = tif.tvips_metadata
12605
assert tvips['Magic'] == 0xAAAAAAAA
12606
assert tvips['ImageFolder'] == 'B:\\4Marco\\Images\\Tiling_EMTOOLS\\'
12607
assert_aszarr_method(tif)
12611
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12612
def test_read_gdal_structural_metadata():
12613
"""Test read non-TIFF GDAL structural metadata."""
12614
fname = private_file('CloudOptimizedGeoTIFF/cog_rgb.tif')
12615
with TiffFile(fname) as tif:
12616
assert not tif.is_geotiff
12617
assert tif.byteorder == '<'
12618
assert len(tif.pages) == 2
12619
assert len(tif.series) == 1
12620
series = tif.series[0]
12621
assert series.shape == (256, 256, 3)
12622
assert series.dtype == numpy.uint8
12623
assert series.axes == 'YXS'
12624
assert series.kind == 'generic'
12625
assert tif.gdal_structural_metadata == {
12626
'LAYOUT': 'IFDS_BEFORE_DATA',
12627
'BLOCK_ORDER': 'ROW_MAJOR',
12628
'BLOCK_LEADER': 'SIZE_AS_UINT4',
12629
'BLOCK_TRAILER': 'LAST_4_BYTES_REPEATED',
12630
'KNOWN_INCOMPATIBLE_EDITION': 'NO',
12634
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12635
def test_read_geotiff_dimapdocument():
12636
"""Test read GeoTIFF with 43 MB XML tag value."""
12637
# tag 65000 45070067s @487 "<Dimap_Document...
12638
fname = private_file('geotiff/DimapDocument.tif')
12639
with TiffFile(fname) as tif:
12640
assert tif.is_geotiff
12641
assert tif.byteorder == '>'
12642
assert len(tif.pages) == 1
12643
assert len(tif.series) == 1
12644
# assert series properties
12645
series = tif.series[0]
12646
assert series.shape == (1830, 1830)
12647
assert series.dtype == numpy.uint16
12648
assert series.axes == 'YX'
12649
assert series.kind == 'uniform'
12650
# assert page properties
12651
page = tif.pages.first
12652
assert page.shape == (1830, 1830)
12653
assert page.imagewidth == 1830
12654
assert page.imagelength == 1830
12655
assert page.bitspersample == 16
12656
assert page.is_contiguous
12657
assert page.tags['65000'].value.startswith(
12658
'<?xml version="1.0" encoding="ISO-8859-1"?>'
12660
# assert GeoTIFF tags
12661
tags = tif.geotiff_metadata
12662
assert tags['GTCitationGeoKey'] == 'WGS 84 / UTM zone 29N'
12663
assert tags['ProjectedCSTypeGeoKey'] == 32629
12664
assert_array_almost_equal(
12665
tags['ModelTransformation'],
12667
[60.0, 0.0, 0.0, 6.0e5],
12668
[0.0, -60.0, 0.0, 5900040.0],
12669
[0.0, 0.0, 0.0, 0.0],
12670
[0.0, 0.0, 0.0, 1.0],
12673
assert_aszarr_method(page)
12677
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12678
def test_read_geotiff_spaf27_markedcorrect():
12679
"""Test read GeoTIFF."""
12680
fname = private_file('geotiff/spaf27_markedcorrect.tif')
12681
with TiffFile(fname) as tif:
12682
assert tif.is_geotiff
12683
assert tif.byteorder == '<'
12684
assert len(tif.pages) == 1
12685
assert len(tif.series) == 1
12686
# assert series properties
12687
series = tif.series[0]
12688
assert series.shape == (20, 20)
12689
assert series.dtype == numpy.uint8
12690
assert series.axes == 'YX'
12691
assert series.kind == 'uniform'
12692
# assert page properties
12693
page = tif.pages.first
12694
assert page.shape == (20, 20)
12695
assert page.imagewidth == 20
12696
assert page.imagelength == 20
12697
assert page.bitspersample == 8
12698
assert page.is_contiguous
12699
# assert GeoTIFF tags
12700
tags = tif.geotiff_metadata
12701
assert tags['GTCitationGeoKey'] == 'NAD27 / California zone VI'
12702
assert tags['GeogAngularUnitsGeoKey'] == 9102
12703
assert tags['ProjFalseOriginLatGeoKey'] == 32.1666666666667
12704
assert_array_almost_equal(
12705
tags['ModelPixelScale'], [195.509321, 198.32184, 0]
12707
assert_aszarr_method(page)
12711
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12712
def test_read_geotiff_cint16():
12713
"""Test read complex integer images."""
12714
fname = private_file('geotiff/cint16.tif')
12715
with TiffFile(fname) as tif:
12716
assert tif.is_geotiff
12717
assert tif.byteorder == '<'
12718
assert len(tif.pages) == 1
12719
assert len(tif.series) == 1
12720
# assert page properties
12721
page = tif.pages.first
12722
assert page.sampleformat == SAMPLEFORMAT.COMPLEXINT
12723
assert page.bitspersample == 32
12724
assert page.dtype == numpy.complex64
12725
assert page.shape == (100, 100)
12726
assert page.imagewidth == 100
12727
assert page.imagelength == 100
12728
assert page.compression == COMPRESSION.ADOBE_DEFLATE
12729
assert not page.is_contiguous
12730
data = page.asarray()
12731
data[9, 11] == 0 + 0j
12732
assert_aszarr_method(page, data)
12736
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12737
@pytest.mark.parametrize('bits', [16, 32])
12738
def test_read_complexint(bits):
12739
"""Test read complex integer images."""
12740
fname = private_file(f'gdal/cint{bits}.tif')
12741
with TiffFile(fname) as tif:
12742
assert tif.is_geotiff
12743
assert tif.byteorder == '<'
12744
assert len(tif.pages) == 1
12745
assert len(tif.series) == 1
12746
# assert page properties
12747
page = tif.pages.first
12748
assert page.sampleformat == SAMPLEFORMAT.COMPLEXINT
12749
assert page.bitspersample == bits * 2
12750
assert page.dtype == f'complex{bits * 4}'
12751
assert page.shape == (20, 20)
12752
assert page.imagewidth == 20
12753
assert page.imagelength == 20
12754
assert not page.is_contiguous
12755
data = page.asarray()
12756
data[9, 11] == 107 + 0j
12757
# assert GeoTIFF tags
12758
tags = tif.geotiff_metadata
12759
assert tags['GTCitationGeoKey'] == 'NAD27 / UTM zone 11N'
12760
assert_aszarr_method(page, data)
12764
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
12765
def test_read_qpi():
12766
"""Test read PerkinElmer-QPI, non Pyramid."""
12767
fname = private_file('PerkinElmer-QPI/18-2470_2471_Scan1.qptiff')
12768
with TiffFile(fname) as tif:
12769
assert len(tif.series) == 4
12770
assert len(tif.pages) == 9
12772
page = tif.pages.first
12773
assert page.compression == COMPRESSION.JPEG
12774
assert page.photometric == PHOTOMETRIC.RGB
12775
assert page.planarconfig == PLANARCONFIG.CONTIG
12776
assert page.imagewidth == 34560
12777
assert page.imagelength == 57600
12778
assert page.bitspersample == 8
12779
assert page.samplesperpixel == 3
12780
assert page.tags['Software'].value == 'PerkinElmer-QPI'
12782
page = tif.pages[1]
12783
assert page.compression == COMPRESSION.LZW
12784
assert page.photometric == PHOTOMETRIC.RGB
12785
assert page.planarconfig == PLANARCONFIG.CONTIG
12786
assert page.imagewidth == 270
12787
assert page.imagelength == 450
12788
assert page.bitspersample == 8
12789
assert page.samplesperpixel == 3
12791
series = tif.series[0]
12792
assert series.kind == 'qpi'
12793
assert series.name == 'Baseline'
12794
assert series.shape == (57600, 34560, 3)
12795
assert series.dtype == numpy.uint8
12796
assert series.is_pyramidal
12797
assert len(series.levels) == 6
12799
series = tif.series[1]
12800
assert series.kind == 'qpi'
12801
assert series.name == 'Thumbnail'
12802
assert series.shape == (450, 270, 3)
12803
assert series.dtype == numpy.uint8
12804
assert not series.is_pyramidal
12806
series = tif.series[2]
12807
assert series.kind == 'qpi'
12808
assert series.name == 'Macro'
12809
assert series.shape == (4065, 2105, 3)
12810
assert series.dtype == numpy.uint8
12811
assert not series.is_pyramidal
12813
series = tif.series[3]
12814
assert series.kind == 'qpi'
12815
assert series.name == 'Label'
12816
assert series.shape == (453, 526, 3)
12817
assert series.dtype == numpy.uint8
12818
assert not series.is_pyramidal
12821
image = tif.asarray(series=1)
12822
image = tif.asarray(series=2)
12823
image = tif.asarray(series=3)
12824
image = tif.asarray(series=0, level=4)
12825
assert image.shape == (3600, 2160, 3)
12826
assert image.dtype == numpy.uint8
12827
assert tuple(image[1200, 1500]) == (244, 233, 229)
12828
assert_aszarr_method(tif, image, series=0, level=4)
12832
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
12833
def test_read_qpi_nopyramid():
12834
"""Test read PerkinElmer-QPI, non Pyramid."""
12835
fname = private_file(
12836
'PerkinElmer-QPI/LuCa-7color_[13860,52919]_1x1component_data.tiff'
12838
with TiffFile(fname) as tif:
12839
assert len(tif.series) == 2
12840
assert len(tif.pages) == 9
12842
page = tif.pages.first
12843
assert page.compression == COMPRESSION.LZW
12844
assert page.photometric == PHOTOMETRIC.MINISBLACK
12845
assert page.planarconfig == PLANARCONFIG.CONTIG
12846
assert page.imagewidth == 1868
12847
assert page.imagelength == 1400
12848
assert page.bitspersample == 32
12849
assert page.samplesperpixel == 1
12850
assert page.tags['Software'].value == 'PerkinElmer-QPI'
12851
series = tif.series[0]
12852
assert series.kind == 'qpi'
12853
assert series.shape == (8, 1400, 1868)
12854
assert series.dtype == numpy.float32
12855
assert not series.is_pyramidal
12856
series = tif.series[1]
12857
assert series.kind == 'qpi'
12858
assert series.shape == (350, 467, 3)
12859
assert series.dtype == numpy.uint8
12860
assert not series.is_pyramidal
12862
image = tif.asarray()
12863
assert image.shape == (8, 1400, 1868)
12864
assert image.dtype == numpy.float32
12865
assert image[7, 1200, 1500] == 2.2132580280303955
12866
image = tif.asarray(series=1)
12867
assert image.shape == (350, 467, 3)
12868
assert image.dtype == numpy.uint8
12869
assert image[300, 400, 1] == 48
12870
assert_aszarr_method(tif, image, series=1)
12871
assert_aszarr_method(tif, image, series=1, chunkmode='page')
12875
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12876
def test_read_indica():
12877
"""Test read Indica Labs pyramid."""
12878
# https://forum.image.sc/t/89191/4
12879
fname = private_file('Indica/mouse_link.tif')
12880
with TiffFile(fname) as tif:
12881
assert len(tif.series) == 1
12882
assert len(tif.pages) == 40
12883
assert tif.is_indica
12884
assert tif.indica_metadata.endswith('</indica>')
12885
page = tif.pages.first
12886
assert page.compression == COMPRESSION.ADOBE_DEFLATE
12887
assert page.photometric == PHOTOMETRIC.MINISBLACK
12888
assert page.shape == (26836, 18282)
12889
assert page.bitspersample == 32
12890
assert page.samplesperpixel == 1
12891
assert page.dtype == numpy.float32
12892
assert page.tags['Software'].value == 'IndicaLabsImageWriter v1.2.1'
12893
series = tif.series[0]
12894
assert series.kind == 'generic' # 'indica'
12895
assert series.axes == 'IYX' # 'CYX'
12896
assert series.shape == (8, 26836, 18282)
12897
assert series.dtype == numpy.float32
12898
assert len(series.levels) == 5
12899
assert series.is_pyramidal
12901
image = tif.asarray(series=0, level=3)
12902
assert image.shape == (8, 3355, 2286)
12903
assert image.dtype == numpy.float32
12904
assert_array_almost_equal(image[7, 3000, 1000], 6.0852714)
12905
assert_aszarr_method(series, image, level=3)
12906
assert_aszarr_method(series, image, level=3, chunkmode='page')
12910
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
12911
def test_read_avs():
12912
"""Test read Argos AVS pyramid."""
12913
# https://github.com/openslide/openslide/issues/614
12914
fname = private_file('ArgosAVS/TestSlide1_ZStack.avs')
12915
with TiffFile(fname) as tif:
12916
assert len(tif.series) == 3
12917
assert len(tif.pages) == 42
12919
assert tif.avs_metadata.startswith('<Argos.Scan.Metadata>')
12920
page = tif.pages.first
12921
assert page.compression == COMPRESSION.JPEG
12922
assert page.photometric == PHOTOMETRIC.YCBCR
12923
assert page.shape == (57440, 130546, 3)
12924
assert page.bitspersample == 8
12925
assert page.samplesperpixel == 3
12926
assert page.dtype == numpy.uint8
12927
series = tif.series[0]
12928
assert series.kind == 'avs'
12929
assert series.name == 'Baseline'
12930
assert series.axes == 'ZYXS'
12931
assert series.shape == (5, 57440, 130546, 3)
12932
assert series.dtype == numpy.uint8
12933
assert series.is_pyramidal
12934
assert len(series.levels) == 8
12935
series = tif.series[1]
12936
assert series.kind == 'avs'
12937
assert series.name == 'Map'
12938
assert series.axes == 'YXS'
12939
assert series.shape == (1399, 3180, 3)
12940
series = tif.series[2]
12941
assert series.kind == 'avs'
12942
assert series.name == 'Macro'
12943
assert series.axes == 'YXS'
12944
assert series.shape == (508, 1489, 3)
12946
series = tif.series[0]
12947
image = tif.asarray(series=0, level=4)
12948
assert image.shape == (5, 3590, 8159, 3)
12949
assert image.dtype == numpy.uint8
12950
assert image[2, 900, 3000, 0] == 218
12951
assert_aszarr_method(series, image, level=4)
12952
assert_aszarr_method(series, image, level=4, chunkmode='page')
12956
@pytest.mark.skipif(
12957
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
12960
def test_read_philips():
12961
"""Test read Philips DP pyramid."""
12962
# https://camelyon17.grand-challenge.org/Data/
12963
fname = private_file('PhilipsDP/test_001.tif')
12964
with TiffFile(fname) as tif:
12965
assert len(tif.series) == 1
12966
assert len(tif.pages) == 9
12967
assert tif.is_philips
12968
assert tif.philips_metadata.endswith('</DataObject>')
12970
page = tif.pages.first
12971
assert page.compression == COMPRESSION.JPEG
12972
assert page.photometric == PHOTOMETRIC.YCBCR
12973
assert page.planarconfig == PLANARCONFIG.CONTIG
12974
assert page.tags['ImageWidth'].value == 86016
12975
assert page.tags['ImageLength'].value == 89600
12976
assert page.imagewidth == 86016
12977
assert page.imagelength == 89600
12978
assert page.bitspersample == 8
12979
assert page.samplesperpixel == 3
12980
assert page.tags['Software'].value == 'Philips DP v1.0'
12982
series = tif.series[0]
12983
assert series.kind == 'philips'
12984
assert series.shape == (89600, 86016, 3)
12985
assert len(series.levels) == 9
12986
assert series.is_pyramidal
12987
assert series.levels[1].shape == (44800, 43008, 3)
12988
assert series.levels[2].shape == (22400, 21504, 3)
12989
assert series.levels[3].shape == (11200, 10752, 3)
12990
assert series.levels[4].shape == (5600, 5376, 3)
12991
assert series.levels[5].shape == (2800, 2688, 3)
12992
assert series.levels[6].shape == (1400, 1344, 3)
12993
assert series.levels[7].shape == (700, 672, 3)
12994
assert series.levels[8].shape == (350, 336, 3)
12996
page = series.levels[1].keyframe
12997
assert page.compression == COMPRESSION.JPEG
12998
assert page.photometric == PHOTOMETRIC.YCBCR
12999
assert page.planarconfig == PLANARCONFIG.CONTIG
13000
assert page.tags['ImageWidth'].value == 43008
13001
assert page.tags['ImageLength'].value == 45056
13002
assert page.imagewidth == 43008
13003
assert page.imagelength == 44800
13005
for level in range(1, 9):
13006
tif.asarray(series=0, level=level)
13009
image = tif.asarray(series=0, level=5)
13010
assert image.shape == (2800, 2688, 3)
13011
assert image[300, 400, 1] == 206
13012
assert_aszarr_method(series, image, level=5)
13013
assert_aszarr_method(series, image, level=5, chunkmode='page')
13017
@pytest.mark.skipif(
13018
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
13021
def test_read_philips_issue249():
13022
"""Test write_fsspec with Philips slide missing row of tiles."""
13023
# https://github.com/cgohlke/tifffile/issues/249
13024
fname = private_file('PhilipsDP/patient_080_node_2.tif')
13025
with TiffFile(fname) as tif:
13026
assert len(tif.series) == 2
13027
assert len(tif.pages) == 11
13028
assert tif.is_philips
13029
assert tif.philips_metadata.endswith('</DataObject>')
13031
page = tif.pages.first
13032
assert page.compression == COMPRESSION.JPEG
13033
assert page.photometric == PHOTOMETRIC.YCBCR
13034
assert page.planarconfig == PLANARCONFIG.CONTIG
13035
assert page.tags['ImageWidth'].value == 155136
13036
assert page.tags['ImageLength'].value == 78336
13037
assert page.imagewidth == 155136
13038
assert page.imagelength == 78336
13039
assert page.bitspersample == 8
13040
assert page.samplesperpixel == 3
13041
assert page.tags['Software'].value == 'Philips DP v1.0'
13043
series = tif.series[1]
13044
assert series.kind == 'philips'
13045
assert series.name == 'Macro'
13046
assert series.shape == (801, 1756, 3)
13047
assert len(series.levels) == 1
13048
assert not series.is_pyramidal
13050
series = tif.series[0]
13051
assert series.kind == 'philips'
13052
assert series.name == 'Baseline'
13053
assert series.shape == (78336, 155136, 3)
13054
assert len(series.levels) == 10
13055
assert series.is_pyramidal
13057
page = series.levels[3].keyframe
13058
assert page.compression == COMPRESSION.JPEG
13059
assert page.photometric == PHOTOMETRIC.YCBCR
13060
assert page.planarconfig == PLANARCONFIG.CONTIG
13061
assert page.tags['ImageWidth'].value == 19456
13062
assert page.tags['ImageLength'].value == 9728
13063
assert page.imagewidth == 19392
13064
assert page.imagelength == 9792
13066
for level in range(1, 10):
13067
tif.asarray(series=0, level=level)
13070
image = tif.asarray(series=0, level=3)
13071
assert image.shape == (9792, 19392, 3)
13072
assert image[300, 400, 1] == 226
13073
assert image[9791, 0, 1] == 0
13074
assert_aszarr_method(series, image, level=3)
13081
from imagecodecs.numcodecs import register_codecs
13083
register_codecs('imagecodecs_jpeg', verbose=False)
13084
url = os.path.dirname(fname).replace('\\', '/')
13085
with TempFileName('issue_philips_fsspec', ext='.json') as jsonfile:
13086
page.aszarr().write_fsspec(jsonfile, url, version=0)
13087
mapper = fsspec.get_mapper(
13090
target_protocol='file',
13091
remote_protocol='file',
13093
zobj = zarr.open(mapper, mode='r')
13094
assert_array_equal(zobj[:], image)
13097
@pytest.mark.skipif(
13098
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
13101
def test_read_philips_issue253():
13102
"""Test read Philips DP pyramid with seemingly extra column of tiles."""
13103
# https://github.com/cgohlke/tifffile/issues/253
13104
# https://registry.opendata.aws/camelyon/
13105
fname = private_file('PhilipsDP/sample.tiff')
13106
with TiffFile(fname) as tif:
13107
assert len(tif.series) == 3
13108
assert len(tif.pages) == 12
13109
assert tif.is_philips
13110
assert tif.philips_metadata.endswith('</DataObject>')
13112
page = tif.pages.first
13113
assert page.compression == COMPRESSION.JPEG
13114
assert page.photometric == PHOTOMETRIC.RGB
13115
assert page.planarconfig == PLANARCONFIG.CONTIG
13116
assert page.tags['ImageWidth'].value == 188416
13117
assert page.tags['ImageLength'].value == 93696
13118
assert page.imagewidth == 188416
13119
assert page.imagelength == 93696
13120
assert page.bitspersample == 8
13121
assert page.samplesperpixel == 3
13122
assert page.tags['Software'].value == 'Philips DP v1.0'
13124
series = tif.series[1]
13125
assert series.kind == 'philips'
13126
assert series.name == 'Macro'
13127
assert series.shape == (812, 1806, 3)
13128
assert not series.is_pyramidal
13130
series = tif.series[2]
13131
assert series.kind == 'philips'
13132
assert series.name == 'Label'
13133
assert series.shape == (812, 671, 3)
13134
assert not series.is_pyramidal
13136
series = tif.series[0]
13137
assert series.kind == 'philips'
13138
assert series.name == 'Baseline'
13139
assert series.shape == (93696, 188416, 3)
13140
assert len(series.levels) == 10
13141
assert series.is_pyramidal
13142
assert series.levels[1].shape == (46848, 94208, 3)
13143
assert series.levels[2].shape == (23424, 47104, 3)
13144
assert series.levels[3].shape == (11712, 23552, 3)
13145
assert series.levels[4].shape == (5856, 11776, 3)
13146
assert series.levels[5].shape == (2928, 5888, 3)
13147
assert series.levels[6].shape == (1464, 2944, 3)
13148
assert series.levels[7].shape == (732, 1472, 3)
13149
assert series.levels[8].shape == (366, 736, 3)
13150
assert series.levels[9].shape == (183, 368, 3)
13152
page = series.levels[1].keyframe
13153
assert page.compression == COMPRESSION.JPEG
13154
assert page.photometric == PHOTOMETRIC.RGB
13155
assert page.planarconfig == PLANARCONFIG.CONTIG
13156
assert page.tags['ImageWidth'].value == 94208
13157
assert page.tags['ImageLength'].value == 47104
13158
assert page.imagewidth == 94208
13159
assert page.imagelength == 46848
13161
for level in range(1, 10):
13162
tif.asarray(series=0, level=level)
13165
image = tif.asarray(series=0, level=5)
13166
assert image.shape == (2928, 5888, 3)
13167
assert image[300, 400, 1] == 254
13168
assert_aszarr_method(series, image, level=5)
13169
assert_aszarr_method(series, image, level=5, chunkmode='page')
13173
@pytest.mark.skipif(
13174
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
13177
def test_read_zif():
13178
"""Test read Zoomable Image Format ZIF."""
13179
fname = private_file('zif/ZoomifyImageExample.zif')
13180
with TiffFile(fname) as tif:
13181
# assert tif.is_zif
13182
assert len(tif.pages) == 5
13183
assert len(tif.series) == 1
13184
for page in tif.pages:
13185
assert page.description == (
13186
'Created by Objective ' 'Pathology Services'
13189
page = tif.pages.first
13190
assert page.photometric == PHOTOMETRIC.YCBCR
13191
assert page.compression == COMPRESSION.JPEG
13192
assert page.shape == (3120, 2080, 3)
13193
assert tuple(page.asarray()[3110, 2070, :]) == (27, 45, 59)
13195
page = tif.pages[-1]
13196
assert page.photometric == PHOTOMETRIC.YCBCR
13197
assert page.compression == COMPRESSION.JPEG
13198
assert page.shape == (195, 130, 3)
13199
assert tuple(page.asarray()[191, 127, :]) == (30, 49, 66)
13201
series = tif.series[0]
13202
assert series.kind == 'generic'
13203
assert series.is_pyramidal
13204
assert len(series.levels) == 5
13205
assert series.shape == (3120, 2080, 3)
13206
assert tuple(series.asarray()[3110, 2070, :]) == (27, 45, 59)
13207
assert series.levels[-1].shape == (195, 130, 3)
13208
assert tuple(series.asarray(level=-1)[191, 127, :]) == (30, 49, 66)
13209
assert_aszarr_method(series, level=-1)
13213
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
13214
def test_read_vsi():
13215
"""Test read Olympus VSI."""
13216
fname = private_file('VSI/brightfield.vsi')
13217
with TiffFile(fname) as tif:
13218
assert not tif.is_sis
13219
assert tif.byteorder == '<'
13220
assert len(tif.pages) == 5
13221
assert len(tif.series) == 5
13222
# assert page properties
13223
page = tif.pages.first
13224
assert not page.is_contiguous
13225
assert page.imagewidth == 991
13226
assert page.imagelength == 375
13227
assert page.bitspersample == 8
13228
assert page.samplesperpixel == 3
13229
assert page.tags['Artist'].value == 'ics'
13231
data = tif.asarray()
13232
assert data.shape == (375, 991, 3)
13233
assert data[200, 256, 1] == 3
13235
sis = tif.sis_metadata
13236
assert sis['magnification'] == 1.0
13237
assert_aszarr_method(tif, data)
13238
assert_aszarr_method(tif, data, chunkmode='page')
13242
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13243
def test_read_sis():
13244
"""Test read Olympus SIS."""
13245
fname = private_file('sis/4A5IE8EM_F00000409.tif')
13246
with TiffFile(fname) as tif:
13248
assert tif.byteorder == '<'
13249
assert len(tif.pages) == 122
13250
assert len(tif.series) == 1
13251
# assert page properties
13252
page = tif.pages.first
13253
assert page.is_contiguous
13254
assert page.imagewidth == 353
13255
assert page.imagelength == 310
13256
assert page.bitspersample == 16
13257
assert page.samplesperpixel == 1
13258
assert page.tags['Software'].value == 'analySIS 5.0'
13260
data = tif.asarray()
13261
assert data.shape == (61, 2, 310, 353)
13262
assert data[30, 1, 256, 256] == 210
13264
sis = tif.sis_metadata
13265
assert sis['axes'] == 'TC'
13266
assert sis['shape'] == (61, 2)
13267
assert sis['Band'][1]['BandName'] == 'Fura380'
13268
assert sis['Band'][0]['LUT'].shape == (256, 3)
13269
assert sis['Time']['TimePos'].shape == (61,)
13270
assert sis['name'] == 'Hela-Zellen'
13271
assert sis['magnification'] == 60.0
13272
assert_aszarr_method(tif, data)
13273
assert_aszarr_method(tif, data, chunkmode='page')
13277
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13278
def test_read_sis_noini():
13279
"""Test read Olympus SIS without INI tag."""
13280
fname = private_file('sis/110.tif')
13281
with TiffFile(fname) as tif:
13283
assert tif.byteorder == '<'
13284
assert len(tif.pages) == 1
13285
assert len(tif.series) == 1
13286
# assert page properties
13287
page = tif.pages.first
13288
assert page.imagewidth == 2560
13289
assert page.imagelength == 1920
13290
assert page.bitspersample == 8
13291
assert page.samplesperpixel == 3
13293
sis = tif.sis_metadata
13294
assert 'axes' not in sis
13295
assert sis['magnification'] == 20.0
13299
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13300
def test_read_sem_metadata():
13301
"""Test read Zeiss SEM metadata."""
13302
# file from hyperspy tests
13303
fname = private_file('hyperspy/test_tiff_Zeiss_SEM_1k.tif')
13304
with TiffFile(fname) as tif:
13306
assert tif.byteorder == '<'
13307
assert len(tif.pages) == 1
13308
assert len(tif.series) == 1
13309
# assert page properties
13310
page = tif.pages.first
13311
assert page.is_contiguous
13312
assert page.photometric == PHOTOMETRIC.PALETTE
13313
assert page.imagewidth == 1024
13314
assert page.imagelength == 768
13315
assert page.bitspersample == 8
13316
assert page.samplesperpixel == 1
13317
# assert data and metadata
13318
data = page.asrgb()
13319
assert tuple(data[563, 320]) == (38550, 38550, 38550)
13320
sem = tif.sem_metadata
13321
assert sem[''][3] == 2.614514e-06
13322
assert sem['ap_date'] == ('Date', '23 Dec 2015')
13323
assert sem['ap_time'] == ('Time', '9:40:32')
13324
assert sem['dp_image_store'] == ('Store resolution', '1024 * 768')
13325
assert sem['ap_fib_fg_emission_actual'] == (
13326
'Flood Gun Emission Actual',
13330
assert_aszarr_method(tif)
13334
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13335
def test_read_sem_bad_metadata():
13336
"""Test read Zeiss SEM metadata with wrong length."""
13337
# reported by Klaus Schwarzburg on 8/27/2018
13338
fname = private_file('issues/sem_bad_metadata.tif')
13339
with TiffFile(fname) as tif:
13341
assert tif.byteorder == '<'
13342
assert len(tif.pages) == 1
13343
assert len(tif.series) == 1
13344
# assert page properties
13345
page = tif.pages.first
13346
assert page.is_contiguous
13347
assert page.photometric == PHOTOMETRIC.PALETTE
13348
assert page.imagewidth == 1024
13349
assert page.imagelength == 768
13350
assert page.bitspersample == 8
13351
assert page.samplesperpixel == 1
13352
# assert data and metadata
13353
data = page.asrgb()
13354
assert tuple(data[350, 150]) == (17476, 17476, 17476)
13355
sem = tif.sem_metadata
13356
assert sem['sv_version'][1] == 'V05.07.00.00 : 08-Jul-14'
13357
assert_aszarr_method(tif)
13361
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13362
def test_read_fei_metadata():
13363
"""Test read Helios FEI metadata."""
13364
# file from hyperspy tests
13365
fname = private_file('hyperspy/test_tiff_FEI_SEM.tif')
13366
with TiffFile(fname) as tif:
13368
assert tif.byteorder == '<'
13369
assert len(tif.pages) == 1
13370
assert len(tif.series) == 1
13371
# assert page properties
13372
page = tif.pages.first
13373
assert page.is_contiguous
13374
assert page.photometric != PHOTOMETRIC.PALETTE
13375
assert page.imagewidth == 1536
13376
assert page.imagelength == 1103
13377
assert page.bitspersample == 8
13378
assert page.samplesperpixel == 1
13379
# assert data and metadata
13380
data = page.asarray()
13381
assert data[563, 320] == 220
13382
fei = tif.fei_metadata
13383
assert fei['User']['User'] == 'supervisor'
13384
assert fei['System']['DisplayHeight'] == 0.324
13385
assert_aszarr_method(tif)
13389
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE or SKIP_ZARR, reason=REASON)
13390
def test_read_mmstack_multifile(caplog):
13391
"""Test read MicroManager 2.0 multi-file, multi-position dataset."""
13392
# TODO: what version of MicroManager does not write corrupted files?
13393
# second ImageDescription tag value is beyond 4 GB
13394
# MicroManager headers are beyond 4 GB
13395
# MicroManager display settings are truncated
13396
fname = private_file('MMStack/NDTiff.index/_4_MMStack_Pos0.ome.tif')
13397
with TiffFile(fname) as tif:
13398
assert 'coercing invalid ASCII to bytes' in caplog.text
13399
assert tif.is_micromanager
13400
assert tif.is_mmstack
13402
assert not tif.is_imagej
13403
assert not tif.is_ndtiff
13404
assert tif.byteorder == '<'
13405
assert len(tif.pages) == 8092
13406
assert len(tif.series) == 1
13407
assert 'failed to read display settings' not in caplog.text
13408
assert 'failed to read comments: invalid header' not in caplog.text
13410
meta = tif.micromanager_metadata
13411
assert meta is not None
13412
assert meta['MajorVersion'] == 0
13413
assert meta['Summary']['MicroManagerVersion'] == '2.0.0'
13414
assert meta['Summary']['Prefix'] == '_4'
13415
assert meta['IndexMap'].shape == (8092, 5)
13416
assert 'Comments' in meta
13417
# assert series properties
13418
series = tif.series[0]
13419
assert len(series) == 17472
13420
assert series.shape == (91, 2, 48, 2, 512, 512)
13421
assert series.axes == 'TRZCYX'
13422
assert series.kind == 'mmstack'
13423
assert series.is_multifile
13425
data = tif.asarray()
13426
assert isinstance(data, numpy.ndarray)
13427
assert data.shape == (91, 2, 48, 2, 512, 512)
13428
assert data.dtype == numpy.uint16
13429
assert data[48, 1, 23, 1, 253, 257] == 1236
13430
# assert_aszarr_method(series, data) # takes 2 minutes
13431
with series.aszarr() as store:
13432
data = zarr.open(store, mode='r')
13433
assert data[48, 1, 23, 1, 253, 257] == 1236
13434
# test OME; ImageJ can't handle multi-file or positions
13435
assert_array_equal(data[:, 0], imread(fname, is_mmstack=False))
13439
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13440
def test_read_mmstack_mosaic(caplog):
13441
"""Test read MicroManager 1.4 mosaic dataset."""
13442
fname = private_file(
13443
'MMStack/mosaic/d220708_HybISS_AS_cycles1to5_NoBridgeProbes_dim3x3__3'
13444
'_MMStack_2-Pos_000_001.ome.tif'
13446
with TiffFile(fname) as tif:
13447
assert 'coercing invalid ASCII to bytes' not in caplog.text
13448
assert tif.is_micromanager
13449
assert tif.is_mmstack
13451
assert tif.is_imagej
13452
assert not tif.is_ndtiff
13453
assert tif.byteorder == '<'
13454
assert len(tif.pages) == 55
13455
assert len(tif.series) == 1
13457
meta = tif.micromanager_metadata
13458
assert meta is not None
13459
assert meta['MajorVersion'] == 0
13460
assert meta['Summary']['MicroManagerVersion'] == '1.4.24 20220315'
13461
assert meta['Summary']['Prefix'] == (
13462
'd220708_HybISS_AS_cycles1to5_NoBridgeProbes_dim3x3__3'
13464
assert meta['IndexMap'].shape == (55, 5)
13465
assert 'Comments' in meta
13466
# assert series properties
13467
series = tif.series[0]
13468
assert len(series) == 495
13469
assert series.shape == (9, 11, 5, 1040, 1388)
13470
assert series.axes == 'RZCYX'
13471
assert series.kind == 'mmstack'
13472
assert series.is_multifile
13474
data = tif.asarray()
13475
assert isinstance(data, numpy.ndarray)
13476
assert data.shape == (9, 11, 5, 1040, 1388)
13477
assert data.dtype == numpy.uint16
13478
assert data[7, 9, 3, 753, 1257] == 90
13479
assert_aszarr_method(series, data)
13483
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13484
def test_read_mmstack_single():
13485
"""Test read MicroManager single-file multi-region dataset."""
13486
fname = private_file(
13487
'MMStack/181003_multi_pos_time_course_1_MMStack.ome.tif'
13489
with TiffFile(fname) as tif:
13490
assert tif.is_micromanager
13491
assert tif.is_mmstack
13493
assert tif.is_imagej
13494
assert not tif.is_ndtiff
13495
assert tif.byteorder == '<'
13496
assert len(tif.pages) == 20
13497
assert len(tif.series) == 1
13499
meta = tif.micromanager_metadata
13500
assert meta is not None
13501
assert meta['MajorVersion'] == 0
13502
assert meta['Summary']['MicroManagerVersion'] == '2.0.0-beta3 20160512'
13503
assert meta['Summary']['Prefix'] == '181003_multi_pos_time_course_1'
13504
assert meta['IndexMap'].shape == (20, 5)
13505
assert meta['Comments']['0_0_4_1'] == ''
13506
# assert series properties
13507
series = tif.series[0]
13508
assert len(series) == 20
13509
assert series.shape == (10, 2, 256, 256)
13510
assert series.axes == 'TRYX'
13511
assert series.kind == 'mmstack'
13512
assert not series.is_multifile
13514
data = tif.asarray()
13515
assert isinstance(data, numpy.ndarray)
13516
assert data.shape == (10, 2, 256, 256)
13517
assert data.dtype == numpy.uint16
13518
assert data[7, 1, 111, 222] == 6991
13519
assert_aszarr_method(series, data)
13520
# test OME; ImageJ can't handle positions
13521
assert_array_equal(data[:, 0], imread(fname, is_mmstack=False))
13525
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13526
def test_read_mmstack_missing(caplog):
13527
"""Test read MicroManager missing files and pages in dataset."""
13528
fname = private_file('MMStack/movie_9_MMStack.ome.tif')
13529
with TiffFile(fname) as tif:
13530
assert tif.is_micromanager
13531
assert tif.is_mmstack
13533
assert tif.is_imagej
13534
assert not tif.is_ndtiff
13535
assert tif.byteorder == '<'
13536
assert len(tif.pages) == 126
13537
assert len(tif.series) == 1
13538
assert 'MMStack series is missing files' in caplog.text
13539
assert 'MMStack is missing 1 page' in caplog.text
13541
meta = tif.micromanager_metadata
13542
assert meta is not None
13543
assert meta['MajorVersion'] == 0
13544
assert meta['Summary']['MicroManagerVersion'] == '1.4.16 20140128'
13545
assert meta['Summary']['Prefix'] == 'movie_9'
13546
assert meta['IndexMap'].shape == (125, 5)
13547
assert meta['Comments'] == {'Summary': ''}
13548
assert meta['DisplaySettings'][0]['Name'] == 'Dual-GFP'
13549
# assert series properties
13550
series = tif.series[0]
13551
assert series[-1] is None # missing page
13552
assert len(series) == 126
13553
assert series.shape == (63, 2, 264, 320)
13554
assert series.axes == 'TCYX'
13555
assert series.kind == 'mmstack'
13556
assert not series.is_multifile
13558
data = tif.asarray()
13559
assert isinstance(data, numpy.ndarray)
13560
assert data.shape == (63, 2, 264, 320)
13561
assert data.dtype == numpy.uint16
13562
assert data[59, 1, 151, 186] == 599
13564
if not SKIP_ZARR and zarr is not None:
13565
with series.aszarr(fillvalue=100) as store:
13566
assert '1.1.0.0' in store
13567
assert '62.1.0.0' not in store # missing page
13568
z = zarr.open(store, mode='r')
13569
assert z[62, 1, 0, 0] == 100
13570
assert_array_equal(data[:62], z[:62])
13571
# test OME and ImageJ
13572
assert_array_equal(data, imread(fname, is_mmstack=False))
13573
assert_array_equal(data, imread(fname, is_mmstack=False, is_ome=False))
13577
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13578
def test_read_mmstack_bytesio(caplog):
13579
"""Test read MicroManager missing data in BytesIO."""
13580
fname = private_file('MMStack/movie_9_MMStack.ome.tif')
13581
with open(fname, 'rb') as fh:
13582
bytesio = BytesIO(fh.read())
13583
with TiffFile(bytesio) as tif:
13584
assert tif.is_micromanager
13585
assert tif.is_mmstack
13587
assert tif.is_imagej
13588
assert not tif.is_ndtiff
13589
assert not tif.filehandle.is_file
13590
assert tif.byteorder == '<'
13591
assert len(tif.pages) == 126
13592
assert len(tif.series) == 1
13593
assert 'MMStack series is missing files' in caplog.text
13594
assert 'MMStack is missing 1 page' in caplog.text
13596
meta = tif.micromanager_metadata
13597
assert meta is not None
13598
assert meta['MajorVersion'] == 0
13599
assert meta['Summary']['MicroManagerVersion'] == '1.4.16 20140128'
13600
assert meta['Summary']['Prefix'] == 'movie_9'
13601
assert meta['IndexMap'].shape == (125, 5)
13602
assert meta['Comments'] == {'Summary': ''}
13603
assert meta['DisplaySettings'][0]['Name'] == 'Dual-GFP'
13604
# assert series properties
13605
series = tif.series[0]
13606
assert len(series) == 126
13607
assert series.shape == (63, 2, 264, 320)
13608
assert series.axes == 'TCYX'
13609
assert series.kind == 'mmstack'
13610
assert not series.is_multifile
13612
data = tif.asarray()
13613
assert isinstance(data, numpy.ndarray)
13614
assert data.shape == (63, 2, 264, 320)
13615
assert data.dtype == numpy.uint16
13616
assert data[59, 1, 151, 186] == 599
13617
assert_aszarr_method(series, data)
13621
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13622
def test_read_mmstack_missing_sbs(caplog):
13623
"""Test read MicroManager dataset with missing data."""
13624
# https://github.com/cgohlke/tifffile/issues/187
13625
fname = private_file('MMStack/10X_c1-SBS-1_A1_Tile-102.sbs.tif')
13626
with TiffFile(fname) as tif:
13627
assert tif.is_micromanager
13628
assert tif.is_mmstack
13630
assert tif.is_imagej
13631
assert not tif.is_ndtiff
13632
assert tif.byteorder == '<'
13633
assert len(tif.pages) == 5
13634
assert len(tif.series) == 1
13635
assert 'MMStack file name is invalid' in caplog.text
13636
assert 'MMStack series is missing files' in caplog.text
13638
meta = tif.micromanager_metadata
13639
assert meta is not None
13640
assert meta['MajorVersion'] == 0
13641
assert meta['Summary']['MicroManagerVersion'].startswith('1.4.23 2019')
13642
assert meta['Summary']['Prefix'] == '10X_c1-SBS-1_1'
13643
assert meta['IndexMap'].shape == (5, 5)
13644
assert meta['Comments']['Summary'] == ''
13645
assert meta['DisplaySettings'][0]['Name'] == 'DAPI_10p'
13646
# assert series properties
13647
series = tif.series[0]
13648
assert len(series) == 5
13649
assert series.shape == (5, 1024, 1024)
13650
assert series.axes == 'CYX'
13651
assert series.kind == 'mmstack'
13652
assert not series.is_multifile
13654
data = tif.asarray()
13655
assert isinstance(data, numpy.ndarray)
13656
assert data.shape == (5, 1024, 1024)
13657
assert data.dtype == numpy.uint16
13658
assert data[3, 151, 186] == 542
13659
assert_aszarr_method(series, data)
13661
assert_array_equal(data, imread(fname, is_mmstack=False))
13665
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
13666
def test_read_mmstack_trzc():
13667
"""Test read MicroManager 6 dimensional dataset."""
13668
fname = private_file(
13670
'/image_stack_tpzc_50tp_2p_5z_3c_512k_1_MMStack_2-Pos000_000.ome.tif'
13672
with TiffFile(fname) as tif:
13673
assert tif.is_micromanager
13674
assert tif.is_mmstack
13676
assert tif.is_imagej
13677
assert not tif.is_ndtiff
13678
assert tif.byteorder == '<'
13679
assert len(tif.pages) == 750
13680
assert len(tif.series) == 1
13682
meta = tif.micromanager_metadata
13683
assert meta is not None
13684
assert meta['MajorVersion'] == 0
13685
assert meta['Summary']['MicroManagerVersion'].startswith('2.0.0-gamma')
13686
assert meta['Summary']['Prefix'] == (
13687
'image_stack_tpzc_50tp_2p_5z_3c_512k_1'
13689
assert meta['IndexMap'].shape == (750, 5)
13690
assert meta['Comments']['Summary'] == ''
13691
assert 'DisplaySettings' not in meta
13692
# assert series properties
13693
series = tif.series[0]
13694
assert len(series) == 1500
13695
assert series.shape == (50, 2, 5, 3, 256, 256)
13696
assert series.axes == 'TRZCYX'
13697
assert series.kind == 'mmstack'
13698
assert series.is_multifile
13700
data = tif.asarray()
13701
assert isinstance(data, numpy.ndarray)
13702
assert data.shape == (50, 2, 5, 3, 256, 256)
13703
assert data.dtype == numpy.uint16
13704
assert data[27, 1, 3, 2, 151, 186] == 16
13705
assert_aszarr_method(series, data)
13707
assert_array_equal(
13708
data[:, 1], imread(fname, is_mmstack=False, series=1)
13713
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13714
def test_read_ndtiff_magellanstack():
13715
"""Test read NDTiffStorage/MagellanStack."""
13716
# https://github.com/cgohlke/tifffile/issues/23
13717
fname = private_file(
13718
'NDTiffStorage/MagellanStack/Full resolution/democam_MagellanStack.tif'
13720
with TiffFile(fname) as tif:
13721
assert tif.is_micromanager
13722
assert len(tif.pages) == 12
13723
# with pytest.warns(UserWarning):
13724
assert tif.micromanager_metadata is not None
13725
assert 'Comments' not in tif.micromanager_metadata
13726
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13727
assert meta['Axes']['repetition'] == 2
13728
assert meta['Axes']['exposure'] == 3
13729
# NDTiff v0 and v1 series are not supported
13730
series = tif.series[0]
13731
assert series.kind == 'uniform' # not 'ndtiff'
13732
assert series.dtype == numpy.uint8
13733
assert series.shape == (12, 512, 512)
13734
assert series.axes == 'IYX'
13735
data = series.asarray()
13736
assert data[8, 100, 100] == 164
13737
assert_aszarr_method(tif, data)
13741
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13742
def test_read_ndtiff_v2():
13743
"""Test read NDTiffStorage v2."""
13744
fname = private_file(
13745
'NDTiffStorage/v2/ndtiffv2.0_test/Full resolution'
13746
'/ndtiffv2.0_test_NDTiffStack.tif'
13748
with TiffFile(fname) as tif:
13749
assert tif.is_micromanager
13750
assert tif.is_ndtiff
13751
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13752
assert meta['Axes'] == {'channel': 1, 'time': 4}
13753
meta = tif.micromanager_metadata
13754
assert meta is not None
13755
assert meta['MajorVersion'] == 2
13756
assert meta['Summary']['PixelType'] == 'GRAY16'
13757
series = tif.series[0]
13758
assert series.kind == 'ndtiff'
13759
assert series.dtype == numpy.uint16
13760
assert series.shape == (5, 2, 32, 32)
13761
assert series.axes == 'TCYX'
13762
data = series.asarray()
13763
if not SKIP_NDTIFF:
13764
ndt = ndtiff.Dataset(os.path.join(os.path.dirname(fname), '..'))
13766
assert_array_equal(
13767
data, ndt.as_array(axes=['time', 'channel'])
13772
assert_aszarr_method(tif, data)
13776
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13777
def test_read_ndtiff_tiled():
13778
"""Test read NDTiffStorage v2 tiled."""
13779
fname = private_file(
13780
'NDTiffStorage/v2/ndtiffv2.0_stitched_test/Full resolution'
13781
'/ndtiffv2.0_stitched_test_NDTiffStack.tif'
13783
with TiffFile(fname) as tif:
13784
assert tif.is_micromanager
13785
assert tif.is_ndtiff
13786
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13787
assert meta['Axes'] == {'channel': 0, 'column': 0, 'row': 0}
13788
meta = tif.micromanager_metadata
13789
assert meta is not None
13790
assert meta['MajorVersion'] == 2
13791
assert meta['Summary']['PixelType'] == 'GRAY16'
13792
series = tif.series[0]
13793
assert series.kind == 'ndtiff'
13794
assert series.dtype == numpy.uint16
13795
assert series.shape == (2, 2, 32, 32)
13796
assert series.axes == 'JKYX'
13797
data = series.asarray()
13798
if not SKIP_NDTIFF:
13799
ndt = ndtiff.Dataset(os.path.join(os.path.dirname(fname), '..'))
13801
assert_array_equal(data, ndt.as_array(axes=['row', 'column']))
13804
assert_aszarr_method(tif, data)
13808
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13809
def test_read_ndtiff_v3():
13810
"""Test read NDTiffStorage v3."""
13811
fname = private_file(
13812
'NDTiffStorage/v3/ndtiffv3.0_test/ndtiffv3.0_test_NDTiffStack.tif'
13814
with TiffFile(fname) as tif:
13815
assert tif.is_micromanager
13816
assert tif.is_ndtiff
13817
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13818
assert meta['Axes'] == {'channel': 1, 'time': 4}
13819
meta = tif.micromanager_metadata
13820
assert meta is not None
13821
assert meta['MajorVersion'] == 3
13822
assert meta['MinorVersion'] == 0
13823
assert meta['Summary']['PixelType'] == 'GRAY16'
13824
series = tif.series[0]
13825
assert series.kind == 'ndtiff'
13826
assert series.dtype == numpy.uint16
13827
assert series.shape == (5, 2, 32, 32)
13828
assert series.axes == 'TCYX'
13829
data = series.asarray()
13830
if not SKIP_NDTIFF:
13831
ndt = ndtiff.Dataset(os.path.dirname(fname))
13833
assert_array_equal(
13834
data, ndt.as_array(axes=['time', 'channel'])
13838
assert_aszarr_method(tif, data)
13842
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13843
def test_read_ndtiff_tcz():
13844
"""Test read NDTiffStorage v3 with squeezed axes."""
13845
fname = private_file(
13846
'NDTiffStorage/v3/mm_mda_tcz_15/mm_mda_tcz_15_NDTiffStack.tif'
13848
with TiffFile(fname) as tif:
13849
assert tif.is_micromanager
13850
assert tif.is_ndtiff
13851
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13852
assert 'Axes' not in meta # missing?
13853
# expected {'channel': 1, 'z': 6, 'position': 0, 'time': 7}
13854
meta = tif.micromanager_metadata
13855
assert meta is not None
13856
assert meta['MajorVersion'] == 3
13857
assert meta['MinorVersion'] == 0
13858
assert meta['Summary']['PixelType'] == 'GRAY16'
13859
series = tif.series[0]
13860
assert series.kind == 'ndtiff'
13861
assert series.dtype == numpy.uint16
13862
assert series.get_shape(False) == (1, 8, 2, 7, 512, 512)
13863
assert series.get_axes(False) == 'RTCZYX'
13864
data = series.asarray(squeeze=True)
13865
assert data.shape == (8, 2, 7, 512, 512)
13866
if not SKIP_NDTIFF:
13867
ndt = ndtiff.Dataset(os.path.dirname(fname))
13869
# axes=['position', 'time', 'channel', 'z']
13870
assert_array_equal(data, numpy.squeeze(ndt.as_array()))
13873
assert_aszarr_method(tif, data)
13877
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13878
def test_read_ndtiff_bytesio(caplog):
13879
"""Test read NDTiffStorage v3 with BytesIO."""
13880
fname = private_file(
13881
'NDTiffStorage/v3/mm_mda_tcz_15/mm_mda_tcz_15_NDTiffStack.tif'
13883
with open(fname, 'rb') as fh:
13884
bytesio = BytesIO(fh.read())
13885
with TiffFile(bytesio) as tif:
13886
assert tif.is_micromanager
13887
assert tif.is_ndtiff
13888
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13889
assert 'Axes' not in meta # missing?
13890
# expected {'channel': 1, 'z': 6, 'position': 0, 'time': 7}
13891
meta = tif.micromanager_metadata
13892
assert meta is not None
13893
assert meta['MajorVersion'] == 3
13894
assert meta['MinorVersion'] == 0
13895
assert meta['Summary']['PixelType'] == 'GRAY16'
13896
series = tif.series[0]
13897
assert 'NDTiff.index not found for' in caplog.text
13898
assert series.kind == 'generic' # not ndtiff
13899
assert series.dtype == numpy.uint16
13900
assert series.get_shape(False) == (112, 512, 512, 1)
13901
assert series.get_axes(False) == 'IYXS'
13902
data = series.asarray(squeeze=True)
13903
assert data.shape == (112, 512, 512)
13904
assert_aszarr_method(tif, data)
13908
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
13909
def test_read_ndtiff_multichannel():
13910
"""Test read NDTiffStorage v3 with channel names."""
13911
fname = private_file(
13912
'NDTiffStorage/v3/ndtiff3.2_multichannel'
13913
'/NDTiff3.2_multichannel_NDTiffStack.tif'
13915
with TiffFile(fname) as tif:
13916
assert tif.is_micromanager
13917
assert tif.is_ndtiff
13918
meta = tif.pages[-1].tags['MicroManagerMetadata'].value
13919
assert meta['Axes'] == {'channel': 'FITC', 'z': 15, 'time': 7}
13920
meta = tif.micromanager_metadata
13921
assert meta is not None
13922
assert meta['MajorVersion'] == 3
13923
assert meta['MinorVersion'] == 2
13924
assert meta['Summary']['PixelType'] == 'GRAY16'
13925
series = tif.series[0]
13926
assert series.kind == 'ndtiff'
13927
assert series.dtype == numpy.uint16
13928
assert series.shape == (8, 2, 16, 64, 64)
13929
assert series.axes == 'TCZYX'
13930
data = series.asarray()
13931
if not SKIP_NDTIFF:
13932
ndt = ndtiff.Dataset(os.path.dirname(fname))
13934
assert_array_equal(
13935
data, ndt.as_array(axes=['time', 'channel', 'z'])
13939
assert_aszarr_method(tif, data)
13943
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
13944
def test_read_zarr():
13945
"""Test read TIFF with zarr."""
13946
fname = public_file('imagecodecs/gray.u1.tif')
13947
with TiffFile(fname) as tif:
13948
image = tif.asarray()
13949
store = tif.aszarr()
13951
data = zarr.open(store, mode='r')
13952
assert_array_equal(image, data)
13958
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
13959
def test_read_zarr_lrucache():
13960
"""Test read TIFF with zarr LRUStoreCache."""
13961
# fails with zarr 2.15/16
13962
# https://github.com/zarr-developers/zarr-python/issues/1497
13963
fname = public_file('imagecodecs/gray.u1.tif')
13964
with TiffFile(fname) as tif:
13965
image = tif.asarray()
13966
store = tif.aszarr()
13968
cache = zarr.LRUStoreCache(store, max_size=2**10)
13969
data = zarr.open(cache, mode='r')
13970
assert_array_equal(image, data)
13976
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
13977
def test_read_zarr_multifile():
13978
"""Test read multifile OME-TIFF with zarr."""
13979
fname = public_file('OME/multifile/multifile-Z1.ome.tiff')
13980
with TiffFile(fname) as tif:
13981
image = tif.asarray()
13982
store = tif.aszarr()
13984
data = zarr.open(store, mode='r')
13985
assert_array_equal(image, data)
13991
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
13992
@pytest.mark.parametrize('multiscales', [None, False, True])
13993
def test_read_zarr_multiscales(multiscales):
13994
"""Test Zarr store multiscales parameter."""
13995
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
13996
with TiffFile(fname) as tif:
13997
page = tif.pages[1]
13998
series = tif.series[0]
13999
assert series.kind == 'ome'
14000
image = page.asarray()
14001
with page.aszarr(multiscales=multiscales) as store:
14002
z = zarr.open(store, mode='r')
14004
assert isinstance(z, zarr.Group)
14005
assert_array_equal(z[0][:], image)
14007
assert isinstance(z, zarr.Array)
14008
assert_array_equal(z[:], image)
14010
with series.aszarr(multiscales=multiscales) as store:
14011
z = zarr.open(store, mode='r')
14012
if multiscales or multiscales is None:
14013
assert isinstance(z, zarr.Group)
14014
assert_array_equal(z[0][0, 0, 1], image)
14016
assert isinstance(z, zarr.Array)
14017
assert_array_equal(z[0, 0, 1], image)
14021
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
14022
def test_read_zarr_level():
14023
"""Test Zarr store of level."""
14024
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
14025
data = imread(fname, key=1, series=0, level=2)
14026
store = imread(fname, key=1, series=0, level=2, aszarr=True)
14027
z = zarr.open(store, mode='r')
14030
assert_array_equal(image, data)
14033
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
14034
def test_read_eer(caplog):
14035
"""Test read EER metadata."""
14036
# https://github.com/fei-company/EerReaderLib/issues/1
14037
fname = private_file('EER/Example_1.eer')
14038
with TiffFile(fname) as tif:
14039
assert not caplog.text # no warning
14040
assert tif.is_bigtiff
14042
assert tif.byteorder == '<'
14043
assert len(tif.pages) == 238
14044
assert len(tif.series) == 1
14045
# assert page properties
14046
page = tif.pages.first
14047
assert not page.is_contiguous
14048
assert page.photometric == PHOTOMETRIC.MINISBLACK
14049
assert page.compression == 65001
14050
assert page.imagewidth == 4096
14051
assert page.imagelength == 4096
14052
assert page.bitspersample == 1
14053
assert page.samplesperpixel == 1
14054
meta = tif.eer_metadata
14055
assert meta.startswith('<metadata>')
14057
data = page.asarray()
14058
assert data.dtype == '?'
14059
assert data[428, 443]
14060
assert not data[428, 444]
14061
assert_aszarr_method(page, data)
14066
from imagecodecs.numcodecs import register_codecs
14067
except ImportError:
14069
register_codecs('imagecodecs_eer', verbose=False)
14070
filename = os.path.split(fname)[-1]
14071
url = URL + 'test/private/EER/'
14072
with TempFileName(filename, ext='.json') as jsonfile:
14073
with page.aszarr() as store:
14074
store.write_fsspec(jsonfile, url)
14075
# if this fails add ".eer" as "image/tiff" to mime types
14076
assert_fsspec(URL + os.path.split(jsonfile)[-1], data)
14079
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
14080
def test_read_astrotiff(caplog):
14081
"""Test read AstroTIFF with FITS metadata."""
14082
# https://astro-tiff.sourceforge.io/
14083
fname = private_file('AstroTIFF/NGC2024_astro-tiff_sample_48bit.tif')
14084
with TiffFile(fname) as tif:
14085
assert not caplog.text # no warning
14086
assert tif.is_astrotiff
14087
assert tif.byteorder == '<'
14088
assert len(tif.pages) == 1
14089
assert len(tif.series) == 1
14090
# assert page properties
14091
page = tif.pages.first
14092
assert not page.is_contiguous
14093
assert page.photometric == PHOTOMETRIC.RGB
14094
assert page.compression == COMPRESSION.ADOBE_DEFLATE
14095
assert page.imagewidth == 3040
14096
assert page.imagelength == 2016
14097
assert page.bitspersample == 16
14098
assert page.samplesperpixel == 3
14099
# assert data and metadata
14100
assert tuple(page.asarray()[545, 1540]) == (10401, 11804, 12058)
14101
meta = tif.astrotiff_metadata
14102
assert meta['SIMPLE']
14103
assert meta['APTDIA'] == 100.0
14104
assert meta['APTDIA:COMMENT'] == 'Aperture diameter of telescope in mm'
14108
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
14109
def test_read_streak():
14110
"""Test read Hamamatus Streak file."""
14111
fname = private_file('HamamatsuStreak/hamamatsu_streak.tif')
14112
with TiffFile(fname) as tif:
14113
assert tif.is_streak
14114
assert tif.byteorder == '<'
14115
assert len(tif.pages) == 1
14116
assert len(tif.series) == 1
14117
# assert page properties
14118
page = tif.pages.first
14119
assert page.is_contiguous
14120
assert page.photometric == PHOTOMETRIC.MINISBLACK
14121
assert page.imagewidth == 672
14122
assert page.imagelength == 508
14123
assert page.bitspersample == 16
14124
assert page.samplesperpixel == 1
14125
# assert data and metadata
14126
assert page.asarray()[277, 341] == 47
14127
meta = tif.streak_metadata
14128
assert meta['Application']['SoftwareVersion'] == '9.5 pf4'
14129
assert meta['Acquisition']['areSource'] == (0, 0, 672, 508)
14130
assert meta['Camera']['Prop_InternalLineInterval'] == 9.74436e-06
14131
assert meta['Camera']['Prop_OutputTriggerPeriod_2'] == 0.000001
14132
assert meta['Camera']['HWidth'] == 672
14133
assert meta['DisplayLUT']['EntrySize'] == 4
14134
assert meta['Spectrograph']['Front Ent. Slitw.'] == 0
14135
assert meta['Scaling']['ScalingYScalingFile'] == 'Focus mode'
14136
xscale = meta['Scaling']['ScalingXScaling']
14137
assert xscale.size == 672
14138
assert xscale[0] == 231.09092712402344
14139
assert xscale[-1] == 242.59259033203125
14143
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
14144
def test_read_agilent():
14145
"""Test read Agilent Technologies file."""
14146
fname = private_file('Agilent/SG11410002_253174651388_S001.tif')
14147
with TiffFile(fname) as tif:
14148
assert tif.is_agilent
14149
assert not tif.is_mdgel
14150
assert len(tif.pages) == 4
14151
assert len(tif.series) == 2
14152
# assert page properties
14153
page = tif.pages.first
14154
assert page.is_contiguous
14155
assert page.photometric == PHOTOMETRIC.MINISBLACK
14156
assert page.imagewidth == 20334
14157
assert page.imagelength == 7200
14158
assert page.bitspersample == 16
14159
assert page.samplesperpixel == 1
14160
assert page.tags[285].value == 'Red'
14161
assert page.tags[37702].value == 'Unknown'
14163
series = tif.series[0]
14164
assert series.shape == (2, 7200, 20334)
14165
assert series.asarray()[1, 277, 341] == 24
14166
series = tif.series[1]
14167
assert series.shape == (2, 2400, 6778)
14168
assert series.asarray()[1, 277, 341] == 634
14172
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
14173
@pytest.mark.parametrize('chunkmode', [0, 2])
14174
def test_read_selection(chunkmode):
14175
"""Test read selection via imread."""
14176
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
14177
selection = (8, slice(16, 17), slice(None), slice(51, 99), slice(51, 99))
14179
assert_array_equal(
14180
imread(fname)[8, 16:17, :, 51:99, 51:99],
14181
imread(fname, selection=selection, chunkmode=chunkmode),
14184
assert_array_equal(
14185
imread(fname, series=0, level=1)[8, 16:17, :, 51:99, 51:99],
14187
fname, series=0, level=1, selection=selection, chunkmode=chunkmode
14191
assert_array_equal(
14192
imread(fname, key=99)[51:99, 51:99],
14196
selection=(slice(51, 99), slice(51, 99)),
14197
chunkmode=chunkmode,
14201
assert_array_equal(
14202
imread(fname, series=1)[51:99, 51:99],
14206
selection=(slice(51, 99), slice(51, 99)),
14207
chunkmode=chunkmode,
14212
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
14213
@pytest.mark.parametrize('out', [None, 'empty', 'memmap', 'name'])
14214
def test_read_selection_out(out):
14215
"""Test read selection via imread into out."""
14216
# https://github.com/cgohlke/tifffile/pull/222
14217
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
14218
selection = (8, slice(16, 17), slice(None), slice(51, 99), slice(51, 99))
14219
expected = imread(fname)[8, 16:17, :, 51:99, 51:99]
14222
image = imread(fname, selection=selection, out=None)
14223
elif out == 'empty':
14225
image = numpy.empty_like(expected)
14226
imread(fname, selection=selection, out=image)
14227
elif out == 'memmap':
14228
# memmap in temp dir
14229
image = imread(fname, selection=selection, out='memmap')
14230
assert isinstance(image, numpy.memmap)
14231
elif out == 'name':
14232
# memmap in specified file
14233
with TempFileName('read_selection_out', ext='.memmap') as fileout:
14234
image = imread(fname, selection=selection, out=fileout)
14235
assert isinstance(image, numpy.memmap)
14237
assert_array_equal(image, expected)
14240
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
14241
def test_read_selection_filesequence():
14242
"""Test read selection from file sequence via imread."""
14243
fname = private_file('TiffSequence/*.tif')
14244
assert_array_equal(
14245
imread(fname)[5:8, 51:99, 51:99],
14246
imread(fname, selection=(slice(5, 8), slice(51, 99), slice(51, 99))),
14250
def test_read_xarray_page_properties():
14251
"""Test read TiffPage xarray properties."""
14252
dtype = numpy.uint8
14253
resolution = (1.1, 2.2)
14254
with TempFileName('read_xarray_page_properties') as fname:
14255
with TiffWriter(fname) as tif:
14260
resolution=resolution,
14261
photometric='minisblack',
14267
resolution=resolution,
14274
resolution=resolution,
14281
resolution=resolution,
14282
photometric='separated',
14284
# gray with extrasamples
14288
resolution=resolution,
14289
photometric='minisblack',
14290
planarconfig='contig',
14296
resolution=resolution,
14298
planarconfig='separate',
14304
resolution=resolution,
14305
photometric='minisblack',
14309
xcoords = numpy.linspace(
14310
0, 31 / resolution[0], 31, endpoint=False, dtype=numpy.float32
14312
ycoords = numpy.linspace(
14313
0, 33 / resolution[1], 33, endpoint=False, dtype=numpy.float32
14315
# zcoords = numpy.linspace(
14316
# 0, 7 / 1, 7, endpoint=False, dtype=numpy.float32
14318
with TiffFile(fname) as tif:
14320
page = tif.pages.first
14321
assert page.name == 'TiffPage 0'
14322
assert page.shape == (33, 31)
14323
assert page.ndim == 2
14324
assert page.axes == 'YX'
14325
assert page.dims == ('height', 'width')
14326
assert page.sizes == {'height': 33, 'width': 31}
14327
assert_array_equal(page.coords['height'], ycoords)
14328
assert_array_equal(page.coords['width'], xcoords)
14329
assert page.attr == {}
14332
page = tif.pages[1]
14333
assert page.name == 'TiffPage 1'
14334
assert page.shape == (33, 31, 3)
14335
assert page.ndim == 3
14336
assert page.axes == 'YXS'
14337
assert page.dims == ('height', 'width', 'sample')
14338
assert page.sizes == {'height': 33, 'width': 31, 'sample': 3}
14339
assert_array_equal(
14340
page.coords['sample'], numpy.array(['Red', 'Green', 'Blue'])
14342
assert_array_equal(page.coords['height'], ycoords)
14343
assert_array_equal(page.coords['width'], xcoords)
14346
page = tif.pages[2]
14347
assert page.name == 'TiffPage 2'
14348
assert page.shape == (33, 31, 4)
14349
assert page.ndim == 3
14350
assert page.axes == 'YXS'
14351
assert page.dims == ('height', 'width', 'sample')
14352
assert page.sizes == {'height': 33, 'width': 31, 'sample': 4}
14353
assert_array_equal(
14354
page.coords['sample'],
14355
numpy.array(['Red', 'Green', 'Blue', 'Unassalpha']),
14357
assert_array_equal(page.coords['height'], ycoords)
14358
assert_array_equal(page.coords['width'], xcoords)
14361
page = tif.pages[3]
14362
assert page.name == 'TiffPage 3'
14363
assert page.shape == (33, 31, 4)
14364
assert page.ndim == 3
14365
assert page.axes == 'YXS'
14366
assert page.dims == ('height', 'width', 'sample')
14367
assert page.sizes == {'height': 33, 'width': 31, 'sample': 4}
14368
assert_array_equal(
14369
page.coords['sample'],
14370
numpy.array(['Cyan', 'Magenta', 'Yellow', 'Black']),
14372
assert_array_equal(page.coords['height'], ycoords)
14373
assert_array_equal(page.coords['width'], xcoords)
14375
# gray with extrasamples
14376
page = tif.pages[4]
14377
assert page.name == 'TiffPage 4'
14378
assert page.shape == (33, 31, 5)
14379
assert page.ndim == 3
14380
assert page.axes == 'YXS'
14381
assert page.dims == ('height', 'width', 'sample')
14382
assert page.sizes == {'height': 33, 'width': 31, 'sample': 5}
14383
assert_array_equal(
14384
page.coords['sample'],
14387
assert_array_equal(page.coords['height'], ycoords)
14388
assert_array_equal(page.coords['width'], xcoords)
14391
page = tif.pages[5]
14392
assert page.name == 'TiffPage 5'
14393
assert page.shape == (3, 33, 31)
14394
assert page.ndim == 3
14395
assert page.axes == 'SYX'
14396
assert page.dims == ('sample', 'height', 'width')
14397
assert page.sizes == {'sample': 3, 'height': 33, 'width': 31}
14398
assert_array_equal(
14399
page.coords['sample'], numpy.array(['Red', 'Green', 'Blue'])
14401
assert_array_equal(page.coords['height'], ycoords)
14402
assert_array_equal(page.coords['width'], xcoords)
14405
page = tif.pages[6]
14406
assert page.name == 'TiffPage 6'
14407
assert page.shape == (7, 33, 31)
14408
assert page.ndim == 3
14409
assert page.axes == 'ZYX'
14410
assert page.dims == ('depth', 'height', 'width')
14411
assert page.sizes == {'depth': 7, 'height': 33, 'width': 31}
14412
assert_array_equal(page.coords['depth'], numpy.arange(7))
14413
assert_array_equal(page.coords['height'], ycoords)
14414
assert_array_equal(page.coords['width'], xcoords)
14417
###############################################################################
14421
WRITE_DATA = numpy.arange(3 * 219 * 301).astype(numpy.uint16)
14422
WRITE_DATA.shape = (3, 219, 301)
14425
@pytest.mark.skipif(SKIP_EXTENDED, reason=REASON)
14426
@pytest.mark.parametrize(
14440
(3, 4, 219, 301, 1),
14443
@pytest.mark.parametrize(
14444
'compression', [None] # , 'zlib', 'lzw', 'lzma', 'zstd', 'packbits']
14446
@pytest.mark.parametrize('dtype', list('?bhiqefdBHIQFD'))
14447
@pytest.mark.parametrize('byteorder', ['>', '<'])
14448
@pytest.mark.parametrize('bigtiff', ['plaintiff', 'bigtiff'])
14449
@pytest.mark.parametrize('tile', [None, (64, 64)])
14450
@pytest.mark.parametrize('data', ['random', None])
14451
def test_write(data, byteorder, bigtiff, compression, dtype, shape, tile):
14452
"""Test TiffWriter with various options."""
14453
if compression is not None and (data is None or SKIP_CODECS):
14454
pytest.xfail(REASON)
14455
fname = 'write_{}_{}_{}_{}{}{}{}'.format(
14457
{'<': 'le', '>': 'be'}[byteorder],
14458
numpy.dtype(dtype).name,
14459
str(shape).replace(' ', ''),
14460
'_tiled' if tile is not None else '',
14461
'_empty' if data is None else '',
14462
f'_{compression}' if compression is not None else '',
14464
bigtiff = bigtiff == 'bigtiff'
14465
if (3 in shape or 4 in shape) and shape[-1] != 1 and dtype != '?':
14466
photometric = 'rgb'
14470
with TempFileName(fname) as fname:
14473
fname, byteorder=byteorder, bigtiff=bigtiff
14476
# cannot write non-contiguous empty file
14477
with pytest.raises(ValueError):
14482
photometric=photometric,
14489
photometric=photometric,
14491
assert__repr__(tif)
14492
with TiffFile(fname) as tif:
14494
image = tif.asarray()
14496
data = random_data(dtype, shape)
14500
byteorder=byteorder,
14503
photometric=photometric,
14504
compression=compression,
14506
image = imread(fname)
14507
assert image.flags['C_CONTIGUOUS']
14508
assert_array_equal(data.squeeze(), image.squeeze())
14510
with imread(fname, aszarr=True) as store:
14511
data = zarr.open(store, mode='r')
14512
assert_array_equal(data, image)
14514
assert shape == image.shape
14515
assert dtype == image.dtype
14517
assert_valid_tiff(fname)
14520
def test_write_deprecated_planarconfig():
14521
"""Test deprecated planarconfig."""
14522
with TempFileName('write_deprecated_planarconfig_contig') as fname:
14523
with pytest.warns(DeprecationWarning):
14524
imwrite(fname, shape=(31, 33, 3), dtype=numpy.float32)
14525
with TiffFile(fname) as tif:
14526
page = tif.pages.first
14527
assert page.photometric == PHOTOMETRIC.RGB
14528
assert page.planarconfig == PLANARCONFIG.CONTIG
14530
with TempFileName('write_deprecated_planarconfig_separate') as fname:
14531
with pytest.warns(DeprecationWarning):
14532
imwrite(fname, shape=(3, 31, 33), dtype=numpy.float32)
14533
with TiffFile(fname) as tif:
14534
page = tif.pages.first
14535
assert page.photometric == PHOTOMETRIC.RGB
14536
assert page.planarconfig == PLANARCONFIG.SEPARATE
14539
def test_write_ycbcr_subsampling(caplog):
14540
"""Test write YCBCR."""
14541
with TempFileName('write_ycbcr_subsampling') as fname:
14546
photometric=PHOTOMETRIC.YCBCR,
14547
subsampling=(1, 2),
14549
assert 'cannot apply subsampling' in caplog.text
14550
with TiffFile(fname) as tif:
14551
page = tif.pages.first
14552
assert page.photometric == PHOTOMETRIC.YCBCR
14553
assert page.subsampling == (1, 1)
14554
assert 'ReferenceBlackWhite' in page.tags
14557
@pytest.mark.parametrize('samples', [0, 1, 2])
14558
def test_write_invalid_samples(samples):
14559
"""Test TiffWriter with invalid options."""
14560
data = numpy.zeros((16, 16, samples) if samples else (16, 16), numpy.uint8)
14561
fname = f'write_invalid_samples{samples}'
14562
with TempFileName(fname) as fname:
14563
with pytest.raises(ValueError):
14564
imwrite(fname, data, photometric='rgb')
14567
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
14568
@pytest.mark.parametrize('tile', [False, True])
14569
@pytest.mark.parametrize(
14585
@pytest.mark.parametrize('mode', ['gray', 'rgb', 'planar'])
14586
def test_write_codecs(mode, tile, codec):
14587
"""Test write various compression."""
14588
if mode in {'gray', 'planar'} and codec == 'webp':
14589
pytest.xfail("WebP doesn't support grayscale or planar mode")
14590
level = {'webp': -1, 'jpeg': 99}.get(codec, None)
14592
compressionargs = {'level': level}
14594
compressionargs = None
14595
tile = (16, 16) if tile else None
14596
data = numpy.load(public_file('tifffile/rgb.u1.npy'))
14598
photometric = PHOTOMETRIC.RGB
14599
planarconfig = PLANARCONFIG.CONTIG
14600
elif mode == 'planar':
14601
photometric = PHOTOMETRIC.RGB
14602
planarconfig = PLANARCONFIG.SEPARATE
14603
data = numpy.moveaxis(data, -1, 0).copy()
14605
planarconfig = None
14606
photometric = PHOTOMETRIC.MINISBLACK
14607
data = data[..., :1].copy()
14608
data = numpy.repeat(data[numpy.newaxis], 3, axis=0)
14609
data[1] = 255 - data[1]
14612
'write_codecs_{}_{}{}'.format(mode, codec, '_tile' if tile else '')
14618
compressionargs=compressionargs,
14620
photometric=photometric,
14621
planarconfig=planarconfig,
14622
subsampling=(1, 1),
14624
assert_valid_tiff(fname)
14625
with TiffFile(fname) as tif:
14626
assert len(tif.pages) == shape[0]
14627
page = tif.pages.first
14628
assert not page.is_contiguous
14629
assert page.compression == enumarg(COMPRESSION, codec)
14630
assert page.photometric in {photometric, PHOTOMETRIC.YCBCR}
14631
if planarconfig is not None:
14632
assert page.planarconfig == planarconfig
14633
assert page.imagewidth == 31
14634
assert page.imagelength == 32
14635
assert page.samplesperpixel == 1 if mode == 'gray' else 3
14636
# samplesperpixel = page.samplesperpixel
14637
image = tif.asarray()
14638
if codec == 'jpeg':
14639
assert_allclose(data, image, atol=10)
14641
assert_array_equal(data, image)
14642
assert_decode_method(page)
14645
imagecodecs.TIFF.available
14646
and codec not in {'png', 'jpegxr', 'jpeg2000', 'jpegxl'}
14647
and mode != 'planar'
14649
im = imagecodecs.imread(fname, index=None)
14650
# if codec == 'jpeg':
14651
# # tiff_decode returns JPEG compressed TIFF as RGBA
14652
# im = numpy.squeeze(im[..., :samplesperpixel])
14653
assert_array_equal(im, numpy.squeeze(image))
14656
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
14657
@pytest.mark.parametrize('mode', ['gray', 'rgb', 'planar'])
14658
@pytest.mark.parametrize('tile', [False, True])
14659
@pytest.mark.parametrize(
14660
'dtype', ['u1', 'u2', 'u4', 'i1', 'i2', 'i4', 'f2', 'f4', 'f8']
14662
@pytest.mark.parametrize('byteorder', ['>', '<'])
14663
def test_write_predictor(byteorder, dtype, tile, mode):
14664
"""Test predictors."""
14665
if dtype[0] == 'f' and SKIP_CODECS:
14666
pytest.xfail('requires imagecodecs')
14667
tile = (32, 32) if tile else None
14668
f4 = imread(public_file('tifffile/gray.f4.tif'))
14670
photometric = PHOTOMETRIC.RGB
14671
planarconfig = PLANARCONFIG.CONTIG
14672
data = numpy.empty((83, 111, 3), 'f4')
14674
data[..., 1] = f4[::-1]
14675
data[..., 2] = f4[::-1, ::-1]
14676
elif mode == 'planar':
14677
photometric = PHOTOMETRIC.RGB
14678
planarconfig = PLANARCONFIG.SEPARATE
14679
data = numpy.empty((3, 83, 111), 'f4')
14682
data[2] = f4[::-1, ::-1]
14684
planarconfig = None
14685
photometric = PHOTOMETRIC.MINISBLACK
14688
if dtype[0] in 'if':
14690
if dtype in 'u1i1':
14692
elif dtype in 'i2u2':
14694
elif dtype in 'i4u4':
14698
data = data.astype(byteorder + dtype)
14701
'write_predictor_{}_{}_{}{}'.format(
14703
'be' if byteorder == '>' else 'le',
14705
'_tile' if tile else '',
14712
compression=COMPRESSION.ADOBE_DEFLATE,
14714
photometric=photometric,
14715
planarconfig=planarconfig,
14716
byteorder=byteorder,
14718
assert_valid_tiff(fname)
14720
with TiffFile(fname) as tif:
14721
assert tif.tiff.byteorder == byteorder
14722
assert len(tif.pages) == 1
14723
page = tif.pages.first
14724
assert not page.is_contiguous
14725
assert page.compression == COMPRESSION.ADOBE_DEFLATE
14726
assert page.predictor == (3 if dtype[0] == 'f' else 2)
14727
assert page.photometric == photometric
14728
if planarconfig is not None:
14729
assert page.planarconfig == planarconfig
14730
assert page.imagewidth == 111
14731
assert page.imagelength == 83
14732
assert page.samplesperpixel == 1 if mode == 'gray' else 3
14733
# samplesperpixel = page.samplesperpixel
14734
image = tif.asarray()
14735
assert_array_equal(data, image)
14736
assert_decode_method(page)
14739
if not SKIP_CODECS and imagecodecs.TIFF.available:
14740
im = imagecodecs.imread(fname, index=None)
14741
assert_array_equal(im, numpy.squeeze(image))
14744
@pytest.mark.parametrize('bytecount', [16, 256])
14745
@pytest.mark.parametrize('count', [1, 2, 4])
14746
@pytest.mark.parametrize('compression', [0, 6])
14747
@pytest.mark.parametrize('tiled', [0, 1])
14748
@pytest.mark.parametrize('bigtiff', [0, 1])
14749
def test_write_bytecount(bigtiff, tiled, compression, count, bytecount):
14750
"""Test write bytecount formats."""
14752
tag = 'TileByteCounts'
14753
rowsperstrip = None
14754
tile = (bytecount, bytecount)
14756
1: (bytecount, bytecount),
14757
2: (bytecount * 2, bytecount),
14758
4: (bytecount * 2, bytecount * 2),
14760
is_contiguous = count != 4 and compression == 0
14762
tag = 'StripByteCounts'
14764
rowsperstrip = bytecount
14765
shape = (bytecount * count, bytecount)
14766
is_contiguous = compression == 0
14767
data = random_data(numpy.uint8, shape)
14770
dtype = DATATYPE.LONG8 if bigtiff else DATATYPE.LONG
14771
elif bytecount == 256:
14772
dtype = DATATYPE.LONG
14774
dtype = DATATYPE.SHORT
14777
'write_bytecounts_{}{}{}{}{}'.format(
14778
bigtiff, tiled, compression, count, bytecount
14786
compression=COMPRESSION.ADOBE_DEFLATE if compression else None,
14787
compressionargs={'level': compression} if compression else None,
14788
rowsperstrip=rowsperstrip,
14791
assert_valid_tiff(fname)
14792
with TiffFile(fname) as tif:
14793
assert len(tif.pages) == 1
14794
page = tif.pages.first
14795
assert page.tags[tag].count == count
14796
assert page.tags[tag].dtype == dtype
14797
assert page.is_contiguous == is_contiguous
14798
assert page.planarconfig == PLANARCONFIG.CONTIG
14799
assert page.photometric == PHOTOMETRIC.MINISBLACK
14800
assert page.imagewidth == shape[1]
14801
assert page.imagelength == shape[0]
14802
assert page.samplesperpixel == 1
14803
assert_array_equal(page.asarray(), data)
14804
assert_aszarr_method(page, data)
14808
@pytest.mark.skipif(SKIP_EXTENDED, reason=REASON)
14809
@pytest.mark.parametrize('repeat', [1, 4])
14810
@pytest.mark.parametrize('shape', [(1, 0), (0, 1), (3, 0, 2, 1)])
14811
@pytest.mark.parametrize('data', ['random', 'empty'])
14812
@pytest.mark.parametrize('shaped', [True, False])
14813
def test_write_zeroshape(shaped, data, repeat, shape):
14814
"""Test write arrays with zero shape."""
14815
dtype = numpy.uint8
14816
fname = 'write_shape_{}x{}{}{}'.format(
14818
str(shape).replace(' ', ''),
14819
'_shaped' if shaped else '',
14820
'_empty' if data == 'empty' else '',
14822
metadata = {} if shaped else None
14824
with TempFileName(fname) as fname:
14825
if data == 'empty':
14826
with TiffWriter(fname) as tif:
14827
with pytest.warns(UserWarning):
14828
for _ in range(repeat):
14835
tif.write(numpy.zeros((16, 16), 'u2'), metadata=metadata)
14836
with TiffFile(fname) as tif:
14838
image = zimage = tif.asarray()
14840
zimage = zarr.open(tif.aszarr(), mode='r')
14842
data = random_data(dtype, shape)
14843
with TiffWriter(fname) as tif:
14844
with pytest.warns(UserWarning):
14845
for _ in range(repeat):
14846
tif.write(data, contiguous=True, metadata=metadata)
14847
tif.write(numpy.zeros((16, 16), 'u2'), metadata=metadata)
14848
with TiffFile(fname) as tif:
14850
image = zimage = tif.asarray()
14852
zimage = zarr.open(tif.aszarr(), mode='r')
14854
assert image.flags['C_CONTIGUOUS']
14857
for i in range(repeat):
14858
assert_array_equal(image[i], data)
14859
assert_array_equal(zimage[i], data)
14861
assert_array_equal(image, data)
14862
assert_array_equal(zimage, data)
14864
empty = numpy.empty((0, 0), dtype)
14866
for i in range(repeat):
14867
assert_array_equal(image[i], empty)
14868
assert_array_equal(zimage[i], empty)
14870
assert_array_equal(image.squeeze(), empty)
14871
# assert_array_equal(zimage.squeeze(), empty)
14874
assert image.shape[0] == repeat
14875
assert zimage.shape[0] == repeat
14877
assert shape == image.shape
14878
assert shape == zimage.shape
14880
assert image.shape == (0, 0)
14881
assert zimage.shape == (0, 0)
14882
assert dtype == image.dtype
14883
assert dtype == zimage.dtype
14886
@pytest.mark.parametrize('repeats', [1, 2])
14887
@pytest.mark.parametrize('series', [1, 2])
14888
@pytest.mark.parametrize('subifds', [0, 1, 2])
14889
@pytest.mark.parametrize('compressed', [False, True])
14890
@pytest.mark.parametrize('tiled', [False, True])
14891
@pytest.mark.parametrize('ome', [False, True])
14892
def test_write_subidfs(ome, tiled, compressed, series, repeats, subifds):
14893
"""Test write SubIFDs."""
14894
# use BigTIFF to prevent Windows explorer from locking the file
14895
if repeats > 1 and (compressed or tiled or ome):
14896
pytest.xfail('contiguous not working with compression, tiles, ome')
14899
(numpy.random.rand(5, 64, 64) * 1023).astype(numpy.uint16),
14900
(numpy.random.rand(5, 32, 32) * 1023).astype(numpy.uint16),
14901
(numpy.random.rand(5, 16, 16) * 1023).astype(numpy.uint16),
14905
'tile': (16, 16) if tiled else None,
14906
'compression': COMPRESSION.ADOBE_DEFLATE if compressed else None,
14907
'compressionargs': {'level': 6} if compressed else None,
14912
f'{ome}-{tiled}-{compressed}-{subifds}-{series}-{repeats}'
14914
with TiffWriter(fname, ome=ome, bigtiff=True) as tif:
14915
for _ in range(series):
14916
for r in range(repeats):
14917
kwargs['contiguous'] = r != 0
14918
tif.write(data[0], subifds=subifds, **kwargs)
14919
for i in range(1, subifds + 1):
14920
for r in range(repeats):
14921
kwargs['contiguous'] = r != 0
14922
tif.write(data[i], subfiletype=1, **kwargs)
14924
with TiffFile(fname) as tif:
14925
for i, page in enumerate(tif.pages):
14926
assert not page.is_subifd
14927
if i % (5 * repeats):
14928
assert page.description == ''
14933
assert page.description == ''
14935
assert page.is_shaped
14937
assert_array_equal(page.asarray(), data[0][i % 5])
14938
assert_aszarr_method(page, data[0][i % 5])
14940
assert len(page.pages) == subifds
14941
for j, subifd in enumerate(page.pages):
14942
assert subifd.is_subifd
14943
assert_array_equal(
14944
subifd.asarray(), data[j + 1][i % 5]
14946
assert_aszarr_method(subifd, data[j + 1][i % 5])
14948
assert page.pages is None
14950
for i, page in enumerate(tif.pages[:-1]):
14951
assert page._nextifd() == tif.pages[i + 1].offset
14954
for j, subifd in enumerate(page.pages[:-1]):
14955
assert subifd.is_subifd
14956
assert subifd.subfiletype == FILETYPE.REDUCEDIMAGE
14957
assert subifd._nextifd() == page.subifds[j + 1]
14958
assert page.pages[-1]._nextifd() == 0
14960
assert page.pages is None
14962
assert len(tif.series) == series
14965
for s in range(series):
14966
assert tif.series[s].kind == 'ome' if ome else 'shaped'
14967
assert_array_equal(tif.series[s].asarray()[0], data[0])
14968
for i in range(subifds):
14969
assert_array_equal(
14970
tif.series[s].levels[i + 1].asarray()[0],
14974
for s in range(series):
14975
assert tif.series[s].kind == 'ome' if ome else 'shaped'
14976
assert_array_equal(tif.series[s].asarray(), data[0])
14977
for i in range(subifds):
14978
assert_array_equal(
14979
tif.series[s].levels[i + 1].asarray(), data[i + 1]
14983
def test_write_lists():
14984
"""Test write lists."""
14985
array = numpy.arange(1000).reshape(10, 10, 10).astype(numpy.uint16)
14986
data = array.tolist()
14987
with TempFileName('write_lists') as fname:
14988
with TiffWriter(fname) as tif:
14989
tif.write(data, dtype=numpy.uint16)
14990
tif.write(data, compression=COMPRESSION.ADOBE_DEFLATE)
14992
with pytest.warns(UserWarning):
14994
with TiffFile(fname) as tif:
14995
assert_array_equal(tif.series[0].asarray(), array)
14996
assert_array_equal(tif.series[1].asarray(), array)
14997
assert_array_equal(tif.series[2].asarray(), [100.0])
14998
assert_array_equal(tif.series[3].asarray(), [])
14999
assert_aszarr_method(tif.series[0], array)
15000
assert_aszarr_method(tif.series[1], array)
15001
assert_aszarr_method(tif.series[2], [100.0])
15002
# assert_aszarr_method(tif.series[3], [])
15005
def test_write_nopages():
15006
"""Test write TIFF with no pages."""
15007
with TempFileName('write_nopages') as fname:
15008
with TiffWriter(fname) as tif:
15010
with TiffFile(fname) as tif:
15011
assert len(tif.pages) == 0
15013
if not SKIP_VALIDATE:
15014
with pytest.raises(ValueError):
15015
assert_valid_tiff(fname)
15018
def test_write_append_not_exists():
15019
"""Test append to non existing file."""
15020
with TempFileName('write_append_not_exists.bin') as fname:
15021
# with self.assertRaises(ValueError):
15022
with TiffWriter(fname, append=True):
15026
def test_write_append_nontif():
15027
"""Test fail to append to non-TIFF file."""
15028
with TempFileName('write_append_nontif.bin') as fname:
15029
with open(fname, 'wb') as fh:
15030
fh.write(b'not a TIFF file')
15031
with pytest.raises(TiffFileError):
15032
with TiffWriter(fname, append=True):
15036
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
15037
def test_write_append_lsm():
15038
"""Test fail to append to LSM file."""
15039
fname = private_file('lsm/take1.lsm')
15040
with pytest.raises(ValueError):
15041
with TiffWriter(fname, append=True):
15045
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
15046
def test_write_append_create():
15047
"""Test append to non-existing file."""
15048
with TempFileName('write_append_create') as fname:
15049
if os.path.exists(fname):
15051
with TiffWriter(fname, append=True) as tif:
15052
tif.write(shape=(31, 33), dtype=numpy.uint8)
15053
data = imread(fname)
15054
assert data.shape == (31, 33)
15057
def test_write_append_imwrite():
15058
"""Test append using imwrite."""
15059
data = random_data(numpy.uint8, (21, 31))
15060
with TempFileName('write_imwrite_append') as fname:
15061
imwrite(fname, data, metadata=None)
15063
imwrite(fname, data, append=True, metadata=None)
15065
assert a.shape == (4, 21, 31)
15066
assert_array_equal(a[3], data)
15069
def test_write_append():
15070
"""Test append to existing TIFF file."""
15071
data = random_data(numpy.uint8, (21, 31))
15072
with TempFileName('write_append') as fname:
15073
with TiffWriter(fname) as tif:
15075
with TiffFile(fname) as tif:
15076
assert len(tif.pages) == 0
15079
with TiffWriter(fname, append=True) as tif:
15081
with TiffFile(fname) as tif:
15082
assert len(tif.series) == 1
15083
assert len(tif.pages) == 1
15084
page = tif.pages.first
15085
assert page.imagewidth == 31
15086
assert page.imagelength == 21
15089
with TiffWriter(fname, append=True) as tif:
15091
tif.write(data, contiguous=True)
15092
with TiffFile(fname) as tif:
15093
assert len(tif.series) == 2
15094
assert len(tif.pages) == 3
15095
page = tif.pages.first
15096
assert page.imagewidth == 31
15097
assert page.imagelength == 21
15098
assert_array_equal(tif.asarray(series=1)[1], data)
15101
assert_valid_tiff(fname)
15104
def test_write_append_bytesio():
15105
"""Test append to existing TIFF file in BytesIO."""
15106
data = random_data(numpy.uint8, (21, 31))
15109
file.write(b'a' * offset)
15111
with TiffWriter(file) as tif:
15114
with TiffFile(file) as tif:
15115
assert len(tif.pages) == 0
15118
with TiffWriter(file, append=True) as tif:
15121
with TiffFile(file) as tif:
15122
assert len(tif.series) == 1
15123
assert len(tif.pages) == 1
15124
page = tif.pages.first
15125
assert page.imagewidth == 31
15126
assert page.imagelength == 21
15130
with TiffWriter(file, append=True) as tif:
15132
tif.write(data, contiguous=True)
15134
with TiffFile(file) as tif:
15135
assert len(tif.series) == 2
15136
assert len(tif.pages) == 3
15137
page = tif.pages.first
15138
assert page.imagewidth == 31
15139
assert page.imagelength == 21
15140
assert_array_equal(tif.asarray(series=1)[1], data)
15144
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
15145
def test_write_roundtrip_filename():
15146
"""Test write and read using file name."""
15147
data = imread(public_file('tifffile/generic_series.tif'))
15148
with TempFileName('write_roundtrip_filename') as fname:
15149
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
15150
assert_array_equal(imread(fname), data)
15153
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
15154
def test_write_roundtrip_openfile():
15155
"""Test write and read using open file."""
15157
data = imread(public_file('tifffile/generic_series.tif'))
15158
with TempFileName('write_roundtrip_openfile') as fname:
15159
with open(fname, 'wb') as fh:
15161
imwrite(fh, data, photometric=PHOTOMETRIC.RGB)
15163
with open(fname, 'rb') as fh:
15165
assert_array_equal(imread(fh), data)
15168
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
15169
def test_write_roundtrip_bytesio():
15170
"""Test write and read using BytesIO."""
15172
data = imread(public_file('tifffile/generic_series.tif'))
15175
imwrite(buf, data, photometric=PHOTOMETRIC.RGB)
15178
assert_array_equal(imread(buf), data)
15181
def test_write_pages():
15182
"""Test write tags for contiguous data in all pages."""
15183
data = random_data(numpy.float32, (17, 219, 301))
15184
with TempFileName('write_pages') as fname:
15185
imwrite(fname, data, photometric=PHOTOMETRIC.MINISBLACK)
15186
assert_valid_tiff(fname)
15188
with TiffFile(fname) as tif:
15189
assert len(tif.pages) == 17
15190
for i, page in enumerate(tif.pages):
15191
assert page.is_contiguous
15192
assert page.planarconfig == PLANARCONFIG.CONTIG
15193
assert page.photometric == PHOTOMETRIC.MINISBLACK
15194
assert page.imagewidth == 301
15195
assert page.imagelength == 219
15196
assert page.samplesperpixel == 1
15197
image = page.asarray()
15198
assert_array_equal(data[i], image)
15200
series = tif.series[0]
15201
assert series.kind == 'shaped'
15202
assert series.dataoffset is not None
15203
image = series.asarray()
15204
assert_array_equal(data, image)
15208
def test_write_truncate():
15209
"""Test only one page is written for truncated files."""
15210
shape = (4, 5, 6, 1)
15211
with TempFileName('write_truncate') as fname:
15212
imwrite(fname, random_data(numpy.uint8, shape), truncate=True)
15213
assert_valid_tiff(fname)
15214
with TiffFile(fname) as tif:
15215
assert len(tif.pages) == 1 # not 4
15216
page = tif.pages.first
15217
assert page.is_shaped
15218
assert page.shape == (5, 6)
15219
assert '"shape": [4, 5, 6, 1]' in page.description
15220
assert '"truncated": true' in page.description
15221
series = tif.series[0]
15222
assert series.is_truncated
15223
assert series.kind == 'shaped'
15224
assert series.shape == shape
15225
assert len(series._pages) == 1
15226
assert len(series.pages) == 1
15227
data = tif.asarray()
15228
assert data.shape == shape
15229
assert_aszarr_method(tif, data)
15230
assert_aszarr_method(tif, data, chunkmode='page')
15234
def test_write_is_shaped():
15235
"""Test files are written with shape."""
15236
with TempFileName('write_is_shaped') as fname:
15239
random_data(numpy.uint8, (4, 5, 6, 3)),
15240
photometric=PHOTOMETRIC.RGB,
15242
assert_valid_tiff(fname)
15243
with TiffFile(fname) as tif:
15244
assert len(tif.pages) == 4
15245
page = tif.pages.first
15246
assert page.is_shaped
15247
assert page.description == '{"shape": [4, 5, 6, 3]}'
15249
with TempFileName('write_is_shaped_with_description') as fname:
15250
descr = 'test is_shaped_with_description'
15253
random_data(numpy.uint8, (5, 6, 3)),
15254
photometric=PHOTOMETRIC.RGB,
15257
assert_valid_tiff(fname)
15258
with TiffFile(fname) as tif:
15259
assert len(tif.pages) == 1
15260
page = tif.pages.first
15261
assert page.is_shaped
15262
assert page.description == descr
15263
assert_aszarr_method(page)
15264
assert_aszarr_method(page, chunkmode='page')
15268
def test_write_bytes_str():
15269
"""Test write bytes in place of 7-bit ascii string."""
15270
micron = b'micron \xB5' # can't be encoded as 7-bit ascii
15271
data = numpy.arange(4, dtype=numpy.uint32).reshape((2, 2))
15272
with TempFileName('write_bytes_str') as fname:
15276
description=micron,
15278
extratags=[(50001, 's', 8, micron, True)],
15280
with TiffFile(fname) as tif:
15281
page = tif.pages.first
15282
assert page.description == 'micron \xB5'
15283
assert page.software == 'micron \xB5'
15284
assert page.tags[50001].value == 'micron \xB5'
15287
def test_write_extratags():
15288
"""Test write extratags."""
15289
data = random_data(numpy.uint8, (2, 219, 301))
15290
description = 'Created by TestTiffWriter\nLorem ipsum dolor...'
15291
pagename = 'Page name'
15293
('ImageDescription', 's', 0, description, True),
15294
('PageName', 's', 0, pagename, False),
15295
(50001, 'b', 1, b'1', True),
15296
(50002, 'b', 2, b'12', True),
15297
(50004, 'b', 4, b'1234', True),
15298
(50008, 'B', 8, b'12345678', True),
15300
with TempFileName('write_extratags') as fname:
15301
imwrite(fname, data, extratags=extratags)
15302
assert_valid_tiff(fname)
15303
with TiffFile(fname) as tif:
15304
assert len(tif.pages) == 2
15305
assert tif.pages.first.description1 == description
15306
assert 'ImageDescription' not in tif.pages[1].tags
15307
assert tif.pages.first.tags['PageName'].value == pagename
15308
assert tif.pages[1].tags['PageName'].value == pagename
15309
assert '50001' not in tif.pages[1].tags
15310
tags = tif.pages.first.tags
15311
assert tags['50001'].value == 49
15312
assert tags['50002'].value == (49, 50)
15313
assert tags['50004'].value == (49, 50, 51, 52)
15314
assert_array_equal(tags['50008'].value, b'12345678')
15315
# (49, 50, 51, 52, 53, 54, 55, 56))
15319
def test_write_double_tags():
15320
"""Test write single and sequences of doubles."""
15321
# older versions of tifffile do not use offset to write doubles
15322
# reported by Eric Prestat on Feb 21, 2016
15323
data = random_data(numpy.uint8, (8, 8))
15326
(34563, 'd', 1, value, False),
15327
(34564, 'd', 1, (value,), False),
15328
(34565, 'd', 2, (value, value), False),
15329
(34566, 'd', 2, [value, value], False),
15330
(34567, 'd', 2, numpy.array((value, value)), False),
15332
with TempFileName('write_double_tags') as fname:
15333
imwrite(fname, data, extratags=extratags)
15334
assert_valid_tiff(fname)
15335
with TiffFile(fname) as tif:
15336
assert len(tif.pages) == 1
15337
tags = tif.pages.first.tags
15338
assert tags['34563'].value == value
15339
assert tags['34564'].value == value
15340
assert tuple(tags['34565'].value) == (value, value)
15341
assert tuple(tags['34566'].value) == (value, value)
15342
assert tuple(tags['34567'].value) == (value, value)
15345
with TempFileName('write_double_tags_bigtiff') as fname:
15346
imwrite(fname, data, bigtiff=True, extratags=extratags)
15347
# assert_jhove(fname)
15348
with TiffFile(fname) as tif:
15349
assert len(tif.pages) == 1
15350
tags = tif.pages.first.tags
15351
assert tags['34563'].value == value
15352
assert tags['34564'].value == value
15353
assert tuple(tags['34565'].value) == (value, value)
15354
assert tuple(tags['34566'].value) == (value, value)
15355
assert tuple(tags['34567'].value) == (value, value)
15359
def test_write_short_tags():
15360
"""Test write single and sequences of words."""
15361
data = random_data(numpy.uint8, (8, 8))
15364
(34564, 'H', 1, (value,) * 1, False),
15365
(34565, 'H', 2, (value,) * 2, False),
15366
(34566, 'H', 3, (value,) * 3, False),
15367
(34567, 'H', 4, (value,) * 4, False),
15369
with TempFileName('write_short_tags') as fname:
15370
imwrite(fname, data, extratags=extratags)
15371
assert_valid_tiff(fname)
15372
with TiffFile(fname) as tif:
15373
assert len(tif.pages) == 1
15374
tags = tif.pages.first.tags
15375
assert tags['34564'].value == value
15376
assert tuple(tags['34565'].value) == (value,) * 2
15377
assert tuple(tags['34566'].value) == (value,) * 3
15378
assert tuple(tags['34567'].value) == (value,) * 4
15382
@pytest.mark.parametrize('subfiletype', [0b1, 0b10, 0b100, 0b1000, 0b1111])
15383
def test_write_subfiletype(subfiletype):
15384
"""Test write subfiletype."""
15385
data = random_data(numpy.uint8, (16, 16))
15386
if subfiletype & 0b100:
15387
data = data.astype('bool')
15388
with TempFileName(f'write_subfiletype_{subfiletype}') as fname:
15389
imwrite(fname, data, subfiletype=subfiletype)
15390
assert_valid_tiff(fname)
15391
with TiffFile(fname) as tif:
15392
page = tif.pages.first
15393
assert page.subfiletype == subfiletype
15394
assert page.is_reduced == bool(subfiletype & 0b1)
15395
assert page.is_multipage == bool(subfiletype & 0b10)
15396
assert page.is_mask == bool(subfiletype & 0b100)
15397
assert page.is_mrc == bool(subfiletype & 0b1000)
15398
assert_array_equal(data, page.asarray())
15402
@pytest.mark.parametrize('dt', [None, True, datetime, '2019:01:30 04:05:37'])
15403
def test_write_datetime_tag(dt):
15404
"""Test write datetime tag."""
15407
arg = datetime.datetime.now().replace(microsecond=0)
15408
data = random_data(numpy.uint8, (31, 32))
15409
with TempFileName('write_datetime') as fname:
15410
imwrite(fname, data, datetime=arg)
15411
with TiffFile(fname) as tif:
15412
page = tif.pages.first
15414
assert 'DateTime' not in page.tags
15415
assert page.datetime is None
15417
dt = datetime.datetime.now().strftime('%Y:%m:%d %H:')
15418
assert page.tags['DateTime'].value.startswith(dt)
15419
elif dt is datetime:
15420
assert page.tags['DateTime'].value == arg.strftime(
15421
'%Y:%m:%d %H:%M:%S'
15423
assert page.datetime == arg
15425
assert page.tags['DateTime'].value == dt
15426
assert page.datetime == datetime.datetime.strptime(
15427
dt, '%Y:%m:%d %H:%M:%S'
15432
def test_write_software_tag():
15433
"""Test write Software tag."""
15434
data = random_data(numpy.uint8, (2, 219, 301))
15435
software = 'test_tifffile.py'
15436
with TempFileName('write_software_tag') as fname:
15437
imwrite(fname, data, software=software)
15438
assert_valid_tiff(fname)
15439
with TiffFile(fname) as tif:
15440
assert len(tif.pages) == 2
15441
assert tif.pages.first.software == software
15442
assert 'Software' not in tif.pages[1].tags
15446
def test_write_description_tag():
15447
"""Test write two description tags."""
15448
data = random_data(numpy.uint8, (2, 219, 301))
15449
description = 'Created by TestTiffWriter\nLorem ipsum dolor...'
15450
with TempFileName('write_description_tag') as fname:
15451
imwrite(fname, data, description=description)
15452
assert_valid_tiff(fname)
15453
with TiffFile(fname) as tif:
15454
assert len(tif.pages) == 2
15455
assert tif.pages.first.description == description
15456
assert tif.pages.first.description1 == '{"shape": [2, 219, 301]}'
15457
assert 'ImageDescription' not in tif.pages[1].tags
15461
def test_write_description_tag_nometadata():
15462
"""Test no JSON description is written with metatata=None."""
15463
data = random_data(numpy.uint8, (2, 219, 301))
15464
description = 'Created by TestTiffWriter\nLorem ipsum dolor...'
15465
with TempFileName('write_description_tag_nometadatan') as fname:
15466
imwrite(fname, data, description=description, metadata=None)
15467
assert_valid_tiff(fname)
15468
with TiffFile(fname) as tif:
15469
assert len(tif.pages) == 2
15470
assert tif.pages.first.description == description
15471
assert 'ImageDescription' not in tif.pages[1].tags
15473
tif.pages.first.tags.get('ImageDescription', index=1) is None
15475
assert tif.series[0].kind == 'generic'
15479
def test_write_description_tag_notshaped():
15480
"""Test no JSON description is written with shaped=False."""
15481
data = random_data(numpy.uint8, (2, 219, 301))
15482
description = 'Created by TestTiffWriter\nLorem ipsum dolor...'
15483
with TempFileName('write_description_tag_notshaped') as fname:
15484
imwrite(fname, data, description=description, shaped=False)
15485
assert_valid_tiff(fname)
15486
with TiffFile(fname) as tif:
15487
assert len(tif.pages) == 2
15488
assert tif.pages.first.description == description
15489
assert 'ImageDescription' not in tif.pages[1].tags
15491
tif.pages.first.tags.get('ImageDescription', index=1) is None
15493
assert tif.series[0].kind == 'generic'
15497
def test_write_description_ome():
15498
"""Test write multiple imagedescription tags to OME."""
15499
# https://forum.image.sc/t/79471
15500
with TempFileName('write_description_ome') as fname:
15501
with pytest.warns(UserWarning):
15507
description='description', # not written
15508
extratags=[('ImageDescription', 2, None, 'extratags', False)],
15510
with TiffFile(fname) as tif:
15512
page = tif.pages.first
15513
assert page.description.startswith('<?xml')
15514
assert page.description1 == 'extratags'
15515
assert tif.pages[1].description == 'extratags'
15518
def test_write_description_imagej():
15519
"""Test write multiple imagedescription tags."""
15520
with TempFileName('write_description_imagej') as fname:
15521
with pytest.warns(UserWarning):
15527
description='description', # not written
15528
extratags=[('ImageDescription', 2, None, 'extratags', False)],
15530
with TiffFile(fname) as tif:
15531
assert tif.is_imagej
15532
page = tif.pages.first
15533
assert page.description.startswith('ImageJ=')
15534
assert page.description1 == 'extratags'
15535
assert tif.pages[1].description == 'extratags'
15538
def test_write_description_shaped():
15539
"""Test write multiple imagedescription tags to shaped."""
15540
with TempFileName('write_description_shaped') as fname:
15545
description='description', # written
15546
extratags=[('ImageDescription', 2, None, 'extratags', False)],
15548
with TiffFile(fname) as tif:
15549
assert tif.is_shaped
15550
page = tif.pages.first
15551
assert page.description == 'description'
15552
assert page.description1.startswith('{')
15553
assert page.tags.getall(270)[2].value == 'extratags'
15554
assert tif.pages[1].description == 'extratags'
15557
def test_write_description_overwrite():
15558
"""Test overwrite imagedescription tag."""
15559
with TempFileName('write_description_overwrite') as fname:
15560
with TiffWriter(fname) as tif:
15564
description='description', # overwritten
15565
extratags=[('ImageDescription', 2, None, 'extratags', False)],
15568
tif.overwrite_description('overwritten description')
15569
with TiffFile(fname) as tif:
15570
assert not tif.is_shaped
15571
page = tif.pages.first
15572
assert page.description == 'overwritten description'
15573
assert page.description1 == 'extratags'
15574
assert tif.pages[1].description == 'extratags'
15577
def test_write_description_extratags():
15578
"""Test write imagedescription tags using extratag."""
15579
with TempFileName('write_description_extratags') as fname:
15580
with TiffWriter(fname) as tif:
15585
(270, 2, None, 'description 0', False),
15586
('ImageDescription', 2, None, 'description 1', False),
15590
with TiffFile(fname) as tif:
15591
assert not tif.is_shaped
15592
page = tif.pages.first
15593
assert page.description == 'description 0'
15594
assert page.description1 == 'description 1'
15595
page = tif.pages[1]
15596
assert page.description == 'description 0'
15597
assert page.description1 == 'description 1'
15600
def test_write_resolution_float():
15601
"""Test write float Resolution tag."""
15602
data = random_data(numpy.uint8, (2, 219, 301))
15603
resolution = (92.0, 92.0)
15604
with TempFileName('write_resolution_float') as fname:
15605
imwrite(fname, data, resolution=resolution)
15606
assert_valid_tiff(fname)
15607
with TiffFile(fname) as tif:
15608
assert len(tif.pages) == 2
15609
assert tif.pages.first.tags['XResolution'].value == (92, 1)
15610
assert tif.pages.first.tags['YResolution'].value == (92, 1)
15611
assert tif.pages.first.tags['ResolutionUnit'].value == 2
15612
assert tif.pages[1].tags['XResolution'].value == (92, 1)
15613
assert tif.pages[1].tags['YResolution'].value == (92, 1)
15614
assert tif.pages.first.tags['ResolutionUnit'].value == 2
15618
def test_write_resolution_rational():
15619
"""Test write rational Resolution tag."""
15620
data = random_data(numpy.uint8, (1, 219, 301))
15621
resolution = ((300, 1), (300, 1))
15622
with TempFileName('write_resolution_rational') as fname:
15623
imwrite(fname, data, resolution=resolution, resolutionunit=1)
15624
assert_valid_tiff(fname)
15625
with TiffFile(fname) as tif:
15626
assert len(tif.pages) == 1
15627
assert tif.pages.first.tags['XResolution'].value == (300, 1)
15628
assert tif.pages.first.tags['YResolution'].value == (300, 1)
15629
assert tif.pages.first.tags['ResolutionUnit'].value == 1
15632
def test_write_resolution_unit():
15633
"""Test write Resolution tag unit."""
15634
data = random_data(numpy.uint8, (219, 301))
15635
resolution = (92.0, (9200, 100), 3)
15636
with TempFileName('write_resolution_unit') as fname:
15637
with pytest.warns(DeprecationWarning):
15638
imwrite(fname, data, resolution=resolution)
15639
assert_valid_tiff(fname)
15640
with TiffFile(fname) as tif:
15641
assert len(tif.pages) == 1
15642
assert tif.pages.first.tags['XResolution'].value == (92, 1)
15643
assert tif.pages.first.tags['YResolution'].value == (92, 1)
15644
assert tif.pages.first.tags['ResolutionUnit'].value == 3
15648
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
15649
@pytest.mark.parametrize('bps', [1, 2, 7, 8])
15650
@pytest.mark.parametrize('dtype', [numpy.uint8, numpy.uint16, numpy.uint32])
15651
def test_write_bitspersample(bps, dtype):
15652
"""Test write with packints."""
15653
dtype = numpy.dtype(dtype)
15654
bps += (dtype.itemsize // 2) * 8
15655
data = numpy.arange(256 * 256 * 3, dtype=dtype).reshape((256, 256, 3))
15656
with TempFileName(f'write_bitspersample_{dtype.char}{bps}') as fname:
15657
# TODO: enable all cases once imagecodecs.packints_encode works
15658
if bps == dtype.itemsize * 8:
15660
fname, data, bitspersample=bps, photometric=PHOTOMETRIC.RGB
15662
assert_array_equal(imread(fname), data)
15664
with pytest.raises(NotImplementedError):
15666
fname, data, bitspersample=bps, photometric=PHOTOMETRIC.RGB
15668
assert_array_equal(imread(fname), data)
15671
def test_write_bitspersample_fail():
15672
"""Test write with packints fails."""
15673
data = numpy.arange(32 * 32 * 3, dtype=numpy.uint32).reshape((32, 32, 3))
15674
with TempFileName('write_bitspersample_fail') as fname:
15675
with TiffWriter(fname) as tif:
15676
# not working with compression
15677
with pytest.raises(ValueError):
15679
data.astype(numpy.uint8),
15681
compression=COMPRESSION.ADOBE_DEFLATE,
15682
photometric=PHOTOMETRIC.RGB,
15684
# dtype.itemsize != bitspersample
15691
with pytest.raises(ValueError):
15693
data.astype(dtype),
15695
photometric=PHOTOMETRIC.RGB,
15697
# bitspersample out of data range
15698
for bps in (0, 9, 16, 32):
15699
with pytest.raises(ValueError):
15701
data.astype(numpy.uint8),
15703
photometric=PHOTOMETRIC.RGB,
15705
for bps in (1, 8, 17, 32):
15706
with pytest.raises(ValueError):
15708
data.astype(numpy.uint16),
15710
photometric=PHOTOMETRIC.RGB,
15712
for bps in (1, 8, 16, 33, 64):
15713
with pytest.raises(ValueError):
15715
data.astype(numpy.uint32),
15717
photometric=PHOTOMETRIC.RGB,
15721
@pytest.mark.parametrize('kind', ['enum', 'int', 'lower', 'upper'])
15722
def test_write_enum_parameters(kind):
15723
"""Test imwrite using different kind of enum"""
15724
data = random_data(numpy.uint8, (2, 6, 219, 301))
15725
with TempFileName(f'write_enum_parameters_{kind}') as fname:
15730
photometric=PHOTOMETRIC.RGB,
15731
planarconfig=PLANARCONFIG.SEPARATE,
15733
EXTRASAMPLE.ASSOCALPHA,
15734
EXTRASAMPLE.UNSPECIFIED,
15735
EXTRASAMPLE.UNASSALPHA,
15737
compression=COMPRESSION.ADOBE_DEFLATE,
15738
predictor=PREDICTOR.HORIZONTAL,
15740
elif kind == 'int':
15746
extrasamples=(1, 0, 2),
15750
elif kind == 'upper':
15755
planarconfig='SEPARATE',
15756
extrasamples=('ASSOCALPHA', 'UNSPECIFIED', 'UNASSALPHA'),
15757
compression='ADOBE_DEFLATE',
15758
predictor='HORIZONTAL',
15760
elif kind == 'lower':
15765
planarconfig='separate',
15766
extrasamples=('assocalpha', 'unspecified', 'unassalpha'),
15767
compression='adobe_deflate',
15768
predictor='horizontal',
15770
with TiffFile(fname) as tif:
15771
assert len(tif.pages) == 2
15772
page = tif.pages.first
15773
assert page.imagewidth == 301
15774
assert page.imagelength == 219
15775
assert page.samplesperpixel == 6
15776
assert page.photometric == PHOTOMETRIC.RGB
15777
assert page.planarconfig == PLANARCONFIG.SEPARATE
15778
assert page.extrasamples == (
15779
EXTRASAMPLE.ASSOCALPHA,
15780
EXTRASAMPLE.UNSPECIFIED,
15781
EXTRASAMPLE.UNASSALPHA,
15783
assert page.compression == COMPRESSION.ADOBE_DEFLATE
15784
assert page.predictor == PREDICTOR.HORIZONTAL
15785
image = tif.asarray()
15786
assert_array_equal(data, image)
15787
assert_aszarr_method(tif, image)
15791
@pytest.mark.parametrize(
15796
(2, COMPRESSION.NONE),
15797
(3, COMPRESSION.ADOBE_DEFLATE),
15800
(6, 'zlib', 5, {'out': None}),
15801
(7, 'zlib', None, {'level': 5}),
15804
def test_write_compression_args(args, recwarn):
15805
"""Test compression parameter."""
15807
compressionargs = args[1:]
15808
compressed = compressionargs[0] not in {0, 1, COMPRESSION.NONE}
15809
if len(compressionargs) == 1:
15810
compressionargs = compressionargs[0]
15811
rowsperstrip = 100 if compressed else None
15814
with TempFileName(f'write_compression_args_{i}') as fname:
15815
# with pytest.warns(DeprecationWarning if i > 4 else None):
15819
compression=compressionargs,
15820
photometric=PHOTOMETRIC.RGB,
15821
rowsperstrip=rowsperstrip,
15824
assert len(recwarn) == 1
15825
user_warning = recwarn.pop(DeprecationWarning)
15826
assert issubclass(user_warning.category, DeprecationWarning)
15827
assert_valid_tiff(fname)
15828
with TiffFile(fname) as tif:
15829
assert len(tif.pages) == 1
15830
page = tif.pages.first
15831
assert page.compression == (
15832
COMPRESSION.ADOBE_DEFLATE if compressed else COMPRESSION.NONE
15834
assert page.planarconfig == PLANARCONFIG.SEPARATE
15835
assert page.photometric == PHOTOMETRIC.RGB
15836
assert page.imagewidth == 301
15837
assert page.imagelength == 219
15838
assert page.samplesperpixel == 3
15839
assert len(page.dataoffsets) == (9 if compressed else 3)
15840
image = tif.asarray()
15841
assert_array_equal(data, image)
15845
@pytest.mark.parametrize(
15850
(2, COMPRESSION.ADOBE_DEFLATE),
15851
(3, COMPRESSION.ADOBE_DEFLATE, 5),
15854
def test_write_compress_args(args):
15855
"""Test compress parameter no longer works in 2022.4.22."""
15857
compressargs = args[1:]
15858
if len(compressargs) == 1:
15859
compressargs = compressargs[0]
15862
with TempFileName(f'write_compression_args_{i}') as fname:
15863
with pytest.raises(TypeError):
15865
fname, data, compress=compressargs, photometric=PHOTOMETRIC.RGB
15869
def test_write_compression_none():
15870
"""Test write compression=0."""
15872
with TempFileName('write_compression_none') as fname:
15873
imwrite(fname, data, compression=0, photometric=PHOTOMETRIC.RGB)
15874
assert_valid_tiff(fname)
15875
with TiffFile(fname) as tif:
15876
assert len(tif.pages) == 1
15877
page = tif.pages.first
15878
assert page.is_contiguous
15879
assert page.compression == COMPRESSION.NONE
15880
assert page.planarconfig == PLANARCONFIG.SEPARATE
15881
assert page.photometric == PHOTOMETRIC.RGB
15882
assert page.imagewidth == 301
15883
assert page.imagelength == 219
15884
assert page.samplesperpixel == 3
15885
assert len(page.dataoffsets) == 3
15886
image = tif.asarray()
15887
assert_array_equal(data, image)
15888
assert_aszarr_method(tif, image)
15892
# @pytest.mark.parametrize('optimize', [None, False, True])
15893
# @pytest.mark.parametrize('smoothing', [None, 10])
15894
@pytest.mark.skipif(
15895
SKIP_PUBLIC or SKIP_CODECS or not imagecodecs.JPEG.available, reason=REASON
15897
@pytest.mark.parametrize('subsampling', ['444', '422', '420', '411'])
15898
@pytest.mark.parametrize('dtype', [numpy.uint8, numpy.uint16])
15899
def test_write_compression_jpeg(dtype, subsampling):
15900
"""Test write JPEG compression with subsampling."""
15901
dtype = numpy.dtype(dtype)
15902
filename = f'write_compression_jpeg_{dtype}_{subsampling}'
15903
subsampling, atol = {
15904
'444': [(1, 1), 5],
15905
'422': [(2, 1), 10],
15906
'420': [(2, 2), 20],
15907
'411': [(4, 1), 40],
15909
data = numpy.load(public_file('tifffile/rgb.u1.npy')).astype(dtype)
15910
data = data[:32, :16].copy() # make divisible by subsamples
15911
with TempFileName(filename) as fname:
15915
compression=COMPRESSION.JPEG,
15916
compressionargs={'level': 99},
15917
subsampling=subsampling,
15918
photometric=PHOTOMETRIC.RGB,
15920
assert_valid_tiff(fname)
15921
with TiffFile(fname) as tif:
15922
assert len(tif.pages) == 1
15923
page = tif.pages.first
15924
assert not page.is_contiguous
15925
if subsampling[0] > 1:
15926
assert page.is_subsampled
15927
assert page.tags['YCbCrSubSampling'].value == subsampling
15928
assert page.compression == COMPRESSION.JPEG
15929
assert page.photometric == PHOTOMETRIC.YCBCR
15930
assert page.imagewidth == data.shape[1]
15931
assert page.imagelength == data.shape[0]
15932
assert page.samplesperpixel == 3
15933
image = tif.asarray()
15934
assert_allclose(data, image, atol=atol)
15935
assert_aszarr_method(tif, image)
15939
@pytest.mark.parametrize('dtype', [numpy.uint8, bool])
15940
def test_write_compression_deflate(dtype):
15941
"""Test write ZLIB compression."""
15942
dtype = numpy.dtype(dtype)
15943
data = WRITE_DATA.astype(dtype)
15944
with TempFileName(f'write_compression_deflate_{dtype}') as fname:
15948
compression=COMPRESSION.DEFLATE,
15949
compressionargs={'level': 6},
15950
photometric=PHOTOMETRIC.RGB,
15953
assert_valid_tiff(fname)
15954
with TiffFile(fname) as tif:
15955
assert len(tif.pages) == 1
15956
page = tif.pages.first
15957
assert not page.is_contiguous
15958
assert page.compression == COMPRESSION.DEFLATE
15959
assert page.planarconfig == PLANARCONFIG.SEPARATE
15960
assert page.photometric == PHOTOMETRIC.RGB
15961
assert page.imagewidth == 301
15962
assert page.imagelength == 219
15963
assert page.samplesperpixel == 3
15964
assert page.rowsperstrip == 108
15965
assert len(page.dataoffsets) == 9
15966
image = tif.asarray()
15967
assert_array_equal(data, image)
15968
assert_aszarr_method(tif, image)
15972
def test_write_compression_deflate_level():
15973
"""Test write ZLIB compression with level."""
15975
with TempFileName('write_compression_deflate_level') as fname:
15979
compression=COMPRESSION.ADOBE_DEFLATE,
15980
compressionargs={'level': 9},
15981
photometric=PHOTOMETRIC.RGB,
15983
assert_valid_tiff(fname)
15984
with TiffFile(fname) as tif:
15985
assert len(tif.pages) == 1
15986
page = tif.pages.first
15987
assert not page.is_contiguous
15988
assert page.compression == COMPRESSION.ADOBE_DEFLATE
15989
assert page.planarconfig == PLANARCONFIG.SEPARATE
15990
assert page.photometric == PHOTOMETRIC.RGB
15991
assert page.imagewidth == 301
15992
assert page.imagelength == 219
15993
assert page.samplesperpixel == 3
15994
image = tif.asarray()
15995
assert_array_equal(data, image)
15996
assert_aszarr_method(tif, image)
16000
@pytest.mark.parametrize('dtype', [numpy.uint8, bool])
16001
def test_write_compression_lzma(dtype):
16002
"""Test write LZMA compression."""
16003
dtype = numpy.dtype(dtype)
16004
data = WRITE_DATA.astype(dtype)
16005
with TempFileName(f'write_compression_lzma_{dtype}') as fname:
16009
compression=COMPRESSION.LZMA,
16010
photometric=PHOTOMETRIC.RGB,
16013
assert_valid_tiff(fname)
16014
with TiffFile(fname) as tif:
16015
assert len(tif.pages) == 1
16016
page = tif.pages.first
16017
assert not page.is_contiguous
16018
assert page.compression == COMPRESSION.LZMA
16019
assert page.planarconfig == PLANARCONFIG.SEPARATE
16020
assert page.photometric == PHOTOMETRIC.RGB
16021
assert page.imagewidth == 301
16022
assert page.imagelength == 219
16023
assert page.samplesperpixel == 3
16024
assert page.rowsperstrip == 108
16025
assert len(page.dataoffsets) == 9
16026
image = tif.asarray()
16027
assert_array_equal(data, image)
16028
assert_aszarr_method(tif, image)
16032
@pytest.mark.skipif(
16033
SKIP_CODECS or not imagecodecs.ZSTD.available, reason=REASON
16035
@pytest.mark.parametrize('dtype', [numpy.uint8, bool])
16036
def test_write_compression_zstd(dtype):
16037
"""Test write ZSTD compression."""
16038
dtype = numpy.dtype(dtype)
16039
data = WRITE_DATA.astype(dtype)
16040
with TempFileName(f'write_compression_zstd_{dtype}') as fname:
16044
compression=COMPRESSION.ZSTD,
16045
photometric=PHOTOMETRIC.RGB,
16048
assert_valid_tiff(fname)
16049
with TiffFile(fname) as tif:
16050
assert len(tif.pages) == 1
16051
page = tif.pages.first
16052
assert not page.is_contiguous
16053
assert page.compression == COMPRESSION.ZSTD
16054
assert page.planarconfig == PLANARCONFIG.SEPARATE
16055
assert page.photometric == PHOTOMETRIC.RGB
16056
assert page.imagewidth == 301
16057
assert page.imagelength == 219
16058
assert page.samplesperpixel == 3
16059
assert page.rowsperstrip == 108
16060
assert len(page.dataoffsets) == 9
16061
image = tif.asarray()
16062
assert_array_equal(data, image)
16063
assert_aszarr_method(tif, image)
16067
@pytest.mark.skipif(
16068
SKIP_CODECS or not imagecodecs.WEBP.available, reason=REASON
16070
def test_write_compression_webp():
16071
"""Test write WEBP compression."""
16072
data = WRITE_DATA.astype(numpy.uint8).reshape((219, 301, 3))
16073
with TempFileName('write_compression_webp') as fname:
16077
compression=COMPRESSION.WEBP,
16078
compressionargs={'level': -1},
16079
photometric=PHOTOMETRIC.RGB,
16081
assert_valid_tiff(fname)
16082
with TiffFile(fname) as tif:
16083
assert len(tif.pages) == 1
16084
page = tif.pages.first
16085
assert not page.is_contiguous
16086
assert page.compression == COMPRESSION.WEBP
16087
assert page.photometric == PHOTOMETRIC.RGB
16088
assert page.imagewidth == 301
16089
assert page.imagelength == 219
16090
assert page.samplesperpixel == 3
16091
image = tif.asarray()
16092
assert_array_equal(data, image)
16093
assert_aszarr_method(tif, image)
16097
@pytest.mark.skipif(
16098
SKIP_CODECS or not imagecodecs.JPEG2K.available, reason=REASON
16100
def test_write_compression_jpeg2k():
16101
"""Test write JPEG 2000 compression."""
16102
data = WRITE_DATA.astype(numpy.uint8).reshape((219, 301, 3))
16103
with TempFileName('write_compression_jpeg2k') as fname:
16107
compression=COMPRESSION.JPEG2000,
16108
compressionargs={'level': -1},
16109
photometric=PHOTOMETRIC.RGB,
16111
assert_valid_tiff(fname)
16112
with TiffFile(fname) as tif:
16113
assert len(tif.pages) == 1
16114
page = tif.pages.first
16115
assert not page.is_contiguous
16116
assert page.compression == COMPRESSION.JPEG2000
16117
assert page.photometric == PHOTOMETRIC.RGB
16118
assert page.imagewidth == 301
16119
assert page.imagelength == 219
16120
assert page.samplesperpixel == 3
16121
image = tif.asarray()
16122
assert_array_equal(data, image)
16123
assert_aszarr_method(tif, image)
16127
@pytest.mark.skipif(
16128
SKIP_CODECS or not imagecodecs.JPEGXL.available, reason=REASON
16130
def test_write_compression_jpegxl():
16131
"""Test write JPEG XL compression."""
16132
data = WRITE_DATA.astype(numpy.uint8).reshape((219, 301, 3))
16133
with TempFileName('write_compression_jpegxl') as fname:
16137
compression=COMPRESSION.JPEGXL,
16138
compressionargs={'level': 101}, # lossless
16139
photometric=PHOTOMETRIC.RGB,
16141
assert_valid_tiff(fname)
16142
with TiffFile(fname) as tif:
16143
assert len(tif.pages) == 1
16144
page = tif.pages.first
16145
assert not page.is_contiguous
16146
assert page.compression == COMPRESSION.JPEGXL
16147
assert page.photometric == PHOTOMETRIC.RGB
16148
assert page.imagewidth == 301
16149
assert page.imagelength == 219
16150
assert page.samplesperpixel == 3
16151
image = tif.asarray()
16152
assert_array_equal(data, image)
16153
assert_aszarr_method(tif, image)
16157
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
16158
@pytest.mark.parametrize('compression', [None, 'deflate', 'zstd'])
16159
def test_write_compression_lerc(compression):
16160
"""Test write LERC compression."""
16161
if not hasattr(imagecodecs, 'LERC'):
16162
pytest.skip('LERC codec missing')
16163
compressionargs = {
16165
'deflate': {'level': 7},
16166
'zstd': {'level': 10},
16174
data = WRITE_DATA.astype(numpy.uint16).reshape((219, 301, 3))
16175
with TempFileName(f'write_compression_lerc_{compression}') as fname:
16179
photometric=PHOTOMETRIC.RGB,
16180
compression=COMPRESSION.LERC,
16182
'compression': compression,
16183
'compressionargs': compressionargs,
16186
assert_valid_tiff(fname)
16187
with TiffFile(fname) as tif:
16188
assert len(tif.pages) == 1
16189
page = tif.pages.first
16190
assert not page.is_contiguous
16191
assert page.compression == COMPRESSION.LERC
16192
assert page.photometric == PHOTOMETRIC.RGB
16193
assert page.imagewidth == 301
16194
assert page.imagelength == 219
16195
assert page.samplesperpixel == 3
16196
assert page.tags['LercParameters'].value == lercparameters
16198
image = tif.asarray()
16199
assert_array_equal(data, image)
16200
assert_aszarr_method(tif, image)
16204
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
16205
def test_write_compression_jetraw():
16206
"""Test write Jetraw compression."""
16208
have_jetraw = imagecodecs.JETRAW.available
16209
except AttributeError:
16210
# requires imagecodecs > 2022.22.2
16211
have_jetraw = False
16212
if not have_jetraw:
16213
pytest.skip('Jetraw codec not available')
16215
data = imread(private_file('jetraw/16ms-1.tif'))
16216
assert data.dtype == numpy.uint16
16217
assert data.shape == (2304, 2304)
16218
assert data[1490, 1830] == 36701
16220
# Jetraw requires initialization
16221
imagecodecs.jetraw_init()
16223
with TempFileName('write_compression_jetraw') as fname:
16228
compression=COMPRESSION.JETRAW,
16229
compressionargs={'identifier': '500202_standard_bin1x'},
16231
except imagecodecs.JetrawError as exc:
16232
if 'license' in str(exc):
16233
pytest.skip('Jetraw_encode requires a license')
16237
with TiffFile(fname) as tif:
16238
assert len(tif.pages) == 1
16239
page = tif.pages.first
16240
assert page.compression == COMPRESSION.JETRAW
16241
assert page.photometric == PHOTOMETRIC.MINISBLACK
16242
assert page.planarconfig == PLANARCONFIG.CONTIG
16243
assert page.imagewidth == 2304
16244
assert page.imagelength == 2304
16245
assert page.rowsperstrip == 2304
16246
assert page.bitspersample == 16
16247
assert page.samplesperpixel == 1
16248
image = tif.asarray()
16249
assert 0.5 > numpy.mean(
16250
image.astype(numpy.float32) - data.astype(numpy.float32)
16255
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
16256
@pytest.mark.parametrize('dtype', [numpy.int8, numpy.uint8, bool])
16257
@pytest.mark.parametrize('tile', [None, (16, 16)])
16258
def test_write_compression_packbits(dtype, tile):
16259
"""Test write PackBits compression."""
16260
dtype = numpy.dtype(dtype)
16261
uncompressed = numpy.frombuffer(
16262
b'\xaa\xaa\xaa\x80\x00\x2a\xaa\xaa\xaa\xaa\x80\x00'
16263
b'\x2a\x22\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa',
16266
shape = 2, 7, uncompressed.size
16267
data = numpy.empty(shape, dtype=dtype)
16268
data[..., :] = uncompressed
16269
with TempFileName(f'write_compression_packits_{dtype}') as fname:
16270
imwrite(fname, data, compression=COMPRESSION.PACKBITS, tile=tile)
16271
assert_valid_tiff(fname)
16272
with TiffFile(fname) as tif:
16273
assert len(tif.pages) == 2
16274
page = tif.pages.first
16275
assert not page.is_contiguous
16276
assert page.compression == COMPRESSION.PACKBITS
16277
assert page.planarconfig == PLANARCONFIG.CONTIG
16278
assert page.imagewidth == uncompressed.size
16279
assert page.imagelength == 7
16280
assert page.samplesperpixel == 1
16281
image = tif.asarray()
16282
assert_array_equal(data, image)
16283
assert_aszarr_method(tif, image)
16287
def test_write_compression_rowsperstrip():
16288
"""Test write rowsperstrip with compression."""
16290
with TempFileName('write_compression_rowsperstrip') as fname:
16294
compression=COMPRESSION.ADOBE_DEFLATE,
16296
photometric=PHOTOMETRIC.RGB,
16298
assert_valid_tiff(fname)
16299
with TiffFile(fname) as tif:
16300
assert len(tif.pages) == 1
16301
page = tif.pages.first
16302
assert not page.is_contiguous
16303
assert page.compression == COMPRESSION.ADOBE_DEFLATE
16304
assert page.planarconfig == PLANARCONFIG.SEPARATE
16305
assert page.photometric == PHOTOMETRIC.RGB
16306
assert page.imagewidth == 301
16307
assert page.imagelength == 219
16308
assert page.samplesperpixel == 3
16309
assert page.rowsperstrip == 32
16310
assert len(page.dataoffsets) == 21
16311
image = tif.asarray()
16312
assert_array_equal(data, image)
16313
assert_aszarr_method(tif, image)
16317
def test_write_compression_tiled():
16318
"""Test write compressed tiles."""
16320
with TempFileName('write_compression_tiled') as fname:
16324
compression=COMPRESSION.ADOBE_DEFLATE,
16326
photometric=PHOTOMETRIC.RGB,
16328
assert_valid_tiff(fname)
16329
with TiffFile(fname) as tif:
16330
assert len(tif.pages) == 1
16331
page = tif.pages.first
16332
assert not page.is_contiguous
16333
assert page.is_tiled
16334
assert page.compression == COMPRESSION.ADOBE_DEFLATE
16335
assert page.planarconfig == PLANARCONFIG.SEPARATE
16336
assert page.photometric == PHOTOMETRIC.RGB
16337
assert page.imagewidth == 301
16338
assert page.imagelength == 219
16339
assert page.samplesperpixel == 3
16340
assert len(page.dataoffsets) == 210
16341
image = tif.asarray()
16342
assert_array_equal(data, image)
16343
assert_aszarr_method(tif, image)
16347
def test_write_compression_predictor():
16348
"""Test write horizontal differencing."""
16350
with TempFileName('write_compression_predictor') as fname:
16354
compression=COMPRESSION.ADOBE_DEFLATE,
16355
predictor=PREDICTOR.HORIZONTAL,
16356
photometric=PHOTOMETRIC.RGB,
16358
assert_valid_tiff(fname)
16359
with TiffFile(fname) as tif:
16360
assert len(tif.pages) == 1
16361
page = tif.pages.first
16362
assert not page.is_contiguous
16363
assert page.compression == COMPRESSION.ADOBE_DEFLATE
16364
assert page.planarconfig == PLANARCONFIG.SEPARATE
16365
assert page.photometric == PHOTOMETRIC.RGB
16366
assert page.predictor == PREDICTOR.HORIZONTAL
16367
assert page.imagewidth == 301
16368
assert page.imagelength == 219
16369
assert page.samplesperpixel == 3
16370
image = tif.asarray()
16371
assert_array_equal(data, image)
16372
assert_aszarr_method(tif, image)
16376
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
16377
@pytest.mark.parametrize('dtype', [numpy.uint16, numpy.float32])
16378
def test_write_compression_predictor_tiled(dtype):
16379
"""Test write horizontal differencing with tiles."""
16380
dtype = numpy.dtype(dtype)
16381
data = WRITE_DATA.astype(dtype)
16382
with TempFileName(f'write_compression_tiled_predictor_{dtype}') as fname:
16386
compression=COMPRESSION.ADOBE_DEFLATE,
16389
photometric=PHOTOMETRIC.RGB,
16391
if dtype.kind != 'f':
16392
assert_valid_tiff(fname)
16393
with TiffFile(fname) as tif:
16394
assert len(tif.pages) == 1
16395
page = tif.pages.first
16396
assert not page.is_contiguous
16397
assert page.is_tiled
16398
assert page.compression == COMPRESSION.ADOBE_DEFLATE
16399
assert page.planarconfig == PLANARCONFIG.SEPARATE
16400
assert page.photometric == PHOTOMETRIC.RGB
16401
assert page.imagewidth == 301
16402
assert page.imagelength == 219
16403
assert page.samplesperpixel == 3
16404
assert page.predictor == 3 if dtype.kind == 'f' else 2
16405
image = tif.asarray()
16406
assert_array_equal(data, image)
16407
assert_aszarr_method(tif, image)
16411
def test_write_rowsperstrip():
16412
"""Test write rowsperstrip without compression."""
16414
with TempFileName('write_rowsperstrip') as fname:
16420
photometric=PHOTOMETRIC.RGB,
16423
assert_valid_tiff(fname)
16424
with TiffFile(fname) as tif:
16425
assert len(tif.pages) == 1
16426
page = tif.pages.first
16427
assert page.is_contiguous
16428
assert page.planarconfig == PLANARCONFIG.SEPARATE
16429
assert page.photometric == PHOTOMETRIC.RGB
16430
assert page.imagewidth == 301
16431
assert page.imagelength == 219
16432
assert page.samplesperpixel == 3
16433
assert page.rowsperstrip == 32
16434
assert len(page.dataoffsets) == 21
16435
stripbytecounts = page.tags['StripByteCounts'].value
16436
assert stripbytecounts[0] == 19264
16437
assert stripbytecounts[6] == 16254
16438
image = tif.asarray()
16439
assert_array_equal(data, image)
16440
assert_aszarr_method(tif, image)
16444
@pytest.mark.skipif(IS_BE, reason=REASON)
16445
def test_write_bigendian():
16446
"""Test write big endian file."""
16447
# also test memory mapping non-native byte order
16448
data = random_data(numpy.float32, (2, 3, 219, 301))
16449
data = data.view(data.dtype.newbyteorder())
16450
data = numpy.nan_to_num(data, copy=False)
16451
with TempFileName('write_bigendian') as fname:
16455
planarconfig=PLANARCONFIG.SEPARATE,
16456
photometric=PHOTOMETRIC.RGB,
16458
assert_valid_tiff(fname)
16459
with TiffFile(fname) as tif:
16460
assert len(tif.pages) == 2
16461
assert len(tif.series) == 1
16462
assert tif.byteorder == '>'
16463
# assert not tif.isnative
16464
assert tif.series[0].dataoffset is not None
16465
page = tif.pages.first
16466
assert page.is_contiguous
16467
assert page.planarconfig == PLANARCONFIG.SEPARATE
16468
assert page.photometric == PHOTOMETRIC.RGB
16469
assert page.imagewidth == 301
16470
assert page.imagelength == 219
16471
assert page.samplesperpixel == 3
16473
image = tif.asarray()
16474
assert_array_equal(data, image)
16475
assert_aszarr_method(tif, image)
16476
image = page.asarray()
16477
assert_array_equal(data[0], image)
16478
# test direct memory mapping; returns big endian array
16479
image = tif.asarray(out='memmap')
16480
assert isinstance(image, numpy.memmap)
16481
assert image.dtype == numpy.dtype('>f4')
16482
assert_array_equal(data, image)
16484
image = page.asarray(out='memmap')
16485
assert isinstance(image, numpy.memmap)
16486
assert image.dtype == numpy.dtype('>f4')
16487
assert_array_equal(data[0], image)
16489
# test indirect memory mapping; returns native endian array
16490
image = tif.asarray(out='memmap:')
16491
assert isinstance(image, numpy.memmap)
16492
assert image.dtype == numpy.dtype('=f4')
16493
assert_array_equal(data, image)
16495
image = page.asarray(out='memmap:')
16496
assert isinstance(image, numpy.memmap)
16497
assert image.dtype == numpy.dtype('=f4')
16498
assert_array_equal(data[0], image)
16501
page = tif.pages[1]
16502
image = page.asarray(out='memmap')
16503
assert isinstance(image, numpy.memmap)
16504
assert image.dtype == numpy.dtype('>f4')
16505
assert_array_equal(data[1], image)
16507
image = page.asarray(out='memmap:')
16508
assert isinstance(image, numpy.memmap)
16509
assert image.dtype == numpy.dtype('=f4')
16510
assert_array_equal(data[1], image)
16515
def test_write_zero_size():
16516
"""Test write zero size array no longer fails."""
16517
# with pytest.raises(ValueError):
16518
with pytest.warns(UserWarning):
16519
with TempFileName('write_empty') as fname:
16520
imwrite(fname, numpy.empty(0))
16523
def test_write_pixel():
16524
"""Test write single pixel."""
16525
data = numpy.zeros(1, dtype=numpy.uint8)
16526
with TempFileName('write_pixel') as fname:
16527
imwrite(fname, data)
16528
assert_valid_tiff(fname)
16529
with TiffFile(fname) as tif:
16530
assert len(tif.pages) == 1
16531
assert tif.series[0].axes == 'Y'
16532
page = tif.pages.first
16533
assert page.is_contiguous
16534
assert page.planarconfig == PLANARCONFIG.CONTIG
16535
assert page.photometric != PHOTOMETRIC.RGB
16536
assert page.imagewidth == 1
16537
assert page.imagelength == 1
16538
assert page.samplesperpixel == 1
16539
image = tif.asarray()
16540
assert_array_equal(data, image)
16541
assert_aszarr_method(tif, image)
16542
assert_aszarr_method(tif, image, chunkmode='page')
16546
def test_write_small():
16547
"""Test write small image."""
16548
data = random_data(numpy.uint8, (1, 1))
16549
with TempFileName('write_small') as fname:
16550
imwrite(fname, data)
16551
assert_valid_tiff(fname)
16552
with TiffFile(fname) as tif:
16553
assert len(tif.pages) == 1
16554
page = tif.pages.first
16555
assert page.is_contiguous
16556
assert page.planarconfig == PLANARCONFIG.CONTIG
16557
assert page.photometric != PHOTOMETRIC.RGB
16558
assert page.imagewidth == 1
16559
assert page.imagelength == 1
16560
assert page.samplesperpixel == 1
16561
image = tif.asarray()
16562
assert_array_equal(data, image)
16563
assert_aszarr_method(tif, image)
16567
def test_write_2d_as_rgb():
16568
"""Test write RGB color palette as RGB image."""
16569
# image length should be 1
16570
data = numpy.arange(3 * 256, dtype=numpy.uint16).reshape(256, 3) // 3
16571
with TempFileName('write_2d_as_rgb_contig') as fname:
16572
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
16573
assert_valid_tiff(fname)
16574
with TiffFile(fname) as tif:
16575
assert len(tif.pages) == 1
16576
assert tif.series[0].axes == 'XS'
16577
page = tif.pages.first
16578
assert page.is_contiguous
16579
assert page.planarconfig == PLANARCONFIG.CONTIG
16580
assert page.photometric == PHOTOMETRIC.RGB
16581
assert page.imagewidth == 256
16582
assert page.imagelength == 1
16583
assert page.samplesperpixel == 3
16584
image = tif.asarray()
16585
assert_array_equal(data, image)
16586
assert_aszarr_method(tif, image)
16587
assert_aszarr_method(tif, image, chunkmode='page')
16591
def test_write_auto_photometric_planar():
16592
"""Test detect photometric in planar mode."""
16593
data = random_data(numpy.uint8, (4, 31, 33))
16594
with TempFileName('write_auto_photometric_planar1') as fname:
16595
with pytest.warns(DeprecationWarning):
16596
imwrite(fname, data)
16597
assert_valid_tiff(fname)
16598
with TiffFile(fname) as tif:
16599
assert len(tif.pages) == 1
16600
page = tif.pages.first
16601
assert page.shape == (4, 31, 33)
16602
assert page.axes == 'SYX'
16603
assert page.planarconfig == PLANARCONFIG.SEPARATE
16604
assert page.photometric == PHOTOMETRIC.RGB
16605
assert len(page.extrasamples) == 1
16607
with TempFileName('write_auto_photometric_planar2') as fname:
16608
with pytest.warns(DeprecationWarning):
16609
imwrite(fname, data, planarconfig='separate')
16610
assert_valid_tiff(fname)
16611
with TiffFile(fname) as tif:
16612
assert len(tif.pages) == 1
16613
page = tif.pages.first
16614
assert page.shape == (4, 31, 33)
16615
assert page.axes == 'SYX'
16616
assert page.planarconfig == PLANARCONFIG.SEPARATE
16617
assert page.photometric == PHOTOMETRIC.RGB
16618
assert len(page.extrasamples) == 1
16620
data = random_data(numpy.uint8, (4, 7, 31, 33))
16621
with TempFileName('write_auto_photometric_volumetric_planar1') as fname:
16622
with pytest.warns(DeprecationWarning):
16623
imwrite(fname, data, volumetric=True)
16624
assert_valid_tiff(fname)
16625
with TiffFile(fname) as tif:
16626
assert len(tif.pages) == 1
16627
page = tif.pages.first
16628
assert page.shape == (4, 7, 31, 33)
16629
assert page.axes == 'SZYX'
16630
assert page.planarconfig == PLANARCONFIG.SEPARATE
16631
assert page.photometric == PHOTOMETRIC.RGB
16632
assert len(page.extrasamples) == 1
16633
assert page.is_volumetric
16635
with TempFileName('write_auto_photometric_volumetric_planar2') as fname:
16636
with pytest.warns(DeprecationWarning):
16637
imwrite(fname, data, planarconfig='separate', volumetric=True)
16638
assert_valid_tiff(fname)
16639
with TiffFile(fname) as tif:
16640
assert len(tif.pages) == 1
16641
page = tif.pages.first
16642
assert page.shape == (4, 7, 31, 33)
16643
assert page.axes == 'SZYX'
16644
assert page.planarconfig == PLANARCONFIG.SEPARATE
16645
assert page.photometric == PHOTOMETRIC.RGB
16646
assert len(page.extrasamples) == 1
16647
assert page.is_volumetric
16650
def test_write_auto_photometric_contig():
16651
"""Test detect photometric in contig mode."""
16652
data = random_data(numpy.uint8, (31, 33, 4))
16653
with TempFileName('write_auto_photometric_contig1') as fname:
16654
imwrite(fname, data)
16655
assert_valid_tiff(fname)
16656
with TiffFile(fname) as tif:
16657
assert len(tif.pages) == 1
16658
page = tif.pages.first
16659
assert page.shape == (31, 33, 4)
16660
assert page.axes == 'YXS'
16661
assert page.planarconfig == PLANARCONFIG.CONTIG
16662
assert page.photometric == PHOTOMETRIC.RGB
16663
assert len(page.extrasamples) == 1
16665
with TempFileName('write_auto_photometric_contig2') as fname:
16666
imwrite(fname, data, planarconfig='contig')
16667
assert_valid_tiff(fname)
16668
with TiffFile(fname) as tif:
16669
assert len(tif.pages) == 1
16670
page = tif.pages.first
16671
assert page.shape == (31, 33, 4)
16672
assert page.axes == 'YXS'
16673
assert page.planarconfig == PLANARCONFIG.CONTIG
16674
assert page.photometric == PHOTOMETRIC.RGB
16675
assert len(page.extrasamples) == 1
16677
data = random_data(numpy.uint8, (7, 31, 33, 4))
16678
with TempFileName('write_auto_photometric_volumetric_contig1') as fname:
16679
imwrite(fname, data, volumetric=True)
16680
assert_valid_tiff(fname)
16681
with TiffFile(fname) as tif:
16682
assert len(tif.pages) == 1
16683
page = tif.pages.first
16684
assert page.shape == (7, 31, 33, 4)
16685
assert page.axes == 'ZYXS'
16686
assert page.planarconfig == PLANARCONFIG.CONTIG
16687
assert page.photometric == PHOTOMETRIC.RGB
16688
assert len(page.extrasamples) == 1
16689
assert page.is_volumetric
16691
with TempFileName('write_auto_photometric_volumetric_contig2') as fname:
16692
imwrite(fname, data, planarconfig='contig', volumetric=True)
16693
assert_valid_tiff(fname)
16694
with TiffFile(fname) as tif:
16695
assert len(tif.pages) == 1
16696
page = tif.pages.first
16697
assert page.shape == (7, 31, 33, 4)
16698
assert page.axes == 'ZYXS'
16699
assert page.planarconfig == PLANARCONFIG.CONTIG
16700
assert page.photometric == PHOTOMETRIC.RGB
16701
assert len(page.extrasamples) == 1
16702
assert page.is_volumetric
16705
def test_write_invalid_contig_rgb():
16706
"""Test write planar RGB with 2 samplesperpixel."""
16707
data = random_data(numpy.uint8, (219, 301, 2))
16708
with pytest.raises(ValueError):
16709
with TempFileName('write_invalid_contig_rgb') as fname:
16710
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
16712
with TempFileName('write_invalid_contig_rgb_pages') as fname:
16713
imwrite(fname, data)
16714
assert_valid_tiff(fname)
16715
with TiffFile(fname) as tif:
16716
assert len(tif.pages) == 219
16717
assert tif.series[0].axes == 'QYX'
16718
page = tif.pages.first
16719
assert page.is_contiguous
16720
assert page.planarconfig == PLANARCONFIG.CONTIG
16721
assert page.photometric != PHOTOMETRIC.RGB
16722
assert page.imagewidth == 2
16723
assert page.imagelength == 301
16724
assert page.samplesperpixel == 1
16725
image = tif.asarray()
16726
assert_array_equal(data, image)
16727
assert_aszarr_method(tif, image)
16729
# better save as contig samples
16730
with TempFileName('write_invalid_contig_rgb_samples') as fname:
16731
imwrite(fname, data, planarconfig=PLANARCONFIG.CONTIG)
16732
assert_valid_tiff(fname)
16733
with TiffFile(fname) as tif:
16734
assert len(tif.pages) == 1
16735
assert tif.series[0].axes == 'YXS'
16736
page = tif.pages.first
16737
assert page.is_contiguous
16738
assert page.planarconfig == PLANARCONFIG.CONTIG
16739
assert page.photometric != PHOTOMETRIC.RGB
16740
assert page.imagewidth == 301
16741
assert page.imagelength == 219
16742
assert page.samplesperpixel == 2
16743
image = tif.asarray()
16744
assert_array_equal(data, image)
16745
assert_aszarr_method(tif, image)
16749
def test_write_invalid_planar_rgb():
16750
"""Test write planar RGB with 2 samplesperpixel."""
16751
data = random_data(numpy.uint8, (2, 219, 301))
16752
with pytest.raises(ValueError):
16753
with TempFileName('write_invalid_planar_rgb') as fname:
16757
photometric=PHOTOMETRIC.RGB,
16758
planarconfig=PLANARCONFIG.SEPARATE,
16761
with TempFileName('write_invalid_planar_rgb_pages') as fname:
16762
imwrite(fname, data)
16763
assert_valid_tiff(fname)
16764
with TiffFile(fname) as tif:
16765
assert len(tif.pages) == 2
16766
assert tif.series[0].axes == 'QYX'
16767
page = tif.pages.first
16768
assert page.is_contiguous
16769
assert page.planarconfig == PLANARCONFIG.CONTIG
16770
assert page.photometric != PHOTOMETRIC.RGB
16771
assert page.imagewidth == 301
16772
assert page.imagelength == 219
16773
assert page.samplesperpixel == 1
16774
image = tif.asarray()
16775
assert_array_equal(data, image)
16776
assert_aszarr_method(tif, image)
16778
# or save as planar samples
16779
with TempFileName('write_invalid_planar_rgb_samples') as fname:
16780
imwrite(fname, data, planarconfig=PLANARCONFIG.SEPARATE)
16781
assert_valid_tiff(fname)
16782
with TiffFile(fname) as tif:
16783
assert len(tif.pages) == 1
16784
assert tif.series[0].axes == 'SYX'
16785
page = tif.pages.first
16786
assert page.is_contiguous
16787
assert page.planarconfig == PLANARCONFIG.SEPARATE
16788
assert page.photometric != PHOTOMETRIC.RGB
16789
assert page.imagewidth == 301
16790
assert page.imagelength == 219
16791
assert page.samplesperpixel == 2
16792
image = tif.asarray()
16793
assert_array_equal(data, image)
16794
assert_aszarr_method(tif, image)
16798
def test_write_extrasamples_gray():
16799
"""Test write grayscale with extrasamples contig."""
16800
data = random_data(numpy.uint8, (301, 219, 2))
16801
with TempFileName('write_extrasamples_gray') as fname:
16802
imwrite(fname, data, extrasamples=[EXTRASAMPLE.UNASSALPHA])
16803
assert_valid_tiff(fname)
16804
with TiffFile(fname) as tif:
16805
assert len(tif.pages) == 1
16806
page = tif.pages.first
16807
assert page.is_contiguous
16808
assert page.photometric == PHOTOMETRIC.MINISBLACK
16809
assert page.planarconfig == PLANARCONFIG.CONTIG
16810
assert page.imagewidth == 219
16811
assert page.imagelength == 301
16812
assert page.samplesperpixel == 2
16813
assert page.extrasamples[0] == 2
16814
image = tif.asarray()
16815
assert_array_equal(data, image)
16816
assert_aszarr_method(tif, image)
16820
def test_write_extrasamples_gray_planar():
16821
"""Test write planar grayscale with extrasamples."""
16822
data = random_data(numpy.uint8, (2, 301, 219))
16823
with TempFileName('write_extrasamples_gray_planar') as fname:
16827
planarconfig=PLANARCONFIG.SEPARATE,
16828
extrasamples=[EXTRASAMPLE.UNASSALPHA],
16830
assert_valid_tiff(fname)
16831
with TiffFile(fname) as tif:
16832
assert len(tif.pages) == 1
16833
page = tif.pages.first
16834
assert page.is_contiguous
16835
assert page.photometric == PHOTOMETRIC.MINISBLACK
16836
assert page.planarconfig == PLANARCONFIG.SEPARATE
16837
assert page.imagewidth == 219
16838
assert page.imagelength == 301
16839
assert page.samplesperpixel == 2
16840
assert page.extrasamples[0] == 2
16841
image = tif.asarray()
16842
assert_array_equal(data, image)
16843
assert_aszarr_method(tif, image)
16847
def test_write_extrasamples_gray_mix():
16848
"""Test write grayscale with multiple extrasamples."""
16849
data = random_data(numpy.uint8, (301, 219, 4))
16850
with TempFileName('write_extrasamples_gray_mix') as fname:
16854
photometric=PHOTOMETRIC.MINISBLACK,
16856
EXTRASAMPLE.ASSOCALPHA,
16857
EXTRASAMPLE.UNASSALPHA,
16858
EXTRASAMPLE.UNSPECIFIED,
16861
assert_valid_tiff(fname)
16862
with TiffFile(fname) as tif:
16863
assert len(tif.pages) == 1
16864
page = tif.pages.first
16865
assert page.is_contiguous
16866
assert page.photometric == PHOTOMETRIC.MINISBLACK
16867
assert page.imagewidth == 219
16868
assert page.imagelength == 301
16869
assert page.samplesperpixel == 4
16870
assert page.extrasamples == (1, 2, 0)
16871
image = tif.asarray()
16872
assert_array_equal(data, image)
16873
assert_aszarr_method(tif, image)
16877
def test_write_extrasamples_unspecified():
16878
"""Test write RGB with unspecified extrasamples by default."""
16879
data = random_data(numpy.uint8, (301, 219, 5))
16880
with TempFileName('write_extrasamples_unspecified') as fname:
16881
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
16882
assert_valid_tiff(fname)
16883
with TiffFile(fname) as tif:
16884
assert len(tif.pages) == 1
16885
page = tif.pages.first
16886
assert page.is_contiguous
16887
assert page.photometric == PHOTOMETRIC.RGB
16888
assert page.imagewidth == 219
16889
assert page.imagelength == 301
16890
assert page.samplesperpixel == 5
16891
assert page.extrasamples == (0, 0)
16892
image = tif.asarray()
16893
assert_array_equal(data, image)
16894
assert_aszarr_method(tif, image)
16898
def test_write_extrasamples_assocalpha():
16899
"""Test write RGB with assocalpha extrasample."""
16900
data = random_data(numpy.uint8, (219, 301, 4))
16901
with TempFileName('write_extrasamples_assocalpha') as fname:
16905
photometric=PHOTOMETRIC.RGB,
16906
extrasamples=EXTRASAMPLE.ASSOCALPHA,
16908
assert_valid_tiff(fname)
16909
with TiffFile(fname) as tif:
16910
assert len(tif.pages) == 1
16911
page = tif.pages.first
16912
assert page.is_contiguous
16913
assert page.planarconfig == PLANARCONFIG.CONTIG
16914
assert page.photometric == PHOTOMETRIC.RGB
16915
assert page.imagewidth == 301
16916
assert page.imagelength == 219
16917
assert page.samplesperpixel == 4
16918
assert page.extrasamples[0] == 1
16919
image = tif.asarray()
16920
assert_array_equal(data, image)
16921
assert_aszarr_method(tif, image)
16925
def test_write_extrasamples_mix():
16926
"""Test write RGB with mixture of extrasamples."""
16927
data = random_data(numpy.uint8, (219, 301, 6))
16928
with TempFileName('write_extrasamples_mix') as fname:
16932
photometric=PHOTOMETRIC.RGB,
16934
EXTRASAMPLE.ASSOCALPHA,
16935
EXTRASAMPLE.UNASSALPHA,
16936
EXTRASAMPLE.UNSPECIFIED,
16939
assert_valid_tiff(fname)
16940
with TiffFile(fname) as tif:
16941
assert len(tif.pages) == 1
16942
page = tif.pages.first
16943
assert page.is_contiguous
16944
assert page.planarconfig == PLANARCONFIG.CONTIG
16945
assert page.photometric == PHOTOMETRIC.RGB
16946
assert page.imagewidth == 301
16947
assert page.imagelength == 219
16948
assert page.samplesperpixel == 6
16949
assert page.extrasamples == (1, 2, 0)
16950
image = tif.asarray()
16951
assert_array_equal(data, image)
16952
assert_aszarr_method(tif, image)
16956
def test_write_extrasamples_contig():
16957
"""Test write contig grayscale with large number of extrasamples."""
16958
data = random_data(numpy.uint8, (3, 219, 301))
16959
with TempFileName('write_extrasamples_contig') as fname:
16960
imwrite(fname, data, planarconfig=PLANARCONFIG.CONTIG)
16961
assert_valid_tiff(fname)
16962
with TiffFile(fname) as tif:
16963
assert len(tif.pages) == 1
16964
page = tif.pages.first
16965
assert page.is_contiguous
16966
assert page.planarconfig == PLANARCONFIG.CONTIG
16967
assert page.photometric != PHOTOMETRIC.RGB
16968
assert page.imagewidth == 219
16969
assert page.imagelength == 3
16970
assert page.samplesperpixel == 301
16971
assert len(page.extrasamples) == 301 - 1
16972
image = tif.asarray()
16973
assert_array_equal(data, image)
16974
assert_aszarr_method(tif, image)
16976
# better save as RGB planar
16977
with TempFileName('write_extrasamples_contig_planar') as fname:
16981
photometric=PHOTOMETRIC.RGB,
16982
planarconfig=PLANARCONFIG.SEPARATE,
16984
assert_valid_tiff(fname)
16985
with TiffFile(fname) as tif:
16986
assert len(tif.pages) == 1
16987
page = tif.pages.first
16988
assert page.is_contiguous
16989
assert page.planarconfig == PLANARCONFIG.SEPARATE
16990
assert page.photometric == PHOTOMETRIC.RGB
16991
assert page.imagewidth == 301
16992
assert page.imagelength == 219
16993
assert page.samplesperpixel == 3
16994
image = tif.asarray()
16995
assert_array_equal(data, image)
16996
assert_aszarr_method(tif, image)
17000
def test_write_extrasamples_contig_rgb2():
17001
"""Test write contig RGB with large number of extrasamples."""
17002
data = random_data(numpy.uint8, (3, 219, 301))
17003
with TempFileName('write_extrasamples_contig_rgb2') as fname:
17007
photometric=PHOTOMETRIC.RGB,
17008
planarconfig=PLANARCONFIG.CONTIG,
17010
assert_valid_tiff(fname)
17011
with TiffFile(fname) as tif:
17012
assert len(tif.pages) == 1
17013
page = tif.pages.first
17014
assert page.is_contiguous
17015
assert page.planarconfig == PLANARCONFIG.CONTIG
17016
assert page.photometric == PHOTOMETRIC.RGB
17017
assert page.imagewidth == 219
17018
assert page.imagelength == 3
17019
assert page.samplesperpixel == 301
17020
assert len(page.extrasamples) == 301 - 3
17021
image = tif.asarray()
17022
assert_array_equal(data, image)
17023
assert_aszarr_method(tif, image)
17025
# better save as planar
17026
with TempFileName('write_extrasamples_contig_rgb2_planar') as fname:
17030
photometric=PHOTOMETRIC.RGB,
17031
planarconfig=PLANARCONFIG.SEPARATE,
17033
assert_valid_tiff(fname)
17034
with TiffFile(fname) as tif:
17035
assert len(tif.pages) == 1
17036
page = tif.pages.first
17037
assert page.is_contiguous
17038
assert page.planarconfig == PLANARCONFIG.SEPARATE
17039
assert page.photometric == PHOTOMETRIC.RGB
17040
assert page.imagewidth == 301
17041
assert page.imagelength == 219
17042
assert page.samplesperpixel == 3
17043
image = tif.asarray()
17044
assert_array_equal(data, image)
17045
assert_aszarr_method(tif, image)
17049
def test_write_extrasamples_planar():
17050
"""Test write planar large number of extrasamples."""
17051
data = random_data(numpy.uint8, (219, 301, 3))
17052
with TempFileName('write_extrasamples_planar') as fname:
17053
imwrite(fname, data, planarconfig=PLANARCONFIG.SEPARATE)
17054
assert_valid_tiff(fname)
17055
with TiffFile(fname) as tif:
17056
assert len(tif.pages) == 1
17057
page = tif.pages.first
17058
assert page.is_contiguous
17059
assert page.planarconfig == PLANARCONFIG.SEPARATE
17060
assert page.photometric != PHOTOMETRIC.RGB
17061
assert page.imagewidth == 3
17062
assert page.imagelength == 301
17063
assert page.samplesperpixel == 219
17064
assert len(page.extrasamples) == 219 - 1
17065
image = tif.asarray()
17066
assert_array_equal(data, image)
17067
assert_aszarr_method(tif, image)
17071
def test_write_extrasamples_planar_rgb2():
17072
"""Test write planar RGB with large number of extrasamples."""
17073
data = random_data(numpy.uint8, (219, 301, 3))
17074
with TempFileName('write_extrasamples_planar_rgb2') as fname:
17078
photometric=PHOTOMETRIC.RGB,
17079
planarconfig=PLANARCONFIG.SEPARATE,
17081
assert_valid_tiff(fname)
17082
with TiffFile(fname) as tif:
17083
assert len(tif.pages) == 1
17084
page = tif.pages.first
17085
assert page.is_contiguous
17086
assert page.planarconfig == PLANARCONFIG.SEPARATE
17087
assert page.photometric == PHOTOMETRIC.RGB
17088
assert page.imagewidth == 3
17089
assert page.imagelength == 301
17090
assert page.samplesperpixel == 219
17091
assert len(page.extrasamples) == 219 - 3
17092
image = tif.asarray()
17093
assert_array_equal(data, image)
17094
assert_aszarr_method(tif, image)
17098
def test_write_minisblack_planar():
17099
"""Test write planar minisblack."""
17100
data = random_data(numpy.uint8, (3, 219, 301))
17101
with TempFileName('write_minisblack_planar') as fname:
17102
imwrite(fname, data, photometric=PHOTOMETRIC.MINISBLACK)
17103
assert_valid_tiff(fname)
17104
with TiffFile(fname) as tif:
17105
assert len(tif.pages) == 3
17106
page = tif.pages.first
17107
assert page.is_contiguous
17108
assert page.planarconfig == PLANARCONFIG.CONTIG
17109
assert page.photometric != PHOTOMETRIC.RGB
17110
assert page.imagewidth == 301
17111
assert page.imagelength == 219
17112
assert page.samplesperpixel == 1
17113
image = tif.asarray()
17114
assert_array_equal(data, image)
17115
assert_aszarr_method(tif, image)
17119
def test_write_minisblack_contig():
17120
"""Test write contig minisblack."""
17121
data = random_data(numpy.uint8, (219, 301, 3))
17122
with TempFileName('write_minisblack_contig') as fname:
17123
imwrite(fname, data, photometric=PHOTOMETRIC.MINISBLACK)
17124
assert_valid_tiff(fname)
17125
with TiffFile(fname) as tif:
17126
assert len(tif.pages) == 219
17127
page = tif.pages.first
17128
assert page.is_contiguous
17129
assert page.planarconfig == PLANARCONFIG.CONTIG
17130
assert page.photometric != PHOTOMETRIC.RGB
17131
assert page.imagewidth == 3
17132
assert page.imagelength == 301
17133
assert page.samplesperpixel == 1
17134
image = tif.asarray()
17135
assert_array_equal(data, image)
17136
assert_aszarr_method(tif, image)
17140
def test_write_scalar():
17141
"""Test write 2D grayscale."""
17142
data = random_data(numpy.uint8, (219, 301))
17143
with TempFileName('write_scalar') as fname:
17144
imwrite(fname, data)
17145
assert_valid_tiff(fname)
17146
with TiffFile(fname) as tif:
17147
assert len(tif.pages) == 1
17148
page = tif.pages.first
17149
assert page.is_contiguous
17150
assert page.planarconfig == PLANARCONFIG.CONTIG
17151
assert page.photometric != PHOTOMETRIC.RGB
17152
assert page.imagewidth == 301
17153
assert page.imagelength == 219
17154
assert page.samplesperpixel == 1
17155
image = tif.asarray()
17156
assert_array_equal(data, image)
17157
assert_aszarr_method(tif, image)
17161
def test_write_scalar_3d():
17162
"""Test write 3D grayscale."""
17163
data = random_data(numpy.uint8, (63, 219, 301))
17164
with TempFileName('write_scalar_3d') as fname:
17165
imwrite(fname, data)
17166
assert_valid_tiff(fname)
17167
with TiffFile(fname) as tif:
17168
assert len(tif.pages) == 63
17169
page = tif.pages[62]
17170
assert page.is_contiguous
17171
assert page.planarconfig == PLANARCONFIG.CONTIG
17172
assert page.photometric != PHOTOMETRIC.RGB
17173
assert page.imagewidth == 301
17174
assert page.imagelength == 219
17175
assert page.samplesperpixel == 1
17176
image = tif.asarray()
17177
assert isinstance(image, numpy.ndarray)
17178
assert_array_equal(data, image)
17179
assert_aszarr_method(tif, image)
17183
def test_write_scalar_4d():
17184
"""Test write 4D grayscale."""
17185
data = random_data(numpy.uint8, (3, 2, 219, 301))
17186
with TempFileName('write_scalar_4d') as fname:
17187
imwrite(fname, data)
17188
assert_valid_tiff(fname)
17189
with TiffFile(fname) as tif:
17190
assert len(tif.pages) == 6
17191
page = tif.pages[5]
17192
assert page.is_contiguous
17193
assert page.planarconfig == PLANARCONFIG.CONTIG
17194
assert page.photometric != PHOTOMETRIC.RGB
17195
assert page.imagewidth == 301
17196
assert page.imagelength == 219
17197
assert page.samplesperpixel == 1
17198
image = tif.asarray()
17199
assert_array_equal(data, image)
17200
assert_aszarr_method(tif, image)
17204
def test_write_contig_extrasample():
17205
"""Test write grayscale with contig extrasamples."""
17206
data = random_data(numpy.uint8, (219, 301, 2))
17207
with TempFileName('write_contig_extrasample') as fname:
17208
imwrite(fname, data, planarconfig=PLANARCONFIG.CONTIG)
17209
assert_valid_tiff(fname)
17210
with TiffFile(fname) as tif:
17211
assert len(tif.pages) == 1
17212
page = tif.pages.first
17213
assert page.is_contiguous
17214
assert page.planarconfig == PLANARCONFIG.CONTIG
17215
assert page.photometric != PHOTOMETRIC.RGB
17216
assert page.imagewidth == 301
17217
assert page.imagelength == 219
17218
assert page.samplesperpixel == 2
17219
image = tif.asarray()
17220
assert_array_equal(data, image)
17221
assert_aszarr_method(tif, image)
17225
def test_write_planar_extrasample():
17226
"""Test write grayscale with planar extrasamples."""
17227
data = random_data(numpy.uint8, (2, 219, 301))
17228
with TempFileName('write_planar_extrasample') as fname:
17229
imwrite(fname, data, planarconfig=PLANARCONFIG.SEPARATE)
17230
assert_valid_tiff(fname)
17231
with TiffFile(fname) as tif:
17232
assert len(tif.pages) == 1
17233
page = tif.pages.first
17234
assert page.is_contiguous
17235
assert page.planarconfig == PLANARCONFIG.SEPARATE
17236
assert page.photometric != PHOTOMETRIC.RGB
17237
assert page.imagewidth == 301
17238
assert page.imagelength == 219
17239
assert page.samplesperpixel == 2
17240
image = tif.asarray()
17241
assert_array_equal(data, image)
17242
assert_aszarr_method(tif, image)
17246
def test_write_auto_rgb_contig():
17247
"""Test write auto contig RGB."""
17248
data = random_data(numpy.uint8, (219, 301, 3))
17249
with TempFileName('write_auto_rgb_contig') as fname:
17250
imwrite(fname, data) # photometric=RGB
17251
assert_valid_tiff(fname)
17252
with TiffFile(fname) as tif:
17253
assert len(tif.pages) == 1
17254
page = tif.pages.first
17255
assert page.is_contiguous
17256
assert page.planarconfig == PLANARCONFIG.CONTIG
17257
assert page.photometric == PHOTOMETRIC.RGB
17258
assert page.imagewidth == 301
17259
assert page.imagelength == 219
17260
assert page.samplesperpixel == 3
17261
image = tif.asarray()
17262
assert_array_equal(data, image)
17263
assert_aszarr_method(tif, image)
17267
def test_write_auto_rgb_planar():
17268
"""Test write auto planar RGB."""
17269
data = random_data(numpy.uint8, (3, 219, 301))
17270
with TempFileName('write_auto_rgb_planar') as fname:
17271
with pytest.warns(DeprecationWarning):
17272
imwrite(fname, data) # photometric=RGB, planarconfig=SEPARATE
17273
assert_valid_tiff(fname)
17274
with TiffFile(fname) as tif:
17275
assert len(tif.pages) == 1
17276
page = tif.pages.first
17277
assert page.is_contiguous
17278
assert page.planarconfig == PLANARCONFIG.SEPARATE
17279
assert page.photometric == PHOTOMETRIC.RGB
17280
assert page.imagewidth == 301
17281
assert page.imagelength == 219
17282
assert page.samplesperpixel == 3
17283
image = tif.asarray()
17284
assert_array_equal(data, image)
17285
assert_aszarr_method(tif, image)
17289
def test_write_auto_rgba_contig():
17290
"""Test write auto contig RGBA."""
17291
data = random_data(numpy.uint8, (219, 301, 4))
17292
with TempFileName('write_auto_rgba_contig') as fname:
17293
imwrite(fname, data) # photometric=RGB
17294
assert_valid_tiff(fname)
17295
with TiffFile(fname) as tif:
17296
assert len(tif.pages) == 1
17297
page = tif.pages.first
17298
assert page.is_contiguous
17299
assert page.planarconfig == PLANARCONFIG.CONTIG
17300
assert page.photometric == PHOTOMETRIC.RGB
17301
assert page.imagewidth == 301
17302
assert page.imagelength == 219
17303
assert page.samplesperpixel == 4
17304
assert page.extrasamples[0] == EXTRASAMPLE.UNASSALPHA
17305
image = tif.asarray()
17306
assert_array_equal(data, image)
17307
assert_aszarr_method(tif, image)
17311
def test_write_auto_rgba_planar():
17312
"""Test write auto planar RGBA."""
17313
data = random_data(numpy.uint8, (4, 219, 301))
17314
with TempFileName('write_auto_rgba_planar') as fname:
17315
with pytest.warns(DeprecationWarning):
17316
imwrite(fname, data) # photometric=RGB, planarconfig=SEPARATE
17317
assert_valid_tiff(fname)
17318
with TiffFile(fname) as tif:
17319
assert len(tif.pages) == 1
17320
page = tif.pages.first
17321
assert page.is_contiguous
17322
assert page.planarconfig == PLANARCONFIG.SEPARATE
17323
assert page.photometric == PHOTOMETRIC.RGB
17324
assert page.imagewidth == 301
17325
assert page.imagelength == 219
17326
assert page.samplesperpixel == 4
17327
assert page.extrasamples[0] == EXTRASAMPLE.UNASSALPHA
17328
image = tif.asarray()
17329
assert_array_equal(data, image)
17330
assert_aszarr_method(tif, image)
17334
def test_write_extrasamples_contig_rgb():
17335
"""Test write contig RGB with extrasamples."""
17336
data = random_data(numpy.uint8, (219, 301, 8))
17337
with TempFileName('write_extrasamples_contig') as fname:
17338
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
17339
assert_valid_tiff(fname)
17340
with TiffFile(fname) as tif:
17341
assert len(tif.pages) == 1
17342
page = tif.pages.first
17343
assert page.is_contiguous
17344
assert page.planarconfig == PLANARCONFIG.CONTIG
17345
assert page.photometric == PHOTOMETRIC.RGB
17346
assert page.imagewidth == 301
17347
assert page.imagelength == 219
17348
assert page.samplesperpixel == 8
17349
assert len(page.extrasamples) == 5
17350
assert page.extrasamples[0] == EXTRASAMPLE.UNSPECIFIED
17351
image = tif.asarray()
17352
assert_array_equal(data, image)
17353
assert_aszarr_method(tif, image)
17357
def test_write_extrasamples_planar_rgb():
17358
"""Test write planar RGB with extrasamples."""
17359
data = random_data(numpy.uint8, (8, 219, 301))
17360
with TempFileName('write_extrasamples_planar') as fname:
17361
imwrite(fname, data, photometric=PHOTOMETRIC.RGB)
17362
assert_valid_tiff(fname)
17363
with TiffFile(fname) as tif:
17364
assert len(tif.pages) == 1
17365
page = tif.pages.first
17366
assert page.is_contiguous
17367
assert page.planarconfig == PLANARCONFIG.SEPARATE
17368
assert page.photometric == PHOTOMETRIC.RGB
17369
assert page.imagewidth == 301
17370
assert page.imagelength == 219
17371
assert page.samplesperpixel == 8
17372
assert len(page.extrasamples) == 5
17373
assert page.extrasamples[0] == EXTRASAMPLE.UNSPECIFIED
17374
image = tif.asarray()
17375
assert_array_equal(data, image)
17376
assert_aszarr_method(tif, image)
17380
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
17381
def test_write_iccprofile():
17382
"""Test write RGB with ICC profile."""
17383
data = random_data(numpy.uint8, (219, 301, 3))
17384
iccprofile = imagecodecs.cms_profile('srgb')
17386
with TempFileName('write_iccprofile') as fname:
17388
fname, data, photometric=PHOTOMETRIC.RGB, iccprofile=iccprofile
17390
assert_valid_tiff(fname)
17391
with TiffFile(fname) as tif:
17392
assert len(tif.pages) == 1
17393
page = tif.pages.first
17394
assert page.is_contiguous
17395
assert page.planarconfig == PLANARCONFIG.CONTIG
17396
assert page.photometric == PHOTOMETRIC.RGB
17397
assert page.imagewidth == 301
17398
assert page.imagelength == 219
17399
assert page.samplesperpixel == 3
17400
assert page.tags[34675].dtype == DATATYPE.UNDEFINED
17401
assert page.iccprofile == iccprofile
17402
imagecodecs.cms_profile_validate(page.iccprofile)
17407
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
17408
def test_write_cfa():
17409
"""Test write uncompressed CFA image."""
17410
# TODO: write a valid TIFF/EP file
17412
private_file('DNG/cinemadng/M14-1451_000085_cDNG_uncompressed.dng')
17415
(271, 's', 4, 'Make', False),
17416
(272, 's', 5, 'Model', False),
17417
(33421, 'H', 2, (2, 2), False), # CFARepeatPatternDim
17418
(33422, 'B', 4, b'\x00\x01\x01\x02', False), # CFAPattern
17419
# (37398, 'B', 4, b'\x01\x00\x00\x00', False), # TIFF/EPStandardID
17420
# (37399, 'H', 1, 0) # SensingMethod Undefined
17421
# (50706, 'B', 4, b'\x01\x04\x00\x00', False), # DNGVersion
17423
with TempFileName('write_cfa') as fname:
17427
photometric=PHOTOMETRIC.CFA,
17428
software='Tifffile',
17430
extratags=extratags,
17432
with TiffFile(fname) as tif:
17433
assert len(tif.pages) == 1
17434
page = tif.pages.first
17435
assert page.compression == 1
17436
assert page.photometric == PHOTOMETRIC.CFA
17437
assert page.imagewidth == 960
17438
assert page.imagelength == 540
17439
assert page.bitspersample == 16
17440
assert page.tags['CFARepeatPatternDim'].value == (2, 2)
17441
assert page.tags['CFAPattern'].value == b'\x00\x01\x01\x02'
17442
assert_array_equal(page.asarray(), data)
17443
assert_aszarr_method(page, data)
17446
def test_write_tiled_compressed():
17447
"""Test write compressed tiles."""
17448
data = random_data(numpy.uint8, (3, 219, 301))
17449
with TempFileName('write_tiled_compressed') as fname:
17453
photometric=PHOTOMETRIC.RGB,
17454
planarconfig=PLANARCONFIG.SEPARATE,
17455
compression=COMPRESSION.ADOBE_DEFLATE,
17456
compressionargs={'level': -1},
17459
assert_valid_tiff(fname)
17460
with TiffFile(fname) as tif:
17461
assert len(tif.pages) == 1
17462
page = tif.pages.first
17463
assert page.is_tiled
17464
assert not page.is_contiguous
17465
assert page.planarconfig == PLANARCONFIG.SEPARATE
17466
assert page.photometric == PHOTOMETRIC.RGB
17467
assert page.imagewidth == 301
17468
assert page.imagelength == 219
17469
assert page.tilewidth == 64
17470
assert page.tilelength == 96
17471
assert page.samplesperpixel == 3
17472
image = tif.asarray()
17473
assert_array_equal(data, image)
17474
assert_aszarr_method(tif, image)
17478
def test_write_tiled():
17479
"""Test write tiled."""
17480
data = random_data(numpy.uint16, (219, 301))
17481
with TempFileName('write_tiled') as fname:
17482
imwrite(fname, data, tile=(96, 64))
17483
assert_valid_tiff(fname)
17484
with TiffFile(fname) as tif:
17485
assert len(tif.pages) == 1
17486
page = tif.pages.first
17487
assert page.is_tiled
17488
assert not page.is_contiguous
17489
assert page.planarconfig == PLANARCONFIG.CONTIG
17490
assert page.photometric != PHOTOMETRIC.RGB
17491
assert page.imagewidth == 301
17492
assert page.imagelength == 219
17493
assert page.tilewidth == 64
17494
assert page.tilelength == 96
17495
assert page.samplesperpixel == 1
17496
image = tif.asarray()
17497
assert_array_equal(data, image)
17498
assert_aszarr_method(tif, image)
17502
def test_write_tiled_planar():
17503
"""Test write planar tiles."""
17504
data = random_data(numpy.uint8, (4, 219, 301))
17505
with TempFileName('write_tiled_planar') as fname:
17510
photometric=PHOTOMETRIC.RGB,
17511
planarconfig=PLANARCONFIG.SEPARATE,
17513
assert_valid_tiff(fname)
17514
with TiffFile(fname) as tif:
17515
assert len(tif.pages) == 1
17516
page = tif.pages.first
17517
assert page.is_tiled
17518
assert not page.is_contiguous
17519
assert not page.is_volumetric
17520
assert page.planarconfig == PLANARCONFIG.SEPARATE
17521
assert page.photometric == PHOTOMETRIC.RGB
17522
assert page.imagewidth == 301
17523
assert page.imagelength == 219
17524
assert page.tilewidth == 64
17525
assert page.tilelength == 96
17526
assert page.samplesperpixel == 4
17527
image = tif.asarray()
17528
assert_array_equal(data, image)
17529
assert_aszarr_method(tif, image)
17533
def test_write_tiled_contig():
17534
"""Test write contig tiles."""
17535
data = random_data(numpy.uint8, (219, 301, 3))
17536
with TempFileName('write_tiled_contig') as fname:
17537
imwrite(fname, data, tile=(96, 64), photometric=PHOTOMETRIC.RGB)
17538
assert_valid_tiff(fname)
17539
with TiffFile(fname) as tif:
17540
assert len(tif.pages) == 1
17541
page = tif.pages.first
17542
assert page.is_tiled
17543
assert not page.is_contiguous
17544
assert page.planarconfig == PLANARCONFIG.CONTIG
17545
assert page.photometric == PHOTOMETRIC.RGB
17546
assert page.imagewidth == 301
17547
assert page.imagelength == 219
17548
assert page.tilewidth == 64
17549
assert page.tilelength == 96
17550
assert page.samplesperpixel == 3
17551
image = tif.asarray()
17552
assert_array_equal(data, image)
17553
assert_aszarr_method(tif, image)
17557
def test_write_tiled_pages():
17558
"""Test write multiple tiled pages."""
17559
data = random_data(numpy.uint8, (5, 219, 301, 3))
17560
with TempFileName('write_tiled_pages') as fname:
17561
imwrite(fname, data, tile=(96, 64), photometric=PHOTOMETRIC.RGB)
17562
assert_valid_tiff(fname)
17563
with TiffFile(fname) as tif:
17564
assert len(tif.pages) == 5
17565
page = tif.pages.first
17566
assert page.is_tiled
17567
assert not page.is_contiguous
17568
assert page.planarconfig == PLANARCONFIG.CONTIG
17569
assert page.photometric == PHOTOMETRIC.RGB
17570
assert not page.is_volumetric
17571
assert page.imagewidth == 301
17572
assert page.imagelength == 219
17573
assert page.tilewidth == 64
17574
assert page.tilelength == 96
17575
assert page.samplesperpixel == 3
17576
image = tif.asarray()
17577
assert_array_equal(data, image)
17578
assert_aszarr_method(tif, image)
17582
@pytest.mark.parametrize('compression', [1, 8])
17583
def test_write_iter_tiles(compression):
17584
"""Test write tiles from iterator."""
17585
data = random_data(numpy.uint16, (12, 16, 16))
17588
for i in range(data.shape[0]):
17591
with TempFileName(f'write_iter_tiles_{compression}') as fname:
17592
with pytest.raises((StopIteration, RuntimeError)):
17599
dtype=numpy.uint16,
17600
compression=compression,
17603
with pytest.raises(ValueError):
17604
# missing parameters
17605
imwrite(fname, tiles(), compression=compression)
17607
with pytest.raises(ValueError):
17608
# missing parameters
17609
imwrite(fname, tiles(), shape=(43, 81), compression=compression)
17611
with pytest.raises(ValueError):
17618
dtype=numpy.uint32,
17619
compression=compression,
17622
with pytest.raises(ValueError):
17629
dtype=numpy.uint16,
17630
compression=compression,
17638
dtype=numpy.uint16,
17639
compression=compression,
17642
with TiffFile(fname) as tif:
17643
page = tif.pages.first
17644
assert page.shape == (43, 61)
17645
assert page.tilelength == 16
17646
assert page.tilewidth == 16
17647
assert page.compression == compression
17648
image = page.asarray()
17649
assert_array_equal(image[:16, :16], data[0])
17650
for i, segment in enumerate(page.segments()):
17651
assert_array_equal(numpy.squeeze(segment[0]), data[i])
17654
@pytest.mark.parametrize('compression', [1, 8])
17655
def test_write_iter_tiles_separate(compression):
17656
"""Test write separate tiles from iterator."""
17657
data = random_data(numpy.uint16, (24, 16, 16))
17660
for i in range(data.shape[0]):
17663
with TempFileName(f'write_iter_tiles_separate_{compression}') as fname:
17669
dtype=numpy.uint16,
17670
planarconfig=PLANARCONFIG.SEPARATE,
17671
compression=compression,
17674
with TiffFile(fname) as tif:
17675
assert len(tif.pages) == 1
17676
page = tif.pages.first
17677
assert page.shape == (2, 43, 61)
17678
assert page.tilelength == 16
17679
assert page.tilewidth == 16
17680
assert page.planarconfig == 2
17681
image = page.asarray()
17682
assert_array_equal(image[0, :16, :16], data[0])
17683
for i, segment in enumerate(page.segments()):
17684
assert_array_equal(numpy.squeeze(segment[0]), data[i])
17687
@pytest.mark.parametrize('compression', [1, 8])
17688
def test_write_iter_tiles_none(compression):
17689
"""Test write tiles from iterator with missing tiles.
17691
Missing tiles are not with tileoffset=0 and tilebytecount=0.
17694
data = random_data(numpy.uint16, (12, 16, 16))
17697
for i in range(data.shape[0]):
17704
with TempFileName(f'write_iter_tiles_none_{compression}') as fname:
17710
dtype=numpy.uint16,
17711
compression=compression,
17713
with TiffFile(fname) as tif:
17714
page = tif.pages.first
17715
assert page.shape == (43, 61)
17716
assert page.tilelength == 16
17717
assert page.tilewidth == 16
17718
assert page.databytecounts[1] == 0
17719
assert page.dataoffsets[1] == 0
17720
image = page.asarray()
17721
assert_array_equal(image[:16, :16], data[0])
17722
for i, segment in enumerate(page.segments()):
17724
assert segment[0] is None
17726
assert_array_equal(numpy.squeeze(segment[0]), data[i])
17729
@pytest.mark.parametrize('compression', [1, 8])
17730
def test_write_iter_tiles_bytes(compression):
17731
"""Test write tiles from iterator of bytes."""
17732
data = random_data(numpy.uint16, (5, 3, 15, 17))
17734
with TempFileName(f'write_iter_tiles_bytes_{compression}') as fname:
17739
compression=compression,
17740
planarconfig='separate',
17745
with TiffFile(fname + 'f') as tif:
17746
fh = tif.filehandle
17747
for page in tif.pages:
17748
for offset, bytecount in zip(
17749
page.dataoffsets, page.databytecounts
17752
strip = fh.read(bytecount)
17761
compression=compression,
17762
planarconfig='separate',
17765
assert_array_equal(imread(fname), data)
17768
@pytest.mark.parametrize('compression', [1, 8])
17769
@pytest.mark.parametrize('rowsperstrip', [5, 16])
17770
def test_write_iter_strips_bytes(compression, rowsperstrip):
17771
"""Test write strips from iterator of bytes."""
17772
data = random_data(numpy.uint16, (5, 3, 16, 16))
17775
f'write_iter_strips_bytes_{compression}{rowsperstrip}'
17780
rowsperstrip=rowsperstrip,
17781
compression=compression,
17782
planarconfig='separate',
17787
with TiffFile(fname + 'f') as tif:
17788
fh = tif.filehandle
17789
for page in tif.pages:
17790
for offset, bytecount in zip(
17791
page.dataoffsets, page.databytecounts
17794
strip = fh.read(bytecount)
17802
rowsperstrip=rowsperstrip,
17803
compression=compression,
17804
planarconfig='separate',
17807
assert_array_equal(imread(fname), data)
17810
@pytest.mark.parametrize('compression', [1, 8])
17811
@pytest.mark.parametrize('rowsperstrip', [5, 16])
17812
def test_write_iter_pages_none(compression, rowsperstrip):
17813
"""Test write pages from iterator with missing pages.
17815
Missing pages are written as zeros.
17818
data = random_data(numpy.uint16, (12, 16, 16))
17821
for i in range(data.shape[0]):
17829
f'write_iter_pages_none_{compression}{rowsperstrip}'
17834
shape=(12, 16, 16),
17835
dtype=numpy.uint16,
17836
rowsperstrip=rowsperstrip,
17837
compression=compression,
17839
with TiffFile(fname) as tif:
17840
for i, page in enumerate(tif.pages):
17841
assert page.shape == (16, 16)
17842
assert page.rowsperstrip == rowsperstrip
17843
assert_array_equal(page.asarray(), data[i])
17844
for j, segment in enumerate(page.segments()):
17845
assert_array_equal(
17846
numpy.squeeze(segment[0]),
17848
data[i, j * rowsperstrip : (j + 1) * rowsperstrip]
17853
def test_write_pyramids():
17854
"""Test write two pyramids to shaped file."""
17855
data = random_data(numpy.uint8, (31, 64, 96, 3))
17856
with TempFileName('write_pyramids') as fname:
17857
with TiffWriter(fname) as tif:
17859
tif.write(data, tile=(16, 16), photometric=PHOTOMETRIC.RGB)
17860
# interrupt pyramid, for example thumbnail
17861
tif.write(data[0, :, :, 0])
17866
subfiletype=FILETYPE.REDUCEDIMAGE,
17867
photometric=PHOTOMETRIC.RGB,
17872
subfiletype=FILETYPE.REDUCEDIMAGE,
17873
photometric=PHOTOMETRIC.RGB,
17875
# second pyramid using volumetric with downsampling factor 3
17876
tif.write(data, tile=(16, 16, 16), photometric=PHOTOMETRIC.RGB)
17878
data[::3, ::3, ::3],
17880
subfiletype=FILETYPE.REDUCEDIMAGE,
17881
photometric=PHOTOMETRIC.RGB,
17884
assert_valid_tiff(fname)
17886
with TiffFile(fname) as tif:
17887
assert len(tif.pages) == 3 * 31 + 2 + 1
17888
assert len(tif.series) == 3
17890
series = tif.series[0]
17891
assert series.kind == 'shaped'
17892
assert series.is_pyramidal
17893
assert len(series.levels) == 3
17894
assert len(series.levels[0].pages) == 31
17895
assert len(series.levels[1].pages) == 31
17896
assert len(series.levels[2].pages) == 31
17897
assert series.levels[0].shape == (31, 64, 96, 3)
17898
assert series.levels[1].shape == (31, 32, 48, 3)
17899
assert series.levels[2].shape == (31, 16, 24, 3)
17901
series = tif.series[1]
17902
assert series.kind == 'shaped'
17903
assert not series.is_pyramidal
17904
assert series.shape == (64, 96)
17906
series = tif.series[2]
17907
assert series.kind == 'shaped'
17908
assert series.is_pyramidal
17909
assert len(series.levels) == 2
17910
assert len(series.levels[0].pages) == 1
17911
assert len(series.levels[1].pages) == 1
17912
assert series.levels[0].keyframe.is_volumetric
17913
assert series.levels[1].keyframe.is_volumetric
17914
assert series.levels[0].shape == (31, 64, 96, 3)
17915
assert series.levels[1].shape == (11, 22, 32, 3)
17917
assert_array_equal(tif.asarray(), data)
17918
assert_array_equal(tif.asarray(series=0, level=0), data)
17919
assert_aszarr_method(tif, data, series=0, level=0)
17921
assert_array_equal(
17922
data[:, ::2, ::2], tif.asarray(series=0, level=1)
17924
assert_aszarr_method(tif, data[:, ::2, ::2], series=0, level=1)
17926
assert_array_equal(
17927
data[:, ::4, ::4], tif.asarray(series=0, level=2)
17929
assert_aszarr_method(tif, data[:, ::4, ::4], series=0, level=2)
17931
assert_array_equal(data[0, :, :, 0], tif.asarray(series=1))
17932
assert_aszarr_method(tif, data[0, :, :, 0], series=1)
17934
assert_array_equal(data, tif.asarray(series=2, level=0))
17935
assert_aszarr_method(tif, data, series=2, level=0)
17937
assert_array_equal(
17938
data[::3, ::3, ::3], tif.asarray(series=2, level=1)
17940
assert_aszarr_method(tif, data[::3, ::3, ::3], series=2, level=1)
17945
def test_write_volumetric_tiled():
17946
"""Test write tiled volume."""
17947
data = random_data(numpy.uint8, (253, 64, 96))
17948
with TempFileName('write_volumetric_tiled') as fname:
17949
imwrite(fname, data, tile=(64, 64, 64))
17950
assert_valid_tiff(fname)
17951
with TiffFile(fname) as tif:
17952
assert len(tif.pages) == 1
17953
page = tif.pages.first
17954
assert page.is_volumetric
17955
assert page.is_tiled
17956
assert not page.is_contiguous
17957
assert page.planarconfig == PLANARCONFIG.CONTIG
17958
assert page.photometric != PHOTOMETRIC.RGB
17959
assert page.imagewidth == 96
17960
assert page.imagelength == 64
17961
assert page.imagedepth == 253
17962
assert page.tilewidth == 64
17963
assert page.tilelength == 64
17964
assert page.tiledepth == 64
17965
assert page.tile == (64, 64, 64)
17966
assert page.samplesperpixel == 1
17967
image = tif.asarray()
17968
assert_array_equal(data, image)
17969
assert_aszarr_method(tif, image)
17973
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
17974
def test_write_volumetric_tiled_png():
17975
"""Test write tiled volume using an image compressor."""
17976
data = random_data(numpy.uint8, (16, 64, 96, 3))
17977
with TempFileName('write_volumetric_tiled_png') as fname:
17982
photometric=PHOTOMETRIC.RGB,
17983
compression=COMPRESSION.PNG,
17985
assert_valid_tiff(fname)
17986
with TiffFile(fname) as tif:
17987
assert len(tif.pages) == 1
17988
page = tif.pages.first
17989
assert page.is_volumetric
17990
assert page.is_tiled
17991
assert page.compression == COMPRESSION.PNG
17992
assert not page.is_contiguous
17993
assert page.planarconfig == PLANARCONFIG.CONTIG
17994
assert page.photometric == PHOTOMETRIC.RGB
17995
assert page.imagewidth == 96
17996
assert page.imagelength == 64
17997
assert page.imagedepth == 16
17998
assert page.tilewidth == 64
17999
assert page.tilelength == 64
18000
assert page.tiledepth == 1
18001
assert page.samplesperpixel == 3
18002
image = tif.asarray()
18003
assert_array_equal(data, image)
18004
assert_aszarr_method(tif, image)
18008
def test_write_volumetric_tiled_planar_rgb():
18009
"""Test write 5D array as grayscale volumes."""
18010
shape = (2, 3, 256, 64, 96)
18011
data = numpy.empty(shape, dtype=numpy.uint8)
18012
data[:] = numpy.arange(256, dtype=numpy.uint8).reshape(1, 1, -1, 1, 1)
18013
with TempFileName('write_volumetric_tiled_planar_rgb') as fname:
18017
tile=(256, 64, 96),
18018
photometric=PHOTOMETRIC.RGB,
18019
planarconfig=PLANARCONFIG.SEPARATE,
18021
assert_valid_tiff(fname)
18022
with TiffFile(fname) as tif:
18023
assert len(tif.pages) == 2
18024
page = tif.pages.first
18025
assert page.is_volumetric
18026
assert page.is_tiled
18027
assert page.is_contiguous
18028
assert page.planarconfig == PLANARCONFIG.SEPARATE
18029
assert page.photometric == PHOTOMETRIC.RGB
18030
assert page.imagewidth == 96
18031
assert page.imagelength == 64
18032
assert page.imagedepth == 256
18033
assert page.tilewidth == 96
18034
assert page.tilelength == 64
18035
assert page.tiledepth == 256
18036
assert page.samplesperpixel == 3
18037
series = tif.series[0]
18038
assert series.kind == 'shaped'
18039
assert len(series._pages) == 1
18040
assert len(series.pages) == 2
18041
assert series.dataoffset is not None
18042
assert series.shape == shape
18043
image = tif.asarray()
18044
assert_array_equal(data, image)
18045
assert_aszarr_method(tif, image)
18049
def test_write_volumetric_tiled_contig_rgb():
18050
"""Test write 6D array as contig RGB volumes."""
18051
shape = (2, 3, 256, 64, 96, 3)
18052
data = numpy.empty(shape, dtype=numpy.uint8)
18053
data[:] = numpy.arange(256, dtype=numpy.uint8).reshape(1, 1, -1, 1, 1, 1)
18054
with TempFileName('write_volumetric_tiled_contig_rgb') as fname:
18055
imwrite(fname, data, tile=(256, 64, 96), photometric=PHOTOMETRIC.RGB)
18056
assert_valid_tiff(fname)
18057
with TiffFile(fname) as tif:
18058
assert len(tif.pages) == 6
18059
page = tif.pages.first
18060
assert page.is_volumetric
18061
assert page.is_tiled
18062
assert page.is_contiguous
18063
assert page.planarconfig == PLANARCONFIG.CONTIG
18064
assert page.photometric == PHOTOMETRIC.RGB
18065
assert page.imagewidth == 96
18066
assert page.imagelength == 64
18067
assert page.imagedepth == 256
18068
assert page.tilewidth == 96
18069
assert page.tilelength == 64
18070
assert page.tiledepth == 256
18071
assert page.samplesperpixel == 3
18072
# self.assertEqual(page.tags['TileOffsets'].value, (352,))
18073
assert page.tags['TileByteCounts'].value == (4718592,)
18074
series = tif.series[0]
18075
assert series.kind == 'shaped'
18076
assert len(series._pages) == 1
18077
assert len(series.pages) == 6
18078
assert series.dataoffset is not None
18079
assert series.shape == shape
18080
image = tif.asarray()
18081
assert_array_equal(data, image)
18082
# assert iterating over series.pages
18083
data = data.reshape(6, 256, 64, 96, 3)
18084
for i, page in enumerate(series.pages):
18085
image = page.asarray()
18086
assert_array_equal(data[i], image)
18087
assert_aszarr_method(page, image)
18091
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18092
def test_write_volumetric_tiled_contig_rgb_empty():
18093
"""Test write empty 6D array as contig RGB volumes."""
18094
shape = (2, 3, 256, 64, 96, 3)
18095
with TempFileName('write_volumetric_tiled_contig_rgb_empty') as fname:
18096
with TiffWriter(fname) as tif:
18100
tile=(256, 64, 96),
18101
photometric=PHOTOMETRIC.RGB,
18103
assert_valid_tiff(fname)
18104
with TiffFile(fname) as tif:
18105
assert len(tif.pages) == 6
18106
page = tif.pages.first
18107
assert page.is_volumetric
18108
assert page.is_tiled
18109
assert page.is_contiguous
18110
assert page.planarconfig == PLANARCONFIG.CONTIG
18111
assert page.photometric == PHOTOMETRIC.RGB
18112
assert page.imagewidth == 96
18113
assert page.imagelength == 64
18114
assert page.imagedepth == 256
18115
assert page.tilewidth == 96
18116
assert page.tilelength == 64
18117
assert page.tiledepth == 256
18118
assert page.samplesperpixel == 3
18119
# self.assertEqual(page.tags['TileOffsets'].value, (352,))
18120
assert page.tags['TileByteCounts'].value == (4718592,)
18121
series = tif.series[0]
18122
assert series.kind == 'shaped'
18123
assert len(series._pages) == 1
18124
assert len(series.pages) == 6
18125
assert series.dataoffset is not None
18126
assert series.shape == shape
18127
image = tif.asarray()
18128
assert_array_equal(image.shape, shape)
18129
assert_aszarr_method(tif, image)
18133
def test_write_volumetric_striped():
18134
"""Test write striped volume."""
18135
data = random_data(numpy.uint8, (15, 63, 95))
18136
with TempFileName('write_volumetric_striped') as fname:
18137
imwrite(fname, data, volumetric=True)
18138
assert_valid_tiff(fname)
18139
with TiffFile(fname) as tif:
18140
assert len(tif.pages) == 1
18141
page = tif.pages.first
18142
assert page.is_volumetric
18143
assert not page.is_tiled
18144
assert page.is_contiguous
18145
assert page.planarconfig == PLANARCONFIG.CONTIG
18146
assert page.photometric != PHOTOMETRIC.RGB
18147
assert page.imagewidth == 95
18148
assert page.imagelength == 63
18149
assert page.imagedepth == 15
18150
assert len(page.dataoffsets) == 15
18151
assert len(page.databytecounts) == 15
18152
assert page.samplesperpixel == 1
18153
image = tif.asarray()
18154
assert_array_equal(data, image)
18155
assert_aszarr_method(tif, image)
18159
@pytest.mark.skipif(SKIP_CODECS, reason=REASON)
18160
def test_write_volumetric_striped_png():
18161
"""Test write tiled volume using an image compressor."""
18162
data = random_data(numpy.uint8, (15, 63, 95, 3))
18163
with TempFileName('write_volumetric_striped_png') as fname:
18167
photometric=PHOTOMETRIC.RGB,
18170
compression=COMPRESSION.PNG,
18172
assert_valid_tiff(fname)
18173
with TiffFile(fname) as tif:
18174
assert len(tif.pages) == 1
18175
page = tif.pages.first
18176
assert page.is_volumetric
18177
assert not page.is_tiled
18178
assert page.compression == COMPRESSION.PNG
18179
assert not page.is_contiguous
18180
assert page.planarconfig == PLANARCONFIG.CONTIG
18181
assert page.photometric == PHOTOMETRIC.RGB
18182
assert page.imagewidth == 95
18183
assert page.imagelength == 63
18184
assert page.imagedepth == 15
18185
assert page.samplesperpixel == 3
18186
assert len(page.dataoffsets) == 30
18187
assert len(page.databytecounts) == 30
18188
image = tif.asarray()
18189
assert_array_equal(data, image)
18190
assert_aszarr_method(tif, image)
18191
assert_aszarr_method(tif, image, chunkmode='page')
18195
def test_write_volumetric_striped_planar_rgb():
18196
"""Test write 5D array as grayscale volumes."""
18197
shape = (2, 3, 15, 63, 96)
18198
data = numpy.empty(shape, dtype=numpy.uint8)
18199
data[:] = numpy.arange(15, dtype=numpy.uint8).reshape(1, 1, -1, 1, 1)
18200
with TempFileName('write_volumetric_striped_planar_rgb') as fname:
18201
imwrite(fname, data, volumetric=True, photometric=PHOTOMETRIC.RGB)
18202
assert_valid_tiff(fname)
18203
with TiffFile(fname) as tif:
18204
assert len(tif.pages) == 2
18205
page = tif.pages.first
18206
assert page.is_volumetric
18207
assert not page.is_tiled
18208
assert page.is_contiguous
18209
assert page.planarconfig == PLANARCONFIG.SEPARATE
18210
assert page.photometric == PHOTOMETRIC.RGB
18211
assert page.imagewidth == 96
18212
assert page.imagelength == 63
18213
assert page.imagedepth == 15
18214
assert page.samplesperpixel == 3
18215
assert len(page.dataoffsets) == 15 * 3
18216
assert len(page.databytecounts) == 15 * 3
18217
series = tif.series[0]
18218
assert series.kind == 'shaped'
18219
assert len(series._pages) == 1
18220
assert len(series.pages) == 2
18221
assert series.dataoffset is not None
18222
assert series.shape == shape
18223
image = tif.asarray()
18224
assert_array_equal(data, image)
18225
assert_aszarr_method(tif, image)
18229
def test_write_volumetric_striped_contig_rgb():
18230
"""Test write 6D array as contig RGB volumes."""
18231
shape = (2, 3, 15, 63, 95, 3)
18232
data = numpy.empty(shape, dtype=numpy.uint8)
18233
data[:] = numpy.arange(15, dtype=numpy.uint8).reshape(1, 1, -1, 1, 1, 1)
18234
with TempFileName('write_volumetric_striped_contig_rgb') as fname:
18235
imwrite(fname, data, volumetric=True, photometric=PHOTOMETRIC.RGB)
18236
assert_valid_tiff(fname)
18237
with TiffFile(fname) as tif:
18238
assert len(tif.pages) == 6
18239
page = tif.pages.first
18240
assert page.is_volumetric
18241
assert not page.is_tiled
18242
assert page.is_contiguous
18243
assert page.planarconfig == PLANARCONFIG.CONTIG
18244
assert page.photometric == PHOTOMETRIC.RGB
18245
assert page.imagewidth == 95
18246
assert page.imagelength == 63
18247
assert page.imagedepth == 15
18248
assert page.samplesperpixel == 3
18249
assert len(page.dataoffsets) == 15
18250
assert len(page.databytecounts) == 15
18251
series = tif.series[0]
18252
assert series.kind == 'shaped'
18253
assert len(series._pages) == 1
18254
assert len(series.pages) == 6
18255
assert series.dataoffset is not None
18256
assert series.shape == shape
18257
image = tif.asarray()
18258
assert_array_equal(data, image)
18259
# assert iterating over series.pages
18260
data = data.reshape((6, 15, 63, 95, 3))
18261
for i, page in enumerate(series.pages):
18262
image = page.asarray()
18263
assert_array_equal(data[i], image)
18264
assert_aszarr_method(page, image)
18268
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18269
def test_write_volumetric_striped_contig_rgb_empty():
18270
"""Test write empty 6D array as contig RGB volumes."""
18271
shape = (2, 3, 15, 63, 95, 3)
18272
with TempFileName('write_volumetric_striped_contig_rgb_empty') as fname:
18273
with TiffWriter(fname) as tif:
18278
photometric=PHOTOMETRIC.RGB,
18280
assert_valid_tiff(fname)
18281
with TiffFile(fname) as tif:
18282
assert len(tif.pages) == 6
18283
page = tif.pages.first
18284
assert page.is_volumetric
18285
assert not page.is_tiled
18286
assert page.is_contiguous
18287
assert page.planarconfig == PLANARCONFIG.CONTIG
18288
assert page.photometric == PHOTOMETRIC.RGB
18289
assert page.imagewidth == 95
18290
assert page.imagelength == 63
18291
assert page.imagedepth == 15
18292
assert page.samplesperpixel == 3
18293
assert len(page.dataoffsets) == 15
18294
assert len(page.databytecounts) == 15
18295
series = tif.series[0]
18296
assert series.kind == 'shaped'
18297
assert len(series._pages) == 1
18298
assert len(series.pages) == 6
18299
assert series.dataoffset is not None
18300
assert series.shape == shape
18301
image = tif.asarray()
18302
assert_array_equal(image.shape, shape)
18303
assert_aszarr_method(tif, image)
18307
def test_write_contiguous():
18308
"""Test contiguous mode."""
18309
data = random_data(numpy.uint8, (5, 4, 219, 301, 3))
18310
with TempFileName('write_contiguous') as fname:
18311
with TiffWriter(fname, bigtiff=True) as tif:
18312
for i in range(data.shape[0]):
18314
data[i], contiguous=True, photometric=PHOTOMETRIC.RGB
18316
# assert_jhove(fname)
18317
with TiffFile(fname) as tif:
18318
assert tif.is_bigtiff
18319
assert len(tif.pages) == 20
18320
# check metadata is updated in-place
18321
assert tif.pages.first.tags[270].valueoffset < tif.pages[1].offset
18322
for page in tif.pages:
18323
assert page.is_contiguous
18324
assert page.planarconfig == PLANARCONFIG.CONTIG
18325
assert page.photometric == PHOTOMETRIC.RGB
18326
assert page.imagewidth == 301
18327
assert page.imagelength == 219
18328
assert page.samplesperpixel == 3
18329
image = tif.asarray()
18330
assert_array_equal(data, image)
18331
assert_aszarr_method(tif, image)
18335
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18336
def test_write_3gb():
18337
"""Test write 3 GB non-BigTIFF file."""
18338
# https://github.com/blink1073/tifffile/issues/47
18339
data = numpy.empty((4096 - 32, 1024, 1024), dtype=numpy.uint8)
18340
with TempFileName('write_3gb') as fname:
18341
imwrite(fname, data)
18343
assert_valid_tiff(fname)
18345
with TiffFile(fname) as tif:
18346
assert not tif.is_bigtiff
18349
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18350
def test_write_6gb():
18351
"""Test write 6 GB non-BigTIFF file."""
18352
# https://stackoverflow.com/questions/74930263
18353
data = numpy.empty((2**16, 2**15, 3), dtype=numpy.uint8)
18354
with TempFileName('write_6gb') as fname:
18356
fname, data, bigtiff=False, photometric='rgb', rowsperstrip=2**15
18359
assert_valid_tiff(fname)
18361
with TiffFile(fname) as tif:
18362
assert not tif.is_bigtiff
18363
assert tif.pages.first.dataoffsets[1] > 2**16
18364
assert tif.pages.first.databytecounts[1] == 3221225472
18365
# image = tif.asarray()
18366
# assert_array_equal(data, image)
18369
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18370
def test_write_5GB_fails():
18371
"""Test data too large for non-BigTIFF file."""
18372
# TiffWriter should fail without bigtiff parameter
18373
data = numpy.empty((640, 1024, 1024), dtype=numpy.float64)
18374
data[:] = numpy.arange(640, dtype=numpy.float64).reshape(-1, 1, 1)
18375
with TempFileName('write_5GB_fails') as fname:
18376
with pytest.raises(ValueError):
18377
with TiffWriter(fname) as tif:
18379
# TODO: test 'unclosed file' not in capsys
18382
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
18383
def test_write_5GB_bigtiff():
18384
"""Test write 5GB BigTiff file."""
18385
data = numpy.empty((640, 1024, 1024), dtype=numpy.float64)
18386
data[:] = numpy.arange(640, dtype=numpy.float64).reshape(-1, 1, 1)
18387
with TempFileName('write_5GB_bigtiff') as fname:
18388
# imwrite should use bigtiff for large data
18389
imwrite(fname, data)
18390
# assert_jhove(fname)
18392
with TiffFile(fname) as tif:
18393
assert tif.is_bigtiff
18394
assert len(tif.pages) == 640
18395
page = tif.pages.first
18396
assert page.is_contiguous
18397
assert page.planarconfig == PLANARCONFIG.CONTIG
18398
assert page.photometric != PHOTOMETRIC.RGB
18399
assert page.imagewidth == 1024
18400
assert page.imagelength == 1024
18401
assert page.samplesperpixel == 1
18402
image = tif.asarray(out='memmap')
18403
assert_array_equal(data, image)
18409
@pytest.mark.parametrize('compression', [0, 6])
18410
@pytest.mark.parametrize('dtype', [numpy.uint8, numpy.uint16])
18411
def test_write_palette(dtype, compression):
18412
"""Test write palette images."""
18413
dtype = numpy.dtype(dtype)
18414
data = random_data(dtype, (3, 219, 301))
18415
cmap = random_data(numpy.uint16, (3, 2 ** (data.itemsize * 8)))
18416
with TempFileName(f'write_palette_{compression}{dtype}') as fname:
18421
compression=COMPRESSION.ADOBE_DEFLATE if compression else None,
18422
compressionargs={'level': compression} if compression else None,
18424
assert_valid_tiff(fname)
18425
with TiffFile(fname) as tif:
18426
assert len(tif.pages) == 3
18427
page = tif.pages.first
18428
assert page.is_contiguous != bool(compression)
18429
assert page.planarconfig == PLANARCONFIG.CONTIG
18430
assert page.photometric == PHOTOMETRIC.PALETTE
18431
assert page.imagewidth == 301
18432
assert page.imagelength == 219
18433
assert page.samplesperpixel == 1
18434
for i, page in enumerate(tif.pages):
18435
assert_array_equal(apply_colormap(data[i], cmap), page.asrgb())
18439
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
18440
def test_write_palette_django():
18441
"""Test write palette read from existing file."""
18442
fname = private_file('django.tiff')
18443
with TiffFile(fname) as tif:
18444
page = tif.pages.first
18445
assert page.photometric == PHOTOMETRIC.PALETTE
18446
assert page.imagewidth == 320
18447
assert page.imagelength == 480
18448
data = page.asarray() # .squeeze() # UserWarning ...
18449
cmap = page.colormap
18451
with TempFileName('write_palette_django') as fname:
18453
fname, data, colormap=cmap, compression=COMPRESSION.ADOBE_DEFLATE
18455
assert_valid_tiff(fname)
18456
with TiffFile(fname) as tif:
18457
assert len(tif.pages) == 1
18458
page = tif.pages.first
18459
assert not page.is_contiguous
18460
assert page.planarconfig == PLANARCONFIG.CONTIG
18461
assert page.photometric == PHOTOMETRIC.PALETTE
18462
assert page.imagewidth == 320
18463
assert page.imagelength == 480
18464
assert page.samplesperpixel == 1
18465
image = page.asrgb(uint8=False)
18466
assert_array_equal(apply_colormap(data, cmap), image)
18470
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
18471
def test_write_multiple_series():
18472
"""Test write multiple data into one file using various options."""
18473
data1 = imread(private_file('ome/multi-channel-4D-series.ome.tif'))
18474
image1 = imread(private_file('django.tiff'))
18475
image2 = imread(private_file('horse-16bit-col-littleendian.tif'))
18476
with TempFileName('write_multiple_series') as fname:
18477
with TiffWriter(fname, bigtiff=False) as tif:
18481
compression=COMPRESSION.ADOBE_DEFLATE,
18482
compressionargs={'level': 5},
18483
description='Django',
18486
tif.write(image2, photometric=PHOTOMETRIC.RGB)
18488
tif.write(data1[0], metadata=dict(axes='TCZYX'))
18489
for i in range(1, data1.shape[0]):
18490
tif.write(data1[i], contiguous=True)
18492
tif.write(data1[0], contiguous=False)
18494
tif.write(data1[0, 0, 0], tile=(64, 64))
18498
compression=COMPRESSION.ADOBE_DEFLATE,
18499
description='DEFLATE',
18501
assert_valid_tiff(fname)
18502
with TiffFile(fname) as tif:
18503
assert len(tif.pages) == 124
18504
assert len(tif.series) == 6
18505
series = tif.series[0]
18506
assert not series.dataoffset
18507
assert series.axes == 'YX'
18508
assert series.kind == 'shaped'
18509
assert_array_equal(image1, series.asarray())
18510
assert_aszarr_method(series, image1)
18511
series = tif.series[1]
18512
assert series.dataoffset
18513
assert series.axes == 'YXS'
18514
assert series.kind == 'shaped'
18515
assert_array_equal(image2, series.asarray())
18516
assert_aszarr_method(series, image2)
18517
series = tif.series[2]
18518
assert series.dataoffset
18519
assert series.keyframe.is_contiguous
18520
assert len(series) == 105
18521
assert len(series.pages) == 105
18522
assert isinstance(series[104], TiffPage)
18523
assert len(series[range(105)]) == 105
18524
assert len(series[slice(0, None, 2)]) == 53
18525
with pytest.raises(TypeError):
18527
assert series.axes == 'TCZYX'
18528
assert series.kind == 'shaped'
18529
result = series.asarray(out='memmap')
18530
assert_array_equal(data1, result)
18531
assert_aszarr_method(series, data1)
18532
assert tif.filehandle.path == result.filename
18534
series = tif.series[3]
18535
assert series.dataoffset
18536
assert series.axes == 'QQYX'
18537
assert series.kind == 'shaped'
18538
assert_array_equal(data1[0], series.asarray())
18539
assert_aszarr_method(series, data1[0])
18540
series = tif.series[4]
18541
assert not series.dataoffset
18542
assert series.axes == 'YX'
18543
assert series.kind == 'shaped'
18544
assert_array_equal(data1[0, 0, 0], series.asarray())
18545
assert_aszarr_method(series, data1[0, 0, 0])
18546
series = tif.series[5]
18547
assert not series.dataoffset
18548
assert series.axes == 'YX'
18549
assert series.kind == 'shaped'
18550
assert_array_equal(image1, series.asarray())
18551
assert_aszarr_method(series, image1)
18554
# test TiffFile.asarray key and series parameters
18555
assert_array_equal(image1, tif.asarray(key=0))
18556
assert_array_equal(image1, tif.asarray(key=-1))
18558
assert_array_equal(image2, tif.asarray(key=[1]))
18559
assert_array_equal(image2, tif.asarray(key=0, series=1))
18560
assert_array_equal(
18561
image2, tif.asarray(key=0, series=tif.series[1])
18564
assert_array_equal(
18565
data1, tif.asarray(key=range(2, 107)).reshape(data1.shape)
18568
assert_array_equal(
18570
tif.asarray(key=range(105), series=2).reshape(data1.shape),
18573
assert_array_equal(
18575
tif.asarray(key=slice(None), series=2).reshape(data1.shape),
18578
assert_array_equal(
18580
tif.asarray(key=slice(107, 122)).reshape(data1[0].shape),
18583
assert_array_equal(
18584
data1[0].reshape(-1, 167, 439)[::2],
18585
tif.asarray(key=slice(107, 122, 2)).reshape((-1, 167, 439)),
18588
with pytest.raises(RuntimeError):
18589
tif.asarray(key=[0, 1])
18591
with pytest.raises(RuntimeError):
18592
tif.asarray(key=[-3, -2])
18594
assert_array_equal(image1, imread(fname, key=0))
18595
assert_array_equal(image1, imread(fname, key=-1))
18596
assert_array_equal(image2, imread(fname, key=[1]))
18597
assert_array_equal(
18598
data1, imread(fname, key=range(2, 107)).reshape(data1.shape)
18600
assert_array_equal(
18601
data1, imread(fname, key=range(105), series=2).reshape(data1.shape)
18603
assert_array_equal(
18605
imread(fname, key=slice(107, 122)).reshape(data1[0].shape),
18609
@pytest.mark.skipif(
18610
SKIP_CODECS or not imagecodecs.PNG.available, reason=REASON
18612
def test_write_multithreaded():
18613
"""Test write large tiled multithreaded."""
18615
numpy.arange(4001 * 6003 * 3)
18616
.astype(numpy.uint8)
18617
.reshape(4001, 6003, 3)
18619
with TempFileName('write_multithreaded') as fname:
18620
imwrite(fname, data, tile=(512, 512), compression='PNG', maxworkers=6)
18621
# assert_valid_tiff(fname)
18622
with TiffFile(fname) as tif:
18623
assert len(tif.pages) == 1
18624
page = tif.pages.first
18625
assert not page.is_contiguous
18626
assert page.compression == COMPRESSION.PNG
18627
assert page.planarconfig == PLANARCONFIG.CONTIG
18628
assert page.imagewidth == 6003
18629
assert page.imagelength == 4001
18630
assert page.samplesperpixel == 3
18631
image = tif.asarray(maxworkers=6)
18632
assert_array_equal(data, image)
18633
assert_aszarr_method(tif, image)
18637
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
18638
def test_write_zarr():
18639
"""Test write to TIFF via Zarr interface."""
18640
with TempFileName('write_zarr', ext='.ome.tif') as fname:
18641
with TiffWriter(fname, bigtiff=True) as tif:
18643
shape=(7, 5, 252, 244),
18644
dtype=numpy.uint16,
18649
shape=(7, 5, 126, 122), dtype=numpy.uint16, tile=(64, 64)
18651
tif.write(shape=(7, 5, 63, 61), dtype=numpy.uint16, tile=(32, 32))
18653
shape=(3, 252, 244),
18656
planarconfig='SEPARATE',
18660
shape=(252, 244, 3),
18666
numpy.zeros((252, 244, 3), numpy.uint8),
18669
compression='zlib',
18672
with TiffFile(fname, mode='r+') as tif:
18673
with tif.series[0].aszarr() as store:
18674
z = zarr.open(store, mode='r+')
18675
z[0][2, 2:3, 100:111, 100:200] = 100
18676
z[1][3, 3:4, 100:111, 100:] = 101
18677
z[2][4, 4:5, 33:40, 41:] = 102
18678
assert tif.asarray(series=0)[2, 2, 100, 199] == 100
18679
assert tif.asarray(series=0, level=1)[3, 3, 100, 121] == 101
18680
assert tif.asarray(series=0, level=2)[4, 4, 33, 41] == 102
18682
with TiffFile(fname, mode='r+') as tif:
18683
with tif.series[1].aszarr() as store:
18684
z = zarr.open(store, mode='r+')
18685
z[1, 100:111, 100:200] = 104
18686
assert tif.series[1].asarray()[1, 100, 199] == 104
18688
with TiffFile(fname, mode='r+') as tif:
18689
with tif.series[2].aszarr() as store:
18690
z = zarr.open(store, mode='r+')
18691
z[200:, 20:, 1] = 105
18692
assert tif.series[2].asarray()[251, 243, 1] == 105
18694
with TiffFile(fname, mode='r+') as tif:
18695
with tif.series[3].aszarr() as store:
18696
z = zarr.open(store, mode='r+')
18697
with pytest.raises(PermissionError):
18701
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
18702
def assert_fsspec(url, data, target_protocol='http'):
18703
"""Assert fsspec ReferenceFileSystem from local http server."""
18704
mapper = fsspec.get_mapper(
18705
'reference://', fo=url, target_protocol=target_protocol
18707
zobj = zarr.open(mapper, mode='r')
18708
if isinstance(zobj, zarr.Group):
18709
assert_array_equal(zobj[0][:], data)
18710
assert_array_equal(zobj[1][:], data[:, ::2, ::2])
18711
assert_array_equal(zobj[2][:], data[:, ::4, ::4])
18713
assert_array_equal(zobj[:], data)
18716
@pytest.mark.skipif(
18717
SKIP_HTTP or SKIP_ZARR or SKIP_CODECS or not imagecodecs.JPEG.available,
18720
@pytest.mark.parametrize('byteorder', ['<', '>'])
18721
@pytest.mark.parametrize('version', [0, 1])
18722
def test_write_fsspec(version, byteorder):
18723
"""Test write fsspec for multi-series OME-TIFF."""
18724
from imagecodecs.numcodecs import register_codecs
18726
register_codecs('imagecodecs_jpeg', verbose=False)
18727
register_codecs('imagecodecs_delta', verbose=False)
18728
register_codecs('imagecodecs_floatpred', verbose=False)
18730
data0 = random_data(numpy.uint8, (3, 252, 244))
18731
data1 = random_data(numpy.uint8, (219, 301, 3))
18732
data2 = random_data(numpy.uint16, (3, 219, 301))
18733
data3 = random_data(numpy.float32, (210, 301))
18735
bo = {'>': 'be', '<': 'le'}[byteorder]
18738
f'write_fsspec_v{version}_{bo}', ext='.ome.tif'
18740
filename = os.path.split(fname)[-1]
18741
with TiffWriter(fname, ome=True, byteorder=byteorder) as tif:
18745
photometric=PHOTOMETRIC.MINISBLACK,
18746
compression=COMPRESSION.DEFLATE,
18747
predictor=PREDICTOR.HORIZONTAL,
18749
tif.write(data0, subifds=2, **options)
18750
tif.write(data0[:, ::2, ::2], subfiletype=1, **options)
18751
tif.write(data0[:, ::4, ::4], subfiletype=1, **options)
18754
data1, photometric=PHOTOMETRIC.RGB, rowsperstrip=data1.shape[0]
18759
rowsperstrip=data1.shape[1],
18760
photometric=PHOTOMETRIC.RGB,
18761
planarconfig=PLANARCONFIG.SEPARATE,
18762
compression=COMPRESSION.DEFLATE,
18763
predictor=PREDICTOR.HORIZONTAL,
18766
tif.write(data1, photometric=PHOTOMETRIC.RGB, rowsperstrip=5)
18770
photometric=PHOTOMETRIC.RGB,
18772
compression=COMPRESSION.JPEG,
18778
photometric=PHOTOMETRIC.MINISBLACK,
18779
compression=COMPRESSION.DEFLATE,
18780
predictor=PREDICTOR.FLOATINGPOINT,
18783
with TiffFile(fname) as tif:
18785
assert len(tif.series) == 6
18787
# TODO: clean up temp JSON files
18788
with tif.series[0].aszarr() as store:
18789
assert store.is_multiscales
18790
store.write_fsspec(
18791
fname + f'.v{version}.s0.json', URL, version=version
18793
assert_array_equal(tif.series[0].asarray(), data0)
18794
assert_fsspec(URL + filename + f'.v{version}.s0.json', data0)
18796
with tif.series[1].aszarr() as store:
18797
assert not store.is_multiscales
18798
store.write_fsspec(
18799
fname + f'.v{version}.s1.json', URL, version=version
18801
assert_array_equal(tif.series[1].asarray(), data1)
18802
assert_fsspec(URL + filename + f'.v{version}.s1.json', data1)
18804
with tif.series[2].aszarr() as store:
18805
store.write_fsspec(
18806
fname + f'.v{version}.s2.json', URL, version=version
18808
assert_array_equal(tif.series[2].asarray(), data2)
18809
assert_fsspec(URL + filename + f'.v{version}.s2.json', data2)
18811
with tif.series[3].aszarr(chunkmode=2) as store:
18812
store.write_fsspec(
18813
fname + f'.v{version}.s3.json', URL, version=version
18815
assert_array_equal(tif.series[3].asarray(), data1)
18816
assert_fsspec(URL + filename + f'.v{version}.s3.json', data1)
18818
with tif.series[3].aszarr() as store:
18819
with pytest.raises(ValueError):
18820
# imagelength % rowsperstrip != 0
18821
store.write_fsspec(
18822
fname + f'.v{version}.s3fail.json',
18827
with tif.series[4].aszarr() as store:
18828
store.write_fsspec(
18829
fname + f'.v{version}.s4.json', URL, version=version
18832
URL + filename + f'.v{version}.s4.json',
18833
tif.series[4].asarray(),
18836
with tif.series[5].aszarr() as store:
18837
store.write_fsspec(
18838
fname + f'.v{version}.s5.json', URL, version=version
18840
assert_array_equal(tif.series[5].asarray(), data3)
18841
assert_fsspec(URL + filename + f'.v{version}.s5.json', data3)
18844
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
18845
@pytest.mark.parametrize('version', [0, 1])
18846
@pytest.mark.parametrize('chunkmode', [0, 2])
18847
def test_write_fsspec_multifile(version, chunkmode):
18848
"""Test write fsspec for multi-file OME series."""
18849
fname = public_file('OME/multifile/multifile-Z1.ome.tiff')
18850
url = os.path.dirname(fname).replace('\\', '/')
18852
f'write_fsspec_multifile_{version}{chunkmode}', ext='.json'
18854
# write to file handle
18855
with open(jsonfile, 'w', encoding='utf-8') as fh:
18856
with TiffFile(fname) as tif:
18857
data = tif.series[0].asarray()
18858
with tif.series[0].aszarr(chunkmode=chunkmode) as store:
18859
store.write_fsspec(
18860
fh, url=url, version=version, templatename='f'
18862
mapper = fsspec.get_mapper(
18865
target_protocol='file',
18866
remote_protocol='file',
18868
zobj = zarr.open(mapper, mode='r')
18869
assert_array_equal(zobj[:], data)
18872
@pytest.mark.skipif(
18873
SKIP_PRIVATE or SKIP_LARGE or SKIP_CODECS or SKIP_ZARR,
18876
@pytest.mark.parametrize('version', [1]) # 0,
18877
def test_write_fsspec_sequence(version):
18878
"""Test write fsspec for multi-file sequence."""
18879
# https://bbbc.broadinstitute.org/BBBC006
18880
categories = {'p': {chr(i + 97): i for i in range(25)}}
18881
ptrn = r'(?:_(z)_(\d+)).*_(?P<p>[a-z])(?P<a>\d+)(?:_(s)(\d))(?:_(w)(\d))'
18882
fnames = private_file('BBBC/BBBC006_v1_images_z_00/*.tif')
18883
fnames += private_file('BBBC/BBBC006_v1_images_z_01/*.tif')
18884
tifs = TiffSequence(
18886
imread=imagecodecs.imread,
18888
axesorder=(1, 2, 0, 3, 4),
18889
categories=categories,
18891
assert len(tifs) == 3072
18892
assert tifs.shape == (16, 24, 2, 2, 2)
18893
assert tifs.axes == 'PAZSW'
18894
data = tifs.asarray()
18896
'write_fsspec_sequence', ext=f'.v{version}.json'
18898
with tifs.aszarr(codec=imagecodecs.tiff_decode) as store:
18899
store.write_fsspec(
18901
'file:///' + store._commonpath.replace('\\', '/'),
18904
mapper = fsspec.get_mapper(
18905
'reference://', fo=fname, target_protocol='file'
18908
from imagecodecs.numcodecs import register_codecs
18912
za = zarr.open(mapper, mode='r')
18913
assert_array_equal(za[:], data)
18916
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_ZARR, reason=REASON)
18917
def test_write_tiff2fsspec():
18918
"""Test tiff2fsspec function."""
18919
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
18920
url = os.path.dirname(fname).replace('\\', '/')
18921
data = imread(fname, series=0, level=1, maxworkers=1)
18922
with TempFileName('write_tiff2fsspec', ext='.json') as jsonfile:
18931
mapper = fsspec.get_mapper(
18934
target_protocol='file',
18935
remote_protocol='file',
18937
zobj = zarr.open(mapper, mode='r')
18938
assert_array_equal(zobj[:], data)
18940
with pytest.raises(ValueError):
18948
chunkmode=CHUNKMODE.PAGE,
18952
@pytest.mark.skipif(SKIP_ZARR, reason=REASON)
18953
def test_write_numcodecs():
18954
"""Test write Zarr with numcodecs.Tiff."""
18955
from tifffile import numcodecs
18957
data = numpy.arange(256 * 256 * 3, dtype=numpy.uint16).reshape(256, 256, 3)
18958
numcodecs.register_codec()
18959
compressor = numcodecs.Tiff(
18961
photometric=PHOTOMETRIC.MINISBLACK,
18962
planarconfig=PLANARCONFIG.CONTIG,
18963
compression=COMPRESSION.ADOBE_DEFLATE,
18964
compressionargs={'level': 5},
18967
with TempFileName('write_numcodecs', ext='.zarr') as fname:
18971
shape=(256, 256, 3),
18972
chunks=(100, 100, 3),
18973
dtype=numpy.uint16,
18974
compressor=compressor,
18977
assert_array_equal(z[:], data)
18980
###############################################################################
18985
@pytest.mark.skipif(SKIP_EXTENDED, reason=REASON)
18986
@pytest.mark.parametrize(
19002
(1, 3, 1, 219, 301),
19003
(3, 1, 1, 219, 301),
19004
(1, 3, 4, 219, 301),
19005
(3, 1, 4, 219, 301),
19006
(3, 4, 1, 219, 301),
19007
(3, 4, 1, 219, 301, 3),
19008
(2, 3, 4, 219, 301),
19009
(4, 3, 2, 219, 301, 3),
19012
@pytest.mark.parametrize(
19013
'dtype', [numpy.uint8, numpy.uint16, numpy.int16, numpy.float32]
19015
@pytest.mark.parametrize('byteorder', ['>', '<'])
19016
def test_write_imagej(byteorder, dtype, shape):
19017
"""Test write ImageJ format."""
19018
# TODO: test compression and bigtiff ?
19019
dtype = numpy.dtype(dtype)
19020
if dtype != numpy.uint8 and shape[-1] in {3, 4}:
19021
pytest.xfail('ImageJ only supports uint8 RGB')
19022
data = random_data(dtype, shape)
19023
fname = 'write_imagej_{}_{}_{}'.format(
19024
{'<': 'le', '>': 'be'}[byteorder], dtype, str(shape).replace(' ', '')
19026
with TempFileName(fname) as fname:
19027
imwrite(fname, data, byteorder=byteorder, imagej=True)
19028
image = imread(fname)
19029
assert_array_equal(data.squeeze(), image.squeeze())
19030
# TODO: assert_aszarr_method
19031
assert_valid_tiff(fname)
19034
def test_write_imagej_voxel_size():
19035
"""Test write ImageJ with xyz voxel size 2.6755x2.6755x3.9474 µm^3."""
19036
data = numpy.zeros((4, 256, 256), dtype=numpy.float32)
19037
data.shape = 4, 1, 256, 256
19038
with TempFileName('write_imagej_voxel_size') as fname:
19043
resolution=(0.373759, 0.373759),
19044
metadata={'spacing': 3.947368, 'unit': 'um'},
19046
with TiffFile(fname) as tif:
19047
assert tif.is_imagej
19048
ijmeta = tif.imagej_metadata
19049
assert ijmeta is not None
19050
assert 'unit' in ijmeta
19051
assert ijmeta['unit'] == 'um'
19052
series = tif.series[0]
19053
assert series.kind == 'imagej'
19054
assert series.axes == 'ZYX'
19055
assert series.shape == (4, 256, 256)
19056
assert series.get_axes(False) == 'TZCYXS'
19057
assert series.get_shape(False) == (1, 4, 1, 256, 256, 1)
19059
assert_valid_tiff(fname)
19062
def test_write_imagej_metadata():
19063
"""Test write additional ImageJ metadata."""
19064
data = numpy.empty((4, 256, 256), dtype=numpy.uint16)
19065
data[:] = numpy.arange(256 * 256, dtype=numpy.uint16).reshape(1, 256, 256)
19066
with TempFileName('write_imagej_metadata') as fname:
19067
imwrite(fname, data, imagej=True, metadata={'unit': 'um'})
19068
with TiffFile(fname) as tif:
19069
assert tif.is_imagej
19070
assert tif.imagej_metadata is not None
19071
assert 'unit' in tif.imagej_metadata
19072
assert tif.imagej_metadata['unit'] == 'um'
19074
assert_valid_tiff(fname)
19077
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
19078
def test_write_imagej_ijmetadata_tag():
19079
"""Test write and read IJMetadata tag."""
19080
fname = private_file('imagej/IJMetadata.tif')
19081
with TiffFile(fname) as tif:
19082
assert tif.is_imagej
19083
assert tif.byteorder == '>'
19084
assert len(tif.pages) == 3
19085
assert len(tif.series) == 1
19086
data = tif.asarray()
19087
ijmeta = tif.pages.first.tags['IJMetadata'].value
19089
assert ijmeta['Info'][:21] == 'FluorescentCells.tif\n'
19090
assert ijmeta['ROI'][:5] == b'Iout\x00'
19091
assert ijmeta['Overlays'][1][:5] == b'Iout\x00'
19092
assert ijmeta['Ranges'] == (0.0, 255.0, 0.0, 255.0, 0.0, 255.0)
19093
assert ijmeta['Labels'] == ['Red', 'Green', 'Blue']
19094
assert ijmeta['LUTs'][2][2, 255] == 255
19095
assert_valid_tiff(fname)
19097
with TempFileName('write_imagej_ijmetadata') as fname:
19098
with pytest.raises(TypeError):
19104
metadata={'mode': 'composite'},
19113
metadata={**ijmeta, 'mode': 'composite'},
19115
with TiffFile(fname) as tif:
19116
assert tif.is_imagej
19117
assert tif.byteorder == '>'
19118
assert len(tif.pages) == 3
19119
assert len(tif.series) == 1
19120
imagej_metadata = tif.imagej_metadata
19121
data2 = tif.asarray()
19122
ijmeta2 = tif.pages.first.tags['IJMetadata'].value
19126
assert_array_equal(data, data2)
19127
assert imagej_metadata is not None
19128
assert imagej_metadata['mode'] == 'composite'
19129
assert imagej_metadata['Info'] == ijmeta['Info']
19130
assert ijmeta2['Info'] == ijmeta['Info']
19131
assert ijmeta2['ROI'] == ijmeta['ROI']
19132
assert ijmeta2['Overlays'] == ijmeta['Overlays']
19133
assert ijmeta2['Ranges'] == ijmeta['Ranges']
19134
assert ijmeta2['Labels'] == ijmeta['Labels']
19135
assert_array_equal(ijmeta2['LUTs'][2], ijmeta['LUTs'][2])
19136
assert_valid_tiff(fname)
19139
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
19140
def test_write_imagej_roundtrip():
19141
"""Test ImageJ metadata survive read/write roundtrip."""
19142
fname = private_file('imagej/IJMetadata.tif')
19143
with TiffFile(fname) as tif:
19144
assert tif.is_imagej
19145
assert tif.byteorder == '>'
19146
assert len(tif.pages) == 3
19147
assert len(tif.series) == 1
19148
data = tif.asarray()
19149
ijmeta = tif.imagej_metadata
19151
assert ijmeta is not None
19152
assert ijmeta['Info'][:21] == 'FluorescentCells.tif\n'
19153
assert ijmeta['ROI'][:5] == b'Iout\x00'
19154
assert ijmeta['Overlays'][1][:5] == b'Iout\x00'
19155
assert ijmeta['Ranges'] == (0.0, 255.0, 0.0, 255.0, 0.0, 255.0)
19156
assert ijmeta['Labels'] == ['Red', 'Green', 'Blue']
19157
assert ijmeta['LUTs'][2][2, 255] == 255
19158
assert ijmeta['mode'] == 'composite'
19159
assert not ijmeta['loop']
19160
assert ijmeta['ImageJ'] == '1.52b'
19161
assert_valid_tiff(fname)
19163
with TempFileName('write_imagej_ijmetadata_roundtrip') as fname:
19164
imwrite(fname, data, byteorder='>', imagej=True, metadata=ijmeta)
19166
with TiffFile(fname) as tif:
19167
assert tif.is_imagej
19168
assert tif.byteorder == '>'
19169
assert len(tif.pages) == 3
19170
assert len(tif.series) == 1
19171
ijmeta2 = tif.imagej_metadata
19172
data2 = tif.asarray()
19175
assert_array_equal(data, data2)
19176
assert ijmeta2 is not None
19177
assert ijmeta2['ImageJ'] == ijmeta['ImageJ']
19178
assert ijmeta2['mode'] == ijmeta['mode']
19179
assert ijmeta2['Info'] == ijmeta['Info']
19180
assert ijmeta2['ROI'] == ijmeta['ROI']
19181
assert ijmeta2['Overlays'] == ijmeta['Overlays']
19182
assert ijmeta2['Ranges'] == ijmeta['Ranges']
19183
assert ijmeta2['Labels'] == ijmeta['Labels']
19184
assert_array_equal(ijmeta2['LUTs'][2], ijmeta['LUTs'][2])
19185
assert_valid_tiff(fname)
19188
@pytest.mark.parametrize('mmap', [False, True])
19189
@pytest.mark.parametrize('truncate', [False, True])
19190
def test_write_imagej_hyperstack(truncate, mmap):
19191
"""Test write ImageJ hyperstack."""
19192
shape = (5, 6, 7, 49, 61, 3)
19193
data = numpy.empty(shape, dtype=numpy.uint8)
19194
data[:] = numpy.arange(210, dtype=numpy.uint8).reshape(5, 6, 7, 1, 1, 1)
19196
_truncate = ['', '_trunc'][truncate]
19197
_memmap = ['', '_memmap'][mmap]
19198
with TempFileName(f'write_imagej_hyperstack{_truncate}{_memmap}') as fname:
19210
imwrite(fname, data, truncate=truncate, imagej=True)
19212
with TiffFile(fname) as tif:
19213
assert not tif.is_bigtiff
19214
assert not tif.is_shaped
19215
assert len(tif.pages) == 1 if truncate else 210
19216
page = tif.pages.first
19217
assert page.is_contiguous
19218
assert page.planarconfig == PLANARCONFIG.CONTIG
19219
assert page.photometric == PHOTOMETRIC.RGB
19220
assert page.imagewidth == 61
19221
assert page.imagelength == 49
19222
assert page.samplesperpixel == 3
19223
# assert series properties
19224
series = tif.series[0]
19225
assert series.is_truncated == truncate
19226
assert series.kind == 'imagej'
19227
assert series.shape == shape
19228
assert len(series._pages) == 1
19229
assert len(series.pages) == 1 if truncate else 210
19230
assert series.dtype == numpy.uint8
19231
assert series.axes == 'TZCYXS'
19232
assert series.get_axes(False) == 'TZCYXS'
19233
assert series.get_shape(False) == shape
19235
image = tif.asarray(out='memmap')
19236
assert_array_equal(data.squeeze(), image.squeeze())
19238
# assert iterating over series.pages
19239
data = data.reshape((210, 49, 61, 3))
19240
for i, page in enumerate(series.pages):
19241
image = page.asarray()
19242
assert_array_equal(data[i], image)
19245
assert_valid_tiff(fname)
19248
def test_write_imagej_append():
19249
"""Test write ImageJ file consecutively."""
19250
data = numpy.empty((256, 1, 256, 256), dtype=numpy.uint8)
19251
data[:] = numpy.arange(256, dtype=numpy.uint8).reshape(-1, 1, 1, 1)
19253
with TempFileName('write_imagej_append') as fname:
19254
with TiffWriter(fname, imagej=True) as tif:
19256
tif.write(image, contiguous=True)
19258
assert_valid_tiff(fname)
19261
with TiffFile(fname) as tif:
19262
assert not tif.is_bigtiff
19263
assert not tif.is_shaped
19264
assert len(tif.pages) == 256
19265
page = tif.pages.first
19266
assert page.is_contiguous
19267
assert page.planarconfig == PLANARCONFIG.CONTIG
19268
assert page.photometric != PHOTOMETRIC.RGB
19269
assert page.imagewidth == 256
19270
assert page.imagelength == 256
19271
assert page.samplesperpixel == 1
19272
# assert series properties
19273
series = tif.series[0]
19274
assert series.kind == 'imagej'
19275
assert series.shape == (256, 256, 256)
19276
assert series.dtype == numpy.uint8
19277
assert series.axes == 'ZYX'
19278
assert series.get_axes(False) == 'TZCYXS'
19279
assert series.get_shape(False) == (1, 256, 1, 256, 256, 1)
19281
image = tif.asarray(out='memmap')
19282
assert_array_equal(data.squeeze(), image)
19287
def test_write_imagej_bigtiff():
19288
"""Test write ImageJ BigTIFF with warning."""
19289
with TempFileName('write_imagej_bigtiff') as fname:
19290
with pytest.warns(UserWarning):
19294
dtype=numpy.float32,
19301
@pytest.mark.skipif(SKIP_LARGE, reason=REASON)
19302
def test_write_imagej_raw():
19303
"""Test write ImageJ 5 GB raw file."""
19304
data = numpy.empty((1280, 1, 1024, 1024), dtype=numpy.float32)
19305
data[:] = numpy.arange(1280, dtype=numpy.float32).reshape(-1, 1, 1, 1)
19307
with TempFileName('write_imagej_big') as fname:
19308
with pytest.warns(UserWarning):
19309
# UserWarning: truncating ImageJ file
19310
imwrite(fname, data, imagej=True)
19311
assert_valid_tiff(fname)
19313
with TiffFile(fname) as tif:
19314
assert not tif.is_bigtiff
19315
assert not tif.is_shaped
19316
assert len(tif.pages) == 1
19317
page = tif.pages.first
19318
assert page.is_contiguous
19319
assert page.planarconfig == PLANARCONFIG.CONTIG
19320
assert page.photometric != PHOTOMETRIC.RGB
19321
assert page.imagewidth == 1024
19322
assert page.imagelength == 1024
19323
assert page.samplesperpixel == 1
19324
# assert series properties
19325
series = tif.series[0]
19326
assert series.kind == 'imagej'
19327
assert len(series._pages) == 1
19328
assert len(series.pages) == 1
19329
assert series.shape == (1280, 1024, 1024)
19330
assert series.dtype == numpy.float32
19331
assert series.axes == 'ZYX'
19332
assert series.get_axes(False) == 'TZCYXS'
19333
assert series.get_shape(False) == (1, 1280, 1, 1024, 1024, 1)
19335
image = tif.asarray(out='memmap')
19336
assert_array_equal(data.squeeze(), image.squeeze())
19340
store = imread(fname, aszarr=True)
19342
z = zarr.open(store, mode='r')
19343
chunk = z[333:356, 99:513, 31:127]
19346
assert_array_equal(chunk, data[333:356, 0, 99:513, 31:127])
19348
store = imread(fname, aszarr=True, chunkmode=2)
19350
z = zarr.open(store, mode='r')
19351
chunk = z[333:356, 99:513, 31:127]
19354
assert_array_equal(chunk, data[333:356, 0, 99:513, 31:127])
19359
@pytest.mark.skipif(SKIP_EXTENDED, reason=REASON)
19360
@pytest.mark.parametrize(
19363
((219, 301, 1), None),
19364
((219, 301, 2), None),
19365
((219, 301, 3), None),
19366
((219, 301, 4), None),
19367
((219, 301, 5), None),
19368
((1, 219, 301), None),
19369
((2, 219, 301), None),
19370
((3, 219, 301), None),
19371
((4, 219, 301), None),
19372
((5, 219, 301), None),
19373
((4, 3, 219, 301), None),
19374
((4, 219, 301, 3), None),
19375
((3, 4, 219, 301), None),
19376
((1, 3, 1, 219, 301), None),
19377
((3, 1, 1, 219, 301), None),
19378
((1, 3, 4, 219, 301), None),
19379
((3, 1, 4, 219, 301), None),
19380
((3, 4, 1, 219, 301), None),
19381
((3, 4, 1, 219, 301, 3), None),
19382
((2, 3, 4, 219, 301), None),
19383
((4, 3, 2, 219, 301, 3), None),
19384
((3, 33, 31), 'CYX'),
19385
((33, 31, 3), 'YXC'),
19386
((5, 1, 33, 31), 'CSYX'),
19387
((5, 1, 33, 31), 'ZCYX'),
19388
((2, 3, 4, 219, 301, 3), 'TCZYXS'),
19389
((10, 5, 63, 65), 'EPYX'),
19390
((2, 3, 4, 5, 6, 7, 33, 31, 3), 'TQCPZRYXS'),
19393
def test_write_ome(shape, axes):
19394
"""Test write OME-TIFF format."""
19396
planarconfig = None
19397
if shape[-1] in {3, 4}:
19398
photometric = PHOTOMETRIC.RGB
19399
planarconfig = PLANARCONFIG.CONTIG
19400
elif shape[-3] in {3, 4}:
19401
photometric = PHOTOMETRIC.RGB
19402
planarconfig = PLANARCONFIG.SEPARATE
19404
metadata = {'axes': axes} if axes is not None else None
19405
data = random_data(numpy.uint8, shape)
19406
fname = 'write_ome_{}.ome'.format(str(shape).replace(' ', ''))
19407
with TempFileName(fname) as fname:
19412
photometric=photometric,
19413
planarconfig=planarconfig,
19415
with TiffFile(fname) as tif:
19417
assert not tif.is_shaped
19418
assert tif.series[0].kind == 'ome'
19419
image = tif.asarray()
19420
omexml = tif.ome_metadata
19424
elif axes == 'YXC':
19426
assert tif.series[0].axes == squeeze_axes(shape, axes)[1]
19427
assert_array_equal(data.squeeze(), image.squeeze())
19428
assert_aszarr_method(tif, image)
19429
assert_valid_omexml(omexml)
19430
assert_valid_tiff(fname)
19433
def test_write_ome_enable():
19434
"""Test OME-TIFF enabling."""
19435
data = numpy.zeros((32, 32), dtype=numpy.uint8)
19436
with TempFileName('write_ome_enable.ome') as fname:
19437
imwrite(fname, data)
19438
with TiffFile(fname) as tif:
19440
imwrite(fname, data, description='not OME')
19441
with TiffFile(fname) as tif:
19442
assert not tif.is_ome
19443
with pytest.warns(UserWarning):
19444
imwrite(fname, data, description='not OME', ome=True)
19445
with TiffFile(fname) as tif:
19447
imwrite(fname, data, imagej=True)
19448
with TiffFile(fname) as tif:
19449
assert not tif.is_ome
19450
assert tif.is_imagej
19451
imwrite(fname, data, imagej=True, ome=True)
19452
with TiffFile(fname) as tif:
19454
assert not tif.is_imagej
19456
with TempFileName('write_ome_auto.tif') as fname:
19457
imwrite(fname, data)
19458
with TiffFile(fname) as tif:
19459
assert not tif.is_ome
19460
imwrite(fname, data, ome=True)
19461
with TiffFile(fname) as tif:
19465
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
19466
@pytest.mark.parametrize(
19467
'method', ['manual', 'copy', 'iter', 'compression', 'xml', 'dask']
19469
def test_write_ome_methods(method):
19470
"""Test re-write OME-TIFF."""
19471
# 4D (7 time points, 5 focal planes)
19472
if method == 'dask' and SKIP_DASK:
19473
pytest.skip('skip dask')
19475
fname = public_file('OME/bioformats-artificial/4D-series.ome.tiff')
19476
with TiffFile(fname) as tif:
19477
series = tif.series[0]
19478
data = series.asarray()
19482
omexml = tif.ome_metadata
19483
if method == 'dask':
19484
store = series.aszarr()
19485
darr = dask.array.from_zarr(store)
19488
yield from data.reshape(-1, *data.shape[-2:])
19490
with TempFileName(f'write_ome_{method}.ome') as fname:
19491
if method == 'xml':
19492
# use original XML metadata
19493
metadata = xml2dict(omexml)
19494
metadata['axes'] = axes
19499
photometric=PHOTOMETRIC.MINISBLACK,
19503
elif method == 'manual':
19504
# manually write omexml to first page and data to individual pages
19506
omexml = omexml.replace(
19507
'4D-series.ome.tiff', os.path.split(fname)[-1]
19509
# omexml = omexml.replace('BigEndian="true"', 'BigEndian="false"')
19510
data = data.view(data.dtype.newbyteorder('>'))
19511
# save image planes in the order referenced in the OME-XML
19512
# make sure storage options (compression, byteorder, photometric)
19514
# write OME-XML to first page only
19515
with TiffWriter(fname, byteorder='>') as tif:
19516
for i, image in enumerate(pages()):
19517
description = omexml if i == 0 else None
19520
description=description,
19521
photometric=PHOTOMETRIC.MINISBLACK,
19526
elif method == 'iter':
19527
# use iterator over individual pages
19534
photometric=PHOTOMETRIC.MINISBLACK,
19535
metadata={'axes': axes},
19538
elif method == 'compression':
19539
# use iterator with compression
19546
photometric=PHOTOMETRIC.MINISBLACK,
19547
compression=COMPRESSION.ADOBE_DEFLATE,
19548
metadata={'axes': axes},
19551
elif method == 'copy':
19552
# use one numpy array
19557
photometric=PHOTOMETRIC.MINISBLACK,
19558
metadata={'axes': axes},
19561
elif method == 'dask':
19567
photometric=PHOTOMETRIC.MINISBLACK,
19568
compression=COMPRESSION.ADOBE_DEFLATE,
19569
metadata={'axes': axes},
19574
with TiffFile(fname) as tif:
19576
assert tif.byteorder == '>'
19577
assert len(tif.pages) == 35
19578
assert len(tif.series) == 1
19579
# assert page properties
19580
page = tif.pages.first
19581
if method not in {'compression', 'dask'}:
19582
assert page.is_contiguous
19583
assert page.compression == COMPRESSION.NONE
19584
assert page.imagewidth == 439
19585
assert page.imagelength == 167
19586
assert page.bitspersample == 8
19587
assert page.samplesperpixel == 1
19588
# assert series properties
19589
series = tif.series[0]
19590
assert series.kind == 'ome'
19591
assert series.shape == (7, 5, 167, 439)
19592
assert series.dtype == numpy.int8
19593
assert series.axes == 'TZYX'
19595
assert_array_equal(data, tif.asarray())
19596
assert_valid_omexml(tif.ome_metadata)
19599
assert_valid_tiff(fname)
19602
@pytest.mark.parametrize('contiguous', [True, False])
19603
def test_write_ome_manual(contiguous):
19604
"""Test write OME-TIFF manually."""
19605
data = numpy.random.randint(0, 255, (19, 31, 21), numpy.uint8)
19607
with TempFileName(f'write_ome__manual{int(contiguous)}.ome') as fname:
19608
with TiffWriter(fname) as tif:
19609
# successively write image data to TIFF pages
19610
# disable tifffile from writing any metadata
19611
# add empty ImageDescription tag to first page
19612
for i, frame in enumerate(data):
19615
contiguous=contiguous,
19617
description=None if i else b'',
19619
# update ImageDescription tag with custom OME-XML
19622
numpy.uint8, (16, 31, 21), (16, 1, 1, 31, 21, 1), axes='ZYX'
19625
numpy.uint8, (3, 31, 21), (3, 1, 1, 31, 21, 1), axes='CYX'
19627
tif.overwrite_description(xml.tostring())
19629
with TiffFile(fname) as tif:
19631
assert len(tif.pages) == 19
19632
assert len(tif.series) == 2
19633
# assert series properties
19634
series = tif.series[0]
19635
assert series.kind == 'ome'
19636
assert series.axes == 'ZYX'
19637
assert bool(series.dataoffset) == contiguous
19638
assert_array_equal(data[:16], series.asarray())
19639
series = tif.series[1]
19640
assert series.kind == 'ome'
19641
assert series.axes == 'CYX'
19642
assert bool(series.dataoffset) == contiguous
19643
assert_array_equal(data[16:], series.asarray())
19645
assert_valid_omexml(tif.ome_metadata)
19648
assert_valid_tiff(fname)
19651
@pytest.mark.skipif(
19652
SKIP_PUBLIC or SKIP_CODECS or not imagecodecs.JPEG.available,
19655
def test_rewrite_ome():
19656
"""Test rewrite multi-series, pyramidal OME-TIFF."""
19657
# https://github.com/cgohlke/tifffile/issues/156
19658
# - data loss in case of JPEG recompression; copy tiles verbatim
19659
# - OME metadata not copied; use ometypes library after writing
19660
# - tifffile does not support multi-file OME-TIFF writing
19661
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
19662
with TiffFile(fname) as tif:
19664
with TempFileName('rewrite_ome', ext='.ome.tif') as fname_copy:
19667
bigtiff=tif.is_bigtiff,
19668
byteorder=tif.byteorder,
19671
for series in tif.series:
19672
subifds = len(series.levels) - 1
19673
metadata = {'axes': series.axes}
19674
for level in series.levels:
19675
keyframe = level.keyframe
19678
planarconfig=keyframe.planarconfig,
19679
photometric=keyframe.photometric,
19680
extrasamples=keyframe.extrasamples,
19681
tile=keyframe.tile,
19682
rowsperstrip=keyframe.rowsperstrip,
19683
compression=keyframe.compression,
19684
predictor=keyframe.predictor,
19685
subsampling=keyframe.subsampling,
19686
datetime=keyframe.datetime,
19687
resolution=keyframe.resolution,
19688
resolutionunit=keyframe.resolutionunit,
19689
subfiletype=keyframe.subfiletype,
19690
colormap=keyframe.colormap,
19691
iccprofile=keyframe.iccprofile,
19698
with TiffFile(fname_copy) as copy:
19699
assert copy.byteorder == tif.byteorder
19700
assert copy.is_bigtiff == tif.is_bigtiff
19701
assert copy.is_imagej == tif.is_imagej
19702
assert copy.is_ome == tif.is_ome
19703
assert len(tif.series) == len(copy.series)
19704
for series, series_copy in zip(tif.series, copy.series):
19705
assert len(series.levels) == len(series_copy.levels)
19706
metadata = {'axes': series.axes}
19707
for level, level_copy in zip(
19708
series.levels, series_copy.levels
19710
assert len(level.pages) == len(level_copy.pages)
19711
assert level.shape == level_copy.shape
19712
assert level.dtype == level_copy.dtype
19713
assert level.keyframe.hash == level_copy.keyframe.hash
19716
@pytest.mark.skipif(
19720
or not imagecodecs.JPEG.available,
19723
def test_write_ome_copy():
19724
"""Test write pyramidal OME-TIFF by copying compressed tiles from SVS."""
19727
# return iterator over compressed tiles in page
19728
assert page.is_tiled
19729
fh = page.parent.filehandle
19730
for offset, bytecount in zip(page.dataoffsets, page.databytecounts):
19732
yield fh.read(bytecount)
19734
with TiffFile(private_file('AperioSVS/CMU-1.svs')) as svs:
19736
levels = svs.series[0].levels
19738
with TempFileName('write_ome_copy', ext='.ome.tif') as fname:
19739
with TiffWriter(fname, ome=True, bigtiff=True) as tif:
19741
assert len(level.pages) == 1
19742
page = level.pages[0]
19743
if page.compression == 7:
19744
# override default that RGB will be compressed as YCBCR
19745
compressionargs = {'outcolorspace': page.photometric}
19747
compressionargs = {}
19749
# copy some extra tags
19750
page.tags.get('ImageDepth').astuple(), # this is ignored
19751
page.tags.get('InterColorProfile').astuple(),
19758
datetime=page.datetime,
19759
photometric=page.photometric,
19760
planarconfig=page.planarconfig,
19761
compression=page.compression,
19762
compressionargs=compressionargs,
19763
jpegtables=page.jpegtables,
19764
iccprofile=page.iccprofile,
19765
subsampling=page.subsampling,
19766
subifds=len(levels) - 1,
19767
extratags=extratags,
19769
for level in levels[1:]:
19770
assert len(level.pages) == 1
19771
page = level.pages[0]
19772
if page.compression == 7:
19773
compressionargs = {'outcolorspace': page.photometric}
19775
compressionargs = {}
19781
datetime=page.datetime,
19782
photometric=page.photometric,
19783
planarconfig=page.planarconfig,
19784
compression=page.compression,
19785
compressionargs=compressionargs,
19786
jpegtables=page.jpegtables,
19787
iccprofile=page.iccprofile,
19788
subsampling=page.subsampling,
19792
with TiffFile(fname) as tif:
19794
assert len(tif.pages) == 1
19795
assert len(tif.pages.first.pages) == 2
19796
assert 'InterColorProfile' in tif.pages.first.tags
19797
assert 'ImageDepth' not in tif.pages.first.tags
19798
assert tif.series[0].kind == 'ome'
19799
levels_ = tif.series[0].levels
19800
assert len(levels_) == len(levels)
19801
for level, level_ in zip(levels[1:], levels_[1:]):
19802
assert level.shape == level_.shape
19803
assert level.dtype == level_.dtype
19804
assert_array_equal(level.asarray(), level_.asarray())
19807
@pytest.mark.skipif(
19808
SKIP_PRIVATE or SKIP_CODECS or not imagecodecs.JPEG.available,
19811
def test_write_geotiff_copy():
19812
"""Test write a copy of striped, compressed GeoTIFF."""
19815
# return iterator over compressed strips in page
19816
assert not page.is_tiled
19817
fh = page.parent.filehandle
19818
for offset, bytecount in zip(page.dataoffsets, page.databytecounts):
19820
yield fh.read(bytecount)
19822
with TiffFile(private_file('GeoTIFF/ML_30m.tif')) as geotiff:
19823
assert geotiff.is_geotiff
19824
assert len(geotiff.pages) == 1
19826
with TempFileName('write_geotiff_copy') as fname:
19828
fname, byteorder=geotiff.byteorder, bigtiff=geotiff.is_bigtiff
19830
page = geotiff.pages[0]
19833
tags.get('ModelPixelScaleTag').astuple(),
19834
tags.get('ModelTiepointTag').astuple(),
19835
tags.get('GeoKeyDirectoryTag').astuple(),
19836
tags.get('GeoAsciiParamsTag').astuple(),
19837
tags.get('GDAL_NODATA').astuple(),
19843
rowsperstrip=page.rowsperstrip,
19844
photometric=page.photometric,
19845
planarconfig=page.planarconfig,
19846
compression=page.compression,
19847
predictor=page.predictor,
19848
jpegtables=page.jpegtables,
19849
iccprofile=page.iccprofile,
19850
subsampling=page.subsampling,
19851
extratags=extratags,
19854
with TiffFile(fname) as tif:
19855
assert tif.is_geotiff
19856
assert len(tif.pages) == 1
19857
page = tif.pages.first
19858
assert page.nodata == -32767
19859
assert page.tags['ModelPixelScaleTag'].value == (
19864
assert page.tags['ModelTiepointTag'].value == (
19872
assert tif.geotiff_metadata['GeogAngularUnitsGeoKey'] == 9102
19873
assert_array_equal(tif.asarray(), geotiff.asarray())
19876
@pytest.mark.parametrize('ext', ['', 'b'])
19877
def test_write_open_mode(ext):
19878
"""Test TiffWriter with file open modes."""
19879
data = numpy.random.randint(0, 255, (5, 31, 21), numpy.uint8)
19880
with TempFileName('write_open_mode' + ext) as fname:
19882
imwrite(fname, data, mode='w' + ext)
19883
assert_array_equal(imread(fname), data)
19884
# exclusive creation
19885
with pytest.raises(FileExistsError):
19886
imwrite(fname, data, mode='x' + ext)
19888
imwrite(fname, data, mode='x' + ext)
19889
assert_array_equal(imread(fname), data)
19891
imwrite(fname, data, mode='r+' + ext)
19892
with TiffFile(fname) as tif:
19893
assert len(tif.pages) == 10
19894
assert len(tif.series) == 2
19895
assert_array_equal(tif.series[0].asarray(), data)
19896
assert_array_equal(tif.series[1].asarray(), data)
19898
# write to file handle
19899
with FileHandle(fname, mode='w' + ext) as fh:
19900
imwrite(fh, data, mode='ignored')
19901
assert_array_equal(imread(fname), data)
19902
# exclusive creation with file handle
19903
with pytest.raises(FileExistsError):
19904
with FileHandle(fname, mode='x' + ext) as fh:
19907
with FileHandle(fname, mode='x' + ext) as fh:
19908
imwrite(fh, data, mode='ignored' + ext)
19909
assert not fh.closed
19911
with pytest.raises(OSError): # io.UnsupportedOperation
19913
assert_array_equal(imread(fname), data)
19914
# append to file handle
19915
with FileHandle(fname, mode='r+' + ext) as fh:
19916
imwrite(fh, data, mode='ignored')
19917
assert not fh.closed
19919
with TiffFile(fh) as tif:
19920
assert len(tif.pages) == 10
19921
assert len(tif.series) == 2
19922
assert_array_equal(tif.series[0].asarray(), data)
19923
assert_array_equal(tif.series[1].asarray(), data)
19925
with pytest.raises(ValueError):
19926
imwrite(fname, data, mode=ext)
19928
with pytest.raises(ValueError):
19929
imwrite(fname, data, mode='w' + ext, append=True)
19932
@pytest.mark.skipif(SKIP_ZARR or SKIP_DASK or SKIP_CODECS, reason=REASON)
19933
@pytest.mark.parametrize('atype', ['numpy', 'dask', 'zarr'])
19934
@pytest.mark.parametrize('compression', [None, 'zlib'])
19935
@pytest.mark.parametrize('tiled', [None, False, True])
19936
@pytest.mark.parametrize('byteorder', ['<', '>'])
19937
def test_write_array_types(atype, byteorder, tiled, compression):
19938
"""Test write array types."""
19940
fname = f'write_{atype}_'
19944
kwargs['tile'] = (64, 64)
19947
kwargs['rowsperstrip'] = 64
19948
fname += 'striped_'
19949
if compression is not None:
19950
kwargs['compression'] = compression
19951
fname += compression
19952
fname += 'be' if byteorder == '>' else 'le'
19954
data = numpy.random.randint(0, 1024, (3, 361, 254, 3), numpy.uint16)
19955
if atype == 'numpy':
19957
elif atype == 'dask':
19958
arr = dask.array.from_array(data, chunks=(1, 32, 64, 3))
19959
elif atype == 'zarr':
19960
arr = zarr.zeros(data.shape, chunks=(1, 32, 64, 3), dtype=data.dtype)
19962
with TempFileName(fname) as fname:
19965
arr[1:, 33 : 33 + 261, 31 : 31 + 200],
19966
byteorder=byteorder,
19969
assert_array_equal(
19970
imread(fname), data[1:, 33 : 33 + 261, 31 : 31 + 200]
19972
assert_array_equal(
19973
imagecodecs.imread(fname, index=None),
19974
data[1:, 33 : 33 + 261, 31 : 31 + 200],
19978
###############################################################################
19980
# Test embedded TIFF files
19982
EMBED_NAME = public_file('tifffile/test_FileHandle.bin')
19985
EMBED_OFFSET1 = 13820
19986
EMBED_SIZE1 = 7936382
19989
def assert_embed_tif(tif):
19990
"""Assert embedded TIFF file."""
19991
# 4 series in 6 pages
19992
assert tif.byteorder == '<'
19993
assert len(tif.pages) == 6
19994
assert len(tif.series) == 4
19995
# assert series 0 properties
19996
series = tif.series[0]
19997
assert series.shape == (3, 20, 20)
19998
assert series.dtype == numpy.uint8
19999
assert series.axes == 'IYX'
20000
assert series.kind == 'generic'
20001
page = series.pages[0]
20002
assert page.compression == COMPRESSION.LZW
20003
assert page.imagewidth == 20
20004
assert page.imagelength == 20
20005
assert page.bitspersample == 8
20006
assert page.samplesperpixel == 1
20007
data = tif.asarray(series=0)
20008
assert isinstance(data, numpy.ndarray)
20009
assert data.shape == (3, 20, 20)
20010
assert data.dtype == numpy.uint8
20011
assert tuple(data[:, 9, 9]) == (19, 90, 206)
20012
# assert series 1 properties
20013
series = tif.series[1]
20014
assert series.shape == (10, 10, 3)
20015
assert series.dtype == numpy.float32
20016
assert series.axes == 'YXS'
20017
assert series.kind == 'generic'
20018
page = series.pages[0]
20019
assert page.photometric == PHOTOMETRIC.RGB
20020
assert page.compression == COMPRESSION.LZW
20021
assert page.imagewidth == 10
20022
assert page.imagelength == 10
20023
assert page.bitspersample == 32
20024
assert page.samplesperpixel == 3
20025
data = tif.asarray(series=1)
20026
assert isinstance(data, numpy.ndarray)
20027
assert data.shape == (10, 10, 3)
20028
assert data.dtype == numpy.float32
20029
assert round(abs(data[9, 9, 1] - 214.5733642578125), 7) == 0
20030
# assert series 2 properties
20031
series = tif.series[2]
20032
assert series.shape == (20, 20, 3)
20033
assert series.dtype == numpy.uint8
20034
assert series.axes == 'YXS'
20035
assert series.kind == 'generic'
20036
page = series.pages[0]
20037
assert page.photometric == PHOTOMETRIC.RGB
20038
assert page.compression == COMPRESSION.LZW
20039
assert page.imagewidth == 20
20040
assert page.imagelength == 20
20041
assert page.bitspersample == 8
20042
assert page.samplesperpixel == 3
20043
data = tif.asarray(series=2)
20044
assert isinstance(data, numpy.ndarray)
20045
assert data.shape == (20, 20, 3)
20046
assert data.dtype == numpy.uint8
20047
assert tuple(data[9, 9, :]) == (19, 90, 206)
20048
# assert series 3 properties
20049
series = tif.series[3]
20050
assert series.shape == (10, 10)
20051
assert series.dtype == numpy.float32
20052
assert series.axes == 'YX'
20053
assert series.kind == 'generic'
20054
page = series.pages[0]
20055
assert page.compression == COMPRESSION.LZW
20056
assert page.imagewidth == 10
20057
assert page.imagelength == 10
20058
assert page.bitspersample == 32
20059
assert page.samplesperpixel == 1
20060
data = tif.asarray(series=3)
20061
assert isinstance(data, numpy.ndarray)
20062
assert data.shape == (10, 10)
20063
assert data.dtype == numpy.float32
20064
assert round(abs(data[9, 9] - 223.1648712158203), 7) == 0
20068
def assert_embed_micromanager(tif):
20069
"""Assert embedded MicroManager TIFF file."""
20071
assert tif.is_imagej
20072
assert tif.is_micromanager
20073
assert tif.byteorder == '<'
20074
assert len(tif.pages) == 15
20075
assert len(tif.series) == 1
20076
# assert non-tiff micromanager_metadata
20077
assert tif.micromanager_metadata is not None
20078
tags = tif.micromanager_metadata['Summary']
20079
assert tags['MicroManagerVersion'] == '1.4.x dev'
20080
assert tags['UserName'] == 'trurl'
20081
# assert page properties
20082
page = tif.pages.first
20083
assert page.is_contiguous
20084
assert page.compression == COMPRESSION.NONE
20085
assert page.imagewidth == 512
20086
assert page.imagelength == 512
20087
assert page.bitspersample == 16
20088
assert page.samplesperpixel == 1
20089
# two description tags
20090
assert page.description.startswith('<?xml')
20091
assert page.description1.startswith('ImageJ')
20092
# assert some metadata
20093
ijmeta = tif.imagej_metadata
20094
assert ijmeta is not None
20095
assert ijmeta is not None
20096
assert ijmeta['frames'] == 5
20097
assert ijmeta['slices'] == 3
20098
assert ijmeta['Ranges'] == (706.0, 5846.0)
20099
tags = tif.pages.first.tags[51123].value
20100
assert tags['FileName'] == 'Untitled_1_MMStack.ome.tif'
20101
assert tags['PixelType'] == 'GRAY16'
20102
# assert series properties
20103
series = tif.series[0]
20104
assert series.shape == (5, 3, 512, 512)
20105
assert series.dtype == numpy.uint16
20106
assert series.axes == 'TZYX'
20107
assert series.kind == 'mmstack'
20109
data = tif.asarray()
20110
assert data.shape == (5, 3, 512, 512)
20111
assert data.dtype == numpy.uint16
20112
assert data[4, 2, 511, 511] == 1602
20114
data = tif.asarray(out='memmap')
20115
assert isinstance(data, numpy.memmap)
20116
assert data.shape == (5, 3, 512, 512)
20117
assert data.dtype == numpy.dtype('<u2')
20118
assert data[4, 2, 511, 511] == 1602
20123
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
20124
def test_embed_tif_filename():
20125
"""Test embedded TIFF from filename."""
20126
with TiffFile(EMBED_NAME, offset=EMBED_OFFSET, size=EMBED_SIZE) as tif:
20127
assert_embed_tif(tif)
20130
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
20131
def test_embed_tif_openfile():
20132
"""Test embedded TIFF from file handle."""
20133
with open(EMBED_NAME, 'rb') as fh:
20134
with TiffFile(fh, offset=EMBED_OFFSET, size=EMBED_SIZE) as tif:
20135
assert_embed_tif(tif)
20138
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
20139
def test_embed_tif_openfile_seek():
20140
"""Test embedded TIFF from seeked file handle."""
20141
with open(EMBED_NAME, 'rb') as fh:
20142
fh.seek(EMBED_OFFSET)
20143
with TiffFile(fh, size=EMBED_SIZE) as tif:
20144
assert_embed_tif(tif)
20147
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
20148
def test_embed_tif_filehandle():
20149
"""Test embedded TIFF from FileHandle."""
20150
with FileHandle(EMBED_NAME, offset=EMBED_OFFSET, size=EMBED_SIZE) as fh:
20151
with TiffFile(fh) as tif:
20152
assert_embed_tif(tif)
20155
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_CODECS, reason=REASON)
20156
def test_embed_tif_bytesio():
20157
"""Test embedded TIFF from BytesIO."""
20158
with open(EMBED_NAME, 'rb') as fh:
20159
bytesio = BytesIO(fh.read())
20160
with TiffFile(bytesio, offset=EMBED_OFFSET, size=EMBED_SIZE) as tif:
20161
assert_embed_tif(tif)
20164
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20165
def test_embed_mm_filename():
20166
"""Test embedded MicroManager TIFF from file name."""
20167
with TiffFile(EMBED_NAME, offset=EMBED_OFFSET1, size=EMBED_SIZE1) as tif:
20168
assert_embed_micromanager(tif)
20171
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20172
def test_embed_mm_openfile():
20173
"""Test embedded MicroManager TIFF from file handle."""
20174
with open(EMBED_NAME, 'rb') as fh:
20175
with TiffFile(fh, offset=EMBED_OFFSET1, size=EMBED_SIZE1) as tif:
20176
assert_embed_micromanager(tif)
20179
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20180
def test_embed_mm_openfile_seek():
20181
"""Test embedded MicroManager TIFF from seeked file handle."""
20182
with open(EMBED_NAME, 'rb') as fh:
20183
fh.seek(EMBED_OFFSET1)
20184
with TiffFile(fh, size=EMBED_SIZE1) as tif:
20185
assert_embed_micromanager(tif)
20188
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20189
def test_embed_mm_filehandle():
20190
"""Test embedded MicroManager TIFF from FileHandle."""
20191
with FileHandle(EMBED_NAME, offset=EMBED_OFFSET1, size=EMBED_SIZE1) as fh:
20192
with TiffFile(fh) as tif:
20193
assert_embed_micromanager(tif)
20196
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20197
def test_embed_mm_bytesio():
20198
"""Test embedded MicroManager TIFF from BytesIO."""
20199
with open(EMBED_NAME, 'rb') as fh:
20200
bytesio = BytesIO(fh.read())
20201
with TiffFile(bytesio, offset=EMBED_OFFSET1, size=EMBED_SIZE1) as tif:
20202
assert_embed_micromanager(tif)
20205
###############################################################################
20207
# Test sequence of image files
20210
def test_sequence_stream_list():
20211
"""Test TiffSequence with list of ByteIO streams raises TypeError."""
20212
data = numpy.random.rand(7, 9)
20213
files = [BytesIO(), BytesIO()]
20214
for buffer in files:
20215
imwrite(buffer, data)
20216
with pytest.raises(TypeError):
20220
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20221
@pytest.mark.parametrize('case', [0, 1, 2, 3])
20222
def test_sequence_glob_pattern(case):
20223
"""Test TiffSequence with glob pattern without axes pattern."""
20224
fname = private_file('TiffSequence/*.tif')
20225
tifs = TiffSequence(fname, pattern=None)
20226
assert len(tifs) == 10
20227
assert tifs.shape == (10,)
20228
assert tifs.axes == 'I'
20229
data = tifs.asarray()
20231
data = tifs.asarray()
20233
data = tifs.asarray(
20234
chunkshape=(480, 640), chunkdtype=numpy.uint8, pattern=None, key=0
20237
data = tifs.asarray(
20238
imreadargs={'key': 0},
20239
chunkshape=(480, 640),
20240
chunkdtype=numpy.uint8,
20246
data = numpy.empty((10, 480, 640), dtype=numpy.uint8)
20248
chunkshape=(480, 640),
20249
chunkdtype=numpy.uint8,
20255
assert isinstance(data, numpy.ndarray)
20256
assert data.flags['C_CONTIGUOUS']
20257
assert data.shape == (10, 480, 640)
20258
assert data.dtype == numpy.uint8
20259
assert data[9, 256, 256] == 135
20261
with tifs.aszarr() as store:
20262
assert_array_equal(data, zarr.open(store, mode='r'))
20263
assert__repr__(tifs)
20266
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20267
def test_sequence_name_list():
20268
"""Test TiffSequence with list of file names without pattern."""
20270
private_file('TiffSequence/AT3_1m4_01.tif'),
20271
private_file('TiffSequence/AT3_1m4_10.tif'),
20273
tifs = TiffSequence(fname, pattern=None)
20274
assert len(tifs) == 2
20275
assert tifs.shape == (2,)
20276
assert tifs.axes == 'I'
20277
data = tifs.asarray()
20278
assert isinstance(data, numpy.ndarray)
20279
assert data.flags['C_CONTIGUOUS']
20280
assert data.shape == (2, 480, 640)
20281
assert data.dtype == numpy.uint8
20282
assert data[1, 256, 256] == 135
20284
with tifs.aszarr() as store:
20285
assert_array_equal(data, zarr.open(store, mode='r'))
20286
assert__repr__(tifs)
20289
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20290
def test_sequence_oif_series():
20291
"""Test TiffSequence with files from Olympus OIF, memory mapped."""
20292
fname = private_file(
20293
'oif/MB231cell1_paxgfp_PDMSgasket_PMMAflat_30nm_378sli.oif.files/*.tif'
20295
tifs = TiffSequence(fname, pattern='axes')
20296
assert len(tifs) == 756
20297
assert tifs.shape == (2, 378)
20298
assert tifs.axes == 'CZ'
20300
data = tifs.asarray(out='memmap', ioworkers=None)
20301
assert isinstance(data, numpy.memmap)
20302
assert data.flags['C_CONTIGUOUS']
20303
assert data.shape == (2, 378, 256, 256)
20304
assert data.dtype == numpy.dtype('<u2')
20305
assert data[1, 377, 70, 146] == 29
20307
with tifs.aszarr() as store:
20308
assert_array_equal(data, zarr.open(store, mode='r'))
20310
assert__repr__(tifs)
20313
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20314
def test_sequence_leica_series():
20315
"""Test TiffSequence with Leica TIFF series, memory mapped."""
20316
fname = private_file('leicaseries/Series019_*.tif')
20317
tifs = TiffSequence(fname, pattern='axes')
20318
assert len(tifs) == 46
20319
assert tifs.shape == (46,)
20320
assert tifs.axes == 'Y'
20322
data = tifs.asarray(out='memmap')
20323
assert isinstance(data, numpy.memmap)
20324
assert data.flags['C_CONTIGUOUS']
20325
assert data.shape == (46, 512, 512, 3)
20326
assert data.dtype == numpy.uint8
20327
assert tuple(data[45, 256, 256]) == (93, 56, 56)
20329
with tifs.aszarr() as store:
20330
assert_array_equal(data, zarr.open(store, mode='r'))
20334
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20335
def test_sequence_zip_container():
20336
"""Test TiffSequence with glob pattern without axes pattern."""
20337
fname = private_file('TiffSequence.zip')
20338
with TiffSequence('*.tif', container=fname, pattern=None) as tifs:
20339
assert len(tifs) == 10
20340
assert tifs.shape == (10,)
20341
assert tifs.axes == 'I'
20342
data = tifs.asarray(chunkshape=(480, 640), chunkdtype=numpy.uint8)
20343
assert isinstance(data, numpy.ndarray)
20344
assert data.flags['C_CONTIGUOUS']
20345
assert data.shape == (10, 480, 640)
20346
assert data.dtype == numpy.uint8
20347
assert data[9, 256, 256] == 135
20348
assert_array_equal(data, imread(container=fname))
20351
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE or SKIP_CODECS, reason=REASON)
20352
def test_sequence_wells_axesorder():
20353
"""Test FileSequence with well plates and axes reorder."""
20354
# https://bbbc.broadinstitute.org/BBBC006
20355
categories = {'p': {chr(i + 97): i for i in range(25)}}
20356
ptrn = r'(?:_(z)_(\d+)).*_(?P<p>[a-z])(?P<a>\d+)(?:_(s)(\d))(?:_(w)(\d))'
20357
fnames = private_file('BBBC/BBBC006_v1_images_z_00/*.tif')
20358
fnames += private_file('BBBC/BBBC006_v1_images_z_01/*.tif')
20359
tifs = TiffSequence(
20360
fnames, pattern=ptrn, categories=categories, axesorder=(1, 2, 0, 3, 4)
20362
assert len(tifs) == 3072
20363
assert tifs.shape == (16, 24, 2, 2, 2)
20364
assert tifs.axes == 'PAZSW'
20365
data = tifs.asarray()
20366
assert isinstance(data, numpy.ndarray)
20367
assert data.flags['C_CONTIGUOUS']
20368
assert data.shape == (16, 24, 2, 2, 2, 520, 696)
20369
assert data.dtype == numpy.uint16
20370
assert data[8, 12, 1, 0, 1, 256, 519] == 1579
20372
with tifs.aszarr() as store:
20373
assert_array_equal(data, zarr.open(store, mode='r'))
20376
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
20377
@pytest.mark.parametrize('tiled', [False, True])
20378
def test_sequence_tiled(tiled):
20379
"""Test FileSequence with tiled OME-TIFFs."""
20380
# Dataset from https://github.com/tlambert03/tifffolder/issues/2
20382
r'\[(?P<U>\d+) x (?P<V>\d+)\].*(C)(\d+).*(Z)(\d+)', re.IGNORECASE
20384
fnames = private_file('TiffSequenceTiled/*.tif', expand=False)
20385
tifs = TiffSequence(fnames, pattern=ptrn)
20386
assert len(tifs) == 60
20387
assert tifs.shape == (2, 3, 2, 5)
20388
assert tifs.axes == 'UVCZ'
20389
tiled = {0: 0, 1: 1} if tiled else None
20390
data = tifs.asarray(axestiled=tiled, is_ome=False)
20391
assert isinstance(data, numpy.ndarray)
20392
assert data.flags['C_CONTIGUOUS']
20393
assert data.dtype == numpy.uint16
20395
assert data.shape == (2, 5, 2 * 2560, 3 * 2160)
20396
assert data[1, 3, 2560 + 1024, 2 * 2160 + 1024] == 596
20398
assert data.shape == (2, 3, 2, 5, 2560, 2160)
20399
assert data[1, 2, 1, 3, 1024, 1024] == 596
20401
with tifs.aszarr(axestiled=tiled, is_ome=False) as store:
20403
assert_array_equal(
20404
data[1, 3, 2048:3072],
20405
zarr.open(store, mode='r')[1, 3, 2048:3072],
20408
assert_array_equal(
20409
data[1, 2, 1, 3:5],
20410
zarr.open(store, mode='r')[1, 2, 1, 3:5],
20414
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20415
def test_sequence_imread():
20416
"""Test TiffSequence with imagecodecs.imread."""
20417
fname = private_file('PNG/*.png')
20418
pngs = TiffSequence(fname, imread=imagecodecs.imread)
20419
assert len(pngs) == 4
20420
assert pngs.shape == (4,)
20421
assert pngs.axes == 'I'
20422
data = pngs.asarray(codec=imagecodecs.png_decode)
20423
assert data.flags['C_CONTIGUOUS']
20424
assert data.shape == (4, 200, 200)
20425
assert data.dtype == numpy.uint16
20427
with pngs.aszarr(codec=imagecodecs.png_decode) as store:
20428
assert_array_equal(data, zarr.open(store, mode='r'))
20432
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20433
def test_sequence_imread_glob():
20434
"""Test imread function with glob pattern."""
20435
fname = private_file('TiffSequence/*.tif')
20438
imreadargs={'key': 0},
20439
chunkshape=(480, 640),
20440
chunkdtype=numpy.uint8,
20442
assert data.shape == (10, 480, 640)
20447
imreadargs={'key': 0},
20448
chunkshape=(480, 640),
20449
chunkdtype=numpy.uint8,
20452
assert_array_equal(data, zarr.open(store, mode='r'))
20457
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_CODECS, reason=REASON)
20458
def test_sequence_imread_one():
20459
"""Test imread function with one item in sequence."""
20460
fname = private_file('TiffSequence/AT3_1m4_01.tif')
20461
assert_array_equal(imread([fname]), imread(fname))
20464
###############################################################################
20466
# Test packages depending on tifffile
20469
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20470
def test_dependent_roifile():
20471
"""Test roifile.ImagejRoi class."""
20472
from roifile import ImagejRoi
20474
for roi in ImagejRoi.fromfile(private_file('imagej/IJMetadata.tif')):
20475
assert roi == ImagejRoi.frombytes(roi.tobytes())
20480
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20481
def test_dependent_lfdfiles():
20482
"""Test lfdfiles conversion to TIFF."""
20483
from lfdfiles import LfdFileSequence, SimfcsInt, SimfcsZ64
20485
filename = private_file('SimFCS/simfcs.Z64')
20486
with TempFileName('depend_simfcsz_z64', ext='.tif') as outfile:
20487
with SimfcsZ64(filename) as z64:
20488
data = z64.asarray()
20489
z64.totiff(outfile)
20490
with TiffFile(outfile) as tif:
20491
assert len(tif.pages) == 256
20492
assert len(tif.series) == 1
20493
assert tif.series[0].shape == (256, 256, 256)
20494
assert tif.series[0].dtype == numpy.float32
20495
assert_array_equal(data, tif.asarray())
20497
filename = private_file('SimFCS/gpint')
20498
with LfdFileSequence(
20499
filename + '/v*001.int',
20500
pattern=r'v(?P<Channel>\d)(?P<Image>\d*).int',
20503
assert ims.axes == 'CI'
20504
assert ims.asarray().shape == (2, 1, 256, 256)
20507
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20508
def test_dependent_cmapfile():
20509
"""Test cmapfile.lsm2cmap."""
20510
from cmapfile import CmapFile, lsm2cmap
20512
filename = private_file('LSM/3d_zfish_onephoton_zoom.lsm')
20513
data = imread(filename)
20514
with TempFileName('depend_cmapfile', ext='.cmap') as cmapfile:
20515
lsm2cmap(filename, cmapfile, step=(1.0, 1.0, 20.0))
20516
fname = os.path.join(
20517
os.path.split(cmapfile)[0],
20518
cmapfile.replace('.cmap', '.ch0000.cmap'),
20520
with CmapFile(fname, mode='r') as cmap:
20521
assert_array_equal(
20522
cmap['map00000']['data00000'], data.squeeze()[:, 0, :, :]
20526
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20527
def test_dependent_czifile():
20528
"""Test czifile.CziFile."""
20529
# TODO: test LZW compressed czi file
20530
from czifile import CziFile
20532
fname = private_file('czi/pollen.czi')
20533
with CziFile(fname) as czi:
20534
assert czi.shape == (1, 1, 104, 365, 364, 1)
20535
assert czi.axes == 'TCZYX0'
20537
data = czi.asarray()
20538
assert data.flags['C_CONTIGUOUS']
20539
assert data.shape == (1, 1, 104, 365, 364, 1)
20540
assert data.dtype == numpy.uint8
20541
assert data[0, 0, 52, 182, 182, 0] == 10
20544
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
20545
def test_dependent_czi2tif():
20546
"""Test czifile.czi2tif."""
20547
from czifile.czifile import CziFile, czi2tif
20549
fname = private_file('CZI/pollen.czi')
20550
with CziFile(fname) as czi:
20551
metadata = czi.metadata()
20552
data = czi.asarray().squeeze()
20553
with TempFileName('depend_czi2tif') as tif:
20554
czi2tif(fname, tif, bigtiff=False)
20555
with TiffFile(tif) as t:
20557
assert t.pages[0].description == metadata
20559
assert_array_equal(im, data)
20562
assert_valid_tiff(tif)
20565
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
20566
def test_dependent_czi2tif_airy():
20567
"""Test czifile.czi2tif with AiryScan."""
20568
from czifile.czifile import czi2tif
20570
fname = private_file('CZI/AiryscanSRChannel.czi')
20571
with TempFileName('depend_czi2tif_airy') as tif:
20572
czi2tif(fname, tif, verbose=True, truncate=True, bigtiff=False)
20574
assert im.shape == (32, 6, 1680, 1680)
20575
assert tuple(im[17, :, 1500, 1000]) == (95, 109, 3597, 0, 0, 0)
20577
assert_valid_tiff(tif)
20580
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20581
def test_dependent_oiffile():
20582
"""Test oiffile.OifFile."""
20583
from oiffile import OifFile
20585
fname = private_file(
20586
'oib/MB231cell1_paxgfp_PDMSgasket_PMMAflat_30nm_378sli.oib'
20588
with OifFile(fname) as oib:
20590
tifs = oib.series[0]
20591
assert len(tifs) == 756
20592
assert tifs.shape == (2, 378)
20593
assert tifs.axes == 'CZ'
20595
data = tifs.asarray(out='memmap')
20596
assert data.flags['C_CONTIGUOUS']
20597
assert data.shape == (2, 378, 256, 256)
20598
assert data.dtype == numpy.dtype('<u2')
20599
assert data[1, 377, 70, 146] == 29
20603
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE, reason=REASON)
20604
def test_dependent_tiffslide():
20605
"""Test tiffslide package."""
20606
# https://github.com/bayer-science-for-a-better-life/tiffslide
20608
from tiffslide import TiffSlide
20609
except ImportError:
20610
pytest.skip('tiffslide missing')
20612
fname = private_file('AperioSVS/CMU-1.svs')
20614
with TiffSlide(fname) as slide:
20615
region = slide.read_region((300, 400), 0, (512, 512), as_array=True)
20616
assert tuple(region[150, 200]) == (243, 246, 246)
20617
slide.get_thumbnail((200, 200))
20620
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_LARGE or not IS_WIN, reason=REASON)
20621
def test_dependent_opentile():
20622
"""Test opentile package."""
20623
# https://github.com/imi-bigpicture/opentile
20625
from hashlib import md5
20628
from opentile.formats import NdpiTiler
20629
from opentile.geometry import Point
20630
except ImportError:
20631
pytest.skip('opentile missing')
20633
fname = private_file('HamamatsuNDPI/CMU-1.ndpi')
20635
turbo_path = os.path.join(
20636
os.path.dirname(turbojpeg.__file__), 'turbojpeg.dll'
20642
turbo_path=turbo_path,
20645
tile = tiler.get_tile(0, 0, 0, (0, 0))
20646
assert md5(tile).hexdigest() in (
20647
'30c69cab610e5b3db4beac63806d6513',
20648
'e813041cd57d1d078cf1564c0ed9ad7f',
20650
# read from file handle
20651
level = tiler.get_level(0)
20652
offset = level._page.dataoffsets[50]
20653
length = level._page.databytecounts[50]
20654
fh = level._page.parent.filehandle
20656
data = fh.read(length)
20657
assert length == 700
20658
assert offset == 33451
20659
assert md5(data).hexdigest() == '2a903c6e05bd10f10d856eecceb591f0'
20661
data = level._read_frame(50)
20662
assert md5(data).hexdigest() == '2a903c6e05bd10f10d856eecceb591f0'
20664
index = level._get_stripe_position_to_index(Point(50, 0))
20665
stripe = level._read_frame(index)
20666
assert md5(stripe).hexdigest() == '2a903c6e05bd10f10d856eecceb591f0'
20668
image = level._read_extended_frame(Point(10, 10), level.frame_size)
20669
assert md5(image).hexdigest() == 'aeffd12997ca6c232d0ef35aaa35f6b7'
20671
tile = level.get_tile((0, 0))
20672
assert md5(tile).hexdigest() in (
20673
'30c69cab610e5b3db4beac63806d6513',
20674
'e813041cd57d1d078cf1564c0ed9ad7f',
20676
tile = level.get_tile((20, 20))
20677
assert md5(tile).hexdigest() in (
20678
'fec8116d05485df513f4f41e13eaa994',
20679
'e755ee12d9fd65fc601e70951ce90696',
20683
@pytest.mark.skipif(SKIP_PUBLIC or SKIP_DASK, reason=REASON)
20684
def test_dependent_aicsimageio():
20685
"""Test aicsimageio package."""
20686
# https://github.com/AllenCellModeling/aicsimageio
20689
except ImportError:
20690
pytest.skip('aicsimageio or dependencies missing')
20692
fname = public_file('tifffile/multiscene_pyramidal.ome.tif')
20694
img = aicsimageio.AICSImage(fname)
20695
assert img.shape == (16, 2, 32, 256, 256)
20696
assert img.dims.order == 'TCZYX'
20697
assert img.dims.X == 256
20698
assert img.data.shape == (16, 2, 32, 256, 256)
20699
assert img.xarray_data.dims == ('T', 'C', 'Z', 'Y', 'X')
20700
t1 = img.get_image_data('ZCYX', T=1)
20701
assert t1.shape == (32, 2, 256, 256)
20702
assert img.current_scene == 'Image:0'
20703
assert img.scenes == ('Image:0', 'Image:1')
20705
assert img.current_scene == 'Image:1'
20706
assert img.shape == (1, 1, 1, 128, 128, 3)
20707
img.set_scene('Image:0')
20708
lazy_t1 = img.get_image_dask_data('ZCYX', T=1)
20709
assert_array_equal(lazy_t1.compute(), t1)
20712
@pytest.mark.xfail(reason=REASON)
20713
@pytest.mark.skipif(SKIP_PUBLIC, reason=REASON)
20714
def test_dependent_imageio():
20715
"""Test imageio package."""
20716
# https://github.com/imageio/imageio/blob/master/tests/test_tifffile.py
20717
# TODO: use imageio.v3
20719
import imageio.v2 as iio
20720
except ImportError:
20721
pytest.skip('imageio missing')
20723
data = numpy.ones((10, 10, 3), numpy.uint8) * 2
20724
filename2 = public_file('imageio/multipage_rgb.tif')
20725
filename3 = public_file('imageio/test_tiff2.tiff')
20727
with TempFileName('depend_imageio') as fname1:
20729
iio.imwrite(fname1, data)
20730
im = iio.imread(fname1)
20731
ims = iio.mimread(fname1)
20732
assert im.shape == data.shape
20733
assert_array_equal(im, data)
20734
assert len(ims) == 1
20737
iio.mimwrite(fname1, [data, data, data])
20738
im = iio.imread(fname1)
20739
ims = iio.mimread(fname1)
20740
assert im.shape == data.shape
20741
assert_array_equal(im, data)
20742
assert len(ims) == 3
20744
assert ims[i].shape == data.shape
20745
assert_array_equal(ims[i], data)
20748
iio.volwrite(fname1, numpy.tile(data, (3, 1, 1, 1)))
20749
vol = iio.volread(fname1)
20750
vols = iio.mvolread(fname1)
20751
assert vol.shape == (3,) + data.shape
20752
assert len(vols) == 1 and vol.shape == vols[0].shape
20754
assert_array_equal(vol[i], data)
20756
# remote channel-first volume rgb (2, 3, 10, 10)
20758
img = iio.mimread(filename2)
20759
assert len(img) == 2
20760
assert img[0].shape == (3, 10, 10)
20763
W = iio.save(fname1)
20764
W.set_meta_data({'planarconfig': 'SEPARATE'})
20765
assert W.format.name == 'TIFF'
20766
W.append_data(data)
20767
W.append_data(data)
20770
R = iio.read(fname1)
20771
assert R.format.name == 'TIFF'
20772
ims = list(R) # == [im for im in R]
20773
assert_array_equal(ims[0], data)
20775
with pytest.raises(IndexError):
20778
with pytest.raises(IndexError):
20781
# ensure imread + imwrite works round trip
20782
im1 = iio.imread(fname1)
20783
iio.imwrite(filename3, im1)
20784
im3 = iio.imread(filename3)
20785
assert im1.ndim == 3
20786
assert im1.shape == im3.shape
20787
assert_array_equal(im1, im3)
20789
# ensure imread + imwrite works round trip - volume like
20790
im1 = numpy.stack(iio.mimread(fname1))
20791
iio.volwrite(filename3, im1)
20792
im3 = iio.volread(filename3)
20793
assert im1.ndim == 4
20794
assert im1.shape == im3.shape
20795
assert_array_equal(im1, im3)
20798
md = iio.get_reader(filename2).get_meta_data()
20799
assert not md['is_imagej']
20800
assert md['description'] == 'shape=(2,3,10,10)'
20801
assert md['description1'] == ""
20802
assert md['datetime'] == datetime.datetime(2015, 5, 9, 9, 8, 29)
20803
assert md['software'] == 'tifffile.py'
20806
dt = datetime.datetime(2018, 8, 6, 15, 35, 5)
20807
with iio.get_writer(fname1, software='testsoftware') as w:
20809
numpy.zeros((10, 10)),
20810
meta={'description': 'test desc', 'datetime': dt},
20813
numpy.zeros((10, 10)), meta={'description': 'another desc'}
20815
with iio.get_reader(fname1) as r:
20816
for md in r.get_meta_data(), r.get_meta_data(0):
20817
assert 'datetime' in md
20818
assert md['datetime'] == dt
20819
assert 'software' in md
20820
assert md['software'] == 'testsoftware'
20821
assert 'description' in md
20822
assert md['description'] == 'test desc'
20824
md = r.get_meta_data(1)
20825
assert 'description' in md
20826
assert md['description'] == 'another desc'
20829
@pytest.mark.skipif(SKIP_PRIVATE, reason=REASON)
20830
def test_dependent_pims():
20831
"""Test PIMS package."""
20832
# https://github.com/soft-matter/pims
20834
from pims import TiffStack_tifffile
20835
except ImportError:
20836
pytest.skip('pims or dependencies missing')
20838
fname = private_file('pims/tiff_stack.tif')
20840
ims = TiffStack_tifffile(fname)
20841
assert_array_equal(ims.get_frame(2), imread(fname, key=2))
20846
@pytest.mark.skipif(SKIP_PRIVATE or SKIP_ZARR, reason=REASON)
20847
def test_dependent_kerchunk():
20848
"""Test kerchunk package."""
20849
# https://github.com/fsspec/kerchunk/blob/main/kerchunk/tests/test_tiff.py
20851
import kerchunk.tiff
20852
except ImportError:
20853
pytest.skip('kerchunk or dependencies missing')
20855
fname = private_file('kerchunk/lcmap_tiny_cog_2019.tif')
20856
fname = pathlib.Path(fname).as_uri()
20858
out = kerchunk.tiff.tiff_to_zarr(fname)
20859
m = fsspec.get_mapper('reference://', fo=out)
20861
assert list(z) == ['0', '1', '2']
20862
assert z.attrs['multiscales'] == [
20864
'datasets': [{'path': '0'}, {'path': '1'}, {'path': '2'}],
20870
assert z['0'].shape == (2048, 2048)
20871
assert z['0'][:].max() == 8
20873
fname = private_file('kerchunk/example.tif')
20874
fname = pathlib.Path(fname).as_uri()
20876
out = kerchunk.tiff.tiff_to_zarr(fname)
20877
m = fsspec.get_mapper('reference://', fo=out)
20881
###############################################################################
20883
if __name__ == '__main__':
20886
# warnings.simplefilter('always')
20887
warnings.filterwarnings('ignore', category=ImportWarning)
20889
argv.append('--cov-report=html')
20890
argv.append('--cov=tifffile')
20891
argv.append('--verbose')
20892
sys.exit(pytest.main(argv))