Giter VIP home page Giter VIP logo

tev's People

Contributors

anderslanglands avatar btebedo avatar cek avatar chaosink avatar diiigle avatar dvicini avatar kingosticks avatar laurelkeys avatar mcrescas avatar merlinnd avatar mmp avatar oktomus avatar reiner-dolp avatar tom94 avatar wouterdek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tev's Issues

Crash due to X error 20 (X_GetProperty) upon file opening under XMonad

I installed tev via the AUR and I can start it just fine. However, as soon as I try to open a file (or start with a file via the command line) I get the following error from tev crashing;

X Error of failed request:  BadAtom (invalid Atom parameter)
  Major opcode of failed request:  20 (X_GetProperty)
  Atom id in failed request:  0x0
  Serial number of failed request:  218
  Current serial number in output stream:  218

It is neither dependent on the file nor the file type (at least as far as I can tell).

I am using version 1.12dev under Arch Linux (4.18.10-arch1-1-ARCH) running xmonad version 0.14

OpenEXR alpha is premultiplied

Hi Thomas,

It seems that tev doesn't handle the alpha channel of OpenEXR images quite right. By convention, OpenEXR images use "premultiplied alpha" (see page 21 in https://www.openexr.com/documentation/TechnicalIntroduction.pdf). That means that the color values stored in the OpenEXR file are already multiplied by alpha.

From what I have seen, tev does not account for this (please correct me if I missed something). This leads to behavior which isn't consistent with standard tools (e.g. Adobe Photoshop or MacOS Preview). I uploaded two example EXR images here:
https://www.dropbox.com/sh/5ngueg2vf6dwvho/AAAoMuo2d0jqO0Y-XJ_AIvzVa?dl=0

The premultiplied image looks wrong in tev, but correct in the other two programs. The problem is most likely easily fixed by dividing the RGB values by alpha when loading the image (and doing nothing if alpha == 0)

Cheers,
Delio

What are the icons for?

With a CMAKE_INSTALL_PREFIX=/opt/tev, I get:

Install the project...
-- Install configuration: "Release"
-- Installing: /opt/tev/bin/tev
-- Installing: /usr/share/applications/tev.desktop
-- Installing: /usr/share/icons/hicolor/512x512/apps/tev.png
-- Installing: /usr/share/icons/hicolor/256x256/apps/tev.png
-- Installing: /usr/share/icons/hicolor/128x128/apps/tev.png
-- Installing: /usr/share/icons/hicolor/96x96/apps/tev.png
-- Installing: /usr/share/icons/hicolor/64x64/apps/tev.png
-- Installing: /usr/share/icons/hicolor/48x48/apps/tev.png
-- Installing: /usr/share/icons/hicolor/32x32/apps/tev.png
-- Installing: /usr/share/icons/hicolor/24x24/apps/tev.png
-- Installing: /usr/share/icons/hicolor/16x16/apps/tev.png

What is the intended purpose of these images?

channels, when specified, are reordered

I have an EXR image that has (among other things) channels named "LeR", "LeG", "LeB" (emitted radiance, RGB). If I run tev :LeR,LeG,LeB out.exr, then the image is displayed with red for "LeB", green for "LeG", and blue for "LeR" (i.e., the blue and red channels are swapped).

This seems to be happening because Image::readExr() loops over the channels in the EXR file in order and takes the ones that match the channel selector in the order that they're found. (I'm not sure what the appropriate fix is, though, or if there's already a way to get the behavior I'm hoping for.)

I can provide a test case if that's helpful.

tev unable to display a very simple png

(Not a big problem, but I thought I'd report it anyway.)

tev silently fails at displaying this image: kdwarp-0, which is a single-channel PNG with a single white scanline and is otherwise black.

Interestingly enough, It has no problem with this one, which is the same resolution, also single channel, and has a few more white scanlines: kdwarp-2

Waveforms instead of histogram

Any interest in implementing support for Video Waveforms instead of Histograms?

I'm willing to help with the change. Most video professionals (that I'm aware of) prefer waveforms to histograms.

UI scaling on high-dpi screen

Hi,
The UI does currently not seem to scale with higher DPI screens. I am using Arch Linux (KDE) and a 4K monitor. The KDE user interface scales nicely, but the tev interface becomes tiny.

I am not sure whether the underlying issue here is a nanogui problem, so feel free to close the issue if you think it should be fixed in nanogui itself. ;)
Delio

Loading all images from a folder

Hello,
Thank you so much for creating this repo.

What do I have to do in order to:

  1. Load 1000 image names from a folder, populate your LHS image list with these names and then trigger image display upon clicking an image name on the list

  2. Following that, I want to display the image and the normalized image side by side in the image pane

Thanks,

[osx] seeing crashes in glDeleteTextures()

I've started seeing fairly frequent (~a few a day) crashes from tev. The only change from my earlier usage has been that I have viewing more PNGs (in addition to lots of EXRs (and rendered images over IPC as before.) I don't have a reliable way of reproducing the crashes; it just happens every few hours, often when tev is not the active application.

FWIW here is a stack trace from a debug build. Let me know what else I can send along that might be useful.

