@@ -510,12 +510,11 @@ bump_to_bumpslopes(ImageBuf& dst, const ImageBuf& src,
510510 return false ;
511511 }
512512 is_height = false ;
513- } else if (Strutil::iequals (
514- bumpformat,
515- " auto" )) { // guess input bump format by analyzing channel count and component
513+ } else if (Strutil::iequals (bumpformat, " auto" )) {
514+ // guess input bump format by analyzing channel count and component
516515 if (src.spec ().nchannels > 2
517- && !ImageBufAlgo::isMonochrome (src)) // maybe it's a normal map?
518- is_height = false ;
516+ && !ImageBufAlgo::isMonochrome (src, 0 . 0f , ROI (), nthreads))
517+ is_height = false ; // maybe it's a normal map?
519518 else
520519 is_height = true ;
521520 } else {
@@ -705,6 +704,8 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
705704 ImageSpec outspec = outspec_template;
706705 outspec.set_format (outputdatatype);
707706
707+ int nthreads = configspec.get_int_attribute (" maketx:threads" );
708+
708709 // Going from float to half is prone to generating Inf values if we had
709710 // any floats that were out of the range that half can represent. Nobody
710711 // wants Inf in textures; better to clamp.
@@ -783,7 +784,8 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
783784
784785 if (clamp_half) {
785786 std::shared_ptr<ImageBuf> tmp (new ImageBuf);
786- ImageBufAlgo::clamp (*tmp, *img, -HALF_MAX, HALF_MAX, true );
787+ ImageBufAlgo::clamp (*tmp, *img, -HALF_MAX, HALF_MAX, true , ROI (),
788+ nthreads);
787789 std::swap (tmp, img);
788790 }
789791 if (!img->write (out)) {
@@ -831,7 +833,8 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
831833 std::shared_ptr<ImageBuf> t (new ImageBuf (smallspec));
832834 ImageBufAlgo::channels (*t, *small, outspec.nchannels ,
833835 cspan<int >(), cspan<float >(),
834- cspan<std::string>(), true );
836+ cspan<std::string>(), true ,
837+ nthreads);
835838 std::swap (t, small);
836839 }
837840 smallspec.tile_width = outspec.tile_width ;
@@ -863,7 +866,7 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
863866 // and pixel windows match. Don't worry, the texture
864867 // engine doesn't care what the upper MIP levels have
865868 // for the window sizes, it uses level 0 to determine
866- // the relatinship between texture 0-1 space (display
869+ // the relationship between texture 0-1 space (display
867870 // window) and the pixels.
868871 smallspec.x = 0 ;
869872 smallspec.y = 0 ;
@@ -875,12 +878,11 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
875878
876879 if (filtername == " box" && !orig_was_overscan
877880 && sharpen <= 0 .0f ) {
878- ImageBufAlgo::parallel_image (get_roi (small->spec ()),
879- std::bind (resize_block,
880- std::ref (*small),
881- std::cref (*img), _1,
882- envlatlmode,
883- allow_shift));
881+ ImageBufAlgo::parallel_image (
882+ get_roi (small->spec ()), paropt (nthreads), [&](ROI roi) {
883+ resize_block (*small, *img, roi, envlatlmode,
884+ allow_shift);
885+ });
884886 } else {
885887 Filter2D* filter = setup_filter (small->spec (), img->spec (),
886888 filtername);
@@ -901,23 +903,27 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
901903 OIIO::print (outstream, " \n " );
902904 }
903905 if (do_highlight_compensation)
904- ImageBufAlgo::rangecompress (*img, *img);
906+ ImageBufAlgo::rangecompress (*img, *img, false , ROI (),
907+ nthreads);
905908 if (sharpen > 0 .0f && sharpen_first) {
906909 std::shared_ptr<ImageBuf> sharp (new ImageBuf);
907910 bool uok = ImageBufAlgo::unsharp_mask (*sharp, *img,
908- sharpenfilt, 3.0 ,
909- sharpen, 0 .0f );
911+ sharpenfilt, 3 .0f ,
912+ sharpen, 0 .0f ,
913+ ROI (), nthreads);
910914 if (!uok)
911915 errorfmt (" {}" , sharp->geterror ());
912916 std::swap (img, sharp);
913917 }
914918 ImageBufAlgo::resize (*small, *img,
915- { make_pv (" filterptr" , filter) });
919+ { make_pv (" filterptr" , filter) },
920+ ROI (), nthreads);
916921 if (sharpen > 0 .0f && !sharpen_first) {
917922 std::shared_ptr<ImageBuf> sharp (new ImageBuf);
918923 bool uok = ImageBufAlgo::unsharp_mask (*sharp, *small,
919- sharpenfilt, 3.0 ,
920- sharpen, 0 .0f );
924+ sharpenfilt, 3 .0f ,
925+ sharpen, 0 .0f ,
926+ ROI (), nthreads);
921927 if (!uok)
922928 errorfmt (" {}" , sharp->geterror ());
923929 std::swap (small, sharp);
@@ -926,13 +932,14 @@ write_mipmap(ImageBufAlgo::MakeTextureMode mode, std::shared_ptr<ImageBuf>& img,
926932 ImageBufAlgo::rangeexpand (*small, *small);
927933 ImageBufAlgo::clamp (*small, *small, 0 .0f ,
928934 std::numeric_limits<float >::max (),
929- true );
935+ true , ROI (), nthreads );
930936 }
931937 Filter2D::destroy (filter);
932938 }
933939 }
934940 if (clamp_half)
935- ImageBufAlgo::clamp (*small, *small, -HALF_MAX, HALF_MAX, true );
941+ ImageBufAlgo::clamp (*small, *small, -HALF_MAX, HALF_MAX, true ,
942+ ROI (), nthreads);
936943
937944 double this_miptime = miptimer ();
938945 stat_miptime += this_miptime;
@@ -1093,6 +1100,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
10931100 if (!configspec.tile_depth )
10941101 configspec.tile_depth = 1 ;
10951102
1103+ int nthreads = configspec.get_int_attribute (" maketx:threads" );
1104+
10961105 bool ignore_unassoc = configspec.get_int_attribute (" maketx:ignore_unassoc" );
10971106 ImageSpec inconfig;
10981107 if (ignore_unassoc)
@@ -1257,8 +1266,7 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
12571266 bool ok = true ;
12581267 OIIO_DISPATCH_COMMON_TYPES (ok, " lightprobe_to_envlatl" ,
12591268 lightprobe_to_envlatl, src->spec ().format ,
1260- *latlong, *src, true );
1261- // lightprobe_to_envlatl(*latlong, *src, true);
1269+ *latlong, *src, true , ROI (), nthreads);
12621270 // Carry on with the lat-long environment map from here on out
12631271 mode = ImageBufAlgo::MakeTxEnvLatl;
12641272 src = latlong;
@@ -1269,7 +1277,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
12691277 if (Strutil::iequals (configspec.get_string_attribute (" maketx:bumprange" ,
12701278 " auto" ),
12711279 " auto" ))
1272- src_pixel_stats = ImageBufAlgo::computePixelStats (*src);
1280+ src_pixel_stats = ImageBufAlgo::computePixelStats (*src, ROI (),
1281+ nthreads);
12731282
12741283 ImageSpec newspec = src->spec ();
12751284 newspec.tile_width = newspec.tile_height = 0 ;
@@ -1286,7 +1295,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
12861295 bool ok;
12871296 OIIO_DISPATCH_COMMON_TYPES (ok, " bump_to_bumpslopes" , bump_to_bumpslopes,
12881297 src->spec ().format , *bumpslopes, *src,
1289- configspec, src_pixel_stats, outstream);
1298+ configspec, src_pixel_stats, outstream,
1299+ ROI (), nthreads);
12901300 // bump_to_bumpslopes(*bumpslopes, *src);
12911301 mode = ImageBufAlgo::MakeTxTexture;
12921302 src = bumpslopes;
@@ -1330,7 +1340,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
13301340 std::vector<imagesize_t > hist;
13311341
13321342 for (int i = 0 ; i < channels; i++) {
1333- hist = ImageBufAlgo::histogram (*src, i, bins, 0 .0f , 1 .0f );
1343+ hist = ImageBufAlgo::histogram (*src, i, bins, 0 .0f , 1 .0f , false ,
1344+ ROI (), nthreads);
13341345
13351346 // Turn the histogram into a non-normalized CDF
13361347 for (uint64_t j = 1 ; j < bins; j++) {
@@ -1389,7 +1400,7 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
13891400 bool compute_stats = (constant_color_detect || opaque_detect
13901401 || compute_average_color || monochrome_detect);
13911402 if (compute_stats) {
1392- pixel_stats = ImageBufAlgo::computePixelStats (*src);
1403+ pixel_stats = ImageBufAlgo::computePixelStats (*src, ROI (), nthreads );
13931404 }
13941405 double stat_pixelstatstime = alltime.lap ();
13951406 STATUS (" pixelstats" , stat_pixelstatstime);
@@ -1420,7 +1431,7 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
14201431 newspec.full_height = newspec.height ;
14211432 newspec.full_depth = newspec.depth ;
14221433 src->reset (newspec);
1423- ImageBufAlgo::fill (*src, constantColor);
1434+ ImageBufAlgo::fill (*src, constantColor, ROI (), nthreads );
14241435 if (verbose) {
14251436 outstream << " Constant color image detected. " ;
14261437 outstream << " Creating " << newspec.width << " x"
@@ -1455,14 +1466,14 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
14551466 && src->spec ().alpha_channel < 0
14561467 && pixel_stats.avg [0 ] == pixel_stats.avg [1 ]
14571468 && pixel_stats.avg [0 ] == pixel_stats.avg [2 ]
1458- && ImageBufAlgo::isMonochrome (*src)) {
1469+ && ImageBufAlgo::isMonochrome (*src, 0 . 0f , ROI (), nthreads )) {
14591470 if (verbose)
14601471 OIIO::print (
14611472 outstream,
14621473 " Monochrome image detected. Converting to single channel texture.\n " );
14631474 std::shared_ptr<ImageBuf> newsrc (new ImageBuf (src->spec ()));
14641475 ImageBufAlgo::channels (*newsrc, *src, 1 , cspan<int >(), cspan<float >(),
1465- cspan<std::string>(), true );
1476+ cspan<std::string>(), true , nthreads );
14661477 newsrc->specmod ().default_channel_names ();
14671478 std::swap (src, newsrc);
14681479 }
@@ -1475,7 +1486,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
14751486 << std::endl;
14761487 std::shared_ptr<ImageBuf> newsrc (new ImageBuf (src->spec ()));
14771488 ImageBufAlgo::channels (*newsrc, *src, nchannels, cspan<int >(),
1478- cspan<float >(), cspan<std::string>(), true );
1489+ cspan<float >(), cspan<std::string>(), true ,
1490+ nthreads);
14791491 std::swap (src, newsrc);
14801492 }
14811493
@@ -1663,7 +1675,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
16631675 && (srcspec.format .basetype == TypeDesc::FLOAT
16641676 || srcspec.format .basetype == TypeDesc::HALF
16651677 || srcspec.format .basetype == TypeDesc::DOUBLE)
1666- && !ImageBufAlgo::fixNonFinite (*src, *src, fixmode, &pixelsFixed)) {
1678+ && !ImageBufAlgo::fixNonFinite (*src, *src, fixmode, &pixelsFixed, ROI (),
1679+ nthreads)) {
16671680 errorfmt (" Error fixing nans/infs." );
16681681 return false ;
16691682 }
@@ -1677,7 +1690,7 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
16771690 || srcspec.format .basetype == TypeDesc::HALF
16781691 || srcspec.format .basetype == TypeDesc::DOUBLE)) {
16791692 int found_nonfinite = 0 ;
1680- ImageBufAlgo::parallel_image (get_roi (srcspec),
1693+ ImageBufAlgo::parallel_image (get_roi (srcspec), nthreads,
16811694 std::bind (check_nan_block, std::ref (*src),
16821695 _1, std::ref (found_nonfinite)));
16831696 if (found_nonfinite) {
@@ -1736,7 +1749,7 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
17361749 outstream << " Unpremulting image..." << std::endl;
17371750
17381751 if (!ImageBufAlgo::colorconvert (*ccSrc, *src, processor.get (),
1739- unpremult)) {
1752+ unpremult, ROI (), nthreads )) {
17401753 errorfmt (" Error applying color conversion to image." );
17411754 return false ;
17421755 }
@@ -1838,10 +1851,12 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
18381851 toplevel.reset (new ImageBuf (dstspec));
18391852 if ((resize_filter == " box" || resize_filter == " triangle" )
18401853 && !orig_was_overscan) {
1841- ImageBufAlgo::parallel_image (
1842- get_roi (dstspec),
1843- std::bind (resize_block, std::ref (*toplevel), std::cref (*src),
1844- _1, envlatlmode, allow_shift != 0 ));
1854+ ImageBufAlgo::parallel_image (get_roi (dstspec), paropt (nthreads),
1855+ [&](ROI roi) {
1856+ resize_block (*toplevel, *src, roi,
1857+ envlatlmode,
1858+ allow_shift != 0 );
1859+ });
18451860 } else {
18461861 Filter2D* filter = setup_filter (toplevel->spec (), src->spec (),
18471862 resize_filter);
@@ -1850,7 +1865,8 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
18501865 return false ;
18511866 }
18521867 ImageBufAlgo::resize (*toplevel, *src,
1853- { make_pv (" filterptr" , filter) });
1868+ { make_pv (" filterptr" , filter) }, ROI (),
1869+ nthreads);
18541870 Filter2D::destroy (filter);
18551871 }
18561872 }
@@ -1906,12 +1922,11 @@ make_texture_impl(ImageBufAlgo::MakeTextureMode mode, const ImageBuf* input,
19061922 addlHashData << " keepaspect=1 " ;
19071923
19081924 const int sha1_blocksize = 256 ;
1909- std::string hash_digest
1910- = configspec.get_int_attribute (" maketx:hash" , 1 )
1911- ? ImageBufAlgo::computePixelHashSHA1 (*toplevel,
1912- addlHashData.str (),
1913- ROI::All (), sha1_blocksize)
1914- : " " ;
1925+ std::string hash_digest = configspec.get_int_attribute (" maketx:hash" , 1 )
1926+ ? ImageBufAlgo::computePixelHashSHA1 (
1927+ *toplevel, addlHashData.str (),
1928+ ROI::All (), sha1_blocksize, nthreads)
1929+ : " " ;
19151930 if (hash_digest.length ()) {
19161931 if (out->supports (" arbitrary_metadata" )) {
19171932 dstspec.attribute (" oiio:SHA-1" , hash_digest);
0 commit comments