Skip to content

Commit

Permalink
Future-proof against poppler 24.10 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
pbs3141 committed Oct 28, 2024
1 parent 94322e9 commit 22304ae
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 69 deletions.
120 changes: 53 additions & 67 deletions src/extension/internal/pdfinput/pdf-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,11 +817,11 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/)
_POPPLER_FREE(obj3);
if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup, "G").isStream()) {
if (_POPPLER_CALL_ARGS_DEREF(obj4, obj3.streamGetDict()->lookup, "Group").isDict()) {
GfxColorSpace *blendingColorSpace = nullptr;
std::unique_ptr<GfxColorSpace> blendingColorSpace;
GBool isolated = gFalse;
GBool knockout = gFalse;
if (!_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "CS").isNull()) {
blendingColorSpace = GfxColorSpace::parse(nullptr, &obj5, nullptr, state);
blendingColorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(nullptr, &obj5, nullptr, state));
}
_POPPLER_FREE(obj5);
if (_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "I").isBool()) {
Expand All @@ -842,7 +842,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/)
}
}
}
doSoftMask(&obj3, alpha, blendingColorSpace, isolated, knockout, funcs[0], &backdropColor);
doSoftMask(&obj3, alpha, blendingColorSpace.get(), isolated, knockout, funcs[0], &backdropColor);
if (funcs[0]) {
delete funcs[0];
}
Expand Down Expand Up @@ -927,9 +927,6 @@ void PdfParser::doSoftMask(Object *str, GBool alpha,
alpha, transferFunc, backdropColor);
--formDepth;

if (blendingColorSpace) {
delete blendingColorSpace;
}
_POPPLER_FREE(obj1);
}

Expand All @@ -946,42 +943,43 @@ void PdfParser::opSetRenderingIntent(Object /*args*/[], int /*numArgs*/)
*
* Maintains a cache for named color spaces to avoid expensive re-parsing.
*/
GfxColorSpace *PdfParser::lookupColorSpaceCopy(Object &arg)
std::unique_ptr<GfxColorSpace> PdfParser::lookupColorSpaceCopy(Object &arg)
{
assert(!arg.isNull());
GfxColorSpace *colorSpace = nullptr;

if (char const *name = arg.isName() ? arg.getName() : nullptr) {
auto const cache_name = std::to_string(formDepth) + "-" + name;
if ((colorSpace = colorSpacesCache[cache_name].get())) {
return colorSpace->copy();
if (auto cached = colorSpacesCache[cache_name].get()) {
return std::unique_ptr<GfxColorSpace>(cached->copy());
}

Object obj = res->lookupColorSpace(name);
if (obj.isNull()) {
colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state);
std::unique_ptr<GfxColorSpace> colorSpace;
if (auto obj = res->lookupColorSpace(name); !obj.isNull()) {
colorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(res, &obj, nullptr, state));
} else {
colorSpace = GfxColorSpace::parse(res, &obj, nullptr, state);
colorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(res, &arg, nullptr, state));
}

if (colorSpace && colorSpace->getMode() != csPattern) {
colorSpacesCache[cache_name].reset(colorSpace->copy());
colorSpacesCache[cache_name] = std::unique_ptr<GfxColorSpace>(colorSpace->copy());
}

return colorSpace;
} else {
// We were passed in an object directly.
colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state);
return std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(res, &arg, nullptr, state));
}
return colorSpace;
}

/**
* Look up pattern/gradients from the GfxResource dictionary
*/
GfxPattern *PdfParser::lookupPattern(Object *obj, GfxState *state)
std::unique_ptr<GfxPattern> PdfParser::lookupPattern(Object *obj, GfxState *state)
{
if (!obj->isName())
return nullptr;
return res->lookupPattern(obj->getName(), nullptr, state);
if (!obj->isName()) {
return {};
}
return std::unique_ptr<GfxPattern>(res->lookupPattern(obj->getName(), nullptr, state));
}