(lldb) bt
* thread #29, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00007fff37b9069d libGL.dylib`glDeleteTextures + 18
    frame #1: 0x00000001000de32b tev`tev::GlTexture::~GlTexture(this=0x000000011fc03948) at GlTexture.h:33:13
    frame #2: 0x00000001000d3735 tev`tev::GlTexture::~GlTexture(this=0x000000011fc03948) at GlTexture.h:31:27
    frame #3: 0x00000001000de3ac tev`tev::ImageTexture::~ImageTexture(this=0x000000011fc03948) at Image.h:32:8
    frame #4: 0x00000001000d3755 tev`tev::ImageTexture::~ImageTexture(this=0x000000011fc03948) at Image.h:32:8
    frame #5: 0x00000001000de213 tev`std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture>::~pair(this=0x000000011fc03930) at utility:314:29
    frame #6: 0x00000001000de1e5 tev`std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture>::~pair(this=0x000000011fc03930) at utility:314:29
    frame #7: 0x00000001000de1c9 tev`void std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, void*> > >::__destroy<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture> >((null)=std::__1::false_type @ 0x000070000d930808, (null)=0x0000000102565ef8, __p=0x000000011fc03930) at memory:1747:23
    frame #8: 0x00000001000de0fd tev`void std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, void*> > >::destroy<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture> >(__a=0x0000000102565ef8, __p=0x000000011fc03930) at memory:1595:14
    frame #9: 0x00000001000de06f tev`std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture> > >::destroy(this=0x0000000102565ef0, __nd=0x000000011fc03910) at __tree:1843:9
    frame #10: 0x00000001000ddfe5 tev`std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture> > >::~__tree(this=0x0000000102565ef0) at __tree:1831:3
    frame #11: 0x00000001000ddfb5 tev`std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture> > >::~__tree(this=0x0000000102565ef0) at __tree:1828:1
    frame #12: 0x00000001000ddf95 tev`std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture> > >::~map(this=0x0000000102565ef0 size=1) at map:873:28
    frame #13: 0x00000001000d28e5 tev`std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, tev::ImageTexture, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, tev::ImageTexture> > >::~map(this=0x0000000102565ef0 size=1) at map:873:28
    frame #14: 0x00000001000f95d5 tev`tev::Image::~Image(this=0x0000000102565e98) at Image.h:37:7
    frame #15: 0x00000001000f9585 tev`tev::Image::~Image(this=0x0000000102565e98) at Image.h:37:7
    frame #16: 0x00000001000f8ee1 tev`std::__1::__shared_ptr_emplace<tev::Image, std::__1::allocator<tev::Image> >::__on_zero_shared(this=0x0000000102565e80) at memory:3706:23
    frame #17: 0x00000001000178da tev`std::__1::__shared_count::__release_shared(this=0x0000000102565e80) at memory:3540:9
    frame #18: 0x000000010001787f tev`std::__1::__shared_weak_count::__release_shared(this=0x0000000102565e80) at memory:3582:27
    frame #19: 0x000000010001784c tev`std::__1::shared_ptr<std::__1::packaged_task<void ()> >::~shared_ptr(this=0x0000000158b128e8) at memory:4518:19
    frame #20: 0x000000010000e1d5 tev`std::__1::shared_ptr<std::__1::packaged_task<void ()> >::~shared_ptr(this=0x0000000158b128e8) at memory:4516:1
    frame #21: 0x000000010011ecec tev`tev::ImageCanvas::canvasStatistics(this=0x0000000158b128e8)::$_4::~$_4() at ImageCanvas.cpp:454:87
    frame #22: 0x00000001001149e5 tev`tev::ImageCanvas::canvasStatistics(this=0x0000000158b128e8)::$_4::~$_4() at ImageCanvas.cpp:454:87
    frame #23: 0x0000000100159ec5 tev`std::__1::__compressed_pair_elem<tev::ImageCanvas::canvasStatistics()::$_4, 0, false>::~__compressed_pair_elem(this=0x0000000158b128e8) at memory:2133:8
    frame #24: 0x0000000100159fc5 tev`std::__1::__compressed_pair<tev::ImageCanvas::canvasStatistics()::$_4, std::__1::allocator<tev::ImageCanvas::canvasStatistics()::$_4> >::~__compressed_pair(this=0x0000000158b128e8) at memory:2207:7
    frame #25: 0x0000000100159fa5 tev`std::__1::__compressed_pair<tev::ImageCanvas::canvasStatistics()::$_4, std::__1::allocator<tev::ImageCanvas::canvasStatistics()::$_4> >::~__compressed_pair(this=0x0000000158b128e8) at memory:2207:7
    frame #26: 0x0000000100159a7f tev`std::__1::__function::__func<tev::ImageCanvas::canvasStatistics()::$_4, std::__1::allocator<tev::ImageCanvas::canvasStatistics()::$_4>, std::__1::shared_ptr<tev::CanvasStatistics> ()>::destroy_deallocate(this=0x0000000158b128e0) at functional:1553:11
    frame #27: 0x000000010015e122 tev`std::__1::function<std::__1::shared_ptr<tev::CanvasStatistics> ()>::operator=(this=0x0000000158b13470, (null)=0x0000000000000000) at functional:1846:14
    frame #28: 0x000000010015df87 tev`std::__1::function<std::__1::shared_ptr<tev::CanvasStatistics> ()>::operator=(this=0x0000000158b13470, __f=0x000070000d930b90)>&&) at functional:1821:11
    frame #29: 0x000000010015de6a tev`tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::compute(this=0x0000000158b13460) at Lazy.h:96:18
    frame #30: 0x000000010015ddce tev`tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync(this=0x0000000158b134f8)::'lambda'()::operator()() const at Lazy.h:80:28
    frame #31: 0x000000010015dd7f tev`decltype(__f=0x0000000158b134f8)::'lambda'()&>(fp)()) std::__1::__invoke<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&) at type_traits:4339:1
    frame #32: 0x000000010015d983 tev`std::__1::__packaged_task_func<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'(), std::__1::allocator<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>, std::__1::shared_ptr<tev::CanvasStatistics> ()>::operator(this=0x0000000158b134f0)() at future:1821:12
    frame #33: 0x0000000100160961 tev`std::__1::__packaged_task_function<std::__1::shared_ptr<tev::CanvasStatistics> ()>::operator(this=0x0000000158b134f0)() const at future:1998:12
    frame #34: 0x0000000100160809 tev`std::__1::packaged_task<std::__1::shared_ptr<tev::CanvasStatistics> ()>::operator(this=0x0000000158b134f0)() at future:2089:24
    frame #35: 0x000000010016076d tev`std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync(this=0x000070000d930e48)::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'()::operator()() const at ThreadPool.h:37:53
    frame #36: 0x000000010016072d tev`decltype(__f=0x000070000d930e48)::'lambda'()>(fp)()) std::__1::__invoke<std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'()&>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&) at type_traits:4339:1
    frame #37: 0x00000001001606dd tev`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync(__args=0x000070000d930e48)::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'()&>(std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'()&) at __functional_base:349:9
    frame #38: 0x000000010015f401 tev`std::__1::__function::__func<std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'(), std::__1::allocator<std::__1::future<std::__1::result_of<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'() ()>::type> tev::ThreadPool::enqueueTask<tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()>(tev::Lazy<std::__1::shared_ptr<tev::CanvasStatistics> >::computeAsync()::'lambda'()&&, bool)::'lambda'()>, void ()>::operator(this=0x000070000d930e40)() at functional:1562:12
    frame #39: 0x0000000100066fb5 tev`std::__1::function<void ()>::operator(this=0x000070000d930e40)() const at functional:1913:12
    frame #40: 0x0000000100213217 tev`tev::ThreadPool::startThreads(this=0x000000010222f4a8)::$_0::operator()() const at ThreadPool.cpp:51:17
    frame #41: 0x000000010021308d tev`decltype(__f=0x000000010222f4a8)::$_0>(fp)()) std::__1::__invoke<tev::ThreadPool::startThreads(unsigned long)::$_0>(tev::ThreadPool::startThreads(unsigned long)::$_0&&) at type_traits:4339:1
    frame #42: 0x0000000100212ff5 tev`void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, tev::ThreadPool::startThreads(unsigned long)::$_0>(__t=size=2, (null)=__tuple_indices<> @ 0x000070000d930eb8)::$_0>&, std::__1::__tuple_indices<>) at thread:342:5
    frame #43: 0x00000001002128c6 tev`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, tev::ThreadPool::startThreads(unsigned long)::$_0> >(__vp=0x000000010222f4a0) at thread:352:5
    frame #44: 0x00007fff5ac842eb libsystem_pthread.dylib`_pthread_body + 126
    frame #45: 0x00007fff5ac87249 libsystem_pthread.dylib`_pthread_start + 66
    frame #46: 0x00007fff5ac8340d libsystem_pthread.dylib`thread_start + 13

and here are all of the running threads

(lldb) thread list
Process 97350 stopped
  thread #1: tid = 0x13d3f41, 0x0000000100059734 tev`std::__1::vector<float, std::__1::allocator<float> >::__construct_at_end(this=0x00007ffeefbfbf50 size=5003059, __n=13746941) at vector:1023:40, queue = 'com.apple.main-thread'
  thread #3: tid = 0x13d3f53, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #4: tid = 0x13d3f54, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #5: tid = 0x13d3f55, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #6: tid = 0x13d3f56, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #7: tid = 0x13d3f57, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #8: tid = 0x13d3f58, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #9: tid = 0x13d3f59, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #10: tid = 0x13d3f5a, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #11: tid = 0x13d3f5b, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #12: tid = 0x13d3f5c, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #13: tid = 0x13d3f5d, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #14: tid = 0x13d3f5e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #15: tid = 0x13d3f5f, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #16: tid = 0x13d3f60, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #17: tid = 0x13d3f61, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #18: tid = 0x13d3f62, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #19: tid = 0x13d3f63, 0x00007fff5ac78992 libsystem_platform.dylib`_platform_bzero$VARIANT$Haswell + 114
  thread #20: tid = 0x13d3f64, 0x00007fff5abc61be libsystem_kernel.dylib`__read_nocancel + 10
  thread #21: tid = 0x13d3f65, 0x00007fff5abc8f32 libsystem_kernel.dylib`__semwait_signal + 10
  thread #25: tid = 0x13d3f79, 0x00007fff5abc522a libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.NSEventThread'
  thread #26: tid = 0x13d3f7c, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #27: tid = 0x13d3f7d, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #28: tid = 0x13d3f7e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
