static void VNGThreaded( Image& target, const GenericImage<P>& source, const DebayerInstance& instance ) { int target_w = source.Width(); int target_h = source.Height(); target.AllocateData( target_w, target_h, 3, ColorSpace::RGB ); target.Status().Initialize( "VNG debayering", target_h-4 ); int numberOfThreads = Thread::NumberOfThreads( target_h-4, 1 ); int rowsPerThread = (target_h - 4)/numberOfThreads; AbstractImage::ThreadData data( target, target_h-4 ); ReferenceArray<VNGThread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new VNGThread<P>( data, target, source, instance, i*rowsPerThread + 2, (j < numberOfThreads) ? j*rowsPerThread + 2 : target_h-2 ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); // copy top and bottom two rows from the adjecent ones for ( int col = 0; col < target_w; col++ ) for ( int i = 0; i < 3; i++ ) { target.Pixel( col, 0, i ) = target.Pixel( col, 1, i ) = target.Pixel( col, 2, i ); target.Pixel( col, target_h-1, i ) = target.Pixel( col, target_h-2, i ) = target.Pixel( col, target_h-3, i ); } target.Status() = data.status; }
template <class P> static void Apply( GenericImage<P>& image, const HistogramTransformation& H ) { if ( image.IsEmptySelection() ) return; image.EnsureUnique(); Rect r = image.SelectedRectangle(); int h = r.Height(); int numberOfThreads = H.IsParallelProcessingEnabled() ? Min( H.MaxProcessors(), pcl::Thread::NumberOfThreads( h, 1 ) ) : 1; int rowsPerThread = h/numberOfThreads; size_type N = image.NumberOfSelectedSamples(); if ( image.Status().IsInitializationEnabled() ) image.Status().Initialize( "Histogram transformation", N ); ThreadData<P> data( image, H, N ); ReferenceArray<Thread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new Thread<P>( data, i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : h ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Status() = data.status; }
static void SuperPixelThreaded( Image& target, const GenericImage<P>& source, const DebayerInstance& instance ) { int target_w = source.Width() >> 1; int target_h = source.Height() >> 1; target.AllocateData( target_w, target_h, 3, ColorSpace::RGB ); target.Status().Initialize( "SuperPixel debayering", target_h ); int numberOfThreads = Thread::NumberOfThreads( target_h, 1 ); int rowsPerThread = target_h/numberOfThreads; AbstractImage::ThreadData data( target, target_h ); ReferenceArray<SuperPixelThread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new SuperPixelThread<P>( data, target, source, instance, i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : target_h ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); target.Status() = data.status; }
static void Apply( GenericImage<P>& image, const ColorSaturationInstance& instance, bool useLUT = false ) { if ( instance.Curve().IsIdentity() ) { Console().WriteLn( "<end><cbr><* Identity *>" ); return; } size_type N = image.NumberOfPixels(); int numberOfThreads = Thread::NumberOfThreads( N, 16 ); size_type pixelsPerThread = N/numberOfThreads; image.Status().Initialize( "Color saturation transformation, HSVL space", N ); ThreadData data( image, N ); if ( useLUT ) data.lut = MakeLUT( instance ); ReferenceArray<ColorSaturationThread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new ColorSaturationThread<P>( instance, data, image, i*pixelsPerThread, (j < numberOfThreads) ? j*pixelsPerThread : N ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Status() = data.status; }
void HistogramTransformation::Make24BitLUT( uint16* lut ) const { if ( lut == 0 ) return; int numberOfThreads = m_parallel ? Min( int( m_maxProcessors ), Thread::NumberOfThreads( uint24_max+1, 256 ) ) : 1; int itemsPerThread = (uint24_max + 1)/numberOfThreads; bool useAffinity = m_parallel && Thread::IsRootThread(); ReferenceArray<LUT2416Thread> threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new LUT2416Thread( lut, *this, i*itemsPerThread, (j < numberOfThreads) ? j*itemsPerThread : uint24_max+1 ) ); if ( numberOfThreads > 1 ) { for ( int i = 0; i < numberOfThreads; ++i ) threads[i].Start( ThreadPriority::DefaultMax, useAffinity ? i : -1 ); for ( int i = 0; i < numberOfThreads; ++i ) threads[i].Wait(); } else threads[0].Run(); threads.Destroy(); }
static void EvaluateNoise( FVector& noiseEstimates, FVector& noiseFractions, StringList& noiseAlgorithms, const Image& image, int algorithm ) { SpinStatus spin; image.SetStatusCallback( &spin ); image.Status().Initialize( "Noise evaluation" ); image.Status().DisableInitialization(); Console console; int numberOfThreads = Thread::NumberOfThreads( image.NumberOfPixels(), 1 ); if ( numberOfThreads >= 3 ) { int numberOfSubthreads = RoundI( numberOfThreads/3.0 ); ReferenceArray<NoiseEvaluationThread> threads; threads.Add( new NoiseEvaluationThread( image, 0, algorithm, numberOfSubthreads ) ); threads.Add( new NoiseEvaluationThread( image, 1, algorithm, numberOfSubthreads ) ); threads.Add( new NoiseEvaluationThread( image, 2, algorithm, numberOfThreads - 2*numberOfSubthreads ) ); AbstractImage::ThreadData data( image, 0 ); // unbounded AbstractImage::RunThreads( threads, data ); for ( int i = 0; i < 3; ++i ) { noiseEstimates[i] = threads[i].noiseEstimate; noiseFractions[i] = threads[i].noiseFraction; noiseAlgorithms[i] = String( threads[i].noiseAlgorithm ); } threads.Destroy(); } else { for ( int i = 0; i < 3; ++i ) { NoiseEvaluationThread thread( image, i, algorithm, 1 ); thread.Run(); noiseEstimates[i] = thread.noiseEstimate; noiseFractions[i] = thread.noiseFraction; noiseAlgorithms[i] = String( thread.noiseAlgorithm ); } } image.ResetSelections(); image.Status().Complete(); console.WriteLn( "<end><cbr>Gaussian noise estimates:" ); for ( int i = 0; i < 3; ++i ) console.WriteLn( String().Format( "s%d = %.3e, n%d = %.4f ", i, noiseEstimates[i], i, noiseFractions[i] ) + '(' + noiseAlgorithms[i] + ')' ); }
static void Apply( GenericImage<P>& image, const CurvesTransformationInstance& instance, bool useLUT = false ) { int numberOfCurves = 0; if ( !instance[CurveIndex::RGBK].IsIdentity() ) numberOfCurves = image.NumberOfNominalChannels(); if ( image.IsColor() ) { for ( int c = 0; c < image.NumberOfNominalChannels(); ++c ) if ( !instance[c].IsIdentity() ) ++numberOfCurves; if ( !instance[CurveIndex::L].IsIdentity() || !instance[CurveIndex::a].IsIdentity() || !instance[CurveIndex::b].IsIdentity() || !instance[CurveIndex::c].IsIdentity() ) ++numberOfCurves; if ( !instance[CurveIndex::H].IsIdentity() || !instance[CurveIndex::S].IsIdentity() ) ++numberOfCurves; } if ( image.HasAlphaChannels() && !instance[CurveIndex::A].IsIdentity() ) ++numberOfCurves; if ( numberOfCurves == 0 ) { Console().WriteLn( "<end><cbr><* Identity *>" ); return; } size_type N = image.NumberOfPixels(); int numberOfThreads = Thread::NumberOfThreads( N, 256 ); size_type pixelsPerThread = N/numberOfThreads; image.Status().Initialize( "Curves transformation", numberOfCurves*N ); ThreadData data( image, numberOfCurves*N ); if ( useLUT ) data.lut.Generate( image, instance ); ReferenceArray<CurvesThread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new CurvesThread<P>( instance, data, image, i*pixelsPerThread, (j < numberOfThreads) ? j*pixelsPerThread : N ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Status() = data.status; }
static void Apply( GenericImage<P>& image, const LocalHistogramEqualizationInstance& instance ) { if ( image.IsColor() ) { Image L; image.GetLightness( L ); L.Status() = image.Status(); Apply( L, instance ); image.Status() = L.Status(); image.SetLightness( L ); return; } // create copy of the luminance to evaluate histogram from GenericImage<P> imageCopy( image ); imageCopy.EnsureUnique(); // really not necessary, but we'll be safer if this is done size_type N = image.NumberOfPixels(); int numberOfThreads = Thread::NumberOfThreads( image.Height(), 1 ); int rowsPerThread = image.Height()/numberOfThreads; image.Status().Initialize( "CLAHE", N ); AbstractImage::ThreadData data( image, N ); // create processing threads ReferenceArray<LocalHistogramEqualizationThread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new LocalHistogramEqualizationThread<P>( data, instance, image, imageCopy, i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : image.Height() ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Status() = data.status; }
template <class P, class S> static void Apply( GenericImage<P>& image, S*, const ICCProfileTransformation& T, ICCProfileTransformation::transformation_handle transformation ) { if ( image.IsEmptySelection() || T.Profiles().IsEmpty() ) return; if ( image.ColorSpace() != ColorSpace::RGB && image.ColorSpace() != ColorSpace::Gray ) throw Error( String().Format( "Unsupported color space %X in ICC color transformation.", image.ColorSpace() ) ); image.EnsureUnique(); Rect r = image.SelectedRectangle(); int h = r.Height(); int numberOfThreads = T.IsParallelProcessingEnabled() ? Min( T.MaxProcessors(), pcl::Thread::NumberOfThreads( h, 1 ) ) : 1; int rowsPerThread = h/numberOfThreads; size_type N = image.NumberOfSelectedPixels(); if ( image.Status().IsInitializationEnabled() ) image.Status().Initialize( "In-place ICC color profile transformation", N ); ThreadData<P> data( image, T, transformation, N ); ReferenceArray<Thread<P,S> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new Thread<P,S>( data, i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : h ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Status() = data.status; }
template <class P> static void Apply( GenericImage<P>& image, const MorphologicalTransformation& transformation ) { if ( image.IsEmptySelection() ) return; image.EnsureUnique(); int n = transformation.OverlappingDistance(); if ( n > image.Height() || n > image.Width() ) { image.Zero(); return; } /* * Dilation requires a reflected structure. We'll unreflect it once the * transformation has finished. */ bool didReflect = false; if ( transformation.Operator().IsDilation() != transformation.Structure().IsReflected() ) { const_cast<StructuringElement&>( transformation.Structure() ).Reflect(); didReflect = true; } int numberOfRows = image.SelectedRectangle().Height(); int numberOfThreads = transformation.IsParallelProcessingEnabled() ? Min( transformation.MaxProcessors(), pcl::Thread::NumberOfThreads( numberOfRows, n ) ) : 1; int rowsPerThread = numberOfRows/numberOfThreads; size_type N = image.NumberOfSelectedSamples(); if ( image.Status().IsInitializationEnabled() ) image.Status().Initialize( "Morphological transformation, " + transformation.Operator().Description(), N ); ThreadData<P> data( image, transformation, N ); ReferenceArray<Thread<P> > threads; for ( int i = 0, j = 1, y0 = image.SelectedRectangle().y0; i < numberOfThreads; ++i, ++j ) threads.Add( new Thread<P>( data, y0 + i*rowsPerThread, y0 + ((j < numberOfThreads) ? j*rowsPerThread : numberOfRows), i > 0, j < numberOfThreads ) ); try { AbstractImage::RunThreads( threads, data ); if ( didReflect ) const_cast<StructuringElement&>( transformation.Structure() ).Reflect(); } catch ( ... ) { if ( didReflect ) const_cast<StructuringElement&>( transformation.Structure() ).Reflect(); throw; } image.SetStatusCallback( nullptr ); int c0 = image.SelectedChannel(); Point p0 = image.SelectedRectangle().LeftTop(); for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) { if ( i > 0 ) image.Mov( threads[i].UpperOverlappingRegion(), Point( p0.x, p0.y + i*rowsPerThread ), c0 ); if ( j < numberOfThreads ) image.Mov( threads[i].LowerOverlappingRegion(), Point( p0.x, p0.y + j*rowsPerThread - threads[i].LowerOverlappingRegion().Height() ), c0 ); } image.Status() = data.status; threads.Destroy(); }
template <class P> static void Apply( GenericImage<P>& image, const Translation& translation ) { if ( translation.Delta() == 0.0 ) return; int width = image.Width(); int height = image.Height(); if ( width == 0 || height == 0 ) return; image.EnsureUnique(); typename P::sample* f = nullptr; typename P::sample** f0 = nullptr; int n = image.NumberOfChannels(); typename GenericImage<P>::color_space cs0 = image.ColorSpace(); StatusMonitor status = image.Status(); int numberOfThreads = translation.IsParallelProcessingEnabled() ? Min( translation.MaxProcessors(), pcl::Thread::NumberOfThreads( height, 1 ) ) : 1; int rowsPerThread = height/numberOfThreads; try { size_type N = size_type( width )*size_type( height ); if ( status.IsInitializationEnabled() ) status.Initialize( String().Format( "Translate dx=%.3lf, dy=%.3lf, ", translation.Delta().x, translation.Delta().y ) + translation.Interpolation().Description(), size_type( n )*N ); f0 = image.ReleaseData(); for ( int c = 0; c < n; ++c ) { ThreadData<P> data( translation.Delta(), width, height, status, N ); data.f = f = image.Allocator().AllocatePixels( size_type( width )*size_type( height ) ); data.fillValue = (c < translation.FillValues().Length()) ? P::ToSample( translation.FillValues()[c] ) : P::MinSampleValue(); ReferenceArray<Thread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new Thread<P>( data, translation.Interpolation().NewInterpolator<P>( f0[c], width, height ), i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : height ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Allocator().Deallocate( f0[c] ); f0[c] = f; f = nullptr; status = data.status; } image.ImportData( f0, width, height, n, cs0 ).Status() = status; } catch ( ... ) { if ( f != nullptr ) image.Allocator().Deallocate( f ); if ( f0 != nullptr ) { for ( int c = 0; c < n; ++c ) if ( f0[c] != nullptr ) image.Allocator().Deallocate( f0[c] ); image.Allocator().Deallocate( f0 ); } image.FreeData(); throw; } }
void ComposeDeploymentUpgradeProgress::ToPublicApi( __in ScopedHeap & heap, __out FABRIC_COMPOSE_DEPLOYMENT_UPGRADE_PROGRESS & publicResult) const { publicResult.DeploymentName = heap.AddString(deploymentName_); publicResult.ApplicationName = heap.AddString(applicationName_.ToString()); switch (upgradeType_) { case UpgradeType::Rolling: case UpgradeType::Rolling_NotificationOnly: case UpgradeType::Rolling_ForceRestart: publicResult.UpgradeKind = FABRIC_APPLICATION_UPGRADE_KIND_ROLLING; break; default: publicResult.UpgradeKind = FABRIC_APPLICATION_UPGRADE_KIND_INVALID; } if (publicResult.UpgradeKind == FABRIC_APPLICATION_UPGRADE_KIND_ROLLING) { auto policyDescription = heap.AddItem<FABRIC_ROLLING_UPGRADE_POLICY_DESCRIPTION>(); switch (rollingUpgradeMode_) { case RollingUpgradeMode::UnmonitoredAuto: policyDescription->RollingUpgradeMode = FABRIC_ROLLING_UPGRADE_MODE_UNMONITORED_AUTO; break; case RollingUpgradeMode::UnmonitoredManual: policyDescription->RollingUpgradeMode = FABRIC_ROLLING_UPGRADE_MODE_UNMONITORED_MANUAL; break; case RollingUpgradeMode::Monitored: { policyDescription->RollingUpgradeMode = FABRIC_ROLLING_UPGRADE_MODE_MONITORED; auto policyDescriptionEx = heap.AddItem<FABRIC_ROLLING_UPGRADE_POLICY_DESCRIPTION_EX1>(); auto monitoringPolicy = heap.AddItem<FABRIC_ROLLING_UPGRADE_MONITORING_POLICY>(); policyDescriptionEx->MonitoringPolicy = monitoringPolicy.GetRawPointer(); monitoringPolicy_.ToPublicApi(heap, *monitoringPolicy); if (healthPolicy_) { auto healthPolicy = heap.AddItem<FABRIC_APPLICATION_HEALTH_POLICY>(); policyDescriptionEx->HealthPolicy = healthPolicy.GetRawPointer(); healthPolicy_->ToPublicApi(heap, *healthPolicy); } else { policyDescriptionEx->HealthPolicy = nullptr; } policyDescription->Reserved = policyDescriptionEx.GetRawPointer(); break; } default: policyDescription->RollingUpgradeMode = FABRIC_ROLLING_UPGRADE_MODE_INVALID; } policyDescription->ForceRestart = forceRestart_? TRUE : FALSE; policyDescription->UpgradeReplicaSetCheckTimeoutInSeconds = replicaSetCheckTimeoutInSeconds_; publicResult.UpgradePolicyDescription = policyDescription.GetRawPointer(); } else { publicResult.UpgradePolicyDescription = nullptr; } publicResult.TargetApplicationTypeVersion = heap.AddString(targetAppTypeVersion_); publicResult.UpgradeState = publicUpgradeState_; publicResult.NextUpgradeDomain = nextUpgradeDomain_.empty() ? nullptr : heap.AddString(nextUpgradeDomain_); ReferenceArray<FABRIC_UPGRADE_DOMAIN_STATUS_DESCRIPTION> domains; UpgradeHelper::ToPublicUpgradeDomains( heap, inProgressUpgradeDomain_, pendingUpgradeDomains_, completedUpgradeDomains_, domains); auto domainListPtr = heap.AddItem<FABRIC_UPGRADE_DOMAIN_STATUS_DESCRIPTION_LIST>(); domainListPtr->Count = static_cast<ULONG>(domains.GetCount()); domainListPtr->Items = domains.GetRawArray(); publicResult.UpgradeDomains = domainListPtr.GetRawPointer(); publicResult.UpgradeDurationInSeconds = static_cast<DWORD>(upgradeDuration_.TotalSeconds()); publicResult.CurrentUpgradeDomainDurationInSeconds = static_cast<DWORD>(currentUpgradeDomainDuration_.TotalSeconds()); auto publicHealthEvaluationsPtr = heap.AddItem<FABRIC_HEALTH_EVALUATION_LIST>(); auto error = PublicApiHelper::ToPublicApiList<HealthEvaluation, FABRIC_HEALTH_EVALUATION, FABRIC_HEALTH_EVALUATION_LIST>( heap, unhealthyEvaluations_, *publicHealthEvaluationsPtr); if (error.IsSuccess()) { publicResult.ApplicationUnhealthyEvaluations = publicHealthEvaluationsPtr.GetRawPointer(); } else { Trace.WriteError("ComposeDeploymentUpgradeStatusDescription", "Unhealthy evaluations to public API failed: error={0}", error); publicResult.ApplicationUnhealthyEvaluations = nullptr; } auto upgradeDomainProgressPtr = heap.AddItem<FABRIC_UPGRADE_DOMAIN_PROGRESS>(); currentUpgradeDomainProgress_.ToPublicApi(heap, *upgradeDomainProgressPtr); publicResult.CurrentUpgradeDomainProgress = upgradeDomainProgressPtr.GetRawPointer(); publicResult.UpgradeStatusDetails = heap.AddString(statusDetails_); publicResult.StartTimestampUtc = commonUpgradeContextData_.StartTime.AsFileTime; publicResult.FailureTimestampUtc = commonUpgradeContextData_.FailureTime.AsFileTime; publicResult.FailureReason = Management::ClusterManager::UpgradeFailureReason::ToPublicApi(commonUpgradeContextData_.FailureReason); if (commonUpgradeContextData_.FailureTime != DateTime::Zero) { auto upgradeProgressAtFailurePtr = heap.AddItem<FABRIC_UPGRADE_DOMAIN_PROGRESS>(); commonUpgradeContextData_.UpgradeProgressAtFailure.ToPublicApi(heap, *upgradeProgressAtFailurePtr); publicResult.UpgradeDomainProgressAtFailure = upgradeProgressAtFailurePtr.GetRawPointer(); } publicResult.ApplicationUpgradeStatusDetails = commonUpgradeContextData_.UpgradeStatusDetails.empty() ? nullptr : heap.AddString(commonUpgradeContextData_.UpgradeStatusDetails); }
template <class P> static void Apply( GenericImage<P>& image, const Resample& resample ) { int width = image.Width(); int w0 = width; int height = image.Height(); int h0 = height; resample.GetNewSizes( width, height ); if ( width == w0 && height == h0 ) return; if ( width <= 0 || height <= 0 ) { image.FreeData(); return; } image.EnsureUnique(); typename P::sample* f = nullptr; typename P::sample** f0 = nullptr; int n = image.NumberOfChannels(); typename GenericImage<P>::color_space cs0 = image.ColorSpace(); double rx = double( w0 )/width; double ry = double( h0 )/height; StatusMonitor status = image.Status(); int numberOfThreads = resample.IsParallelProcessingEnabled() ? Min( resample.MaxProcessors(), pcl::Thread::NumberOfThreads( height, 1 ) ) : 1; int rowsPerThread = height/numberOfThreads; try { size_type N = size_type( width )*size_type( height ); if ( status.IsInitializationEnabled() ) status.Initialize( String().Format( "Resampling to %dx%d px, ", width, height ) + resample.Interpolation().Description(), size_type( n )*N ); f0 = image.ReleaseData(); for ( int c = 0; c < n; ++c ) { ThreadData<P> data( rx, ry, width, status, N ); data.f = f = image.Allocator().AllocatePixels( width, height ); ReferenceArray<Thread<P> > threads; for ( int i = 0, j = 1; i < numberOfThreads; ++i, ++j ) threads.Add( new Thread<P>( data, resample.Interpolation().NewInterpolator<P>( f0[c], w0, h0 ), i*rowsPerThread, (j < numberOfThreads) ? j*rowsPerThread : height ) ); AbstractImage::RunThreads( threads, data ); threads.Destroy(); image.Allocator().Deallocate( f0[c] ); f0[c] = f; f = nullptr; status = data.status; } image.ImportData( f0, width, height, n, cs0 ).Status() = status; } catch ( ... ) { if ( f != nullptr ) image.Allocator().Deallocate( f ); if ( f0 != nullptr ) { for ( int c = 0; c < n; ++c ) if ( f0[c] != nullptr ) image.Allocator().Deallocate( f0[c] ); image.Allocator().Deallocate( f0 ); } image.FreeData(); throw; } }