// TODO not good that numArgs is ignored but args[] is used:
Expand All @@ -990,7 +988,7 @@ void PdfParser::opSetFillGray(Object args[], int /*numArgs*/)
GfxColor color;
builder->beforeStateChange(state);
state->setFillPattern(nullptr);
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
color.c[0] = dblToCol(args[0].getNum());
state->setFillColor(&color);
builder->updateStyle(state);
Expand All @@ -1002,7 +1000,7 @@ void PdfParser::opSetStrokeGray(Object args[], int /*numArgs*/)
GfxColor color;
builder->beforeStateChange(state);
state->setStrokePattern(nullptr);
state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
color.c[0] = dblToCol(args[0].getNum());
state->setStrokeColor(&color);
builder->updateStyle(state);
Expand All @@ -1015,7 +1013,7 @@ void PdfParser::opSetFillCMYKColor(Object args[], int /*numArgs*/)
int i;
builder->beforeStateChange(state);
state->setFillPattern(nullptr);
state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceCMYKColorSpace>()));
for (i = 0; i < 4; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
Expand All @@ -1029,7 +1027,7 @@ void PdfParser::opSetStrokeCMYKColor(Object args[], int /*numArgs*/)
GfxColor color;
builder->beforeStateChange(state);
state->setStrokePattern(nullptr);
state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace());
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceCMYKColorSpace>()));
for (int i = 0; i < 4; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
Expand All @@ -1043,7 +1041,7 @@ void PdfParser::opSetFillRGBColor(Object args[], int /*numArgs*/)
GfxColor color;
builder->beforeStateChange(state);
state->setFillPattern(nullptr);
state->setFillColorSpace(new GfxDeviceRGBColorSpace());
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceRGBColorSpace>()));
for (int i = 0; i < 3; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
Expand All @@ -1056,7 +1054,7 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) {
GfxColor color;
builder->beforeStateChange(state);
state->setStrokePattern(nullptr);
state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceRGBColorSpace>()));
for (int i = 0; i < 3; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
Expand All @@ -1068,14 +1066,14 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) {
void PdfParser::opSetFillColorSpace(Object args[], int numArgs)
{
assert(numArgs >= 1);
GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]);
auto colorSpace = lookupColorSpaceCopy(args[0]);
builder->beforeStateChange(state);
state->setFillPattern(nullptr);

if (colorSpace) {
GfxColor color;
state->setFillColorSpace(colorSpace);
colorSpace->getDefaultColor(&color);
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
state->setFillColor(&color);
builder->updateStyle(state);
} else {
Expand All @@ -1089,14 +1087,14 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int numArgs)
assert(numArgs >= 1);
builder->beforeStateChange(state);

GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]);
auto colorSpace = lookupColorSpaceCopy(args[0]);

state->setStrokePattern(nullptr);

if (colorSpace) {
GfxColor color;
state->setStrokeColorSpace(colorSpace);
colorSpace->getDefaultColor(&color);
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
state->setStrokeColor(&color);
builder->updateStyle(state);
} else {
Expand Down Expand Up @@ -1159,7 +1157,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) {
builder->updateStyle(state);
}
if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) {
state->setFillPattern(pattern);
state->setFillPattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern));
builder->updateStyle(state);
}

Expand Down Expand Up @@ -1202,7 +1200,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) {
builder->updateStyle(state);
}
if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) {
state->setStrokePattern(pattern);
state->setStrokePattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern));
builder->updateStyle(state);
}

