mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Bugfixing: Crash in case of invalid image, invalid font CID character 0 width
This commit is contained in:
@ -174,42 +174,61 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
|
|||||||
|
|
||||||
const unsigned int imageWidth = imageData.getWidth();
|
const unsigned int imageWidth = imageData.getWidth();
|
||||||
const unsigned int imageHeight = imageData.getHeight();
|
const unsigned int imageHeight = imageData.getHeight();
|
||||||
//for (unsigned int i = 0, rowCount = imageData.getHeight(); i < rowCount; ++i)
|
|
||||||
|
QMutex exceptionMutex;
|
||||||
|
std::optional<PDFException> exception;
|
||||||
|
|
||||||
auto transformPixelLine = [&](unsigned int i)
|
auto transformPixelLine = [&](unsigned int i)
|
||||||
{
|
{
|
||||||
PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent());
|
try
|
||||||
reader.seek(i * imageData.getStride());
|
|
||||||
|
|
||||||
const double max = reader.max();
|
|
||||||
const double coefficient = 1.0 / max;
|
|
||||||
unsigned char* outputLine = image.scanLine(i);
|
|
||||||
|
|
||||||
std::vector<float> inputColors(imageWidth * componentCount, 0.0f);
|
|
||||||
auto itInputColor = inputColors.begin();
|
|
||||||
for (unsigned int j = 0; j < imageData.getWidth(); ++j)
|
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0; k < componentCount; ++k)
|
PDFBitReader reader(&imageData.getData(), imageData.getBitsPerComponent());
|
||||||
{
|
reader.seek(i * imageData.getStride());
|
||||||
PDFReal value = reader.read();
|
|
||||||
|
|
||||||
// Interpolate value, if it is not empty
|
const double max = reader.max();
|
||||||
if (!decode.empty())
|
const double coefficient = 1.0 / max;
|
||||||
|
unsigned char* outputLine = image.scanLine(i);
|
||||||
|
|
||||||
|
std::vector<float> inputColors(imageWidth * componentCount, 0.0f);
|
||||||
|
auto itInputColor = inputColors.begin();
|
||||||
|
for (unsigned int j = 0; j < imageData.getWidth(); ++j)
|
||||||
|
{
|
||||||
|
for (unsigned int k = 0; k < componentCount; ++k)
|
||||||
{
|
{
|
||||||
*itInputColor++ = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]);
|
PDFReal value = reader.read();
|
||||||
}
|
|
||||||
else
|
// Interpolate value, if it is not empty
|
||||||
{
|
if (!decode.empty())
|
||||||
*itInputColor++ = value * coefficient;
|
{
|
||||||
|
*itInputColor++ = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*itInputColor++ = value * coefficient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fillRGBBuffer(inputColors, outputLine, intent, cms, reporter);
|
fillRGBBuffer(inputColors, outputLine, intent, cms, reporter);
|
||||||
|
}
|
||||||
|
catch (PDFException lineException)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&exceptionMutex);
|
||||||
|
if (!exception)
|
||||||
|
{
|
||||||
|
exception = lineException;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto range = PDFIntegerRange<unsigned int>(0, imageHeight);
|
auto range = PDFIntegerRange<unsigned int>(0, imageHeight);
|
||||||
std::for_each(std::execution::parallel_policy(), range.begin(), range.end(), transformPixelLine);
|
std::for_each(std::execution::parallel_policy(), range.begin(), range.end(), transformPixelLine);
|
||||||
|
|
||||||
|
if (exception)
|
||||||
|
{
|
||||||
|
throw *exception;
|
||||||
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,10 +538,17 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Glyph for composite font character with cid '%1' not found.").arg(cid));
|
if (cid > 0)
|
||||||
|
{
|
||||||
|
// Character with CID == 0 is treated as default whitespace, it hasn't glyph
|
||||||
|
reporter->reportRenderError(RenderErrorType::Warning, PDFTranslationContext::tr("Glyph for composite font character with cid '%1' not found.").arg(cid));
|
||||||
|
}
|
||||||
|
|
||||||
if (glyphWidth > 0)
|
if (glyphWidth > 0)
|
||||||
{
|
{
|
||||||
textSequence.items.emplace_back(nullptr, QChar(), glyphWidth * m_pixelSize * FONT_WIDTH_MULTIPLIER);
|
// We do not multiply advance with font size and FONT_WIDTH_MULTIPLIER, because in the code,
|
||||||
|
// "advance" is treated as in font space.
|
||||||
|
textSequence.items.emplace_back(nullptr, QChar(), -glyphWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user