Exemplo n.º 1
0
void
CacheDrivenTask::process(
	PageInfo const& page_info, AbstractFilterDataCollector* collector,
	ImageTransformation const& xform, QPolygonF const& content_rect_phys)
{
	if (ThumbnailCollector* thumb_col = dynamic_cast<ThumbnailCollector*>(collector)) {
		
		QString const out_file_path(m_outFileNameGen.filePathFor(page_info.id()));
		Params const params(m_ptrSettings->getParams(page_info.id()));

		ImageTransformation new_xform(xform);
		new_xform.postScaleToDpi(params.outputDpi());

		bool need_reprocess = false;

		do { // Just to be able to break from it.

			std::auto_ptr<OutputParams> stored_output_params(
				m_ptrSettings->getOutputParams(page_info.id())
			);

			if (!stored_output_params.get()) {
				need_reprocess = true;
				break;
			}

			OutputGenerator const generator(
				params.outputDpi(), params.colorParams(), params.despeckleLevel(),
				new_xform, content_rect_phys
			);
			OutputImageParams const new_output_image_params(
				generator.outputImageSize(), generator.outputContentRect(),
				new_xform, params.outputDpi(), params.colorParams(),
				params.dewarpingMode(), params.distortionModel(),
				params.depthPerception(), params.despeckleLevel()
			);

			if (!stored_output_params->outputImageParams().matches(new_output_image_params)) {
				need_reprocess = true;
				break;
			}

			ZoneSet const new_picture_zones(m_ptrSettings->pictureZonesForPage(page_info.id()));
			if (!PictureZoneComparator::equal(stored_output_params->pictureZones(), new_picture_zones)) {
				need_reprocess = true;
				break;
			}

			ZoneSet const new_fill_zones(m_ptrSettings->fillZonesForPage(page_info.id()));
			if (!FillZoneComparator::equal(stored_output_params->fillZones(), new_fill_zones)) {
				need_reprocess = true;
				break;
			}
			
			QFileInfo const out_file_info(out_file_path);

			if (!out_file_info.exists()) {
				need_reprocess = true;
				break;
			}
			
			if (!stored_output_params->outputFileParams().matches(OutputFileParams(out_file_info))) {
				need_reprocess = true;
				break;
			}
		} while (false);

		if (need_reprocess) {
			thumb_col->processThumbnail(
				std::auto_ptr<QGraphicsItem>(
					new IncompleteThumbnail(
						thumb_col->thumbnailCache(),
						thumb_col->maxLogicalThumbSize(),
						page_info.imageId(), new_xform
					)
				)
			);
		} else {
			ImageTransformation const out_xform(
				new_xform.resultingRect(), params.outputDpi()
			);

			thumb_col->processThumbnail(
				std::auto_ptr<QGraphicsItem>(
					new Thumbnail(
						thumb_col->thumbnailCache(),
						thumb_col->maxLogicalThumbSize(),
						ImageId(out_file_path), out_xform
					)
				)
			);
		}
	}
}
Exemplo n.º 2
0
Arquivo: Task.cpp Projeto: DikBSD/STE
FilterResultPtr
Task::process(
	TaskStatus const& status, FilterData const& data,
	QPolygonF const& content_rect_phys, QPolygonF const& page_rect_phys)
{
	status.throwIfCancelled();
	
	Params const params(m_ptrSettings->getParams(m_pageId));
	RenderParams const render_params(params.colorParams());
	QString const out_file_path(m_outFileNameGen.filePathFor(m_pageId));
	QFileInfo const out_file_info(out_file_path);

	QString const automask_dir(Utils::automaskDir(m_outFileNameGen.outDir()));
	QString const automask_file_path(
		QDir(automask_dir).absoluteFilePath(out_file_info.fileName())
	);
	QFileInfo automask_file_info(automask_file_path);

	QString const speckles_dir(Utils::specklesDir(m_outFileNameGen.outDir()));
	QString const speckles_file_path(
		QDir(speckles_dir).absoluteFilePath(out_file_info.fileName())
	);
	QFileInfo speckles_file_info(speckles_file_path);

	bool const need_picture_editor = render_params.mixedOutput() && !m_batchProcessing;
	bool const need_speckles_image = params.despeckleLevel() != DESPECKLE_OFF
		&& params.colorParams().colorMode() != ColorParams::COLOR_GRAYSCALE && !m_batchProcessing;
	
	OutputGenerator const generator(
		params.outputDpi(), params.colorParams(), params.despeckleLevel(),
		data.xform(), content_rect_phys, page_rect_phys
	);
	
	OutputImageParams const new_output_image_params(
		generator.outputImageSize(), generator.outputContentRect(),
		data.xform(), params.outputDpi(), params.colorParams(),
		params.dewarpingMode(), params.distortionModel(),
		params.depthPerception(), params.despeckleLevel()
	);

	ZoneSet const new_picture_zones(m_ptrSettings->pictureZonesForPage(m_pageId));
	ZoneSet const new_fill_zones(m_ptrSettings->fillZonesForPage(m_pageId));
	
	bool need_reprocess = false;
	do { // Just to be able to break from it.
		
		std::auto_ptr<OutputParams> stored_output_params(
			m_ptrSettings->getOutputParams(m_pageId)
		);
		
		if (!stored_output_params.get()) {
			need_reprocess = true;
			break;
		}
		
		if (!stored_output_params->outputImageParams().matches(new_output_image_params)) {
			need_reprocess = true;
			break;
		}

		if (!PictureZoneComparator::equal(stored_output_params->pictureZones(), new_picture_zones)) {
			need_reprocess = true;
			break;
		}

		if (!FillZoneComparator::equal(stored_output_params->fillZones(), new_fill_zones)) {
			need_reprocess = true;
			break;
		}
		
		if (!out_file_info.exists()) {
			need_reprocess = true;
			break;
		}
		
		if (!stored_output_params->outputFileParams().matches(OutputFileParams(out_file_info))) {
			need_reprocess = true;
			break;
		}

		if (need_picture_editor) {
			if (!automask_file_info.exists()) {
				need_reprocess = true;
				break;
			}

			if (!stored_output_params->automaskFileParams().matches(OutputFileParams(automask_file_info))) {
				need_reprocess = true;
				break;
			}
		}

		if (need_speckles_image) {
			if (!speckles_file_info.exists()) {
				need_reprocess = true;
				break;
			}
			if (!stored_output_params->specklesFileParams().matches(OutputFileParams(speckles_file_info))) {
				need_reprocess = true;
				break;
			}
		}
	
	} while (false);
	
	QImage out_img;
	BinaryImage automask_img;
	BinaryImage speckles_img;
	
	if (!need_reprocess) {
		QFile out_file(out_file_path);
		if (out_file.open(QIODevice::ReadOnly)) {
			out_img = ImageLoader::load(out_file, 0);
		}
		need_reprocess = out_img.isNull();

		if (need_picture_editor && !need_reprocess) {
			QFile automask_file(automask_file_path);
			if (automask_file.open(QIODevice::ReadOnly)) {
				automask_img = BinaryImage(ImageLoader::load(automask_file, 0));
			}
			need_reprocess = automask_img.isNull() || automask_img.size() != out_img.size();
		}

		if (need_speckles_image && !need_reprocess) {
			QFile speckles_file(speckles_file_path);
			if (speckles_file.open(QIODevice::ReadOnly)) {
				speckles_img = BinaryImage(ImageLoader::load(speckles_file, 0));
			}
			need_reprocess = speckles_img.isNull();
		}
	}

	if (need_reprocess) {
		// Even in batch processing mode we should still write automask, because it
		// will be needed when we view the results back in interactive mode.
		// The same applies even more to speckles file, as we need it not only
		// for visualization purposes, but also for re-doing despeckling at
		// different levels without going through the whole output generation process.
		bool const write_automask = render_params.mixedOutput();
		bool const write_speckles_file = params.despeckleLevel() != DESPECKLE_OFF &&
			params.colorParams().colorMode() != ColorParams::COLOR_GRAYSCALE; 

		automask_img = BinaryImage();
		speckles_img = BinaryImage();

		out_img = generator.process(
			status, data, new_picture_zones, new_fill_zones,
			params.dewarpingMode() != DewarpingMode::OFF
			? params.distortionModel() : DistortionModel(),
			params.depthPerception(),
			write_automask ? &automask_img : 0,
			write_speckles_file ? &speckles_img : 0,
			m_ptrDbg.get()
		);

		if (write_speckles_file && speckles_img.isNull()) {
			// Even if despeckling didn't actually take place, we still need
			// to write an empty speckles file.  Making it a special case
			// is simply not worth it.
			BinaryImage(out_img.size(), WHITE).swap(speckles_img);
		}

		bool invalidate_params = false;
		
		if (!TiffWriter::writeImage(out_file_path, out_img)) {
			invalidate_params = true;
		} else {
			deleteMutuallyExclusiveOutputFiles();
		}

		if (write_automask) {
			if (!QDir().mkpath(automask_dir)) {
				invalidate_params = true;
			} else if (!TiffWriter::writeImage(automask_file_path, automask_img.toQImage())) {
				invalidate_params = true;
			}
		}
		if (write_speckles_file) {
			if (!QDir().mkpath(speckles_dir)) {
				invalidate_params = true;
			} else if (!TiffWriter::writeImage(speckles_file_path, speckles_img.toQImage())) {
				invalidate_params = true;
			}
		}

		if (invalidate_params) {
			m_ptrSettings->removeOutputParams(m_pageId);
		} else {
			// Note that we can't reuse *_file_info objects
			// as we've just overwritten those files.
			OutputParams const out_params(
				new_output_image_params,
				OutputFileParams(QFileInfo(out_file_path)),
				write_automask ? OutputFileParams(QFileInfo(automask_file_path))
				: OutputFileParams(),
				write_speckles_file ? OutputFileParams(QFileInfo(speckles_file_path))
				: OutputFileParams(),
				new_picture_zones, new_fill_zones
			);

			m_ptrSettings->setOutputParams(m_pageId, out_params);
		}
		
		m_ptrThumbnailCache->recreateThumbnail(ImageId(out_file_path), out_img);
	}

	DespeckleState const despeckle_state(
		out_img, speckles_img, params.despeckleLevel(), params.outputDpi()
	);

	DespeckleVisualization despeckle_visualization;
	if (m_lastTab == TAB_DESPECKLING) {
		// Because constructing DespeckleVisualization takes a noticeable
		// amount of time, we only do it if we are sure we'll need it.
		// Otherwise it will get constructed on demand.
		despeckle_visualization = despeckle_state.visualize();
	}

	return FilterResultPtr(
		new UiUpdater(
			m_ptrFilter, m_ptrSettings, m_ptrDbg, params,
			generator.toOutput(), generator.outputContentRect(),
			QRectF(QPointF(0.0, 0.0), generator.outputImageSize()),
			m_pageId, data.origImage(), out_img, automask_img,
			params.distortionModel(), despeckle_state, despeckle_visualization,
			m_batchProcessing, m_debug
		)
	);
}