diff --git a/OpenEXR_CTL/exr_ctl_exr/main.cpp b/OpenEXR_CTL/exr_ctl_exr/main.cpp index 7b52d64e..ca07e8d1 100644 --- a/OpenEXR_CTL/exr_ctl_exr/main.cpp +++ b/OpenEXR_CTL/exr_ctl_exr/main.cpp @@ -351,5 +351,15 @@ main(int argc, char **argv) exitStatus = 1; } + // clean up dynamically allocated memory + if(extraAttrs.size() > 0) + { + for(AttrMap::iterator it=extraAttrs.begin() ; it!=extraAttrs.end() ; it++) + { + delete it->second; + } + } + extraAttrs.clear(); + return exitStatus; } diff --git a/resources/test/scripts/run_valgrind.sh b/resources/test/scripts/run_valgrind.sh index 83e17004..b7e982c1 100644 --- a/resources/test/scripts/run_valgrind.sh +++ b/resources/test/scripts/run_valgrind.sh @@ -92,11 +92,21 @@ valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak test_20_status=$? test_20_label="exrdpx-exr-to-dpx" +cd ../exr_ctl_exr +cp ../../OpenEXR_CTL/exr_ctl_exr/*.ctl . +valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak-kinds=all ../../OpenEXR_CTL/exr_ctl_exr/exr_ctl_exr -C change_saturation ../../../unittest/exr_ctl_exr/marci-512.exr ./output/exr_ctl_exr-no-args.exr +test_21_status=$? +test_21_label="exr_ctl_exr" + +valgrind -s --error-exitcode=1 --leak-check=full --track-origins=yes --show-leak-kinds=all ../../OpenEXR_CTL/exr_ctl_exr/exr_ctl_exr -C change_saturation -float sScale 1.2 ../../../unittest/exr_ctl_exr/marci-512.exr ./output/exr_ctl_exr-sScale-1.2.exr +test_22_status=$? +test_22_label="exr_ctl_exr-float" + # go back to initial path cd $SCRIPTPATH # return valgrind exit codes -if [ $test_01_status -eq 0 ] && [ $test_02_status -eq 0 ] && [ $test_03_status -eq 0 ] && [ $test_04_status -eq 0 ] && [ $test_05_status -eq 0 ] && [ $test_06_status -eq 0 ] && [ $test_07_status -eq 0 ] && [ $test_08_status -eq 0 ] && [ $test_09_status -eq 0 ] && [ $test_10_status -eq 0 ] && [ $test_11_status -eq 0 ] && [ $test_12_status -eq 0 ] && [ $test_13_status -eq 0 ] && [ $test_14_status -eq 0 ] && [ $test_15_status -eq 0 ] && [ $test_16_status -eq 0 ] && [ $test_17_status -eq 0 ] && [ $test_18_status -eq 0 ] && [ $test_19_status -eq 0 ] && [ $test_20_status -eq 0 ] +if [ $test_01_status -eq 0 ] && [ $test_02_status -eq 0 ] && [ $test_03_status -eq 0 ] && [ $test_04_status -eq 0 ] && [ $test_05_status -eq 0 ] && [ $test_06_status -eq 0 ] && [ $test_07_status -eq 0 ] && [ $test_08_status -eq 0 ] && [ $test_09_status -eq 0 ] && [ $test_10_status -eq 0 ] && [ $test_11_status -eq 0 ] && [ $test_12_status -eq 0 ] && [ $test_13_status -eq 0 ] && [ $test_14_status -eq 0 ] && [ $test_15_status -eq 0 ] && [ $test_16_status -eq 0 ] && [ $test_17_status -eq 0 ] && [ $test_18_status -eq 0 ] && [ $test_19_status -eq 0 ] && [ $test_20_status -eq 0 ] && [ $test_21_status -eq 0 ] && [ $test_22_status -eq 0 ] then echo "Success: valgrind detected no errors" exit 0 @@ -203,5 +213,15 @@ else echo "$test_20_label: valgrind detected errors" fi + if [ $test_21_status -ne 0 ] + then + echo "$test_21_label: valgrind detected errors" + fi + + if [ $test_22_status -ne 0 ] + then + echo "$test_22_label: valgrind detected errors" + fi + exit 1 fi diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index bb1de532..2493a746 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -4,5 +4,6 @@ add_subdirectory(IlmImfCtl) if (CTL_BUILD_TOOLS) add_subdirectory(ctlrender) add_subdirectory(exrdpx) + add_subdirectory(exr_ctl_exr) endif() diff --git a/unittest/exr_ctl_exr/CMakeLists.txt b/unittest/exr_ctl_exr/CMakeLists.txt new file mode 100644 index 00000000..3e3d9461 --- /dev/null +++ b/unittest/exr_ctl_exr/CMakeLists.txt @@ -0,0 +1,43 @@ +if(NOT DEFINED EXR_CTL_EXR_BUILD_DIR) + set(EXR_CTL_EXR_BUILD_DIR "${CMAKE_BINARY_DIR}/OpenEXR_CTL/exr_ctl_exr") + message("exr_ctl_exr build director: ${EXR_CTL_EXR_BUILD_DIR}") +endif() + +if(NOT DEFINED EXR_CTL_EXR_EXECUTABLE_PATH) + set(EXR_CTL_EXR_EXECUTABLE_PATH "${EXR_CTL_EXR_BUILD_DIR}/exr_ctl_exr") + message("exr_ctl_exr test executable: ${EXR_CTL_EXR_EXECUTABLE_PATH}") +endif() + +set(EXR_CTL_EXR_OUTPUT_FOLDER "${CMAKE_BINARY_DIR}/unittest/exr_ctl_exr/output") +message("exr_ctl_exr test output folder will be created at: ${EXR_CTL_EXR_OUTPUT_FOLDER}") +add_custom_target(exr-ctl-exr-build-time-make-directory ALL + COMMAND ${CMAKE_COMMAND} -E make_directory ${EXR_CTL_EXR_OUTPUT_FOLDER}) + +set(TEST_FILES "${PROJECT_SOURCE_DIR}/unittest/exr_ctl_exr") + +# copy CTL files to build folder +add_custom_target( + exr-ctl-exr-build-time-copy-CTL-file1 ALL + COMMAND ${CMAKE_COMMAND} -E copy + ${TEST_FILES}/change_saturation.ctl + "${EXR_CTL_EXR_BUILD_DIR}") + +if(OpenEXR_FOUND) + + add_test(NAME "exr-ctl-exr-noargs" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-noargs.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-t-3" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -t 3 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-t-3.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-t-4" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -t 4 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-t-4.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-sScale-1.0" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -float sScale 1.0 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-sScale-1.0.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-sScale-1.2" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -float sScale 1.2 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-sScale-1.2.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-sScale-0.8" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -float sScale 0.8 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-sScale-0.8.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-sScale-1.2-adoptedNeutral-D65" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -float sScale 1.2 -float2 adoptedNeutral 0.31271 0.32902 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-sScale-1.2-adoptedNeutral-D65.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + + add_test(NAME "exr-ctl-exr-sScale-1.2-adoptedNeutral-D93" COMMAND ${EXR_CTL_EXR_EXECUTABLE_PATH} -C change_saturation -float sScale 1.2 -float2 adoptedNeutral 0.28315 0.29711 "${TEST_FILES}/marci-512.exr" "${EXR_CTL_EXR_OUTPUT_FOLDER}/exr-ctl-exr-sScale-1.2-adoptedNeutral-D93.exr" WORKING_DIRECTORY "${EXR_CTL_EXR_BUILD_DIR}") + +endif() diff --git a/unittest/exr_ctl_exr/change_saturation.ctl b/unittest/exr_ctl_exr/change_saturation.ctl new file mode 100644 index 00000000..33914a5b --- /dev/null +++ b/unittest/exr_ctl_exr/change_saturation.ctl @@ -0,0 +1,131 @@ +/////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2013 Academy of Motion Picture Arts and Sciences +// ("A.M.P.A.S."). Portions contributed by others as indicated. +// All rights reserved. +// +// A worldwide, royalty-free, non-exclusive right to copy, modify, create +// derivatives, and use, in source and binary forms, is hereby granted, +// subject to acceptance of this license. Performance of any of the +// aforementioned acts indicates acceptance to be bound by the following +// terms and conditions: +// +// * Copies of source code, in whole or in part, must retain the +// above copyright notice, this list of conditions and the +// Disclaimer of Warranty. +// +// * Use in binary form must retain the above copyright notice, +// this list of conditions and the Disclaimer of Warranty in the +// documentation and/or other materials provided with the distribution. +// +// * Nothing in this license shall be deemed to grant any rights to +// trademarks, copyrights, patents, trade secrets or any other +// intellectual property of A.M.P.A.S. or any contributors, except +// as expressly stated herein. +// +// * Neither the name "A.M.P.A.S." nor the name of any other +// contributors to this software may be used to endorse or promote +// products derivative of or based on this software without express +// prior written permission of A.M.P.A.S. or the contributors, as +// appropriate. +// +// This license shall be construed pursuant to the laws of the State of +// California, and any disputes related thereto shall be subject to the +// jurisdiction of the courts therein. +// +// Disclaimer of Warranty: THIS SOFTWARE IS PROVIDED BY A.M.P.A.S. AND +// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO +// EVENT SHALL A.M.P.A.S., OR ANY CONTRIBUTORS OR DISTRIBUTORS, BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, RESITUTIONARY, +// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// +// WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE ACADEMY +// SPECIFICALLY DISCLAIMS ANY REPRESENTATIONS OR WARRANTIES WHATSOEVER +// RELATED TO PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS IN THE ACADEMY +// COLOR ENCODING SYSTEM, OR APPLICATIONS THEREOF, HELD BY PARTIES OTHER +// THAN A.M.P.A.S., WHETHER DISCLOSED OR UNDISCLOSED. +/////////////////////////////////////////////////////////////////////////// + +// +// Function change_saturation() saturates or desaturates an RGB image by +// converting the pixels to CIELAB, multiplying the a* and b* components +// by a caller-supplied factor, sScale, and converting back to RGB. +// +// Parameters: +// +// R, G, B Input pixel value +// +// ROut, GOut, BOut Output pixel value +// +// sScale Saturation scale factor: +// sScale > 1 increases saturation, +// 0 <= sScale < 1 decreases saturation, +// +// chromaticities CIE (x,y) coordinates of the primaries +// and white point for the input and output +// pixels +// +// whiteLuminance Luminance of pixels with R = G = B = 1 +// +// adoptedNeutral CIE (x,y) coordinates of the white stimulus +// for RGB-to-LAB and LAB-to-RGB conversion. +// Decreasing or increasing saturation makes +// the pixel colors move towards or away from +// the adoptedNeutral value. +// + +void +change_saturation + (output varying half ROut, + output varying half GOut, + output varying half BOut, + varying half R, + varying half G, + varying half B, + float adoptedNeutral[2], + Chromaticities chromaticities, + float whiteLuminance = 1.0, + float sScale = 1.0) +{ + // + // Compute the XYZ coordinates of the white stimulus. + // + + float XYZn[3]; + XYZn[0] = adoptedNeutral[0] * whiteLuminance / adoptedNeutral[1]; + XYZn[1] = whiteLuminance; + XYZn[2] = whiteLuminance / adoptedNeutral[1] - XYZn[0] - whiteLuminance; + + // + // Convert input RGB value first to XYZ, then to LAB + // + + float toXYZ[4][4] = RGBtoXYZ (chromaticities, whiteLuminance); + float RGB[3] = {R, G, B}; + float XYZ[3] = mult_f3_f44 (RGB, toXYZ); + float Lab[3] = XYZtoLab (XYZ, XYZn); + + // + // Change saturation by scaling the a* and b* coordinates. + // + + Lab[1] = Lab[1] * sScale; + Lab[2] = Lab[2] * sScale; + + // + // Convert back to XYZ and then to RGB + // + + XYZ = LabtoXYZ (Lab, XYZn); + float toRGB[4][4] = XYZtoRGB (chromaticities, whiteLuminance); + RGB = mult_f3_f44 (XYZ, toRGB); + ROut = RGB[0]; + GOut = RGB[1]; + BOut = RGB[2]; +} diff --git a/unittest/exr_ctl_exr/marci-512.exr b/unittest/exr_ctl_exr/marci-512.exr new file mode 100644 index 00000000..04ce5a52 Binary files /dev/null and b/unittest/exr_ctl_exr/marci-512.exr differ