def __save_existing(self, fileobj, atoms, path, ilst_data, padding_func): # Replace the old ilst atom. ilst = path[-1] offset = ilst.offset length = ilst.length # Use adjacent free atom if there is one free = _find_padding(path) if free is not None: offset = min(offset, free.offset) length += free.length # Always add a padding atom to make things easier padding_overhead = len(Atom.render(b"free", b"")) content_size = get_size(fileobj) - (offset + length) padding_size = length - (len(ilst_data) + padding_overhead) info = PaddingInfo(padding_size, content_size) new_padding = info._get_padding(padding_func) # Limit padding size so we can be sure the free atom overhead is as we # calculated above (see Atom.render) new_padding = min(0xFFFFFFFF, new_padding) ilst_data += Atom.render(b"free", b"\x00" * new_padding) resize_bytes(fileobj, length, len(ilst_data), offset) delta = len(ilst_data) - length fileobj.seek(offset) fileobj.write(ilst_data) self.__update_parents(fileobj, path[:-1], delta) self.__update_offsets(fileobj, atoms, delta, offset)
def __save_new(self, fileobj, atoms, ilst_data, padding_func): hdlr = Atom.render(b"hdlr", b"\x00" * 8 + b"mdirappl" + b"\x00" * 9) meta_data = b"\x00\x00\x00\x00" + hdlr + ilst_data try: path = atoms.path(b"moov", b"udta") except KeyError: path = atoms.path(b"moov") offset = path[-1]._dataoffset # ignoring some atom overhead... but we don't have padding left anyway # and padding_size is guaranteed to be less than zero content_size = get_size(fileobj) - offset padding_size = -len(meta_data) assert padding_size < 0 info = PaddingInfo(padding_size, content_size) new_padding = info._get_padding(padding_func) new_padding = min(0xFFFFFFFF, new_padding) free = Atom.render(b"free", b"\x00" * new_padding) meta = Atom.render(b"meta", meta_data + free) if path[-1].name != b"udta": # moov.udta not found -- create one data = Atom.render(b"udta", meta) else: data = meta insert_bytes(fileobj, len(data), offset) fileobj.seek(offset) fileobj.write(data) self.__update_parents(fileobj, path, len(data)) self.__update_offsets(fileobj, atoms, len(data), offset)