mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Bugfix: Bad performance with soft masked images
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user