Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-10-20 02:16:36 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-10-20 02:31:30 +0300
commitef9269bd62f31e39d39cc59cd34354b53eae6661 (patch)
tree5ff2fb2f3b03678b7e58a23397d4d53bb83f35f8 /release/bin
parentbca2701236ab60dce5e32a8731f3bba43783b5b2 (diff)
Thumbnails: refactor extraction to use one code-path for all platforms
Thumbnail extraction now shares code between Linux/Windows, allowing thumbnails from Zstd compressed blend files to be extracted. The main logic is placed in blendthumb_extract.cc and is built as static library. For windows there is DLL which is registered during blender install and which then reads and generates thumbnails. For other platforms there is blender-thumbnailer executable file which takes blend file as an input and generates PNG file. As a result Python script blender-thumbnailer.py is no longer needed. The thumbnail extractor shares the same code-path as Blenders file reading, so there is no need to duplicate any file reading logic. This means reading compressed blend files is supported (broken since the recent move Zstd compression - D5799). This resolves T63736. Contributors: - @alausic original patch. - @LazyDodo windows fixes/support. - @campbellbarton general fixes/update. - @lukasstockner97 Zstd support. Reviewed By: sybren, mont29, LazyDodo, campbellbarton Ref D6408
Diffstat (limited to 'release/bin')
-rwxr-xr-xrelease/bin/blender-thumbnailer.py193
1 files changed, 0 insertions, 193 deletions
diff --git a/release/bin/blender-thumbnailer.py b/release/bin/blender-thumbnailer.py
deleted file mode 100755
index e050a681ca0..00000000000
--- a/release/bin/blender-thumbnailer.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env python3
-
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-"""
-Thumbnailer runs with python 2.7 and 3.x.
-To run automatically with a file manager such as Nautilus, save this file
-in a directory that is listed in PATH environment variable, and create
-blender.thumbnailer file in ${HOME}/.local/share/thumbnailers/ directory
-with the following contents:
-
-[Thumbnailer Entry]
-TryExec=blender-thumbnailer.py
-Exec=blender-thumbnailer.py %u %o
-MimeType=application/x-blender;
-"""
-
-import struct
-
-
-def open_wrapper_get():
- """ wrap OS specific read functionality here, fallback to 'open()'
- """
-
- class GFileWrapper:
- __slots__ = ("mode", "g_file")
-
- def __init__(self, url, mode='r'):
- self.mode = mode # used in gzip module
- self.g_file = Gio.File.parse_name(url).read(None)
-
- def read(self, size):
- return self.g_file.read_bytes(size, None).get_data()
-
- def seek(self, offset, whence=0):
- self.g_file.seek(offset, [1, 0, 2][whence], None)
- return self.g_file.tell()
-
- def tell(self):
- return self.g_file.tell()
-
- def close(self):
- self.g_file.close(None)
-
- def open_local_url(url, mode='r'):
- o = urlparse(url)
- if o.scheme == '':
- path = o.path
- elif o.scheme == 'file':
- path = unquote(o.path)
- else:
- raise(IOError('URL scheme "%s" needs gi.repository.Gio module' % o.scheme))
- return open(path, mode)
-
- try:
- from gi.repository import Gio
- return GFileWrapper
- except ImportError:
- try:
- # Python 3
- from urllib.parse import urlparse, unquote
- except ImportError:
- # Python 2
- from urlparse import urlparse
- from urllib import unquote
- return open_local_url
-
-
-def blend_extract_thumb(path):
- import os
- open_wrapper = open_wrapper_get()
-
- REND = b'REND'
- TEST = b'TEST'
-
- blendfile = open_wrapper(path, 'rb')
-
- head = blendfile.read(12)
-
- if head[0:2] == b'\x1f\x8b': # gzip magic
- import gzip
- blendfile.close()
- blendfile = gzip.GzipFile('', 'rb', 0, open_wrapper(path, 'rb'))
- head = blendfile.read(12)
-
- if not head.startswith(b'BLENDER'):
- blendfile.close()
- return None, 0, 0
-
- is_64_bit = (head[7] == b'-'[0])
-
- # true for PPC, false for X86
- is_big_endian = (head[8] == b'V'[0])
-
- # blender pre 2.5 had no thumbs
- if head[9:11] <= b'24':
- return None, 0, 0
-
- sizeof_bhead = 24 if is_64_bit else 20
- int_endian = '>i' if is_big_endian else '<i'
- int_endian_pair = int_endian + 'i'
-
- while True:
- bhead = blendfile.read(sizeof_bhead)
-
- if len(bhead) < sizeof_bhead:
- return None, 0, 0
-
- code = bhead[:4]
- length = struct.unpack(int_endian, bhead[4:8])[0] # 4 == sizeof(int)
-
- if code == REND:
- blendfile.seek(length, os.SEEK_CUR)
- else:
- break
-
- if code != TEST:
- return None, 0, 0
-
- try:
- x, y = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
- except struct.error:
- return None, 0, 0
-
- length -= 8 # sizeof(int) * 2
-
- if length != x * y * 4:
- return None, 0, 0
-
- image_buffer = blendfile.read(length)
-
- if len(image_buffer) != length:
- return None, 0, 0
-
- return image_buffer, x, y
-
-
-def write_png(buf, width, height):
- import zlib
-
- # reverse the vertical line order and add null bytes at the start
- width_byte_4 = width * 4
- raw_data = b"".join(b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4))
-
- def png_pack(png_tag, data):
- chunk_head = png_tag + data
- return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
-
- return b"".join([
- b'\x89PNG\r\n\x1a\n',
- png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
- png_pack(b'IDAT', zlib.compress(raw_data, 9)),
- png_pack(b'IEND', b'')])
-
-
-def main():
- import sys
-
- if len(sys.argv) < 3:
- print("Expected 2 arguments <input.blend> <output.png>")
- else:
- file_in = sys.argv[-2]
-
- buf, width, height = blend_extract_thumb(file_in)
-
- if buf:
- file_out = sys.argv[-1]
-
- f = open(file_out, "wb")
- f.write(write_png(buf, width, height))
- f.close()
-
-
-if __name__ == '__main__':
- main()