IndirectArray<TreeBox::Node> TreeBox::SelectedNodes() const { IndirectArray<TreeBox::Node> nodes; size_type n = 0; (*API->TreeBox->GetTreeBoxSelectedNodes)( handle, 0, &n ); if ( n > 0 ) { nodes.Add( nullptr, n ); if ( (*API->TreeBox->GetTreeBoxSelectedNodes)( handle, reinterpret_cast< ::api_handle*>( nodes.Begin() ), &n ) == api_false ) throw APIFunctionError( "GetTreeBoxSelectedNodes" ); nodes.Pack(); } return nodes; }
void Apply( GenericImage<P>& image ) { size_type N = image.NumberOfPixels(); int numberOfThreads = Thread::NumberOfThreads( N, 16 ); size_type pixelsPerThread = N/numberOfThreads; /* * For USM filters of size <= 49px, we use separable convolutions in the * spatial domain. For larger filters, FFT convolutions are faster. This * limit has been determined empirically. */ GaussianFilter G( instance.sigma, 0.05F ); AutoPointer<ImageTransformation> T; if ( G.Size() < 49 ) T = new SeparableConvolution( G.AsSeparableFilter() ); else T = new FFTConvolution( G ); double a = 1 - 0.499*instance.amount; double a1 = a/(a+a - 1); double a2 = (1 - a)/(a+a - 1); image.ResetSelections(); GenericImage<P> im0; // deringing working image if ( instance.deringing ) { image.SelectNominalChannels(); im0 = image; im0.SetStatusCallback( 0 ); } for ( int ch = 0; ch < image.NumberOfNominalChannels(); ++ch ) { if ( useConsole && image.IsColor() ) Console().WriteLn( "<end><cbr>Processing channel #" + String( ch ) ); image.SelectChannel( ch ); Image mask( image ); mask.Status().Initialize( useConsole ? String( "Generating USM mask" ) : String(), mask.NumberOfPixels() ); mask.Status().DisableInitialization(); *T >> mask; image.Status().Initialize( useConsole ? String( "Applying unsharp mask filter" ) : String(), N ); IndirectArray<USMThread<P> > threads; typename P::sample* v = image[ch]; const typename P::sample* vN = v + N; const float* m = *mask; for ( int i = 0; i < numberOfThreads; ++i, v += pixelsPerThread, m += pixelsPerThread ) threads.Add( new USMThread<P>( (P*)0, v, (i < numberOfThreads-1) ? v+pixelsPerThread : vN, m, a1, a2 ) ); for ( int i = 0; i < numberOfThreads; ++i ) threads[i]->Start( ThreadPriority::DefaultMax, i ); for ( int i = 0; i < numberOfThreads; ++i ) threads[i]->Wait(); threads.Destroy(); image.Status() += N; } image.ResetSelections(); image.SelectNominalChannels(); if ( instance.deringing ) Dering( image, im0 ); Normalize( image ); image.ResetSelections(); }