@@ -1574,12 +1574,22 @@ def _save(im, fp, filename):
15741574 ifd [COLORMAP ] = tuple (v * 256 for v in lut )
15751575 # data orientation
15761576 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
15791585 if strip_byte_counts >= 2 ** 16 :
15801586 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
15831593 # no compression by default:
15841594 ifd [COMPRESSION ] = COMPRESSION_INFO_REV .get (compression , 1 )
15851595
0 commit comments