43
43
#include " DDImage/Pixel.h"
44
44
#include " DDImage/Tile.h"
45
45
#include " IECore/CachedReader.h"
46
+ #include " IECore/FastFloat.h"
46
47
#include " IECore/Reader.h"
47
48
#include " IECore/NumericParameter.h"
48
49
#include " boost/algorithm/string.hpp"
@@ -223,9 +224,10 @@ void LensDistort::_validate(bool for_real)
223
224
}
224
225
225
226
// Set the output bounding box according to the lens model.
227
+ bool black = input0 ().black_outside ();
226
228
Imath::Box2i input ( Imath::V2i ( input0 ().info ().x (), input0 ().info ().y () ), Imath::V2i ( input0 ().info ().r ()-1 , input0 ().info ().t ()-1 ) );
227
229
Imath::Box2i box ( m_model[0 ]->bounds ( m_mode, input, format ().width (), format ().height () ) );
228
- info_.set ( box.min .x , box.min .y , box.max .x , box.max .y );
230
+ info_.set ( box.min .x -black , box.min .y -black , box.max .x +black , box.max .y +black );
229
231
230
232
set_out_channels ( Mask_All );
231
233
}
@@ -243,6 +245,14 @@ void LensDistort::_request( int x, int y, int r, int t, ChannelMask channels, in
243
245
244
246
void LensDistort::engine ( int y, int x, int r, ChannelMask channels, Row & outrow )
245
247
{
248
+ // Provide an early-out for any black rows.
249
+ bool blackOutside = info ().black_outside ();
250
+ if ( blackOutside && ( y == info ().t ()-1 || y == info ().y () ) )
251
+ {
252
+ outrow.erase ( channels );
253
+ return ;
254
+ }
255
+
246
256
const Info &info = input0 ().info ();
247
257
const double h ( format ().height () );
248
258
const double w ( format ().width () );
@@ -305,10 +315,20 @@ void LensDistort::engine( int y, int x, int r, ChannelMask channels, Row & outro
305
315
DD::Image::Pixel out (channels);
306
316
307
317
// Lock the tile into the cache
308
- DD::Image::Tile t ( input0 (), int (floor (x_min)), int (floor (y_min)), int (ceil (x_max)), int (ceil (y_max)), channels );
309
-
310
- // Loop over our array of precomputed points, and ask nuke to perform a filtered lookup for us
311
- for ( int i = x; i < r; i++ )
318
+ DD::Image::Tile t ( input0 (), IECore::fastFloatFloor ( x_min ), IECore::fastFloatFloor ( y_min ), IECore::fastFloatCeil ( x_max ), IECore::fastFloatCeil ( y_max ), channels );
319
+
320
+ // Write the black outside pixels.
321
+ if ( blackOutside )
322
+ {
323
+ foreach ( z, channels )
324
+ {
325
+ outrow.writable (z)[x] = 0 .f ;
326
+ outrow.writable (z)[r-1 ] = 0 .f ;
327
+ }
328
+ }
329
+
330
+ // Loop over our array of precomputed points, and ask nuke to perform a filtered lookup for us.
331
+ for ( int i = x+blackOutside; i < r-blackOutside; i++ )
312
332
{
313
333
if (aborted ()) break ;
314
334
input0 ().sample ( distort[i-x].x +0.5 , distort[i-x].y +0.5 , 1.0 , 1.0 , &m_filter, out );
@@ -317,7 +337,6 @@ void LensDistort::engine( int y, int x, int r, ChannelMask channels, Row & outro
317
337
outrow.writable (z)[i] = out[z];
318
338
}
319
339
}
320
-
321
340
}
322
341
323
342
void LensDistort::append ( DD::Image::Hash &hash )
0 commit comments