Page MenuHome

Thumbnails: refactor extraction to use one code-path for all platforms
ClosedPublic

Authored by Campbell Barton (campbellbarton) on Dec 13 2019, 2:25 PM.

Details

Summary

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:

Diff Detail

Repository
rB Blender
Branch
T (branched from master)
Build Status
Buildable 17486
Build 17486: arc lint + arc unit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Fix compilation error after D5799 changes (thanks, Windows, for defining min as a macro...). Also rebased.

This revision now requires review to proceed.Jul 30 2021, 4:16 PM

Can confirm it works on windows. thumbnail dll went from 50k to 400k, not super thrilled about that, but it's much better than earlier in the patch where it linked half of blender so I guess that's a win.

@Campbell Barton (campbellbarton) anything specific you wanted me to test/checkout?

@Campbell Barton (campbellbarton) anything specific you wanted me to test/checkout?

Just that this doesn't cause any problems on macOS, although this change should only impact Linux/Windows.

@Campbell Barton (campbellbarton) anything specific you wanted me to test/checkout?

Just that this doesn't cause any problems on macOS, although this change should only impact Linux/Windows.

Ah, you got the wrong guy then. You want @Sebastián Barschkis (sebbas)

Sybren A. Stüvel (sybren) requested changes to this revision.Sep 10 2021, 3:30 PM

The patch description needs updating. It still refers to using LZ4 compression, which got me confused for a minute.

The build fails on my Kubuntu 20.04 LTS machine:

: && /usr/bin/g++-9 -Wuninitialized -Wredundant-decls -Wall -Wno-invalid-offsetof -Wno-sign-compare -Wlogical-op -Winit-self -Wmissing-include-dirs -Wno-div-by-zero -Wtype-limits -Werror=return-type -Wno-char-subscripts -Wno-unknown-pragmas -Wpointer-arith -Wunused-parameter -Wwrite-strings -Wundef -Wformat-signedness -Wrestrict -Wno-suggest-override -Wuninitialized -Wundef -Wmissing-declarations -Wimplicit-fallthrough=5  -fuse-ld=gold -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing -ffp-contract=off -msse2 -D_GLIBCXX_USE_CXX11_ABI=0 -fmacro-prefix-map="/home/sybren/workspace/blender-git/blender/"="" -fmacro-prefix-map="/home/sybren/workspace/blender-git/build_linux/"="" -Wno-maybe-uninitialized -O2 -DNDEBUG -static-libstdc++ -no-pie source/blender/blendthumb/CMakeFiles/blender-thumbnailer.dir/src/blendthumb_extract.cc.o source/blender/blendthumb/CMakeFiles/blender-thumbnailer.dir/src/blendthumb_png.cc.o source/blender/blendthumb/CMakeFiles/blender-thumbnailer.dir/src/blender_thumbnailer.cc.o -o bin/blender-thumbnailer  lib/libbf_blenlib.a  lib/libbf_intern_eigen.a  /usr/lib/gcc/x86_64-linux-gnu/9/libgomp.a  lib/libbf_intern_guardedalloc.a  lib/libbf_intern_numaapi.a  lib/libextern_wcwidth.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/freetype/lib/libfreetype.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/zlib/lib/libz.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/zstd/lib/libzstd.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/tbb/lib/libtbb.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/gmp/lib/libgmpxx.a  /home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/gmp/lib/libgmp.a  lib/libbf_intern_libc_compat.a && :
/home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/zstd/lib/libzstd.a(pool.c.o):pool.c:function POOL_free: error: undefined reference to 'pthread_join'
/home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/zstd/lib/libzstd.a(pool.c.o):pool.c:function POOL_create_advanced: error: undefined reference to 'pthread_create'
/home/sybren/workspace/blender-git/lib/linux_centos7_x86_64/zstd/lib/libzstd.a(pool.c.o):pool.c:function POOL_resize: error: undefined reference to 'pthread_create'
collect2: error: ld returned 1 exit status
[32/1849] Building C object source/blender/windowmanager/CMakeFiles/bf_windowmanager.dir/intern/wm_event_system.c.o
ninja: build stopped: subcommand failed.

The code also needs a pass to mark any local variable or parameter that isn't changing value with const.

