def _write_remaining_pages(self):
        """Write outstanding IFDs and tags to file."""
        if not self._tags or self._truncate:
            return

        pageno = self._shape[0] * self._datashape[0] - 1
        if pageno < 1:
            self._tags = None
            self._datadtype = None
            self._dataoffset = None
            self._databytecounts = None
            return

        fh = self._fh
        fhpos = fh.tell()
        if fhpos % 2:
            fh.write(b'\0')
            fhpos += 1

        pack = struct.pack
        offsetformat = self._byteorder + self._offsetformat
        offsetsize = self._offsetsize
        tagnoformat = self._byteorder + self._tagnoformat
        tagsize = self._tagsize
        dataoffset = self._dataoffset
        pagedatasize = sum(self._databytecounts)

        # construct template IFD in memory
        # need to patch offsets to next IFD and data before writing to file
        ifd = io.BytesIO()
        ifd.write(pack(tagnoformat, len(self._tags)))
        tagoffset = ifd.tell()
        ifd.write(b''.join(t[1] for t in self._tags))
        ifdoffset = ifd.tell()
        ifd.write(pack(offsetformat, 0))  # offset to next IFD
        # tag values
        for tagindex, tag in enumerate(self._tags):
            offset = tagoffset + tagindex * tagsize + offsetsize + 4
            code = tag[0]
            value = tag[2]
            if value:
                pos = ifd.tell()
                if pos % 2:
                    # tag value is expected to begin on word boundary
                    ifd.write(b'\0')
                    pos += 1
                ifd.seek(offset)
                try:
                    ifd.write(pack(offsetformat, fhpos + pos))
                except Exception:  # struct.error
                    if self._imagej:
                        warnings.warn('truncating ImageJ file')
                        self._truncate = True
                        return
                    raise ValueError('data too large for non-BigTIFF file')
                ifd.seek(pos)
                ifd.write(value)
                if code == self._tagoffsets:
                    # save strip/tile offsets for later updates
                    dataoffsetsoffset = offset, pos
            elif code == self._tagoffsets:
                dataoffsetsoffset = offset, None

        ifdsize = ifd.tell()
        if ifdsize % 2:
            ifd.write(b'\0')
            ifdsize += 1

        # check if all IFDs fit in file
        if not self._bigtiff and fhpos + ifdsize * pageno > 2**32 - 32:
            if self._imagej:
                warnings.warn('truncating ImageJ file')
                self._truncate = True
                return
            raise ValueError('data too large for non-BigTIFF file')

        # assemble IFD chain in memory from IFD template
        ifds = io.BytesIO(bytes(ifdsize * pageno))
        ifdpos = fhpos
        for _ in range(pageno):
            # update strip/tile offsets in IFD
            dataoffset += pagedatasize  # offset to image data
            offset, pos = dataoffsetsoffset
            ifd.seek(offset)
            if pos:
                ifd.write(pack(offsetformat, ifdpos + pos))
                ifd.seek(pos)
                offset = dataoffset
                for size in self._databytecounts:
                    ifd.write(pack(offsetformat, offset))
                    offset += size
            else:
                ifd.write(pack(offsetformat, dataoffset))
            # update pointer at ifdoffset to point to next IFD in file
            ifdpos += ifdsize
            ifd.seek(ifdoffset)
            ifd.write(pack(offsetformat, ifdpos))
            # write IFD entry
            ifds.write(iogetbuffer(ifd))

        # terminate IFD chain
        ifdoffset += ifdsize * (pageno - 1)
        ifds.seek(ifdoffset)
        ifds.write(pack(offsetformat, 0))
        # write IFD chain to file
        fh.write(iogetbuffer(ifds))
        # update file to point to new IFD chain
        pos = fh.tell()
        fh.seek(self._ifdoffset)
        fh.write(pack(offsetformat, fhpos))
        fh.flush()
        fh.seek(pos)

        self._ifdoffset = fhpos + ifdoffset
        self._tags = None
        self._datadtype = None
        self._dataoffset = None
        self._databytecounts = None
def _write_remaining_pages ( self ) : if not self . _tags or self . _truncate : return pageno = self . _shape [ 0 ] * self . _datashape [ 0 ] - 1 if pageno < 1 : self . _tags = None self . _datadtype = None self . _dataoffset = None self . _databytecounts = None return fh = self . _fh fhpos = fh . tell ( ) if fhpos % 2 : fh . write ( b'\0' ) fhpos += 1 pack = struct . pack offsetformat = self . _byteorder + self . _offsetformat offsetsize = self . _offsetsize tagnoformat = self . _byteorder + self . _tagnoformat tagsize = self . _tagsize dataoffset = self . _dataoffset pagedatasize = sum ( self . _databytecounts ) ifd = io . BytesIO ( ) ifd . write ( pack ( tagnoformat , len ( self . _tags ) ) ) tagoffset = ifd . tell ( ) ifd . write ( b'' . join ( t [ 1 ] for t in self . _tags ) ) ifdoffset = ifd . tell ( ) ifd . write ( pack ( offsetformat , 0 ) ) for tagindex , tag in enumerate ( self . _tags ) : offset = tagoffset + tagindex * tagsize + offsetsize + 4 code = tag [ 0 ] value = tag [ 2 ] if value : pos = ifd . tell ( ) if pos % 2 : ifd . write ( b'\0' ) pos += 1 ifd . seek ( offset ) try : ifd . write ( pack ( offsetformat , fhpos + pos ) ) except Exception : if self . _imagej : warnings . warn ( 'truncating ImageJ file' ) self . _truncate = True return raise ValueError ( 'data too large for non-BigTIFF file' ) ifd . seek ( pos ) ifd . write ( value ) if code == self . _tagoffsets : dataoffsetsoffset = offset , pos elif code == self . _tagoffsets : dataoffsetsoffset = offset , None ifdsize = ifd . tell ( ) if ifdsize % 2 : ifd . write ( b'\0' ) ifdsize += 1 if not self . _bigtiff and fhpos + ifdsize * pageno > 2 ** 32 - 32 : if self . _imagej : warnings . warn ( 'truncating ImageJ file' ) self . _truncate = True return raise ValueError ( 'data too large for non-BigTIFF file' ) ifds = io . BytesIO ( bytes ( ifdsize * pageno ) ) ifdpos = fhpos for _ in range ( pageno ) : dataoffset += pagedatasize offset , pos = dataoffsetsoffset ifd . seek ( offset ) if pos : ifd . write ( pack ( offsetformat , ifdpos + pos ) ) ifd . seek ( pos ) offset = dataoffset for size in self . _databytecounts : ifd . write ( pack ( offsetformat , offset ) ) offset += size else : ifd . write ( pack ( offsetformat , dataoffset ) ) ifdpos += ifdsize ifd . seek ( ifdoffset ) ifd . write ( pack ( offsetformat , ifdpos ) ) ifds . write ( iogetbuffer ( ifd ) ) ifdoffset += ifdsize * ( pageno - 1 ) ifds . seek ( ifdoffset ) ifds . write ( pack ( offsetformat , 0 ) ) fh . write ( iogetbuffer ( ifds ) ) pos = fh . tell ( ) fh . seek ( self . _ifdoffset ) fh . write ( pack ( offsetformat , fhpos ) ) fh . flush ( ) fh . seek ( pos ) self . _ifdoffset = fhpos + ifdoffset self . _tags = None self . _datadtype = None self . _dataoffset = None self . _databytecounts = None
Write outstanding IFDs and tags to file.