* thread #29: tid = 0x13d3f7f, 0x00007fff37b9069d libGL.dylib`glDeleteTextures + 18, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  thread #30: tid = 0x13d3f80, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #31: tid = 0x13d3f81, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #32: tid = 0x13d3f82, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #33: tid = 0x13d3f83, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #34: tid = 0x13d3f84, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #35: tid = 0x13d3f85, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #36: tid = 0x13d3f86, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #37: tid = 0x13d3f87, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #38: tid = 0x13d3f88, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #39: tid = 0x13d3f89, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #40: tid = 0x13d3f8a, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #41: tid = 0x13d3f8b, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #42: tid = 0x13d3f8c, 0x00007fff5abc8f32 libsystem_kernel.dylib`__semwait_signal + 10
  thread #43: tid = 0x13d3f93, 0x00007fff5abc8f32 libsystem_kernel.dylib`__semwait_signal + 10
  thread #46: tid = 0x143686e, 0x00007fff5abc6bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #47: tid = 0x1437cfa, 0x00007fff5abc6bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #48: tid = 0x1437d7e, 0x0000000000000000
  thread #129: tid = 0x143828c, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #130: tid = 0x143828d, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #131: tid = 0x143828e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #132: tid = 0x143828f, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #133: tid = 0x1438290, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #134: tid = 0x1438291, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #135: tid = 0x1438292, 0x0000000100172838 tev`Eigen::DenseStorage<float, -1, -1, -1, 0>::rows(this=0x00000001dca00a68) const at DenseStorage.h:410
  thread #136: tid = 0x1438293, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #137: tid = 0x1438294, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #138: tid = 0x1438295, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #139: tid = 0x1438296, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #140: tid = 0x1438297, 0x0000000100008b88 tev`Eigen::internal::evaluator<Eigen::Matrix<int, 2, 1, 0, 2, 1> >::~evaluator(this=0x000070000fe8bb68) at CoreEvaluators.h:273
  thread #141: tid = 0x1438298, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #142: tid = 0x1438299, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #143: tid = 0x143829a, 0x000000010011603f tev`std::__1::shared_ptr<tev::CanvasStatistics>::operator->(this=0x000070000d9b3c08) const at memory:3930:49
  thread #144: tid = 0x143829b, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #145: tid = 0x143829d, 0x0000000100090524 tev`Eigen::DenseCoeffsBase<Eigen::Matrix<float, -1, -1, 1, -1, -1>, 0>::coeff(this=0x0000000102415bb8, index=2092909) const at DenseCoeffsBase.h:145:14
  thread #146: tid = 0x143829e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #147: tid = 0x143829f, 0x0000000100010370 tev`Eigen::DenseStorage<float, -1, -1, -1, 1>::cols(this=0x0000000102415c18) const at DenseStorage.h:411:47
  thread #148: tid = 0x14382a0, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #149: tid = 0x14382a1, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #150: tid = 0x14382a2, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #151: tid = 0x14382a3, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #152: tid = 0x14382a4, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #153: tid = 0x14382a5, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #154: tid = 0x14382a6, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #155: tid = 0x14382a7, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #156: tid = 0x14382a8, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #157: tid = 0x14382a9, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #158: tid = 0x14382aa, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #159: tid = 0x14382ab, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #160: tid = 0x14382ac, 0x00000001000102dc tev`Eigen::DenseStorage<float, -1, -1, -1, 1>::data(this=0x0000000102286648) const at DenseStorage.h:432:54
  thread #161: tid = 0x14382e6, 0x000000010017967f tev`tev::ImageCanvas::computeCanvasStatistics(this=0x0000000119f01a18, i=1)::$_12::operator()(int) const at ImageCanvas.cpp:630:46
  thread #162: tid = 0x14382e7, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #163: tid = 0x14382e8, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #164: tid = 0x14382e9, 0x0000000100174add tev`Eigen::internal::evaluator<Eigen::Matrix<int, -1, -1, 0, -1, -1> >::evaluator(this=0x0000700010ad3b68, m=0x000070000da36790) at CoreEvaluators.h:284:5
  thread #165: tid = 0x14382ea, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #166: tid = 0x14382eb, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #167: tid = 0x14382ec, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #168: tid = 0x14382ed, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #169: tid = 0x14382ee, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #170: tid = 0x14382ef, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #171: tid = 0x14382f0, 0x00000001000102b0 tev`Eigen::internal::plainobjectbase_evaluator_data<float, -1>::plainobjectbase_evaluator_data(this=0x0000700010e68b68, ptr=0x000000022f693000, outerStride=4296494157) at CoreEvaluators.h:154
  thread #172: tid = 0x14382f1, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #173: tid = 0x14382f2, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #174: tid = 0x14382f3, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #175: tid = 0x14382f4, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #176: tid = 0x14382f5, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #177: tid = 0x1438306, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #178: tid = 0x1438307, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #179: tid = 0x1438308, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #180: tid = 0x1438309, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #181: tid = 0x143830a, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #182: tid = 0x143830b, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #183: tid = 0x143830c, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #184: tid = 0x143830d, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #185: tid = 0x143830e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #186: tid = 0x143830f, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #187: tid = 0x1438310, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #188: tid = 0x1438311, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #189: tid = 0x1438312, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #190: tid = 0x1438313, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #191: tid = 0x1438314, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #192: tid = 0x1438315, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #193: tid = 0x1438316, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #194: tid = 0x1438317, 0x00000001000100fc tev`Eigen::DenseStorage<float, -1, -1, -1, 1>::rows(this=0x0000000119f046f8) const at DenseStorage.h:410:54
  thread #195: tid = 0x1438318, 0x00000001000904b8 tev`Eigen::DenseCoeffsBase<Eigen::Matrix<float, -1, -1, 1, -1, -1>, 0>::operator(this=0x0000000119f04728, index=339996)(long) const at DenseCoeffsBase.h:181:7
  thread #196: tid = 0x1438319, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #197: tid = 0x143831a, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #198: tid = 0x143831b, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #199: tid = 0x143831c, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #200: tid = 0x143831d, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #201: tid = 0x143831e, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #202: tid = 0x143831f, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #203: tid = 0x1438320, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #204: tid = 0x1438321, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #205: tid = 0x1438322, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #206: tid = 0x1438323, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #207: tid = 0x1438324, 0x00007fff5abc886a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #208: tid = 0x1438325, 0x0000000100010370 tev`Eigen::DenseStorage<float, -1, -1, -1, 1>::cols(this=0x0000000119f046c8) const at DenseStorage.h:411:47

[osx] Crash when quitting tev

I just noticed this... (Possibly related to the #126 fix?) To reproduce, run tev x.png with the attached, hit command-q to quit, and it crashes.

x

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1e0)
  * frame #0: 0x00007fff5ac82137 libsystem_pthread.dylib`pthread_mutex_lock
    frame #1: 0x00007fff57cbd959 libc++.1.dylib`std::__1::mutex::lock() + 9
    frame #2: 0x00000001001ce433 tev`std::__1::lock_guard<std::__1::mutex>::lock_guard(this=0x00007ffeefbfce30, __m=0x00000000000001e0) at __mutex_base:104:27
    frame #3: 0x00000001001ce3ad tev`std::__1::lock_guard<std::__1::mutex>::lock_guard(this=0x00007ffeefbfce30, __m=0x00000000000001e0) at __mutex_base:104:21
    frame #4: 0x00000001001cdbde tev`tev::SharedQueue<std::__1::function<void ()> >::push(this=0x00000000000001b0, newElem= Function = _mh_execute_header )>) at SharedQueue.h:28:37
    frame #5: 0x000000010021ea4a tev`void tev::ImageViewer::scheduleToUiThread<std::__1::function<void ()> >(this=0x0000000000000000, fun= Function = _mh_execute_header )> const&) at ImageViewer.h:136:20
    frame #6: 0x000000010021e9d7 tev`tev::scheduleToMainThread(fun= Function = _mh_execute_header )> const&) at main.cpp:37:19
    frame #7: 0x00000001000ddb24 tev`tev::GlTexture::~GlTexture(this=0x000000010235bd58) at GlTexture.h:37:13
    frame #8: 0x00000001000d2f05 tev`tev::GlTexture::~GlTexture(this=0x000000010235bd58) at GlTexture.h:32:27
    frame #9: 0x0000000100217ee2 tev`tev::UberShader::~UberShader(this=0x000000010235bcf0) at UberShader.cpp:206:1
    frame #10: 0x0000000100217f45 tev`tev::UberShader::~UberShader(this=0x000000010235bcf0) at UberShader.cpp:204:27
    frame #11: 0x000000010011fe77 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #12: 0x0000000100117b65 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #13: 0x0000000100117b89 tev`tev::ImageCanvas::~ImageCanvas(this=0x000000010235bbc0) at ImageCanvas.h:24:7
    frame #14: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235bbc0, dealloc=true) const at common.cpp:345:9
    frame #15: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:35:20
    frame #16: 0x00000001003dbf15 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:32:19
    frame #17: 0x00000001003dbf39 tev`nanogui::Widget::~Widget(this=0x000000010235b810) at widget.cpp:32:19
    frame #18: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235b810, dealloc=true) const at common.cpp:345:9
    frame #19: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:35:20
    frame #20: 0x00000001003dbf15 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:32:19
    frame #21: 0x00000001003dbf39 tev`nanogui::Widget::~Widget(this=0x000000010235b770) at widget.cpp:32:19
    frame #22: 0x00000001003d5dac tev`nanogui::Object::decRef(this=0x000000010235b770, dealloc=true) const at common.cpp:345:9
    frame #23: 0x00000001003dbdb0 tev`nanogui::Widget::~Widget(this=0x0000000102225460) at widget.cpp:35:20
    frame #24: 0x00000001003f211b tev`nanogui::Screen::~Screen(this=0x0000000102225460) at screen.cpp:389:1
    frame #25: 0x000000010018e8b1 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:447:1
    frame #26: 0x000000010018e915 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:442:29
    frame #27: 0x000000010018e939 tev`tev::ImageViewer::~ImageViewer(this=0x0000000102225460) at ImageViewer.cpp:442:29
    frame #28: 0x0000000100268abf tev`std::__1::default_delete<tev::ImageViewer>::operator(this=0x00000001007e39c0, __ptr=0x0000000102225460)(tev::ImageViewer*) const at memory:2335:5
    frame #29: 0x0000000100223a3f tev`std::__1::unique_ptr<tev::ImageViewer, std::__1::default_delete<tev::ImageViewer> >::reset(this=0x00000001007e39c0, __p=0x0000000000000000) at memory:2648:7
    frame #30: 0x0000000100222acc tev`tev::mainFunc(arguments=size=2) at main.cpp:405:18
    frame #31: 0x0000000100223d16 tev`main(argc=2, argv=0x00007ffeefbff6d0) at main.cpp:433:9
    frame #32: 0x00007fff5aa903d5 libdyld.dylib`start + 1

