Add Chromium-only Blender WebEngine parity work
This commit is contained in:
123
blender-5.2.0/scripts/modules/blend_render_info.py
Executable file
123
blender-5.2.0/scripts/modules/blend_render_info.py
Executable file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-FileCopyrightText: 2010-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This module can get render info without running from inside blender.
|
||||
|
||||
|
||||
__all__ = (
|
||||
"read_blend_rend_chunk",
|
||||
)
|
||||
|
||||
import _blendfile_header
|
||||
|
||||
|
||||
class RawBlendFileReader:
|
||||
"""
|
||||
Return a file handle to the raw blend file data (abstracting compressed formats).
|
||||
"""
|
||||
__slots__ = (
|
||||
# The path to load.
|
||||
"_filepath",
|
||||
# The file base file handler or None (only set for compressed formats).
|
||||
"_blendfile_base",
|
||||
# The file handler to return to the caller (always uncompressed data).
|
||||
"_blendfile",
|
||||
)
|
||||
|
||||
def __init__(self, filepath):
|
||||
self._filepath = filepath
|
||||
self._blendfile_base = None
|
||||
self._blendfile = None
|
||||
|
||||
def __enter__(self):
|
||||
blendfile = open(self._filepath, "rb")
|
||||
blendfile_base = None
|
||||
head = blendfile.read(4)
|
||||
blendfile.seek(0)
|
||||
if head[0:2] == b'\x1f\x8b': # GZIP magic.
|
||||
import gzip
|
||||
blendfile_base = blendfile
|
||||
blendfile = gzip.open(blendfile, "rb")
|
||||
elif head[0:4] == b'\x28\xb5\x2f\xfd': # Z-standard magic.
|
||||
import zstandard
|
||||
blendfile_base = blendfile
|
||||
blendfile = zstandard.open(blendfile, "rb")
|
||||
|
||||
self._blendfile_base = blendfile_base
|
||||
self._blendfile = blendfile
|
||||
|
||||
return self._blendfile
|
||||
|
||||
def __exit__(self, _exc_type, _exc_value, _exc_traceback):
|
||||
self._blendfile.close()
|
||||
if self._blendfile_base is not None:
|
||||
self._blendfile_base.close()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_render_info_structure(endian_str, size):
|
||||
import struct
|
||||
# The maximum size of the scene name changed over time, so create a different
|
||||
# structure depending on the size of the entire block.
|
||||
if size == 2 * 4 + 24:
|
||||
return struct.Struct(endian_str + b'ii24s')
|
||||
if size == 2 * 4 + 64:
|
||||
return struct.Struct(endian_str + b'ii64s')
|
||||
if size == 2 * 4 + 256:
|
||||
return struct.Struct(endian_str + b'ii256s')
|
||||
raise ValueError("Unknown REND chunk size: {:d}".format(size))
|
||||
|
||||
|
||||
def _read_blend_rend_chunk_from_file(blendfile, filepath):
|
||||
import sys
|
||||
|
||||
from os import SEEK_CUR
|
||||
|
||||
try:
|
||||
blender_header = _blendfile_header.BlendFileHeader(blendfile)
|
||||
except _blendfile_header.BlendHeaderError:
|
||||
sys.stderr.write("Not a blend file: {:s}\n".format(filepath))
|
||||
return []
|
||||
|
||||
scenes = []
|
||||
|
||||
endian_str = b'<' if blender_header.is_little_endian else b'>'
|
||||
|
||||
block_header_struct = blender_header.create_block_header_struct()
|
||||
while bhead := _blendfile_header.BlockHeader(blendfile, block_header_struct):
|
||||
if bhead.code == b'ENDB':
|
||||
break
|
||||
remaining_bytes = bhead.size
|
||||
if bhead.code == b'REND':
|
||||
rend_block_struct = get_render_info_structure(endian_str, bhead.size)
|
||||
start_frame, end_frame, scene_name = rend_block_struct.unpack(blendfile.read(rend_block_struct.size))
|
||||
remaining_bytes -= rend_block_struct.size
|
||||
|
||||
scene_name = scene_name[:scene_name.index(b'\0')]
|
||||
# It's possible old blend files are not UTF8 compliant, use `surrogateescape`.
|
||||
scene_name = scene_name.decode("utf8", errors="surrogateescape")
|
||||
scenes.append((start_frame, end_frame, scene_name))
|
||||
|
||||
blendfile.seek(remaining_bytes, SEEK_CUR)
|
||||
|
||||
return scenes
|
||||
|
||||
|
||||
def read_blend_rend_chunk(filepath):
|
||||
with RawBlendFileReader(filepath) as blendfile:
|
||||
return _read_blend_rend_chunk_from_file(blendfile, filepath)
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
|
||||
for filepath in sys.argv[1:]:
|
||||
for value in read_blend_rend_chunk(filepath):
|
||||
print("{:d} {:d} {:s}".format(*value))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user