The biggest issue with the code I feel is the use of std::string for non-string data. C++ has a rich type system, and there are plenty of ways to gracefully handle binary data (like blender::Vector<uint8_t>).

source/blender/blendthumb/src/blendthumb_extract.cc
128–141

This nesting is too deep, needs refactoring into one or more separate functions.

169

This function does too many different things. It's better to split up into smaller functions.

This revision now requires changes to proceed.Sep 10 2021, 3:30 PM

@Sybren A. Stüvel (sybren) could you check if this resolves the linking error? P2431

NOTE: we might consider linking pthread to blenlib, so each blenlib user doesn't run into this problem.

Yup, P2431 fixes the linker error.

Campbell Barton (campbellbarton) retitled this revision from Unify blend file thumbnail extraction to Thumbnails: refactor extraction to use one code-path for all platforms.
Campbell Barton (campbellbarton) edited the summary of this revision. (Show Details)

arc refused to apply this, but manually applying did the trick, still works on windows, no issues.

  • Replace std::string and blender::StringRef with blender::Vector & blender::Span.
  • Use optional types instead of empty vectors to signify failure.

@Ray Molenkamp (LazyDodo) I had to update the patch manually, getting SSL errors downloading/uploading with arc at the moment which I need to look into.

Campbell Barton (campbellbarton) edited the summary of this revision. (Show Details)

Quiet clang-tidy warnings, correct version check.


Updated with arc.

  • Avoid overly verbose array syntax (blender::Span<char>({..}) can be written as {..} in some cases).
  • Avoid reallocations, calculate the space needed ahead of time.
  • Replace reference to blender-thumbnailer.py with blender-thumbnailer in code comments.
  • Add back early-exit behavior which stops reading the thumbnail when any block that isn't a TEST / REND is reached.
  • Move file seek fallback into it's own function, reuse the same buffer when reading to seek (instead of new allocations each time).
  • Return an error when seek fails.
  • Read into pre-allocated buffers instead of creating arrays (avoid allocations for very small arrays).
  • Use sizeof instead of repeating header size.
  • Remove freetype dependancy (committed to master rBfd592538d983bec51e331f1d073c39582d43520f)
  • Return an error if writing the file fails.
  • Close file on failure.
  • Use BLI_fopen for writing the file since it's used for reading and has better compatibility for file paths (if this is ever used on Windows).

Quickly check the code itself, looks fine to me, besides the trivial note below.

source/blender/blendthumb/src/blender_thumbnailer.cc
91

This is not closing dst_file

source/blender/blendthumb/src/blender_thumbnailer.cc
91

This is in fact being closed, blendthumb_create_png_data_from_thumb takes ownership and closes this file in the case of an error.

Since this reads like a bug, I'll note this in a comment.

Campbell Barton (campbellbarton) marked an inline comment as not done.Oct 19 2021, 12:56 AM
Campbell Barton (campbellbarton) added inline comments.
source/blender/blendthumb/src/blender_thumbnailer.cc
91

Correction, you were right (the logic described above is done for src_file, where BLI_filereader_new_file takes ownership).

Campbell Barton (campbellbarton) marked an inline comment as not done.
  • Fix file handle recource leak.
  • Use uint8_t instead of char for binary data.
Campbell Barton (campbellbarton) added inline comments.
source/blender/blendthumb/src/blendthumb_extract.cc
37

Using fized size char arrays now.

101

Using blender::Array<uint8_t>.

128–141

Split file_seek into a separate function.

Campbell Barton (campbellbarton) marked 3 inline comments as done.

Quiet warnings on WIN32, resolve build error on macOS.

Fix: Build issues on windows

This fixes the following issues:

  • missing namespace in the usage of std::max in blendthumb_win32.cc
  • Windows.h redefines min and max macros
  • blenlib's stack trace code requires version.lib and dbghelp.lib to be linked
  • version.lib tries to implicitly drag in the release CRT, which leads to a linker warning for debug builds

Removing sebbas since he isn't available at the moment.

This revision is now accepted and ready to land.Oct 20 2021, 1:05 AM
Campbell Barton (campbellbarton) edited the summary of this revision. (Show Details)

Closing, as this has been commited.