Closed michaeldsmith closed 1 year ago
Here are the steps to reproduce the ctlrender valgrind issue using OpenEXR 3.1:
git clone https://github.com/ampas/CTL.git
cd CTL
docker build --rm -f Dockerfile_openexr3 -t ctl:latest .
docker run -it --rm ctl:latest
cd build
rm -R *
cmake .. -DCMAKE_BUILD_TYPE=Debug
make
make install
cd unittest/ctlrender/
valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak-kinds=all ../../ctlrender/ctlrender -force -format exr16 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==846== Memcheck, a memory error detector
==846== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==846== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==846== Command: ../../ctlrender/ctlrender -force -format exr16 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==846==
==846== Invalid read of size 2
==846== at 0x49163C3: Imf_3_1::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_3_1::Compressor::Format, Imf_3_1::PixelType) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x4924109: Imf_3_1::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x522F3E0: IlmThread_3_1::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x522F6F6: IlmThread_3_1::ThreadPool::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x49249B8: Imf_3_1::OutputFile::writePixels(int) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x1C36DA: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846== Address 0x5749754 is 4 bytes after a block of size 194,400 alloc'd
==846== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==846== by 0x1C41DF: ctl::dpx::fb<Imath_3_2::half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==846== by 0x1C3515: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846==
==846== Invalid read of size 2
==846== at 0x49163B0: Imf_3_1::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_3_1::Compressor::Format, Imf_3_1::PixelType) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x4924109: Imf_3_1::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x522F3E0: IlmThread_3_1::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x522F6F6: IlmThread_3_1::ThreadPool::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x49249B8: Imf_3_1::OutputFile::writePixels(int) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x1C36DA: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846== Address 0x574975c is 12 bytes after a block of size 194,400 alloc'd
==846== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==846== by 0x1C41DF: ctl::dpx::fb<Imath_3_2::half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==846== by 0x1C3515: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846==
==846==
==846== HEAP SUMMARY:
==846== in use at exit: 0 bytes in 0 blocks
==846== total heap usage: 1,038 allocs, 1,038 frees, 13,541,155 bytes allocated
==846==
==846== All heap blocks were freed -- no leaks are possible
==846==
==846== ERROR SUMMARY: 24300 errors from 2 contexts (suppressed: 0 from 0)
==846==
==846== 12051 errors in context 1 of 2:
==846== Invalid read of size 2
==846== at 0x49163C3: Imf_3_1::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_3_1::Compressor::Format, Imf_3_1::PixelType) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x4924109: Imf_3_1::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x522F3E0: IlmThread_3_1::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x522F6F6: IlmThread_3_1::ThreadPool::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x49249B8: Imf_3_1::OutputFile::writePixels(int) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x1C36DA: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846== Address 0x5749754 is 4 bytes after a block of size 194,400 alloc'd
==846== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==846== by 0x1C41DF: ctl::dpx::fb<Imath_3_2::half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==846== by 0x1C3515: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846==
==846==
==846== 12249 errors in context 2 of 2:
==846== Invalid read of size 2
==846== at 0x49163B0: Imf_3_1::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_3_1::Compressor::Format, Imf_3_1::PixelType) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x4924109: Imf_3_1::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x522F3E0: IlmThread_3_1::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x522F6F6: IlmThread_3_1::ThreadPool::addTask(IlmThread_3_1::Task*) (in /usr/local/lib/libIlmThread-3_1.so.30.5.1)
==846== by 0x49249B8: Imf_3_1::OutputFile::writePixels(int) (in /usr/local/lib/libOpenEXR-3_1.so.30.5.1)
==846== by 0x1C36DA: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846== Address 0x574975c is 12 bytes after a block of size 194,400 alloc'd
==846== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==846== by 0x1C41DF: ctl::dpx::fb<Imath_3_2::half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==846== by 0x1C3515: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==846== by 0x1C37FF: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==846== by 0x1BE4D6: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==846== by 0x1B7748: main (main.cc:678)
==846==
==846== ERROR SUMMARY: 24300 errors from 2 contexts (suppressed: 0 from 0)
Here are the steps to reproduce the ctlrender valgrind issue using OpenEXR 2.5:
git clone https://github.com/ampas/CTL.git
cd CTL
docker build --rm -f Dockerfile -t ctl:latest .
docker run -it --rm ctl:latest
cd build
rm -R *
cmake .. -DCMAKE_BUILD_TYPE=Debug
make
make install
cd unittest/ctlrender/
valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak-kinds=all ../../ctlrender/ctlrender -force -format exr16 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==785== Memcheck, a memory error detector
==785== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==785== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==785== Command: ../../ctlrender/ctlrender -force -format exr16 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==785==
==785== Invalid read of size 2
==785== at 0x48E59A3: Imf_2_5::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_2_5::Compressor::Format, Imf_2_5::PixelType) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x48BDAC9: Imf_2_5::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x5204450: IlmThread_2_5::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x5204726: IlmThread_2_5::ThreadPool::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x48BE378: Imf_2_5::OutputFile::writePixels(int) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x1C267A: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785== Address 0x57156e4 is 4 bytes after a block of size 194,400 alloc'd
==785== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==785== by 0x1C309D: ctl::dpx::fb<half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==785== by 0x1C24B5: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785==
==785== Invalid read of size 2
==785== at 0x48E5990: Imf_2_5::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_2_5::Compressor::Format, Imf_2_5::PixelType) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x48BDAC9: Imf_2_5::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x5204450: IlmThread_2_5::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x5204726: IlmThread_2_5::ThreadPool::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x48BE378: Imf_2_5::OutputFile::writePixels(int) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x1C267A: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785== Address 0x57156ec is 12 bytes after a block of size 194,400 alloc'd
==785== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==785== by 0x1C309D: ctl::dpx::fb<half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==785== by 0x1C24B5: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785==
==785==
==785== HEAP SUMMARY:
==785== in use at exit: 0 bytes in 0 blocks
==785== total heap usage: 1,037 allocs, 1,037 frees, 13,541,107 bytes allocated
==785==
==785== All heap blocks were freed -- no leaks are possible
==785==
==785== ERROR SUMMARY: 24300 errors from 2 contexts (suppressed: 0 from 0)
==785==
==785== 12051 errors in context 1 of 2:
==785== Invalid read of size 2
==785== at 0x48E59A3: Imf_2_5::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_2_5::Compressor::Format, Imf_2_5::PixelType) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x48BDAC9: Imf_2_5::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x5204450: IlmThread_2_5::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x5204726: IlmThread_2_5::ThreadPool::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x48BE378: Imf_2_5::OutputFile::writePixels(int) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x1C267A: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785== Address 0x57156e4 is 4 bytes after a block of size 194,400 alloc'd
==785== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==785== by 0x1C309D: ctl::dpx::fb<half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==785== by 0x1C24B5: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785==
==785==
==785== 12249 errors in context 2 of 2:
==785== Invalid read of size 2
==785== at 0x48E5990: Imf_2_5::copyFromFrameBuffer(char*&, char const*&, char const*, unsigned long, Imf_2_5::Compressor::Format, Imf_2_5::PixelType) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x48BDAC9: Imf_2_5::(anonymous namespace)::LineBufferTask::execute() (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x5204450: IlmThread_2_5::(anonymous namespace)::NullThreadPoolProvider::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x5204726: IlmThread_2_5::ThreadPool::addTask(IlmThread_2_5::Task*) (in /usr/local/lib/libIlmThread-2_5.so.25.0.7)
==785== by 0x48BE378: Imf_2_5::OutputFile::writePixels(int) (in /usr/local/lib/libIlmImf-2_5.so.26.0.0)
==785== by 0x1C267A: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:247)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785== Address 0x57156ec is 12 bytes after a block of size 194,400 alloc'd
==785== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==785== by 0x1C309D: ctl::dpx::fb<half>::init(unsigned int, unsigned int, unsigned int) (dpx.tcc:85)
==785== by 0x1C24B5: exr_write16(char const*, float, ctl::dpx::fb<float> const&, Compression*) (exr_file.cc:228)
==785== by 0x1C279D: exr_write(char const*, float, ctl::dpx::fb<float> const&, format_t*, Compression*) (exr_file.cc:257)
==785== by 0x1BD476: transform(char const*, char const*, float, float, format_t*, Compression*, std::__cxx11::list<ctl_operation_t, std::allocator<ctl_operation_t> > const&, std::__cxx11::list<ctl_parameter_t, std::allocator<ctl_parameter_t> > const&) (transform.cc:843)
==785== by 0x1B6786: main (main.cc:678)
==785==
==785== ERROR SUMMARY: 24300 errors from 2 contexts (suppressed: 0 from 0)
using -format exr32
to set ctlrender output to 32-bit EXR does not cause any valgrind issue with OpenEXR 3.1 or OpenEXR 2.5
valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak-kinds=all ../../ctlrender/ctlrender -force -format exr32 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==847== Memcheck, a memory error detector
==847== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==847== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==847== Command: ../../ctlrender/ctlrender -force -format exr32 -ctl ../../../unittest/ctlrender/unity.ctl ../../../unittest/ctlrender/bars_photoshop.exr out.exr
==847==
==847==
==847== HEAP SUMMARY:
==847== in use at exit: 0 bytes in 0 blocks
==847== total heap usage: 1,030 allocs, 1,030 frees, 13,224,179 bytes allocated
==847==
==847== All heap blocks were freed -- no leaks are possible
==847==
==847== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I'm not at a keyboard now to check but I think the setFrameBuffer in the CTL exr_write16 assumes you always have exactly four channels (since it treats the buffer as an Rgba array) Using the more verbose approach that write32 uses to set up the FrameBuffer might work better
thanks @peterhillman - I re-wrote the ctlrender exr_write16() function similar to exr_write32() as you suggested and it has resolved the valgrind issue. Thanks again for the suggestion. If you have a few minutes and want to review my pull request, it is here https://github.com/ampas/CTL/pull/116
Also, I wanted to note that while researching this issue, I found this ancient 2003 email [1] from Florian that I think suggests the RgbaOutputFile
and setFrameBuffer
did support RGB in the past. If it that is no longer the case and if they only support the WRITE_RGBA
option, it might make sense to throw a warning or exception if the WRITE_RGB
value is used with the RgbaOutputFile
constructor.
Here is Florian's code snippet from that email using WRITE_RGB
Header header (width, height);
RgbaOutputFile out (fileName, header, WRITE_RGB);
out.setFrameBuffer (&pixels[0][0], 1, width);
out.writePixels (height);
It also seems there are several example uses of RgbaOutputFile
with WRITE_RGB
are included in the current OpenEXR main branch, for example:
There is one use of WRITE_RGB
in this file at line 32:
\bazel\example\main.cpp
and 4 uses of WRITE_RGB
in this file at lines 188, 211, 326 and 364
\src\test\OpenEXRTest\testStandardAttributes.cpp
Just for the records regarding \bazel\example\main.cpp
Here is a slightly modified version of the file that also reads in the written .exr file and outputs some data: https://github.com/Vertexwahn/Piper/blob/main/BazelDemos/third_party_libraries/cpp/OpenEXR/main.cpp ->
for (Imf::ChannelList::ConstIterator channel = exrChannels.begin();
channel != exrChannels.end();
channel++) {
std::cout << channel.name() << std::endl;
}
Gives me
width: 100 height: 100
A
B
G
R
when RgbaOutputFile
is used with WRITE_RGBA
.
WRITE_RGB
outputs:
width: 100 height: 100
B
G
R
WRITE_RGB
Seems to work - does not have an alpha channel, whereas WRITE_RGBA
has an alpha channel
@Vertexwahn it would be interesting to see if valgrind also reports errors when using WRITE_RGB
with \bazel\example\main.cpp
versus using WRITE_RGBA
with \bazel\example\main.cpp
I think this makes sense, and I don't think anything is wrong with the library. That setFrameBuffer method always assumes that the data is stored as an Rgba array: WRITE_RGB and WRITE_RGBA change which channels are written, not which channels are assumed to be in the provided array. So, even if you only write RGB, you still need to provide four half floats per pixel to use that setFrameBuffer method, and the alpha value slot will be ignored if you specify WRITE_RGB.
The valgrind error arose because a three-halfs-per-pixel array was cast to an Rgba array, causing the library to read beyond the end of the array.
thanks again @peterhillman - closing the issue since there is noting wrong with the OpenEXR library
hi - I'm the maintainer of https://github.com/ampas/CTL/
I recently added a test for ctlrender to output 16-bit EXR and 32-bit EXR files. I ran valgrind on these tests, and the 16-bit EXR output test results in a valgrind error while the 32-bit EXR output test does not result in valgrind error. I've filed issue (https://github.com/ampas/CTL/issues/109) in CTL repo to track this, the valgrind test that is part of the CI is now failing.
I don't believe the valgrind issue is due to code in the the CTL repo, I think it may be due to issue in OpenEXR code. I will post the steps to reproduce the issue with OpenEXR 3.1 and OpenEXR 2.5 below.