@@ -1574,12 +1574,22 @@ def _save(im, fp, filename):
1574
1574
ifd [COLORMAP ] = tuple (v * 256 for v in lut )
1575
1575
# data orientation
1576
1576
stride = len (bits ) * ((im .size [0 ] * bits [0 ] + 7 ) // 8 )
1577
- ifd [ROWSPERSTRIP ] = im .size [1 ]
1578
- strip_byte_counts = stride * im .size [1 ]
1577
+ # aim for 64 KB strips when using libtiff writer
1578
+ if libtiff :
1579
+ rows_per_strip = min ((2 ** 16 + stride - 1 ) // stride , im .size [1 ])
1580
+ else :
1581
+ rows_per_strip = im .size [1 ]
1582
+ strip_byte_counts = stride * rows_per_strip
1583
+ strips_per_image = (im .size [1 ] + rows_per_strip - 1 ) // rows_per_strip
1584
+ ifd [ROWSPERSTRIP ] = rows_per_strip
1579
1585
if strip_byte_counts >= 2 ** 16 :
1580
1586
ifd .tagtype [STRIPBYTECOUNTS ] = TiffTags .LONG
1581
- ifd [STRIPBYTECOUNTS ] = strip_byte_counts
1582
- ifd [STRIPOFFSETS ] = 0 # this is adjusted by IFD writer
1587
+ ifd [STRIPBYTECOUNTS ] = (strip_byte_counts ,) * (strips_per_image - 1 ) + (
1588
+ stride * im .size [1 ] - strip_byte_counts * (strips_per_image - 1 ),
1589
+ )
1590
+ ifd [STRIPOFFSETS ] = tuple (
1591
+ range (0 , strip_byte_counts * strips_per_image , strip_byte_counts )
1592
+ ) # this is adjusted by IFD writer
1583
1593
# no compression by default:
1584
1594
ifd [COMPRESSION ] = COMPRESSION_INFO_REV .get (compression , 1 )
1585
1595
0 commit comments