Skip to content

Commit 8f2e9ef

Browse files
committed
Refactor IBA::resample()
More cleanly separate the deep and non-deep cases.
1 parent 64e43f7 commit 8f2e9ef

File tree

1 file changed

+72
-38
lines changed

1 file changed

+72
-38
lines changed

src/libOpenImageIO/imagebufalgo_xform.cpp

Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,11 @@ static bool
501501
resample_ (ImageBuf &dst, const ImageBuf &src, bool interpolate,
502502
ROI roi, int nthreads)
503503
{
504+
ASSERT (!src.deep() && !dst.deep());
504505
ImageBufAlgo::parallel_image (roi, nthreads, [&](ROI roi){
505506
const ImageSpec &srcspec (src.spec());
506507
const ImageSpec &dstspec (dst.spec());
507508
int nchannels = src.nchannels();
508-
bool deep = src.deep();
509-
ASSERT (deep == dst.deep());
510509

511510
// Local copies of the source image window, converted to float
512511
float srcfx = srcspec.full_x;
@@ -535,21 +534,7 @@ resample_ (ImageBuf &dst, const ImageBuf &src, bool interpolate,
535534
float s = (x-dstfx+0.5f)*dstpixelwidth;
536535
float src_xf = srcfx + s * srcfw;
537536
int src_x = ifloor (src_xf);
538-
if (deep) {
539-
srcpel.pos (src_x, src_y, 0);
540-
int nsamps = srcpel.deep_samples();
541-
ASSERT (nsamps == out.deep_samples());
542-
if (! nsamps)
543-
continue;
544-
for (int c = 0; c < nchannels; ++c) {
545-
if (dstspec.channelformat(c) == TypeDesc::UINT32)
546-
for (int samp = 0; samp < nsamps; ++samp)
547-
out.set_deep_value (c, samp, srcpel.deep_value_uint(c, samp));
548-
else
549-
for (int samp = 0; samp < nsamps; ++samp)
550-
out.set_deep_value (c, samp, srcpel.deep_value(c, samp));
551-
}
552-
} else if (interpolate) {
537+
if (interpolate) {
553538
// Non-deep image, bilinearly interpolate
554539
src.interppixel (src_xf, src_yf, pel);
555540
for (int c = roi.chbegin; c < roi.chend; ++c)
@@ -568,6 +553,75 @@ resample_ (ImageBuf &dst, const ImageBuf &src, bool interpolate,
568553

569554

570555

556+
static bool
557+
resample_deep (ImageBuf &dst, const ImageBuf &src, bool interpolate,
558+
ROI roi, int nthreads)
559+
{
560+
ASSERT (src.deep() && dst.deep());
561+
562+
// If it's deep, figure out the sample allocations first, because
563+
// it's not thread-safe to do that simultaneously with copying the
564+
// values.
565+
const ImageSpec &srcspec (src.spec());
566+
const ImageSpec &dstspec (dst.spec());
567+
float srcfx = srcspec.full_x;
568+
float srcfy = srcspec.full_y;
569+
float srcfw = srcspec.full_width;
570+
float srcfh = srcspec.full_height;
571+
float dstfx = dstspec.full_x;
572+
float dstfy = dstspec.full_y;
573+
float dstfw = dstspec.full_width;
574+
float dstfh = dstspec.full_height;
575+
float dstpixelwidth = 1.0f / dstfw;
576+
float dstpixelheight = 1.0f / dstfh;
577+
ImageBuf::ConstIterator<float> srcpel (src, roi);
578+
ImageBuf::Iterator<float> dstpel (dst, roi);
579+
for ( ; !dstpel.done(); ++dstpel, ++srcpel) {
580+
float s = (dstpel.x()-dstspec.full_x+0.5f)*dstpixelwidth;
581+
float t = (dstpel.y()-dstspec.full_y+0.5f)*dstpixelheight;
582+
int src_y = ifloor (srcfy + t * srcfh);
583+
int src_x = ifloor (srcfx + s * srcfw);
584+
srcpel.pos (src_x, src_y, 0);
585+
dstpel.set_deep_samples (srcpel.deep_samples ());
586+
}
587+
588+
ImageBufAlgo::parallel_image (roi, nthreads, [=,&dst,&src](ROI roi){
589+
int nchannels = src.nchannels();
590+
const ImageSpec &dstspec (dst.spec());
591+
ImageBuf::Iterator<float> out (dst, roi);
592+
ImageBuf::ConstIterator<float> srcpel (src);
593+
for (int y = roi.ybegin; y < roi.yend; ++y) {
594+
// s,t are NDC space
595+
float t = (y-dstfy+0.5f)*dstpixelheight;
596+
// src_xf, src_xf are image space float coordinates
597+
float src_yf = srcfy + t * srcfh;
598+
// src_x, src_y are image space integer coordinates of the floor
599+
int src_y = ifloor (src_yf);
600+
for (int x = roi.xbegin; x < roi.xend; ++x, ++out) {
601+
float s = (x-dstfx+0.5f)*dstpixelwidth;
602+
float src_xf = srcfx + s * srcfw;
603+
int src_x = ifloor (src_xf);
604+
srcpel.pos (src_x, src_y, 0);
605+
int nsamps = srcpel.deep_samples();
606+
ASSERT (nsamps == out.deep_samples());
607+
if (! nsamps)
608+
continue;
609+
for (int c = 0; c < nchannels; ++c) {
610+
if (dstspec.channelformat(c) == TypeDesc::UINT32)
611+
for (int samp = 0; samp < nsamps; ++samp)
612+
out.set_deep_value (c, samp, srcpel.deep_value_uint(c, samp));
613+
else
614+
for (int samp = 0; samp < nsamps; ++samp)
615+
out.set_deep_value (c, samp, srcpel.deep_value(c, samp));
616+
}
617+
}
618+
}
619+
});
620+
return true;
621+
}
622+
623+
624+
571625
bool
572626
ImageBufAlgo::resample (ImageBuf &dst, const ImageBuf &src,
573627
bool interpolate, ROI roi, int nthreads)
@@ -579,27 +633,7 @@ ImageBufAlgo::resample (ImageBuf &dst, const ImageBuf &src,
579633
return false;
580634

581635
if (dst.deep()) {
582-
// If it's deep, figure out the sample allocations first, because
583-
// it's not thread-safe to do that simultaneously with copying the
584-
// values.
585-
const ImageSpec &srcspec (src.spec());
586-
const ImageSpec &dstspec (dst.spec());
587-
float srcfx = srcspec.full_x;
588-
float srcfy = srcspec.full_y;
589-
float srcfw = srcspec.full_width;
590-
float srcfh = srcspec.full_height;
591-
float dstpixelwidth = 1.0f / dstspec.full_width;
592-
float dstpixelheight = 1.0f / dstspec.full_height;
593-
ImageBuf::ConstIterator<float> srcpel (src, roi);
594-
ImageBuf::Iterator<float> dstpel (dst, roi);
595-
for ( ; !dstpel.done(); ++dstpel, ++srcpel) {
596-
float s = (dstpel.x()-dstspec.full_x+0.5f)*dstpixelwidth;
597-
float t = (dstpel.y()-dstspec.full_y+0.5f)*dstpixelheight;
598-
int src_y = ifloor (srcfy + t * srcfh);
599-
int src_x = ifloor (srcfx + s * srcfw);
600-
srcpel.pos (src_x, src_y, 0);
601-
dstpel.set_deep_samples (srcpel.deep_samples ());
602-
}
636+
return resample_deep (dst, src, interpolate, roi, nthreads);
603637
}
604638

605639
bool ok;

0 commit comments

Comments
 (0)