Expand Down Expand Up @@ -1579,11 +1577,11 @@ void PdfParser::doShadingPatternFillFallback(GfxShadingPattern *sPat,
// TODO not good that numArgs is ignored but args[] is used:
void PdfParser::opShFill(Object args[], int /*numArgs*/)
{
GfxShading *shading = nullptr;
GfxPath *savedPath = nullptr;
bool savedState = false;

if (!(shading = res->lookupShading(args[0].getName(), nullptr, state))) {
auto shading = std::unique_ptr<GfxShading>(res->lookupShading(args[0].getName(), nullptr, state));
if (!shading) {
return;
}

Expand Down Expand Up @@ -1615,19 +1613,19 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/)
// do shading type-specific operations
switch (shading->getType()) {
case 1: // Function-based shading
doFunctionShFill(static_cast<GfxFunctionShading *>(shading));
doFunctionShFill(static_cast<GfxFunctionShading *>(shading.get()));
break;
case 2: // Axial shading
case 3: // Radial shading
builder->addClippedFill(shading, stateToAffine(state));
builder->addClippedFill(shading.get(), stateToAffine(state));
break;
case 4: // Free-form Gouraud-shaded triangle mesh
case 5: // Lattice-form Gouraud-shaded triangle mesh
doGouraudTriangleShFill(static_cast<GfxGouraudTriangleShading *>(shading));
doGouraudTriangleShFill(static_cast<GfxGouraudTriangleShading *>(shading.get()));
break;
case 6: // Coons patch mesh
case 7: // Tensor-product patch mesh
doPatchMeshShFill(static_cast<GfxPatchMeshShading *>(shading));
doPatchMeshShFill(static_cast<GfxPatchMeshShading *>(shading.get()));
break;
}

Expand All @@ -1636,8 +1634,6 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/)
restoreState();
state->setPath(savedPath);
}

delete shading;
}

void PdfParser::doFunctionShFill(GfxFunctionShading *shading) {
Expand Down Expand Up @@ -2528,7 +2524,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)

} else {
// get color space and color map
GfxColorSpace *colorSpace;
std::unique_ptr<GfxColorSpace> colorSpace;
_POPPLER_CALL_ARGS(obj1, dict->lookup, "ColorSpace");
if (obj1.isNull()) {
_POPPLER_FREE(obj1);
Expand All @@ -2537,13 +2533,11 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
if (!obj1.isNull()) {
colorSpace = lookupColorSpaceCopy(obj1);
} else if (csMode == streamCSDeviceGray) {
colorSpace = new GfxDeviceGrayColorSpace();
colorSpace = std::make_unique<GfxDeviceGrayColorSpace>();
} else if (csMode == streamCSDeviceRGB) {
colorSpace = new GfxDeviceRGBColorSpace();
colorSpace = std::make_unique<GfxDeviceRGBColorSpace>();
} else if (csMode == streamCSDeviceCMYK) {
colorSpace = new GfxDeviceCMYKColorSpace();
} else {
colorSpace = nullptr;
colorSpace = std::make_unique<GfxDeviceCMYKColorSpace>();
}
_POPPLER_FREE(obj1);
if (!colorSpace) {
Expand All @@ -2554,10 +2548,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
_POPPLER_FREE(obj1);
_POPPLER_CALL_ARGS(obj1, dict->lookup, "D");
}
GfxImageColorMap *colorMap = new GfxImageColorMap(bits, &obj1, colorSpace);
auto colorMap = std::make_unique<GfxImageColorMap>(bits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
_POPPLER_FREE(obj1);
if (!colorMap->isOk()) {
delete colorMap;
goto err1;
}

Expand All @@ -2568,7 +2561,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
int maskWidth = 0;
int maskHeight = 0;
maskInvert = gFalse;
GfxImageColorMap *maskColorMap = nullptr;
std::unique_ptr<GfxImageColorMap> maskColorMap;
_POPPLER_CALL_ARGS(maskObj, dict->lookup, "Mask");
_POPPLER_CALL_ARGS(smaskObj, dict->lookup, "SMask");
Dict* maskDict;
Expand Down Expand Up @@ -2624,7 +2617,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
_POPPLER_FREE(obj1);
_POPPLER_CALL_ARGS(obj1, maskDict->lookup, "CS");
}
GfxColorSpace *maskColorSpace = lookupColorSpaceCopy(obj1);
auto maskColorSpace = lookupColorSpaceCopy(obj1);
_POPPLER_FREE(obj1);
if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) {
goto err1;
Expand All @@ -2634,10 +2627,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
_POPPLER_FREE(obj1);
_POPPLER_CALL_ARGS(obj1, maskDict->lookup, "D");
}
maskColorMap = new GfxImageColorMap(maskBits, &obj1, maskColorSpace);
maskColorMap = std::make_unique<GfxImageColorMap>(maskBits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(maskColorSpace));
_POPPLER_FREE(obj1);
if (!maskColorMap->isOk()) {
delete maskColorMap;
goto err1;
}
//~ handle the Matte entry
Expand Down Expand Up @@ -2718,17 +2710,15 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)

