docs: 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