@@ -8198,3 +8198,149 @@ OCIO_ADD_TEST(Config, get_processor_alias)
81988198 OCIO::TRANSFORM_TYPE_FIXED_FUNCTION);
81998199 }
82008200}
8201+
8202+ OCIO_ADD_TEST (Config, optimization_with_bitdepths)
8203+ {
8204+ // The unit test validates that the bit-depth conversion is correctly done for an empty list of
8205+ // ops i.e. the color transformation does nothing.
8206+
8207+ static constexpr char sFromSpace [] = " ACEScg" ;
8208+ static constexpr char sDiplay [] = " AdobeRGB" ;
8209+ static constexpr char sView [] = " raw" ;
8210+
8211+ static constexpr char CONFIG[] = { R"( ocio_profile_version: 2
8212+ environment: {}
8213+ search_path: "./"
8214+ roles:
8215+ data: Raw
8216+ default: Raw
8217+ scene_linear: ACEScg
8218+
8219+ file_rules:
8220+ - !<Rule> {name: Default, colorspace: default}
8221+
8222+ displays:
8223+ AdobeRGB:
8224+ - !<View> {name: Raw, colorspace: Raw}
8225+
8226+ colorspaces:
8227+ - !<ColorSpace>
8228+ name: ACEScg
8229+ to_reference: !<MatrixTransform> {matrix: [ 0.695452241357, 0.140678696470, 0.163869062172, 0, 0.044794563372, 0.859671118456, 0.095534318172, 0, -0.005525882558, 0.004025210306, 1.001500672252, 0, 0, 0, 0, 1 ]}
8230+ - !<ColorSpace>
8231+ name: Raw
8232+ isdata: true)" };
8233+
8234+ {
8235+ std::istringstream iss;
8236+ iss.str (CONFIG);
8237+
8238+ OCIO::ConstConfigRcPtr mOCIOCfg ;
8239+ OCIO_CHECK_NO_THROW (mOCIOCfg = OCIO::Config::CreateFromStream (iss));
8240+ OCIO_CHECK_NO_THROW (mOCIOCfg ->validate ());
8241+
8242+ // Create the two processors.
8243+
8244+ OCIO::DisplayViewTransformRcPtr transform = OCIO::DisplayViewTransform::Create ();
8245+ transform->setSrc (sFromSpace );
8246+ transform->setDisplay (sDiplay );
8247+ transform->setView (sView );
8248+
8249+ auto proc = mOCIOCfg ->getProcessor (transform);
8250+
8251+ auto cpu1 = proc->getDefaultCPUProcessor ();
8252+ auto cpu2 = proc->getOptimizedCPUProcessor (OCIO::BIT_DEPTH_F32, OCIO::BIT_DEPTH_UINT8, OCIO::OPTIMIZATION_DEFAULT);
8253+
8254+ // Declare all the buffers.
8255+
8256+ float inCol[4 ] = { 0 .5f , 0 .5f , 0 .5f , 1 .0f };
8257+ float outCol1[4 ];
8258+ uint8_t outCol2[4 ];
8259+
8260+ // Wrap source and destination colors.
8261+
8262+ OCIO::PackedImageDesc descSrc (inCol, 1 , 1 , OCIO::CHANNEL_ORDERING_RGBA);
8263+
8264+ OCIO::PackedImageDesc descDst1 (outCol1, 1 , 1 , OCIO::CHANNEL_ORDERING_RGBA);
8265+ OCIO::PackedImageDesc descDst2 (outCol2, 1 , 1 , OCIO::CHANNEL_ORDERING_RGBA, OCIO::BIT_DEPTH_UINT8, 1 , 4 , 4 );
8266+
8267+ cpu1->apply (descSrc, descDst1);
8268+ cpu2->apply (descSrc, descDst2);
8269+
8270+ // Check results.
8271+
8272+ OCIO_CHECK_EQUAL (outCol1[0 ], 0 .5f );
8273+ OCIO_CHECK_EQUAL (outCol1[1 ], 0 .5f );
8274+ OCIO_CHECK_EQUAL (outCol1[2 ], 0 .5f );
8275+ OCIO_CHECK_EQUAL (outCol1[3 ], 1 .0f );
8276+
8277+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[0 ], 128 );
8278+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[1 ], 128 );
8279+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[2 ], 128 );
8280+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[3 ], 255 );
8281+ }
8282+
8283+ {
8284+ std::istringstream iss;
8285+ iss.str (CONFIG);
8286+
8287+ OCIO::ConstConfigRcPtr mOCIOCfg ;
8288+ OCIO_CHECK_NO_THROW (mOCIOCfg = OCIO::Config::CreateFromStream (iss));
8289+ OCIO_CHECK_NO_THROW (mOCIOCfg ->validate ());
8290+
8291+ // Setup viewing pipeline for proc1.
8292+
8293+ OCIO::DisplayViewTransformRcPtr transform = OCIO::DisplayViewTransform::Create ();
8294+ transform->setSrc (sFromSpace );
8295+ transform->setDisplay (sDiplay );
8296+ transform->setView (sView );
8297+ OCIO::LegacyViewingPipelineRcPtr vp = OCIO::LegacyViewingPipeline::Create ();
8298+ vp->setDisplayViewTransform (transform);
8299+
8300+ // Add Exposure / Contrast.
8301+ {
8302+ OCIO::ExposureContrastTransformRcPtr ex = OCIO::ExposureContrastTransform::Create ();
8303+ ex->setStyle (OCIO::EXPOSURE_CONTRAST_LINEAR);
8304+ ex->setPivot (0.18 );
8305+ ex->makeExposureDynamic ();
8306+ ex->makeContrastDynamic ();
8307+ ex->makeGammaDynamic ();
8308+ vp->setLinearCC (ex);
8309+ }
8310+
8311+ // Create two processors 1: using viewing pipeline, 2: using just Display/View pair.
8312+
8313+ auto processor1 = vp->getProcessor (mOCIOCfg , mOCIOCfg ->getCurrentContext ());
8314+ auto processor2 = mOCIOCfg ->getProcessor (sFromSpace , sDiplay , sView , OCIO::TRANSFORM_DIR_FORWARD);
8315+
8316+ // Get optimized processors.
8317+
8318+ auto cpu1 = processor1->getOptimizedCPUProcessor (OCIO::BIT_DEPTH_F32, OCIO::BIT_DEPTH_UINT8, OCIO::OPTIMIZATION_DEFAULT);
8319+ auto cpu2 = processor2->getOptimizedCPUProcessor (OCIO::BIT_DEPTH_F32, OCIO::BIT_DEPTH_UINT8, OCIO::OPTIMIZATION_DEFAULT);
8320+
8321+ // Declare all the buffers.
8322+
8323+ float inCol[4 ] = { 0 .5f , 0 .5f , 0 .5f , 1 .0f };
8324+ uint8_t outCol1[3 ];
8325+ uint8_t outCol2[3 ];
8326+
8327+ // Wrap source and destination colors.
8328+
8329+ OCIO::PackedImageDesc descSrc (inCol, 1 , 1 , OCIO::CHANNEL_ORDERING_RGBA);
8330+ OCIO::PackedImageDesc descDst1 (outCol1, 1 , 1 , OCIO::CHANNEL_ORDERING_RGB, OCIO::BIT_DEPTH_UINT8, 1 , 3 , 3 );
8331+ OCIO::PackedImageDesc descDst2 (outCol2, 1 , 1 , OCIO::CHANNEL_ORDERING_RGB, OCIO::BIT_DEPTH_UINT8, 1 , 3 , 3 );
8332+
8333+ cpu1->apply (descSrc, descDst1);
8334+ cpu2->apply (descSrc, descDst2);
8335+
8336+ // Check results.
8337+
8338+ OCIO_CHECK_EQUAL ((uint32_t )outCol1[0 ], 128 );
8339+ OCIO_CHECK_EQUAL ((uint32_t )outCol1[1 ], 128 );
8340+ OCIO_CHECK_EQUAL ((uint32_t )outCol1[2 ], 128 );
8341+
8342+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[0 ], 128 );
8343+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[1 ], 128 );
8344+ OCIO_CHECK_EQUAL ((uint32_t )outCol2[2 ], 128 );
8345+ }
8346+ }
0 commit comments