bool ImageBufAlgo::sub(ImageBuf& dst, Image_or_Const A_, Image_or_Const B_, ROI roi, int nthreads) { pvt::LoggedTimer logtime("IBA::sub"); if (A_.is_img() && B_.is_img()) { const ImageBuf &A(A_.img()), &B(B_.img()); if (!IBAprep(roi, &dst, &A, &B)) return false; ROI origroi = roi; roi.chend = std::min(roi.chend, std::min(A.nchannels(), B.nchannels())); bool ok; OIIO_DISPATCH_COMMON_TYPES3(ok, "sub", sub_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); if (roi.chend < origroi.chend && A.nchannels() != B.nchannels()) { // Edge case: A and B differed in nchannels, we allocated dst to be // the bigger of them, but adjusted roi to be the lesser. Now handle // the channels that got left out because they were not common to // all the inputs. ASSERT(roi.chend <= dst.nchannels()); roi.chbegin = roi.chend; roi.chend = origroi.chend; if (A.nchannels() > B.nchannels()) { // A exists copy(dst, A, dst.spec().format, roi, nthreads); } else { // B exists copy(dst, B, dst.spec().format, roi, nthreads); } } return ok; } if (A_.is_val() && B_.is_img()) // canonicalize to A_img, B_val A_.swap(B_); if (A_.is_img() && B_.is_val()) { const ImageBuf& A(A_.img()); cspan<float> b = B_.val(); if (!IBAprep(roi, &dst, &A, IBAprep_CLAMP_MUTUAL_NCHANNELS | IBAprep_SUPPORT_DEEP)) return false; IBA_FIX_PERCHAN_LEN_DEF(b, A.nchannels()); // Negate b (into a copy) int nc = A.nchannels(); float* vals = ALLOCA(float, nc); for (int c = 0; c < nc; ++c) vals[c] = -b[c]; b = cspan<float>(vals, nc); if (dst.deep()) { // While still serial, set up all the sample counts dst.deepdata()->set_all_samples(A.deepdata()->all_samples()); return add_impl_deep(dst, A, b, roi, nthreads); } bool ok; OIIO_DISPATCH_COMMON_TYPES2(ok, "sub", add_impl, dst.spec().format, A.spec().format, dst, A, b, roi, nthreads); return ok; } // Remaining cases: error dst.error("ImageBufAlgo::sub(): at least one argument must be an image"); return false; }
bool ImageBufAlgo::absdiff (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; ROI origroi = roi; roi.chend = std::min (roi.chend, std::min (A.nchannels(), B.nchannels())); bool ok; OIIO_DISPATCH_COMMON_TYPES3 (ok, "absdiff", absdiff_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); if (roi.chend < origroi.chend && A.nchannels() != B.nchannels()) { // Edge case: A and B differed in nchannels, we allocated dst to be // the bigger of them, but adjusted roi to be the lesser. Now handle // the channels that got left out because they were not common to // all the inputs. ASSERT (roi.chend <= dst.nchannels()); roi.chbegin = roi.chend; roi.chend = origroi.chend; if (A.nchannels() > B.nchannels()) { // A exists abs (dst, A, roi, nthreads); } else { // B exists abs (dst, B, roi, nthreads); } } return ok; }
bool ImageBufAlgo::sub (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { IBAprep (roi, &dst, &A, &B); OIIO_DISPATCH_COMMON_TYPES3 ("sub", sub_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return true; }
bool ImageBufAlgo::mul (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("mul", mul_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return true; }
bool ImageBufAlgo::sub (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; bool ok; OIIO_DISPATCH_COMMON_TYPES3 (ok, "sub", sub_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return ok; }
bool ImageBufAlgo::div (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B, NULL, IBAprep_CLAMP_MUTUAL_NCHANNELS)) return false; bool ok; OIIO_DISPATCH_COMMON_TYPES3 (ok, "div", div_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return ok; }
bool ImageBufAlgo::div(ImageBuf& dst, Image_or_Const A_, Image_or_Const B_, ROI roi, int nthreads) { pvt::LoggedTimer logtime("IBA::div"); if (A_.is_img() && B_.is_img()) { const ImageBuf &A(A_.img()), &B(B_.img()); if (!IBAprep(roi, &dst, &A, &B, IBAprep_CLAMP_MUTUAL_NCHANNELS)) return false; bool ok; OIIO_DISPATCH_COMMON_TYPES3(ok, "div", div_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return ok; } if (A_.is_val() && B_.is_img()) // canonicalize to A_img, B_val A_.swap(B_); if (A_.is_img() && B_.is_val()) { const ImageBuf& A(A_.img()); cspan<float> b = B_.val(); if (!IBAprep(roi, &dst, &A, IBAprep_CLAMP_MUTUAL_NCHANNELS | IBAprep_SUPPORT_DEEP)) return false; IBA_FIX_PERCHAN_LEN_DEF(b, dst.nchannels()); int nc = dst.nchannels(); float* binv = OIIO_ALLOCA(float, nc); for (int c = 0; c < nc; ++c) binv[c] = (b[c] == 0.0f) ? 0.0f : 1.0f / b[c]; b = cspan<float>(binv, nc); // re-wrap if (dst.deep()) { // While still serial, set up all the sample counts dst.deepdata()->set_all_samples(A.deepdata()->all_samples()); return mul_impl_deep(dst, A, b, roi, nthreads); } bool ok; OIIO_DISPATCH_COMMON_TYPES2(ok, "div", mul_impl, dst.spec().format, A.spec().format, dst, A, b, roi, nthreads); return ok; } // Remaining cases: error dst.error("ImageBufAlgo::div(): at least one argument must be an image"); return false; }