IPC docs

First of all thanks for writing this tool, it very quick and easy to use!

I read that tev supports some kind of IPC protocol where it can show an image while it is being rendered. From what I gather you're supposed to send the image data to tev using TCP on the port it prints when it starts up, and the port is also configurable from the commandline options, that all makes sense.

What I can't find anywhere is what exactly I'm supposed to send to tev. Do I just dump the content of an exr file in a single TCP packet? Or is there some kind of custom protocol for sending incremental updates to tev?

Maybe instructions for this could be added to the README? I could be missing something but I can't find any documentation about the IPC feature.

Tev cannot open images on SMB network drive on Windows 10

Recently, I attempted to open an EXR image located on an SMB network drive using Tev. It failed to open the image, with error message File <filename> could not be opened.

I think this could be due to the double backslashes in the front of SMB-mapped filenames, like \\<remote>\<folder>\<image>.exr. I suspect this is the reason, because in the error message, the double backslashes are stripped, leaving only File <remote>\<folder>\<image>.exr could not be opened.

For comparison, Tev can read the same image successfully on MacOS (Catalina), and can also read an image mapped with SSHFS-Win (whose path starts with Y:\ instead of \\) on the same Windows machine.

I don't know how to make this issue reproducible, but it sounds very specific and I hope there is an easy fix.

Thanks!

An option to have a manually fixed range histogram

It would be useful to be able to manually fix the minimum and maximum values for the histogram.

That way, you would be able to directly compare the histogram values when flip back-and-forth between two images. Otherwise, if one histogram is stretched on one side (due to an error for example), the only option is to compare the images using one of the error metrics, which gives us a histogram of the error values.

Issues building on MacOS

Hi,

It seems that Tev, specifically one of its dependencies, doesn't compile on MacOS.
Here is the compiling error.

caojiayin@Caos-Air build % make
[  1%] Built target clip
[  1%] Building C object dependencies/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_init.m.o
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:282:1: error: expected identifier or '('
@interface GLFWLayoutListener : NSObject
^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:292:1: error: expected identifier or '('
@end
^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:354:9: error: expected expression
        [NSApp setDelegate:nil];
        ^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:355:9: error: expected expression
        [_glfw.ns.delegate release];
        ^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:361:9: error: expected expression
        [[NSDistributedNotificationCenter defaultCenter]
        ^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:365:9: error: expected expression
        [_glfw.ns.listener release];
        ^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:369:5: error: expected expression
    [_glfw.ns.cursor release];
    ^
/Users/caojiayin/Desktop/GitHub/tev/dependencies/nanogui/ext/glfw/src/cocoa_init.m:378:5: error: expected expression
    [_glfw.ns.autoreleasePool release];
    ^
8 errors generated.
make[2]: *** [dependencies/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_init.m.o] Error 1
make[1]: *** [dependencies/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/all] Error 2
make: *** [all] Error 2
  • MacOS version, Big Sur 11.1
  • XCode version, Version 12.2 (12B45b)
  • Both Intel and M1 Mac have this problem

Multipart EXR Image Loading

Currently tev does not support loading multipart EXRs. When such an image is loaded, only one part will be shown, which is the first part containing a layer that matches the provided layer selector.

Recently I have managed to let tev load multipart EXRs more correctly by showing all layers that match the selector. It's not a big change, so before creating a PR I would like to know whether there is a reason behind this seemingly buggy behavior.

Thanks!
Xianyao

memory leak when the network update function is used

I'm seeing a memory leak in recent versions of tev when sending images from pbrt running another process. (I've been seeing this for a while now, maybe a few months, but only made a repro case now--apologies.)

The attached repro program (extracted from pbrt, so not minimal!) takes a single command-line argument and connects to a running tev server at that address. It then spams it continuously with image updates. I am seeing two things (this is on OSX, FWIW):

  • tev's memory use (as reported by top) grows by about 1 MB every second
  • interestingly, if I hide tev (command-H), or make another window active and then click on tev to make it active again, memory use jumps up by about 50MB within a few seconds than another 40MB or so again a few seconds later.

So, between those two, it can add up to gigabytes after a while, especially with a long render running.

PF4 (PFM but with RGBA)

tev already supports PFM, which is very useful for quickly/easily writing out HDR images.
However, it is currently limited to monochrome or RGB. To add RGBA support, an extension exists called PF4 which adds an extra alpha channel.
You can find more details here: https://www.cse.cuhk.edu.hk/~ttwong/data/hdrfire/hdrfire.html

The only change compared to PFM is the magic keyword in the header, and the extra 4 bytes per pixel, so adding support should be fairly easy.

Thank you for creating tev!

`optional` header not included

Hello, I'm trying to build tev tag v1.19 on Manjaro Linux. I come across the following error.
It does fix the error and compiles correctly when I include optional header

In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ClipboardImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ClipboardImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional<T> tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘<optional>’; did you forget to ‘#include <optional>’?
    8 | #include <deque>
  +++ |+#include <optional>
    9 | #include <mutex>
