Bugfix: Bad performance with soft masked images

This commit is contained in:
Jakub Melka
2020-07-10 13:19:13 +02:00
parent 882347591d
commit 863ae5a873

View File

@ -251,10 +251,8 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
throw PDFException(PDFTranslationContext::tr("Invalid size of the decode array. Expected %1, actual %2.").arg(componentCount * 2).arg(decode.size())); throw PDFException(PDFTranslationContext::tr("Invalid size of the decode array. Expected %1, actual %2.").arg(componentCount * 2).arg(decode.size()));
} }
PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent()); const unsigned int imageWidth = imageData.getWidth();
const unsigned int imageHeight = imageData.getHeight();
PDFColor color;
color.resize(componentCount);
QImage alphaMask = createAlphaMask(softMask); QImage alphaMask = createAlphaMask(softMask);
if (alphaMask.size() != image.size()) if (alphaMask.size() != image.size())
@ -263,14 +261,25 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
alphaMask = alphaMask.scaled(image.size()); alphaMask = alphaMask.scaled(image.size());
} }
QMutex exceptionMutex;
std::optional<PDFException> exception;
auto transformPixelLine = [&](unsigned int i)
{
try
{
PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent());
reader.seek(i * imageData.getStride());
const double max = reader.max(); const double max = reader.max();
const double coefficient = 1.0 / max; const double coefficient = 1.0 / max;
for (unsigned int i = 0, rowCount = imageData.getHeight(); i < rowCount; ++i)
{
reader.seek(i * imageData.getStride());
unsigned char* outputLine = image.scanLine(i); unsigned char* outputLine = image.scanLine(i);
unsigned char* alphaLine = alphaMask.scanLine(i); unsigned char* alphaLine = alphaMask.scanLine(i);
std::vector<float> inputColors(imageWidth * componentCount, 0.0f);
std::vector<unsigned char> outputColors(imageWidth * componentCount, 0);
auto itInputColor = inputColors.begin();
for (unsigned int j = 0; j < imageData.getWidth(); ++j) for (unsigned int j = 0; j < imageData.getWidth(); ++j)
{ {
for (unsigned int k = 0; k < componentCount; ++k) for (unsigned int k = 0; k < componentCount; ++k)
@ -280,23 +289,43 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
// Interpolate value, if it is not empty // Interpolate value, if it is not empty
if (!decode.empty()) if (!decode.empty())
{ {
color[k] = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]); *itInputColor++ = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]);
} }
else else
{ {
color[k] = value * coefficient; *itInputColor++ = value * coefficient;
}
} }
} }
QColor transformedColor = getColor(color, cms, intent, reporter); fillRGBBuffer(inputColors, outputColors.data(), intent, cms, reporter);
QRgb rgb = transformedColor.rgb();
*outputLine++ = qRed(rgb); const unsigned char* transformedLine = outputColors.data();
*outputLine++ = qGreen(rgb); for (unsigned int i = 0; i < imageWidth; ++i)
*outputLine++ = qBlue(rgb); {
*outputLine++ = *transformedLine++;
*outputLine++ = *transformedLine++;
*outputLine++ = *transformedLine++;
*outputLine++ = *alphaLine++; *outputLine++ = *alphaLine++;
} }
} }
catch (PDFException lineException)
{
QMutexLocker lock(&exceptionMutex);
if (!exception)
{
exception = lineException;
}
}
};
auto range = PDFIntegerRange<unsigned int>(0, imageHeight);
PDFExecutionPolicy::execute(PDFExecutionPolicy::Scope::Content, range.begin(), range.end(), transformPixelLine);
if (exception)
{
throw *exception;
}
return image; return image;
} }