// draw it
if (haveSoftMask) {
builder->addSoftMaskedImage(state, str, width, height, colorMap, interpolate,
maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate);
delete maskColorMap;
builder->addSoftMaskedImage(state, str, width, height, colorMap.get(), interpolate,
maskStr, maskWidth, maskHeight, maskColorMap.get(), maskInterpolate);
} else if (haveExplicitMask) {
builder->addMaskedImage(state, str, width, height, colorMap, interpolate,
builder->addMaskedImage(state, str, width, height, colorMap.get(), interpolate,
maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate);
} else {
builder->addImage(state, str, width, height, colorMap, interpolate,
haveColorKeyMask ? maskColors : static_cast<int *>(nullptr));
builder->addImage(state, str, width, height, colorMap.get(), interpolate,
haveColorKeyMask ? maskColors : nullptr);
}
delete colorMap;

_POPPLER_FREE(maskObj);
_POPPLER_FREE(smaskObj);
Expand All @@ -2746,7 +2736,6 @@ void PdfParser::doForm(Object *str, double *offset)
{
Dict *dict;
GBool transpGroup, isolated, knockout;
GfxColorSpace *blendingColorSpace;
Object matrixObj, bboxObj;
double m[6], bbox[4];
Object resObj;
Expand Down Expand Up @@ -2812,12 +2801,12 @@ void PdfParser::doForm(Object *str, double *offset)

// check for a transparency group
transpGroup = isolated = knockout = gFalse;
blendingColorSpace = nullptr;
std::unique_ptr<GfxColorSpace> blendingColorSpace;
if (_POPPLER_CALL_ARGS_DEREF(obj1, dict->lookup, "Group").isDict()) {
if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup, "S").isName("Transparency")) {
transpGroup = gTrue;
if (!_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "CS").isNull()) {
blendingColorSpace = GfxColorSpace::parse(nullptr, &obj3, nullptr, state);
blendingColorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(nullptr, &obj3, nullptr, state));
}
_POPPLER_FREE(obj3);
if (_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "I").isBool()) {
Expand All @@ -2835,12 +2824,9 @@ void PdfParser::doForm(Object *str, double *offset)

// draw it
++formDepth;
doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace, isolated, knockout);
doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace.get(), isolated, knockout);
--formDepth;

if (blendingColorSpace) {
delete blendingColorSpace;
}
_POPPLER_FREE(resObj);
}

Expand Down
4 changes: 2 additions & 2 deletions src/extension/internal/pdfinput/pdf-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class PdfParser {
void loadPatternColorProfiles(Dict *resources);
void loadColorProfile();
void loadColorSpaceProfile(GfxColorSpace *space, Object *obj);
GfxPattern *lookupPattern(Object *obj, GfxState *state);
std::unique_ptr<GfxPattern> lookupPattern(Object *obj, GfxState *state);

std::shared_ptr<CairoFontEngine> getFontEngine();

Expand Down Expand Up @@ -176,7 +176,7 @@ class PdfParser {
//! Caches color spaces by name
std::map<std::string, std::unique_ptr<GfxColorSpace>> colorSpacesCache;

GfxColorSpace *lookupColorSpaceCopy(Object &);
std::unique_ptr<GfxColorSpace> lookupColorSpaceCopy(Object &);

void setDefaultApproximationPrecision(); // init color deltas
void pushOperator(const char *name);
Expand Down
Loading

0 comments on commit 22304ae

Please sign in to comment.