in cpp/spectrum/core/recipes/BaseRecipe.cpp [29:97]
image::Specification BaseRecipe::perform(const Operation& operation) const {
const auto& parameters = operation.parameters;
const auto decisions = decisions::BaseDecision::calculate(operation);
// processing blocks
std::vector<std::unique_ptr<proc::ScanlineProcessingBlock>> processingBlocks;
auto decompressor =
operation.makeDecompressor(decisions.resize.getSamplingRatio());
const auto scanlineGenerator = [&decompressor] {
return decompressor->readScanline();
};
// (1) cropping
if (decisions.resize.shouldCrop()) {
const auto cropRequirement = decisions.resize.cropRequirement();
const auto croppingInput = decisions.resize.sizeAfterSampling();
processingBlocks.push_back(
std::make_unique<proc::CroppingScanlineProcessingBlock>(
parameters.inputImageSpecification.pixelSpecification,
croppingInput,
cropRequirement->apply(croppingInput)));
}
// (2) scaling
if (decisions.resize.shouldScale()) {
processingBlocks.push_back(
std::make_unique<proc::ScalingScanlineProcessingBlock>(
parameters.inputImageSpecification.pixelSpecification,
decisions.resize.sizeAfterCropping(),
decisions.resize.sizeAfterScaling(),
operation.configuration.general.samplingMethod()));
}
// (3) rotation
if (decisions.orientation.shouldRotatePixels()) {
processingBlocks.push_back(
std::make_unique<proc::RotationScanlineProcessingBlock>(
parameters.inputImageSpecification.pixelSpecification,
decisions.resize.sizeAfterScaling(),
decisions.orientation.orientation));
}
auto compressor =
operation.makeCompressor(decisions.outputImageSpecification);
const auto scanlineConverter = proc::makeScanlineConverter(
parameters.inputImageSpecification.pixelSpecification,
decisions.outputImageSpecification.pixelSpecification,
operation.configuration.general.defaultBackgroundColor());
// scanline consumer
const auto scanlineConsumer = [scanlineConverter = scanlineConverter.get(),
&compressor = *compressor](auto scanline) {
compressor.writeScanline(
scanlineConverter->convertScanline(std::move(scanline)));
};
// run chain
proc::ScanlinePump scanlinePump(
scanlineGenerator,
std::move(processingBlocks),
scanlineConsumer,
decompressor->outputImageSpecification().size.height);
scanlinePump.pumpAll();
return decisions.outputImageSpecification;
}