@@ -1159,7 +1159,7 @@ ImageBufAlgo::rotate(const ImageBuf& src, float angle, string_view filtername,
1159
1159
template <typename DSTTYPE, typename SRCTYPE, typename STTYPE>
1160
1160
static bool
1161
1161
st_warp_ (ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf, int chan_s,
1162
- int chan_t , bool flip_s, bool flip_t , Filter2D* filter, ROI roi,
1162
+ int chan_t , bool flip_s, bool flip_t , const Filter2D* filter, ROI roi,
1163
1163
int nthreads)
1164
1164
{
1165
1165
OIIO_DASSERT (filter);
@@ -1199,11 +1199,8 @@ st_warp_(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf, int chan_s,
1199
1199
// the outer loop.
1200
1200
// XXX: Sampling of the source buffer can be entirely random, so there
1201
1201
// are probably some opportunities for optimization in here...
1202
- for (; !st_iter.done (); ++st_iter) {
1202
+ for (; !st_iter.done (); ++st_iter, ++out_iter ) {
1203
1203
// Look up source coordinates from ST channels.
1204
- // We don't care about faithfully maintaining `STTYPE`: Half will be
1205
- // promoted accurately, and double isn't really useful, since filter
1206
- // lookups don't support that (excessive) level of precision.
1207
1204
float src_s = st_iter[chan_s];
1208
1205
float src_t = st_iter[chan_t ];
1209
1206
@@ -1251,7 +1248,6 @@ st_warp_(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf, int chan_s,
1251
1248
out_iter[chan] = 0 ;
1252
1249
}
1253
1250
}
1254
- ++out_iter;
1255
1251
}
1256
1252
}); // end of parallel_image
1257
1253
return true ;
@@ -1269,7 +1265,7 @@ check_st_warp_args(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf,
1269
1265
return false ;
1270
1266
}
1271
1267
1272
- const ImageSpec& stSpec ( stbuf.spec () );
1268
+ const ImageSpec& stSpec = stbuf.spec ();
1273
1269
// XXX: Wanted to use `uint32_t` for channel indices, but I don't want to
1274
1270
// break from the rest of the API and introduce a bunch of compile warnings.
1275
1271
if (chan_s >= stSpec.nchannels ) {
@@ -1282,44 +1278,25 @@ check_st_warp_args(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf,
1282
1278
chan_t );
1283
1279
return false ;
1284
1280
}
1285
- // N.B. We currently require floating-point ST channels
1286
- if (!stSpec.format .is_floating_point ()) {
1287
- dst.error (" ImageBufAlgo::st_warp : ST buffer must be holding floating-"
1288
- " point data" );
1289
- return false ;
1290
- }
1291
1281
1292
- if (dst.initialized ()) {
1293
- // XXX: Currently requiring the pixel scales of ST and a preallocated
1294
- // output buffer to match.
1295
- if (dst.spec ().full_width != stSpec.full_width
1296
- || dst.spec ().full_height != stSpec.full_height ) {
1297
- dst.error (" ImageBufAlgo::st_warp : Output and ST buffers must have "
1298
- " the same full width and height" );
1299
- return false ;
1300
- }
1301
- }
1302
-
1303
- // Prep the dest spec using the channels from `src`, and the intersection of
1304
- // `roi` and the ROI from the ST buffer (since the ST warp is only defined
1305
- // for pixels in the ST buffer). We grab a copy of the input ROI before
1306
- // `IBAprep`, since we want to intersect it ourselves.
1307
- ROI inputROI (roi);
1282
+ // Prep the output buffer, and then intersect the resulting ROI with the ST
1283
+ // buffer's ROI, since the ST warp is only defined for pixels in the latter.
1308
1284
bool res
1309
1285
= ImageBufAlgo::IBAprep (roi, &dst, &src,
1310
1286
ImageBufAlgo::IBAprep_NO_SUPPORT_VOLUME
1311
1287
| ImageBufAlgo::IBAprep_NO_COPY_ROI_FULL);
1312
1288
if (res) {
1313
- roi = roi_intersection (inputROI, stSpec.roi ());
1314
- roi.chbegin = std::max (roi.chbegin , 0 );
1315
- roi.chend = std::min (roi.chend , src.spec ().nchannels );
1316
-
1317
- ImageSpec destSpec (dst.spec ());
1318
- destSpec.set_roi (roi);
1319
- destSpec.set_roi_full (stSpec.roi_full ());
1320
- // XXX: It would be nice to be able to tell `IBAprep` to skip the buffer
1321
- // initialization. Worth adding a new prep flag?
1322
- dst.reset (destSpec);
1289
+ const int chbegin = roi.chbegin ;
1290
+ const int chend = roi.chend ;
1291
+ roi = roi_intersection (roi, stSpec.roi ());
1292
+ if (roi.npixels () <= 0 ) {
1293
+ dst.errorfmt (" ImageBufAlgo::st_warp : Output ROI does not "
1294
+ " intersect ST buffer." );
1295
+ return false ;
1296
+ }
1297
+ // Make sure to preserve the channel range determined by `IBAprep`.
1298
+ roi.chbegin = chbegin;
1299
+ roi.chend = chend;
1323
1300
}
1324
1301
return res;
1325
1302
}
@@ -1328,8 +1305,8 @@ check_st_warp_args(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf,
1328
1305
1329
1306
bool
1330
1307
ImageBufAlgo::st_warp (ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf,
1331
- Filter2D* filter, int chan_s, int chan_t , bool flip_s ,
1332
- bool flip_t , ROI roi, int nthreads)
1308
+ const Filter2D* filter, int chan_s, int chan_t ,
1309
+ bool flip_s, bool flip_t , ROI roi, int nthreads)
1333
1310
{
1334
1311
pvt::LoggedTimer logtime (" IBA::st_warp" );
1335
1312
@@ -1376,8 +1353,8 @@ ImageBufAlgo::st_warp(ImageBuf& dst, const ImageBuf& src, const ImageBuf& stbuf,
1376
1353
1377
1354
ImageBuf
1378
1355
ImageBufAlgo::st_warp (const ImageBuf& src, const ImageBuf& stbuf,
1379
- Filter2D* filter, int chan_s, int chan_t , bool flip_s ,
1380
- bool flip_t , ROI roi, int nthreads)
1356
+ const Filter2D* filter, int chan_s, int chan_t ,
1357
+ bool flip_s, bool flip_t , ROI roi, int nthreads)
1381
1358
{
1382
1359
ImageBuf result;
1383
1360
bool ok = st_warp (result, src, stbuf, filter, chan_s, chan_t , flip_s,
0 commit comments