Whole compilation log
[  1%] Building CXX object dependencies/clip/CMakeFiles/clip.dir/clip.cpp.o
[  1%] Building CXX object dependencies/openexr/IlmBase/Half/CMakeFiles/Half.dir/half.cpp.o
[  1%] Building CXX object dependencies/clip/CMakeFiles/clip.dir/image.cpp.o
[  1%] Building CXX object dependencies/openexr/IlmBase/Iex/CMakeFiles/Iex.dir/IexBaseExc.cpp.o
[  1%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/context.c.o
[  1%] Building CXX object dependencies/openexr/IlmBase/Iex/CMakeFiles/Iex.dir/IexThrowErrnoExc.cpp.o
[  1%] Building CXX object dependencies/clip/CMakeFiles/clip.dir/clip_x11.cpp.o
[  1%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/input.c.o
[  1%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/monitor.c.o
[  3%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/init.c.o
[  3%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/window.c.o
[  5%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/vulkan.c.o
[  5%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/x11_init.c.o
[  5%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/x11_monitor.c.o
[  6%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/x11_window.c.o
[  6%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/xkb_unicode.c.o
[  6%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/posix_time.c.o
[  8%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/posix_thread.c.o
[  8%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/glx_context.c.o
[  8%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/egl_context.c.o
[  8%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/osmesa_context.c.o
[ 10%] Building C object dependencies/nanogui/ext/glfw/src/CMakeFiles/glfw_objects.dir/linux_joystick.c.o
/var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/openexr/IlmBase/Half/half.cpp: In static member function ‘static float half::overflow()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/openexr/IlmBase/Half/half.cpp:73:11: warning: compound assignment with ‘volatile’-qualified left operand is deprecated [-Wvolatile]
   73 |         f *= f;                         // this will overflow before
      |         ~~^~~~
[ 10%] Linking CXX static library libHalf-2_5.a
[ 10%] Built target Half
[ 10%] Built target glfw_objects
[ 10%] Running bin2c
[ 12%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/renderpass_gl.cpp.o
[ 12%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/shader_gl.cpp.o
[ 12%] Building C object dependencies/nanogui/CMakeFiles/nanogui.dir/ext/nanovg/src/nanovg.c.o
[ 12%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/texture_gl.cpp.o
[ 12%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/opengl.cpp.o
[ 13%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/nanogui_resources.cpp.o
[ 13%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/common.cpp.o
[ 13%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/theme.cpp.o
[ 13%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/widget.cpp.o
[ 15%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/layout.cpp.o
[ 15%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/screen.cpp.o
[ 15%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/label.cpp.o
[ 17%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/window.cpp.o
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/src/layout.cpp:14:
/var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/layout.h: In function ‘nanogui::AdvancedGridLayout::Anchor::operator std::string() const’:
/var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/layout.h:414:82: warning: ‘, ’ directive output may be truncated writing 2 bytes into a region of size between 0 and 10 [-Wformat-truncation=]
  414 |             std::snprintf(buf, 50, "Format[pos=(%i, %i), size=(%i, %i), align=(%i, %i)]",
      |                                                                                  ^~
/var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/layout.h:414:36: note: directive argument in the range [0, 255]
  414 |             std::snprintf(buf, 50, "Format[pos=(%i, %i), size=(%i, %i), align=(%i, %i)]",
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/stdio.h:866,
                 from /usr/include/c++/11.1.0/cstdio:42,
                 from /usr/include/c++/11.1.0/ext/string_conversions.h:43,
                 from /usr/include/c++/11.1.0/bits/basic_string.h:6594,
                 from /usr/include/c++/11.1.0/string:55,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/common.h:21,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/object.h:15,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/include/nanogui/layout.h:18,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/dependencies/nanogui/src/layout.cpp:14:
/usr/include/bits/stdio2.h:71:35: note: ‘__builtin___snprintf_chk’ output between 46 and 58 bytes into a destination of size 50
   71 |   return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   72 |                                    __glibc_objsize (__s), __fmt,
      |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   73 |                                    __va_arg_pack ());
      |                                    ~~~~~~~~~~~~~~~~~
[ 17%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/popup.cpp.o
[ 17%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/checkbox.cpp.o
[ 17%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/button.cpp.o
[ 18%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/popupbutton.cpp.o
[ 20%] Linking CXX static library libIex-2_5.a
[ 20%] Linking CXX static library libclip.a
[ 20%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/combobox.cpp.o
[ 20%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/progressbar.cpp.o
[ 20%] Built target clip
[ 20%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/slider.cpp.o
[ 20%] Built target Iex
[ 20%] Building CXX object dependencies/openexr/IlmBase/IexMath/CMakeFiles/IexMath.dir/IexMathFloatExc.cpp.o
[ 22%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/messagedialog.cpp.o
[ 22%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThread.cpp.o
[ 22%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/textbox.cpp.o
[ 22%] Building CXX object dependencies/openexr/IlmBase/IexMath/CMakeFiles/IexMath.dir/IexMathFpu.cpp.o
[ 22%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/textarea.cpp.o
[ 24%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/imagepanel.cpp.o
[ 24%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/vscrollpanel.cpp.o
[ 24%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/colorwheel.cpp.o
[ 24%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/colorpicker.cpp.o
[ 25%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/graph.cpp.o
[ 25%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/tabwidget.cpp.o
[ 27%] Linking CXX static library libIexMath-2_5.a
[ 27%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/canvas.cpp.o
[ 27%] Built target IexMath
[ 27%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathRandom.cpp.o
[ 27%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadMutex.cpp.o
[ 29%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/texture.cpp.o
[ 31%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadMutexPosix.cpp.o
[ 31%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/shader.cpp.o
[ 31%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathColorAlgo.cpp.o
[ 31%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/imageview.cpp.o
[ 31%] Building CXX object dependencies/nanogui/CMakeFiles/nanogui.dir/src/traits.cpp.o
[ 31%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadPool.cpp.o
[ 31%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathFun.cpp.o
[ 31%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadPosix.cpp.o
[ 32%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathVec.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadSemaphore.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathMatrixAlgo.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/Imath/CMakeFiles/Imath.dir/ImathExc.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadSemaphorePosixCompat.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadSemaphorePosix.cpp.o
[ 34%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadSemaphoreOSX.cpp.o
[ 36%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadMutexWin32.cpp.o
[ 36%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadSemaphoreWin32.cpp.o
[ 36%] Building CXX object dependencies/openexr/IlmBase/IlmThread/CMakeFiles/IlmThread.dir/IlmThreadWin32.cpp.o
[ 37%] Linking CXX static library libIlmThread-2_5.a
[ 37%] Built target IlmThread
[ 39%] Linking CXX static library libImath-2_5.a
[ 39%] Built target Imath
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfAttribute.cpp.o
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfBoxAttribute.cpp.o
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfFrameBuffer.cpp.o
[ 43%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfChannelListAttribute.cpp.o
[ 44%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfHeader.cpp.o
[ 44%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfIO.cpp.o
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfCRgbaFile.cpp.o
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfChannelList.cpp.o
[ 41%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfFloatAttribute.cpp.o
[ 44%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfInputFile.cpp.o
[ 44%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfIntAttribute.cpp.o
[ 46%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfLineOrderAttribute.cpp.o
[ 46%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfMatrixAttribute.cpp.o
[ 46%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfOpaqueAttribute.cpp.o
[ 48%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfOutputFile.cpp.o
[ 48%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRgbaFile.cpp.o
[ 48%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfStringAttribute.cpp.o
[ 50%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfHuf.cpp.o
[ 50%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfVecAttribute.cpp.o
[ 50%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfThreading.cpp.o
[ 50%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfWav.cpp.o
[ 51%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfLut.cpp.o
[ 51%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfCompressor.cpp.o
[ 51%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRleCompressor.cpp.o
[ 51%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfZipCompressor.cpp.o
[ 53%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfPizCompressor.cpp.o
[ 53%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfB44Compressor.cpp.o
[ 53%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDwaCompressor.cpp.o
[ 53%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfMisc.cpp.o
[ 55%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfCompressionAttribute.cpp.o
[ 55%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDoubleAttribute.cpp.o
[ 55%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfConvert.cpp.o
[ 56%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfPreviewImage.cpp.o
[ 56%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfPreviewImageAttribute.cpp.o
[ 56%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfVersion.cpp.o
[ 56%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfChromaticities.cpp.o
[ 58%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfChromaticitiesAttribute.cpp.o
[ 58%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfKeyCode.cpp.o
[ 58%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfKeyCodeAttribute.cpp.o
[ 60%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTimeCode.cpp.o
[ 62%] Linking CXX static library libnanogui.a
[ 62%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTimeCodeAttribute.cpp.o
[ 62%] Built target nanogui
[ 62%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRational.cpp.o
[ 62%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRationalAttribute.cpp.o
[ 63%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfFramesPerSecond.cpp.o
[ 63%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfStandardAttributes.cpp.o
[ 63%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfStdIO.cpp.o
[ 63%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfEnvmap.cpp.o
[ 65%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfEnvmapAttribute.cpp.o
[ 65%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfScanLineInputFile.cpp.o
[ 65%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledInputFile.cpp.o
[ 67%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledMisc.cpp.o
[ 67%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledOutputFile.cpp.o
[ 67%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledRgbaFile.cpp.o
[ 67%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTileDescriptionAttribute.cpp.o
[ 68%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTileOffsets.cpp.o
[ 68%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRgbaYca.cpp.o
[ 68%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfPxr24Compressor.cpp.o
[ 70%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTestFile.cpp.o
[ 70%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfStringVectorAttribute.cpp.o
[ 70%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfMultiView.cpp.o
[ 70%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfAcesFile.cpp.o
[ 72%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfMultiPartOutputFile.cpp.o
[ 72%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfGenericOutputFile.cpp.o
[ 72%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfOutputPartData.cpp.o
[ 74%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfMultiPartInputFile.cpp.o
[ 74%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfGenericInputFile.cpp.o
[ 74%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfPartType.cpp.o
[ 74%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfInputPartData.cpp.o
[ 75%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfOutputPart.cpp.o
[ 75%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledOutputPart.cpp.o
[ 75%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfInputPart.cpp.o
[ 75%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfTiledInputPart.cpp.o
[ 77%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepScanLineInputPart.cpp.o
[ 77%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepScanLineOutputPart.cpp.o
[ 77%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepScanLineInputFile.cpp.o
[ 79%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepScanLineOutputFile.cpp.o
[ 79%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepTiledInputPart.cpp.o
[ 79%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepTiledOutputPart.cpp.o
[ 79%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepTiledInputFile.cpp.o
[ 81%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepTiledOutputFile.cpp.o
[ 81%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepFrameBuffer.cpp.o
[ 81%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepCompositing.cpp.o
[ 82%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfCompositeDeepScanLine.cpp.o
[ 82%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfDeepImageStateAttribute.cpp.o
[ 82%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfFastHuf.cpp.o
[ 82%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfFloatVectorAttribute.cpp.o
[ 84%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfRle.cpp.o
[ 84%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfSystemSpecific.cpp.o
[ 84%] Building CXX object dependencies/openexr/OpenEXR/IlmImf/CMakeFiles/IlmImf.dir/ImfZip.cpp.o
[ 86%] Linking CXX static library libIlmImf-2_5.a
[ 86%] Built target IlmImf
[ 86%] Building CXX object CMakeFiles/tev.dir/src/imageio/ClipboardImageLoader.cpp.o
[ 87%] Building CXX object CMakeFiles/tev.dir/src/imageio/ExrImageLoader.cpp.o
[ 87%] Building CXX object CMakeFiles/tev.dir/src/imageio/ExrImageSaver.cpp.o
[ 87%] Building CXX object CMakeFiles/tev.dir/src/imageio/ImageLoader.cpp.o
[ 86%] Building CXX object CMakeFiles/tev.dir/src/imageio/EmptyImageLoader.cpp.o
[ 87%] Building CXX object CMakeFiles/tev.dir/src/imageio/ImageSaver.cpp.o
[ 89%] Building CXX object CMakeFiles/tev.dir/src/imageio/PfmImageLoader.cpp.o
[ 89%] Building CXX object CMakeFiles/tev.dir/src/imageio/StbiHdrImageSaver.cpp.o
[ 89%] Building CXX object CMakeFiles/tev.dir/src/imageio/StbiImageLoader.cpp.o
[ 89%] Building CXX object CMakeFiles/tev.dir/src/imageio/StbiLdrImageSaver.cpp.o
[ 89%] Building CXX object CMakeFiles/tev.dir/src/Channel.cpp.o
[ 91%] Building CXX object CMakeFiles/tev.dir/src/Box.cpp.o
[ 91%] Building CXX object CMakeFiles/tev.dir/src/Common.cpp.o
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ClipboardImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ClipboardImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/PfmImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/PfmImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/EmptyImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/EmptyImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ClipboardImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ClipboardImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/PfmImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/PfmImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/EmptyImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/EmptyImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ExrImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ExrImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ClipboardImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ExrImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ExrImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
[ 93%] Building CXX object CMakeFiles/tev.dir/src/FalseColor.cpp.o
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/ClipboardImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/ImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
[ 93%] Building CXX object CMakeFiles/tev.dir/src/HelpWindow.cpp.o
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:8,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/StbiImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/StbiImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:46:10: error: ‘optional’ in namespace ‘std’ does not name a template type
   46 |     std::optional tryPop() {
      |          ^~~~~~~~
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/SharedQueue.h:9:1: note: ‘std::optional’ is defined in header ‘’; did you forget to ‘#include ’?
    8 | #include 
  +++ |+#include 
    9 | #include 
In file included from /var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/imageio/StbiImageLoader.h:6,
                 from /var/tmp/pamac-build-harshithg/tev/src/tev/src/imageio/StbiImageLoader.cpp:4:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h: In member function ‘std::optional tev::BackgroundImagesLoader::tryPop()’:
/var/tmp/pamac-build-harshithg/tev/src/tev/include/tev/Image.h:234:66: error: ‘class tev::SharedQueue’ has no member named ‘tryPop’
  234 |     std::optional tryPop() { return mLoadedImages.tryPop(); }
      |                                                                  ^~~~~~
make[2]: *** [CMakeFiles/tev.dir/build.make:76: CMakeFiles/tev.dir/src/imageio/ClipboardImageLoader.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [CMakeFiles/tev.dir/build.make:160: CMakeFiles/tev.dir/src/imageio/PfmImageLoader.cpp.o] Error 1
make[2]: *** [CMakeFiles/tev.dir/build.make:90: CMakeFiles/tev.dir/src/imageio/EmptyImageLoader.cpp.o] Error 1
make[2]: *** [CMakeFiles/tev.dir/build.make:132: CMakeFiles/tev.dir/src/imageio/ImageLoader.cpp.o] Error 1
make[2]: *** [CMakeFiles/tev.dir/build.make:104: CMakeFiles/tev.dir/src/imageio/ExrImageLoader.cpp.o] Error 1
make[2]: *** [CMakeFiles/tev.dir/build.make:188: CMakeFiles/tev.dir/src/imageio/StbiImageLoader.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:694: CMakeFiles/tev.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
==> ERROR: A failure occurred in build().
    Aborting...

Unicode not handled in filenames in sidebar

(OSX, FWIW)

If I load an image in tev using, say,

$ tev 🐨.exr --hostname 192.168.86.70:6502

Then although the filename is correctly displayed in the title bar, it is not correct in the list of files in the sidebar.

image

(Not the most important bug ever, but more common characters like those with umlauts seem to have trouble as well...)

image

tev color mismatch issue

Color space mismatch in tev

image

When I render in blender, and open the result image(exr) in tev, color looks different from blender.

In the left, tev and windows image viewer(jpg converted from exr). In the right, blender render result viewer.

You can see the reflections of the ball in the right clipped in tev and windows image viewer.

It looks just like in windows image viewer, so I think this is problem related to icc profile or something.

I'm not color professional, so I don't know what's behind this but there clearly is a color mismatch anyway.

I am currently using win10, blender 2.79b. tev version is 1.9.

Gamma controls

Is it possible to control gamma value for tone mapping?

Keyboard shortcuts: shift does too many things

I'm enjoying tev, thanks for you work 🙏 . I am comparing EXRs by going into 'error' mode and pumping the Exposure using the 'E' key. However decrease exposure is 'Shift-E', but 'Shift' toggles the reference image as well.

Maybe 'Alt-E' could be added as an alternative to 'Shift-E' (or some other workaround)?

Moving tev between monitors causes scale factor problems

I built tev from master branch (for macOS HDR features! - thank you). I notice that if I open tev.app on an external display, then move it to the macbook pro display (or vice versa) I end up with scaling problems in the UI. The hitboxes for the mouse do seem to be correctly scaled, just not the image (making it extra difficult to use as they don't line up).

This screenshot is what happens if I move the app from the laptop display to an external display (extra small text etc). The opposite (extra big text) happens if I go the other way.

Screenshot 2021-09-06 at 15 37 16

I built from dafebdb

gamma correction

Relate to 149

I think gamma correction is misleading visually and has numerical errors. Right?

    res = 512
    img_ori = np.zeros([res, res, 3]).astype(np.float32)  # RGB
    img_ori[:, :, :2] = 0
    img_ori[:, :, 2] = 1
    img_ori = cv2.cvtColor(img_ori, cv2.COLOR_RGB2BGR)  # BGR

    if True:
        img_nT = (img_ori + 1) / 2
        cv2.imwrite("check_gamma_nT.exr", img_nT)
        print("img_nT:", img_nT[0, 0, :])  # ! print: 1. 0.5 0.5; tev: 0.5000 0.5000 1.0000
        TMP_img_nT = cv2.imread("check_gamma_nT.exr", -1)
        print("TMP_img_nT:", TMP_img_nT[0, 0, :])  # ! print: 1. 0.5 0.5;
        print()
    if True:
        img_nT = (img_ori + 1) / 2
        img_nT = img_nT * 255
        img_nT = img_nT.astype(np.uint8)  # 0.5 ~ 127 ~ 0.4980
        cv2.imwrite("check_gamma_nT.png", img_nT)
        print("img_nT:", img_nT[0, 0, :], img_nT[0, 0, :] / 255)  # ! print: 255 127 127 / 1. 0.4980 0.4980; tev: 0.2122 0.2122 1.0000
        TMP_img_nT = cv2.imread("check_gamma_nT.png", -1)
        print("TMP_img_nT:", TMP_img_nT[0, 0, :], TMP_img_nT[0, 0, :] / 255)  # ! print: 255 127 127 / 1. 0.4980 0.4980;
        print()

check in tev
Kazam_screenshot_00001

Kazam_screenshot_00000

check in DaVinci Resolve
image

Crash when viewing multi channel image

With the attached image, if I:

  • load it in tev
  • click the "2 Albedo" at the bottom of the screen
  • press "6" on the keyboard

tev crashes with this stacktrace:

  * frame #0: 0x000000010034f813 tev`nanogui::Screen::keyboardCharacterEvent(this=0x0000000101c07810, codepoint=54) at screen.cpp:509:44
    frame #1: 0x0000000100350864 tev`nanogui::Screen::charCallbackEvent(this=0x0000000101c07810, codepoint=54) at screen.cpp:627:16
    frame #2: 0x0000000100355bd9 tev`nanogui::Screen::Screen(this=0x0000000101c07bd0, w=0x0000000101c07bd0, codepoint=54)::$_4::operator()(GLFWwindow*, unsigned int) const at screen.cpp:260:16
    frame #3: 0x0000000100355b3b tev`nanogui::Screen::Screen(w=0x0000000101c07bd0, codepoint=54)::$_4::__invoke(GLFWwindow*, unsigned int) at screen.cpp:253:9
    frame #4: 0x00000001003df5ca tev`_glfwInputChar(window=0x0000000101c07bd0, codepoint=54, mods=0, plain=1) at input.c:78:13
    frame #5: 0x00000001003eadd5 tev`-[GLFWContentView insertText:replacementRange:](self=0x000000010b40bbe0, _cmd="insertText:replacementRange:", string=@"6", replacementRange=location=9223372036854775807, length=0) at cocoa_window.m:750:9
[...]

small.exr.zip

How the displayed value is calculated?

I want to analyze an image numerically. The displayed result is different from the output of OpenCV/cvkit.

Take the first-pixel(top-left) value, when check in cvkit with: sv ORTHO_ColorN_01_Z000_PRO.png, and point to the top-left, the result is (126, 131, 254) and is consistent with the first print(). After gammaCorrection and divided by 255, the value is (0.21176471, 0.22745098, 0.98823529), but the displaied value is (0.2086, 0.2270, 0.9911).

Since the image is a normal maps(or in other formats such as depth maps), the accuracy of the values is critical.
So we hope tev can add the ability to display raw value.

CODE:

import cv2
import numpy as np


def gammaCorrectionDecoding(src, gamma):
    """
    NOTE: https://stackoverflow.com/a/16521337/10636347
        Gamma decoding is used to restore the original values, so the formula for that is:
        original = ((encoded / 255) ^ gamma) * 255
    """
    table = [((i / 255) ** gamma) * 255 for i in range(256)]
    table = np.array(table, np.uint8)
    return cv2.LUT(src, table)


path_img = "/home/lab9/Videos/for_tev/ORTHO_ColorN_01_Z000_PRO.png"
img = cv2.imread(path_img, -1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img[1082:1084, 990:993]
print(img)
img = gammaCorrectionDecoding(img, 2.2)
img = img / 255.0
print(img)

RES:

>>> [[[126 131 254]
  [127 131 254]
  [128 131 254]]

 [[123 126 254]
  [123 127 254]
  [122 127 254]]]

>>> [[[0.21176471 0.22745098 0.98823529]
  [0.21568627 0.22745098 0.98823529]
  [0.21568627 0.22745098 0.98823529]]

 [[0.2        0.21176471 0.98823529]
  [0.2        0.21568627 0.98823529]
  [0.19607843 0.21568627 0.98823529]]]

ORTHO_ColorN_01_Z000_PRO
tmp

Automatically append correct extension when saving file

Currently, when saving a file on Windows, the selected extension does nothing while the extension in the chosen filename is all that matters. The behavior should be, that the selected extension is automatically appended when it is not already present.

Wrong binary in release package?

Hi,

I noticed that the pre-compiled binaries ( both Mac and Windows ) try listening to the port through UDP, instead of TCP.
Since you mentioned in the other bug that TEV used to use UDP before, is there any chance that precompiled binary is an mismatched version with the release version?

Thanks

PNG with embedded color profile not displayed correctly

Hi,

I was trying to load a PNG image in TEV which was exported from GIMP. I did not create the image myself, but the person who created the image essentially loaded an EXR image in GIMP and exported it as a PNG with minor changes. The PNG displays correctly in Adobe Photoshop and Preview on MacOS, but not in TEV.

Upon closer inspection, I found that the PNG was stored in 16 bit with a custom color profile from GIMP. Reducing to 8 bit, but keeping the profile, does not change anything about the way TEV displays the image. If I convert the profile to a more standard RGB profile in Photoshop, TEV displays the image correctly.

So it seems that the problem is that TEV ignores custom color profiles in PNG files (?). I am not sure how easy it is to change that, but it would be good to at least have a warning being shown.

I have attached both an 8 bit and the original 16 bit version of the file.

test_images.zip

Best,
Delio

Compile error on VS2017 from the UTF-8 without signature encoding

I failed to build the project in VS2017 (in English, on a Chinese Windows 10) because there is one unrecognized character, the triple dots in the following screenshot:

ImageButton.cpp:146-148
image

The error list is as follows:
image

Changing the encoding from UTF-8 without signature to UTF-8 with signature solves the problem.

Display of pixel values text for single-channel images with alpha channel

Hi,

It seems that the display of the pixel values as text behaves in a surprising way for EXR images with only a luminance and an alpha channel:
image

The luminance value is displayed twice, whereas the alpha channel values are not displayed. The compositing of the image is correct, just the text output is confusing. For RGBA images, everything works as expected and I get text labels for R,G,B and A.

Delio

View multiple channels in layer

Hello Tom94,

Thank you for the software, it is amazing.

Here is my issue. I have an image with RGB channels as well as XYZ ones.
They are all listed as part of the layer when the mouse hovers above the image name on the left panel. I guess the color image I see on the main window is only the display of the RGB channels as it should but what about the XYZ channels ? I can't even view their values when zooming in nor switch between layers since there is only the one.

I know I could make a new layer for the XYZ channels but I propose two additional features.
The first would be to display all the values of the channels of the current layer when zooming in instead of only the first three (or RGB). The downside is that the display would could become quite hectic when there is more than 6-7 channels.

The second would be to have a way to switch between channels like the way we can switch between layers (this feature is already so useful).
Or a way to select the channels we want to display.

What do you (and other people) think ?

tev gui does not appear after launch

I cloned tev, built and installed it... When I try to load an image using tev,

tev multipart.0001.exr

I get the following message:

09:14:57 SUCCESS Connected to primary instance at 127.0.0.1:14158

but the tev gui does not appear, although it does seem to be running, as verify through ps -aef |grep tev.

IPC updateImage performance issue

I was running a render that was pretty fast, about one minute for 1920x1080, data sent to tev in 16x16 blocks of pixels which looks like this:

image

I imagine that this is a typical intented usecase of the IPC. I noticed that tev was using about 25% of the CPU, and some profiling revealed that a lot of the time was spent in setting up and taking down the threadpool here:

tev/src/Ipc.cpp

Line 251 in d7aaf6c

ThreadPool threadPool;

Could this threadpool be made persistent? Right now it's created and destroyed for each updateImage packet received which is not very efficient.

More flexible image data format for updating

Hi,

This is not a necessary feature, though, it would be a lot more helpful to have it.

Basically, the way to update multiple channels together is to do it the way similar we update one single channel. The difference here is to send three channels of data together, instead of just one. This does eliminate the possibility of partially updating one single channel before refreshing the image viewer, which was the purpose.

However, the way it requires the data to be packed is a bit inefficient. Since lots of application commonly saves data in the form of interleaved data, like this

  • [ R, G, B, A, R, G, B, A, R, G, B, A ]

While tev requires this form

  • [ [R,R,R], [G,G,G], [B,B,B], [A,A,A] ]

This means that for an app with the above internal memory layout, it has to create a temporary memory to hold the data in the format tev wants and also an extra memory copy because of tev.

It would be nice to support the above format too. A solution to support this is fairly simple, tev can ask for per-channel metadata, that should have 'stride' and 'base_offset'

  • stride, the memory size in terms of bytes between each channel value of the pixels
  • base_offset, the start address of the memory for this channel.

With the two, we can actually support both the two layouts in a unified implementation and there is definitely flexibility to support more memory layout with this change.

  • [ R, G, B, A, R, G, B, A, R, G, B, A ]
    Channel meta data would be, ['R', 0, 16], ['G', 4, 16], ['B', 8, 16], ['A', 12, 16]
  • [ R, R, R, G, G, G, B, B, B, A, A, A ]
    Channel meta data would be, ['R', 0, 4], ['G', 12, 4], ['B', 24, 4], [A, 36, 4]

This way, applications, like ray tracer, don't need to create a separate memory just for holding data to pass to tev and also saves the cost of memory copying from its own memory layout to tev requested memory layout

Thanks

Window keeps repainting when idle

Thank You for such a great tool. This is currently my favorite exr viewer.

Crossposted in wjakob/nanogui#337
On Win10 tev window keeps constantly repainting itself eating GPU cycles. Task manager shows 1% GPU utilization on GTX 780 even when out of focus. To be a good desktop citizen, application should repaint its windows only when required. A quick investigation showed that repaint is configured in the main.cpp:
nanogui::mainloop(250)
I disabled continous refresh rate with:
nonogui::mainloop(0)
GPU utilization dropped to 0.5%, but surprisingly didn't disable repaints completely. Digging further I noticed that glfwWaitEvents in nanogui::mainloop keeps returning every second. This is caused by the constant stream of WM_GETICON messages (verified with Spy++). I couldn't resist to hack glfwWaitEvents to ignore this message:

void _glfwPlatformWaitEvents(void)
{
#define HACK_GETICON
#ifndef HACK_GETICON
    // Original implementation
    WaitMessage();
#else
    // Hack: Process WM_GETICON and keep waiting
    while (1)
    {
        MsgWaitForMultipleObjects(0, NULL, FALSE, INFINITE, QS_ALLEVENTS);
        MSG msg;
        if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (msg.message == WM_GETICON)
            {
                // Remove message from the queue
                GetMessageW(&msg, NULL, 0, 0);
                TranslateMessage(&msg);
                DispatchMessage(&msg);
                // Keep waiting
            }
            else // No more waiting
            {
                break;
            }
        }
    }
#endif
    _glfwPlatformPollEvents();
}

GPU utilization dropped to 0% after this hack. This is obviously more of a problem of nanogui rather than TEV itself. I'm reporting this just to keep You noted.

Pixels with RGB>0 and A=0 are still displayed

Hi Thomas,
Opening the attached EXR file leads to an odd behavior in tev. The file contains pixels with non-zero RGB components and a zero alpha. Opening them in Photoshop or Gimp displays these pixels as fully transparent, while in tev these are partially visible. This behavior was observed using tev 1.16dev on a Ubuntu 18.04 machine.

EXR file:
test.zip

display raw RGB values

Tev currently displays floating point color values in the top border of the window.
Would it be possible to also display the raw color values as well? So for png, jpg, it would show RGB(A) as 8b integers. There are many uses of this, but for example, i was recently looking at a semantic segmentation dataset, and i wanted to know the exact value at a pixel because the image was encoding the class label ID there.

Pixel RGB label behavior when zoomed in

Hi,
When I zoom in too much, the text label for the pixel color breaks. Initially everything is fine, as shown here:
image
But as I zoom in further, I get artifacts and the editor also starts to lag:
image

Delio

High CPU usage on Windows

I recently updated my tev binary (Windows, pre-built) from v1.17 to v1.19 and experience a consistent high CPU load of tev (1 thread, 100%). This happens even if I just start the application in idle with no images loaded yet.

I think it is connected to the IPC communication as I observed some interesting behaviour there:

Background

I have an app that starts the tev process, connects to it over TCP, sends a CreateImage, then an UpdateImage packet. I can also repeat this process on the click of a button.

Steps

When I open an image the first time, the tev instance opens correctly, but doesn't show the image. Tev runs with 100% CPU load on one thread. Even if I reopen the image (different name, so new CreateImage, UpdateImage combo) from my GUI it doesn't show either. If I close the tev window, the process stays there, with 100% CPU load on one thread.

If I kill the tev process, and click on the "reopen image" button again, a second instance opens, and shows the image correctly on the first go.

Thoughts

I'm inclined to rule out my side of the IPC implementation, as it works fine with v1.17 (every time) and v1.19 (the second time). Even if this is unrelated to IPC, the high CPU load is still indicating a blocking call (possibly some mutex) somewhere.

PS: It doesn't matter if the instance is the primary or a secondary. The CPU load is high in both cases.

Out of memory lock-up

A useful feature would be to choose whether to load the images into memory, for particularly large EXR files. Loading a sequence of 600 130MB caused the system to entirely lock up.

Add chromaticity processing

As of recently, tev can render to wider gamut color spaces that differ from the default sRGB/Rec 709 space (e.g. DCI-P3), by specifying an image with negative component values. It's a neat trick---however, the more principled way would be that the OpenEXR file specifies a Imf::Chromaticities header entry and uses positive-only values.

However, tev does not consider this header field and as such treats any input file as sRGB. I suggest adding some transformation code that detects non-default chromaticities and then internally transforms to equivalent Rec 709 with negative component values.

Here is some example code of how this is done in Mitsuba 2, feel free to copy-paste.

// equality comparison for Imf::Chromaticities instances
auto chroma_eq = [](const Imf::Chromaticities &a,
                    const Imf::Chromaticities &b) {
    return (a.red  - b.red).length2()  + (a.green - b.green).length2() +
           (a.blue - b.blue).length2() + (a.white - b.white).length2() < 1e-6f;
};

Imf::Chromaticities itu_rec_b_709; // default rec709 (sRGB) primaries

// Check if there is a chromaticity header entry
Imf::Chromaticities file_chroma;
if (Imf::hasChromaticities(file.header()))
    file_chroma = Imf::chromaticities(file.header());


if (!chroma_eq(file_chroma, itu_rec_b_709)) {
    Imath::M44f M = Imf::RGBtoXYZ(file_chroma, 1) *
                    Imf::XYZtoRGB(itu_rec_b_709, 1);

    auto convert = [&](auto *data) {
        using T = std::decay_t<decltype(*data)>;

        for (size_t j = 0; j < pixel_count; ++j) {
            float R = (float) data[0],
                  G = (float) data[1],
                  B = (float) data[2];

            if (std::is_integral<T>::value) {
                float scale = float(1) / std::numeric_limits<T>::max();
                R *= scale; G *= scale; B *= scale;
            }

            Imath::V3f rgb = Imath::V3f(R, G, B) * M;
            R = rgb[0]; G = rgb[1]; B = rgb[2];

            if (std::is_integral<T>::value) {
                float scale = std::numeric_limits<T>::max();
                R = R * scale + 0.5f;
                G = G * scale + 0.5f;
                B = B * scale + 0.5f;
            }

            data[0] = T(R); data[1] = T(G); data[2] = T(B);
            data += channel_count();
        }
    };

    switch (m_component_format) {
        case Struct::EFloat16: convert((enoki::half *) m_data.get()); break;
        case Struct::EFloat32: convert((float *)       m_data.get()); break;
        case Struct::EUInt32:  convert((uint32_t*)     m_data.get()); break;
        default: Throw("Internal error!");
    }
}

1mb limitation is a too small for large images

Hi

I've been working on supporting TEV in my renderer.
https://sort-renderer.com/

And I noticed one limitation that is unnecessary to exist. Fixing it takes probably half an hour at most.
The size of this buffer 'mBuffer' in IPC is hard-coded as 1mb, this is not entirely necessary since you know the buffer size needed to hold all of the temporary memory when you receive a package from socket.
1 mb is can only update an image tile up to 256 x 256, this is nowhere near a full 1080p or 4k image.
So if I want to refresh half of my image, there is no easy way to do it without tiling that half image.

It would be nice to remove the limitation and have probably a way bigger limitation like 1GB in case it is really requested through socket.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.