void CaptureParticleProcess::processResult(const WorkResult *wr, bool cancelled) { const CaptureParticleWorkResult *result = static_cast<const CaptureParticleWorkResult *>(wr); const RangeWorkUnit *range = result->getRangeWorkUnit(); if (cancelled) return; m_resultMutex->lock(); increaseResultCount(range->getSize()); /* Accumulate the received pixel data */ float *imageData = m_accumBitmap->getFloatData(); size_t pixelIndex, imagePixelIndex = 0; Float r, g, b; Vector2i start(result->getBorder(), result->getBorder()); Vector2i end(result->getFullSize().x - result->getBorder(), result->getFullSize().y - result->getBorder()); for (int y=start.y; y<end.y; ++y) { pixelIndex = y*result->getFullSize().x + start.x; for (int x=start.x; x<end.x; ++x) { Spectrum spec(result->getPixel(pixelIndex)); spec.toLinearRGB(r,g,b); imageData[imagePixelIndex++] += r; imageData[imagePixelIndex++] += g; imageData[imagePixelIndex++] += b; ++imagePixelIndex; ++pixelIndex; } } develop(); m_resultMutex->unlock(); }
void CaptureParticleProcess::processResult(const WorkResult *wr, bool cancelled) { const CaptureParticleWorkResult *result = static_cast<const CaptureParticleWorkResult *>(wr); const RangeWorkUnit *range = result->getRangeWorkUnit(); if (cancelled) return; LockGuard lock(m_resultMutex); increaseResultCount(range->getSize()); m_accum->put(result); if (m_job->isInteractive() || m_receivedResultCount == m_workCount) develop(); }
int main ( int argc, char ** argv ) { printf("***** %s *****\n",TITLE); SetupLib(argc,argv,NAME,PROG_UNKNOWN); printf("term width = %d\n",GetTermWidth(80,0)); #ifdef HAVE_FIEMAP printf("* HAVE_FIEMAP defined!\n"); #endif #ifdef FS_IOC_FIEMAP printf("* FS_IOC_FIEMAP defined!\n"); #endif #if defined(TEST) && defined(DEBUG) if (0) { id6_t * id6 = (id6_t*)iobuf; PRINT("sizeof(id6_t)=%zd, %p,%p,%p -> %zu,%zu,%zu\n", sizeof(id6_t), id6, id6+1, id6+2, (ccp)id6-iobuf, (ccp)(id6+1)-iobuf, (ccp)(id6+2)-iobuf ); } #endif if ( argc < 2 ) help_exit(); int cmd_stat; const CommandTab_t * cmd_ct = ScanCommand(&cmd_stat,argv[1],CommandTab); if (!cmd_ct) { PrintCommandError(CommandTab,argv[1],cmd_stat,0); help_exit(); } argv[1] = argv[0]; argv++; argc--; switch(cmd_ct->id) { case CMD_TEST: return test(argc,argv); break; case CMD_FILENAME: test_filename(argc,argv); break; case CMD_MATCH_PATTERN: test_match_pattern(argc,argv); break; case CMD_OPEN_DISC: test_open_disc(argc,argv); break; case CMD_HEXDUMP: test_hexdump(argc,argv); break; #ifdef HAVE_OPENSSL case CMD_SHA1: test_sha1(); break; #endif #ifndef NO_BZIP2 case CMD_BZIP2: test_bzip2(argc,argv); break; #endif #ifdef HAVE_WORK_DIR case CMD_WIIMM: test_wiimm(argc,argv); break; #endif case CMD_DEVELOP: develop(argc,argv); break; //case CMD_HELP: default: help_exit(); } CloseAll(); if (SIGINT_level) ERROR0(ERR_INTERRUPT,"Program interrupted by user."); return max_error; }
//Function------------------------------------------------------------------------- bool ImagePipeline::filmulate(matrix<float> &input_image, matrix<float> &output_density, ParameterManager * paramManager, ImagePipeline * pipeline) { FilmParams filmParam; AbortStatus abort; Valid valid; std::tie(valid, abort, filmParam) = paramManager->claimFilmParams(FilmFetch::initial); if(abort == AbortStatus::restart) { return true; } //Extract parameters from struct float initial_developer_concentration = filmParam.initialDeveloperConcentration; float reservoir_thickness = filmParam.reservoirThickness; float active_layer_thickness = filmParam.activeLayerThickness; float crystals_per_pixel = filmParam.crystalsPerPixel; float initial_crystal_radius = filmParam.initialCrystalRadius; float initial_silver_salt_density = filmParam.initialSilverSaltDensity; float developer_consumption_const = filmParam.developerConsumptionConst; float crystal_growth_const = filmParam.crystalGrowthConst; float silver_salt_consumption_const = filmParam.silverSaltConsumptionConst; float total_development_time = filmParam.totalDevelopmentTime; int agitate_count = filmParam.agitateCount; int development_steps = filmParam.developmentSteps; float film_area = filmParam.filmArea; float sigma_const = filmParam.sigmaConst; float layer_mix_const = filmParam.layerMixConst; float layer_time_divisor = filmParam.layerTimeDivisor; float rolloff_boundary = filmParam.rolloffBoundary; //Set up timers struct timeval initialize_start, development_start, develop_start, diffuse_start, agitate_start, layer_mix_start; double develop_dif = 0, diffuse_dif = 0, agitate_dif = 0, layer_mix_dif= 0; gettimeofday(&initialize_start,NULL); int nrows = (int) input_image.nr(); int ncols = (int) input_image.nc()/3; int npix = nrows*ncols; //Now we activate some of the crystals on the film. This is literally //akin to exposing film to light. matrix<float> active_crystals_per_pixel; active_crystals_per_pixel = exposure(input_image, crystals_per_pixel, rolloff_boundary); //We set the crystal radius to a small seed value for each color. matrix<float> crystal_radius; crystal_radius.set_size(nrows,ncols*3); crystal_radius = initial_crystal_radius; //All layers share developer, so we only make it the original image size. matrix<float> developer_concentration; developer_concentration.set_size(nrows,ncols); developer_concentration = initial_developer_concentration; //Each layer gets its own silver salt which will feed crystal growth. matrix<float> silver_salt_density; silver_salt_density.set_size(nrows,ncols*3); silver_salt_density = initial_silver_salt_density; //Now, we set up the reservoir. //Because we don't want the film area to influence the brightness, we // increase the reservoir size in proportion. #define FILMSIZE 864;//36x24mm reservoir_thickness *= film_area/FILMSIZE; float reservoir_developer_concentration = initial_developer_concentration; //This is a value used in diffuse to set the length scale. float pixels_per_millimeter = sqrt(npix/film_area); //Here we do some math for the control logic for the differential //equation approximation computations. float timestep = total_development_time/development_steps; int agitate_period; if(agitate_count > 0) { agitate_period = floor(development_steps/agitate_count); } else { agitate_period = 3*development_steps; } int half_agitate_period = floor(agitate_period/2); tout << "Initialization time: " << timeDiff(initialize_start) << " seconds" << endl; gettimeofday(&development_start,NULL); //Now we begin the main development/diffusion loop, which approximates the //differential equation of film development. for(int i = 0; i <= development_steps; i++) { //Check for cancellation std::tie(valid, abort, filmParam) = paramManager->claimFilmParams(FilmFetch::subsequent); if(abort == AbortStatus::restart) { return true; } //Updating for starting the development simulation. Valid is one too high here. pipeline->updateProgress(Valid::prefilmulation, float(i)/float(development_steps)); gettimeofday(&develop_start,NULL); //This is where we perform the chemical reaction part. //The crystals grow. //The developer in the active layer is consumed. //So is the silver salt in the film. // The amount consumed increases as the crystals grow larger. //Because the developer and silver salts are consumed in bright regions, // this reduces the rate at which they grow. This gives us global // contrast reduction. develop(crystal_radius,crystal_growth_const,active_crystals_per_pixel, silver_salt_density,developer_concentration, active_layer_thickness,developer_consumption_const, silver_salt_consumption_const,timestep); develop_dif += timeDiff(develop_start); gettimeofday(&diffuse_start,NULL); //Check for cancellation std::tie(valid, abort, filmParam) = paramManager->claimFilmParams(FilmFetch::subsequent); if(abort == AbortStatus::restart) { return true; } //Updating for starting the diffusion simulation. Valid is one too high here. pipeline->updateProgress(Valid::prefilmulation, (float(i)+0.5)/float(development_steps)); //Now, we are going to perform the diffusion part. //Here we mix the layer among itself, which grants us the // local contrast increases. // diffuse(developer_concentration, // sigma_const, // pixels_per_millimeter, // timestep); diffuse_short_convolution(developer_concentration, sigma_const, pixels_per_millimeter, timestep); diffuse_dif += timeDiff(diffuse_start); gettimeofday(&layer_mix_start,NULL); //This performs mixing between the active layer adjacent to the film // and the reservoir. //This keeps the effects from getting too crazy. layer_mix(developer_concentration, active_layer_thickness, reservoir_developer_concentration, reservoir_thickness, layer_mix_const, layer_time_divisor, pixels_per_millimeter, timestep); layer_mix_dif += timeDiff(layer_mix_start); gettimeofday(&agitate_start,NULL); //I want agitation to only occur in the middle of development, not //at the very beginning or the ends. So, I add half the agitate //period to the current cycle count. if((i+half_agitate_period) % agitate_period ==0) agitate(developer_concentration, active_layer_thickness, reservoir_developer_concentration, reservoir_thickness, pixels_per_millimeter); agitate_dif += timeDiff(agitate_start); } tout << "Development time: " <<timeDiff(development_start)<< " seconds" << endl; tout << "Develop time: " << develop_dif << " seconds" << endl; tout << "Diffuse time: " << diffuse_dif << " seconds" << endl; tout << "Layer mix time: " << layer_mix_dif << " seconds" << endl; tout << "Agitate time: " << agitate_dif << " seconds" << endl; //Done filmulating, now do some housecleaning silver_salt_density.free(); developer_concentration.free(); //Now we compute the density (opacity) of the film. //We assume that overlapping crystals or dye clouds are //nonexistant. It works okay, for now... //The output is crystal_radius^2 * active_crystals_per_pixel struct timeval mult_start; gettimeofday(&mult_start,NULL); std::tie(valid, abort, filmParam) = paramManager->claimFilmParams(FilmFetch::subsequent); if(abort == AbortStatus::restart) { return true; } output_density = crystal_radius % crystal_radius % active_crystals_per_pixel; tout << "Output density time: "<<timeDiff(mult_start) << endl; #ifdef DOUT debug_out.close(); #endif return false; }