Commit 5927e0b0 authored by Philipp Knechtges's avatar Philipp Knechtges Committed by Albert Astals Cid

GfxState: substitute manual ref counting in GfxColorTransform by a shared_ptr

This patch as said replaces the manual ref counting in GfxColorTransform. Along the lines
it also introduces another shared_ptr for cmsHPROFILEs, which is named GfxLCMSProfilePtr.
parent ae2fa0be
......@@ -654,8 +654,8 @@ void Gfx::initDisplayProfile() {
Stream *iccStream = profile.getStream();
int length = 0;
unsigned char *profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
if (hp == nullptr) {
auto hp = make_GfxLCMSProfilePtr(cmsOpenProfileFromMem(profBuf,length));
if (!hp) {
error(errSyntaxWarning, -1, "read ICCBased color space profile error");
} else {
state->setDisplayProfile(hp);
......
This diff is collapsed.
......@@ -42,6 +42,7 @@
#include <cassert>
#include <map>
#include <memory>
class Array;
class Gfx;
......@@ -189,12 +190,21 @@ enum GfxColorSpaceMode {
csPattern
};
// This shall hold a cmsHPROFILE handle.
// Only use the make_GfxLCMSProfilePtr function to construct this pointer,
// to ensure that the resources are properly released after usage.
typedef std::shared_ptr<void> GfxLCMSProfilePtr;
#ifdef USE_CMS
GfxLCMSProfilePtr make_GfxLCMSProfilePtr(void* profile);
#endif
// wrapper of cmsHTRANSFORM to copy
class GfxColorTransform {
public:
void doTransform(void *in, void *out, unsigned int size);
// transformA should be a cmsHTRANSFORM
GfxColorTransform(void *sourceProfileA, void *transformA, int cmsIntent,
GfxColorTransform(const GfxLCMSProfilePtr& sourceProfileA, void *transformA, int cmsIntent,
unsigned int inputPixelType, unsigned int transformPixelType);
~GfxColorTransform();
GfxColorTransform(const GfxColorTransform &) = delete;
......@@ -202,15 +212,12 @@ public:
int getIntent() const { return cmsIntent; }
int getInputPixelType() const { return inputPixelType; }
int getTransformPixelType() const { return transformPixelType; }
void ref();
unsigned int unref();
void *getSourceProfile() { return sourceProfile; }
GfxLCMSProfilePtr getSourceProfile() { return sourceProfile; }
char *getPostScriptCSA();
private:
GfxColorTransform() {}
void *sourceProfile;
GfxLCMSProfilePtr sourceProfile;
void *transform;
unsigned int refCount;
int cmsIntent;
unsigned int inputPixelType;
unsigned int transformPixelType;
......@@ -282,13 +289,10 @@ public:
#ifdef USE_CMS
static int setupColorProfiles();
// displayProfileA should be a cmsHPROFILE
static void setDisplayProfile(void *displayProfileA);
static void setDisplayProfile(const GfxLCMSProfilePtr& displayProfileA);
static void setDisplayProfileName(GooString *name);
// result will be a cmsHPROFILE
static void *getRGBProfile();
// result will be a cmsHPROFILE
static void *getDisplayProfile();
static GfxLCMSProfilePtr getRGBProfile();
static GfxLCMSProfilePtr getDisplayProfile();
#endif
protected:
......@@ -370,7 +374,7 @@ private:
double kr, kg, kb; // gamut mapping mulitpliers
void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
GfxColorTransform *transform;
std::shared_ptr<GfxColorTransform> transform;
#endif
};
......@@ -452,7 +456,7 @@ private:
double kr, kg, kb; // gamut mapping mulitpliers
void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
GfxColorTransform *transform;
std::shared_ptr<GfxColorTransform> transform;
#endif
};
......@@ -533,7 +537,7 @@ private:
double kr, kg, kb; // gamut mapping mulitpliers
void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
GfxColorTransform *transform;
std::shared_ptr<GfxColorTransform> transform;
#endif
};
......@@ -589,8 +593,8 @@ private:
Ref iccProfileStream; // the ICC profile
#ifdef USE_CMS
int getIntent() { return (transform != nullptr) ? transform->getIntent() : 0; }
GfxColorTransform *transform;
GfxColorTransform *lineTransform; // color transform for line
std::shared_ptr<GfxColorTransform> transform;
std::shared_ptr<GfxColorTransform> lineTransform; // color transform for line
mutable std::map<unsigned int, unsigned int> cmsCache;
#endif
};
......@@ -1601,9 +1605,9 @@ public:
{ strncpy(renderingIntent, intent, 31); }
#ifdef USE_CMS
void setDisplayProfile(void *localDisplayProfileA);
void *getDisplayProfile() { return localDisplayProfile; }
GfxColorTransform *getXYZ2DisplayTransform();
void setDisplayProfile(const GfxLCMSProfilePtr& localDisplayProfileA);
GfxLCMSProfilePtr getDisplayProfile() { return localDisplayProfile; }
std::shared_ptr<GfxColorTransform> getXYZ2DisplayTransform();
int getCmsRenderingIntent();
#endif
......@@ -1701,12 +1705,11 @@ private:
GfxState(const GfxState *state, bool copyPath);
#ifdef USE_CMS
void *localDisplayProfile;
int displayProfileRef;
GfxColorTransform *XYZ2DisplayTransformRelCol;
GfxColorTransform *XYZ2DisplayTransformAbsCol;
GfxColorTransform *XYZ2DisplayTransformSat;
GfxColorTransform *XYZ2DisplayTransformPerc;
GfxLCMSProfilePtr localDisplayProfile;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformRelCol;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformAbsCol;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformSat;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformPerc;
#endif
};
......
......@@ -648,7 +648,7 @@ namespace Poppler {
void Document::setColorDisplayProfile(void* outputProfileA)
{
#if defined(USE_CMS)
GfxColorSpace::setDisplayProfile((cmsHPROFILE)outputProfileA);
GfxColorSpace::setDisplayProfile(make_GfxLCMSProfilePtr(outputProfileA));
#else
Q_UNUSED(outputProfileA);
#endif
......@@ -668,7 +668,7 @@ namespace Poppler {
void* Document::colorRgbProfile() const
{
#if defined(USE_CMS)
return (void*)GfxColorSpace::getRGBProfile();
return GfxColorSpace::getRGBProfile().get();
#else
return nullptr;
#endif
......@@ -677,7 +677,7 @@ namespace Poppler {
void* Document::colorDisplayProfile() const
{
#if defined(USE_CMS)
return (void*)GfxColorSpace::getDisplayProfile();
return GfxColorSpace::getDisplayProfile().get();
#else
return nullptr;
#endif
......
......@@ -1190,7 +1190,10 @@ delete it;
\param outputProfileA is a \c cmsHPROFILE of the LCMS library.
\note This should be called before any rendering happens and only once during the lifetime of the current process.
\note This should be called before any rendering happens.
\note It is assumed that poppler takes over the owernship of the corresponding cmsHPROFILE. In particular,
it is no longer the caller's responsibility to close the profile after use.
\since 0.12
*/
......@@ -1210,6 +1213,9 @@ delete it;
\return a \c cmsHPROFILE of the LCMS library.
\note The returned profile stays a property of poppler and shall NOT be closed by the user. It's
existence is guaranteed for as long as this instance of the Document class is not deleted.
\since 0.12
*/
void* colorRgbProfile() const;
......@@ -1218,6 +1224,9 @@ delete it;
\return a \c cmsHPROFILE of the LCMS library.
\note The returned profile stays a property of poppler and shall NOT be closed by the user. It's
existence is guaranteed for as long as this instance of the Document class is not deleted.
\since 0.12
*/
void *colorDisplayProfile() const;
......
......@@ -288,7 +288,7 @@ static cairo_antialias_t antialiasEnum = CAIRO_ANTIALIAS_DEFAULT;
#ifdef USE_CMS
static unsigned char *icc_data;
static int icc_data_size;
static cmsHPROFILE profile;
static GfxLCMSProfilePtr profile;
#endif
struct AntialiasOption
......@@ -413,7 +413,7 @@ static void writePageImage(GooString *filename)
cmsUInt8Number profileID[17];
profileID[16] = '\0';
cmsGetHeaderProfileID(profile,profileID);
cmsGetHeaderProfileID(profile.get(),profileID);
static_cast<PNGWriter*>(writer)->setICCProfile(reinterpret_cast<char *>(profileID), icc_data, icc_data_size);
} else {
static_cast<PNGWriter*>(writer)->setSRGBProfile();
......@@ -1128,13 +1128,13 @@ int main(int argc, char *argv[]) {
exit(4);
}
fclose(file);
profile = cmsOpenProfileFromMem(icc_data, icc_data_size);
profile = make_GfxLCMSProfilePtr(cmsOpenProfileFromMem(icc_data, icc_data_size));
if (!profile) {
fprintf(stderr, "Error: lcms error opening profile\n");
exit(4);
}
} else {
profile = cmsCreate_sRGBProfile();
profile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
}
GfxColorSpace::setDisplayProfile(profile);
#endif
......@@ -1286,7 +1286,6 @@ int main(int argc, char *argv[]) {
delete userPW;
#ifdef USE_CMS
cmsCloseProfile(profile);
if (icc_data)
gfree(icc_data);
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment