void MagicKernelScalingBlockImpl::runMagicKernel()

in cpp/spectrum/core/proc/ScalingScanlineProcessingBlock.cpp [97:147]


void MagicKernelScalingBlockImpl::runMagicKernel() {
  const auto numComponents = _pixelSpecification.bytesPerPixel;
  const auto stride = outputSize.width * numComponents;

  std::unique_ptr<std::uint8_t[]> lineBuffer(new std::uint8_t[stride]);

  legacy::SeparableFiltersResampler magicResampler(
      inputSize.width,
      inputSize.height,
      outputSize.width,
      outputSize.height,
      numComponents);

  legacy::Sharpener magicSharpener(
      outputSize.width, outputSize.height, numComponents, lineBuffer.get());

  // run
  const std::size_t inputSize = input.size();
  while (nextLineToRelease < inputSize) {
    // input -> resampler
    SPECTRUM_ENFORCE_IF_NOT(input[nextLineToRelease]);
    std::uint8_t* buffer =
        reinterpret_cast<std::uint8_t*>(input[nextLineToRelease]->data());
    SPECTRUM_ENFORCE_IF_NOT(buffer);
    magicResampler.putLine(buffer);

    // resampler -> sharpener
    // elements of `pResampledRow` are Q21.11 fixed-point numbers
    while (const int32_t* pResampledRow = magicResampler.getLine()) {
      magicSharpener.putLine(pResampledRow);

      // sharpener -> output
      while (magicSharpener.getLine(lineBuffer.get())) {
        auto scanline = std::make_unique<image::Scanline>(
            _pixelSpecification, outputSize.width);

        SPECTRUM_ENFORCE_IF_NOT(stride == scanline->sizeBytes());
        SPECTRUM_ENFORCE_IF_NOT(scanline && scanline->data());
        SPECTRUM_ENFORCE_IF_NOT(lineBuffer.get());

        memcpy(scanline->data(), lineBuffer.get(), stride);

        magicOutput.push_back(std::move(scanline));
      }
    }

    // free processed input
    input[nextLineToRelease].reset();
    nextLineToRelease++;
  }
}