Commit 066b9b80 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Fix memory leaks

svn path=/trunk/koffice/; revision=1036173
parent b55139f7
......@@ -65,7 +65,6 @@ struct KoColorConversionCache::Private {
KoColorConversionCache::KoColorConversionCache() : d(new Private)
{
}
KoColorConversionCache::~KoColorConversionCache()
......
......@@ -55,10 +55,7 @@ KoColorConversionSystem::KoColorConversionSystem() : d(new Private)
KoColorConversionSystem::~KoColorConversionSystem()
{
qDeleteAll(d->graph);
foreach(Vertex* vertex, d->vertexes)
{
delete vertex;
}
qDeleteAll(d->vertexes);
delete d;
}
......
......@@ -17,8 +17,21 @@
* Boston, MA 02110-1301, USA.
*/
#include <QList>
struct KoColorConversionSystem::Node {
Node() : isIcc(false), isHdr(false), isInitialized(false), referenceDepth(0), isGray(false), crossingCost(1), colorSpaceFactory(0), isEngine(false),engine(0) {}
Node()
: isIcc(false)
, isHdr(false)
, isInitialized(false)
, referenceDepth(0)
, isGray(false)
, crossingCost(1)
, colorSpaceFactory(0)
, isEngine(false)
, engine(0) {}
void init( const KoColorSpaceFactory* _colorSpaceFactory)
{
dbgPigment << "Initialise " << modelId << " " << depthId << " " << profileName;
......@@ -32,9 +45,10 @@ struct KoColorConversionSystem::Node {
colorSpaceFactory = _colorSpaceFactory;
referenceDepth = _colorSpaceFactory->referenceDepth();
isGray = ( _colorSpaceFactory->colorModelId() == GrayAColorModelID
or _colorSpaceFactory->colorModelId() == GrayColorModelID );
or _colorSpaceFactory->colorModelId() == GrayColorModelID );
}
}
void init( const KoColorSpaceEngine* _engine)
{
Q_ASSERT(not isInitialized);
......@@ -42,9 +56,11 @@ struct KoColorConversionSystem::Node {
isInitialized = true;
engine = _engine;
}
QString id() const {
return modelId + " " + depthId + " " + profileName;
}
QString modelId;
QString depthId;
QString profileName;
......@@ -61,32 +77,47 @@ struct KoColorConversionSystem::Node {
};
struct KoColorConversionSystem::Vertex {
Vertex(Node* _srcNode, Node* _dstNode) : srcNode(_srcNode), dstNode(_dstNode), factoryFromSrc(0), factoryFromDst(0)
Vertex(Node* _srcNode, Node* _dstNode)
: srcNode(_srcNode)
, dstNode(_dstNode)
, factoryFromSrc(0)
, factoryFromDst(0)
{
}
~Vertex()
{
delete factoryFromSrc;
delete factoryFromDst;
if (factoryFromSrc == factoryFromDst) {
delete factoryFromSrc;
}
else {
delete factoryFromSrc;
delete factoryFromDst;
}
}
void setFactoryFromSrc(KoColorConversionTransformationFactory* factory)
{
factoryFromSrc = factory;
initParameter(factoryFromSrc);
}
void setFactoryFromDst(KoColorConversionTransformationFactory* factory)
{
factoryFromDst = factory;
if( not factoryFromSrc) initParameter(factoryFromDst);
if (!factoryFromSrc) initParameter(factoryFromDst);
}
void initParameter(KoColorConversionTransformationFactory* transfo)
{
conserveColorInformation = transfo->conserveColorInformation();
conserveDynamicRange = transfo->conserveDynamicRange();
}
KoColorConversionTransformationFactory* factory()
{
if(factoryFromSrc) return factoryFromSrc;
if (factoryFromSrc) return factoryFromSrc;
return factoryFromDst;
}
......@@ -95,39 +126,58 @@ struct KoColorConversionSystem::Vertex {
bool conserveColorInformation;
bool conserveDynamicRange;
private:
KoColorConversionTransformationFactory* factoryFromSrc; // Factory provided by the destination node
KoColorConversionTransformationFactory* factoryFromDst; // Factory provided by the destination node
private:
KoColorConversionTransformationFactory* factoryFromSrc; // Factory provided by the destination node
KoColorConversionTransformationFactory* factoryFromDst; // Factory provided by the destination node
};
struct KoColorConversionSystem::NodeKey {
NodeKey(QString _modelId, QString _depthId, QString _profileName) : modelId(_modelId), depthId(_depthId), profileName(_profileName)
NodeKey(QString _modelId, QString _depthId, QString _profileName)
: modelId(_modelId)
, depthId(_depthId)
, profileName(_profileName)
{}
bool operator==(const KoColorConversionSystem::NodeKey& rhs) const
{
return modelId == rhs.modelId and depthId == rhs.depthId and profileName == rhs.profileName;
}
QString modelId;
QString depthId;
QString profileName;
};
struct KoColorConversionSystem::Path {
Path() : respectColorCorrectness(true), referenceDepth(0), keepDynamicRange(true), isGood(false), cost(0)
Path()
: respectColorCorrectness(true)
, referenceDepth(0)
, keepDynamicRange(true)
, isGood(false)
, cost(0)
{}
Node* startNode() {
return (vertexes.first())->srcNode;
}
const Node* startNode() const {
return (vertexes.first())->srcNode;
}
Node* endNode() {
return (vertexes.last())->dstNode;
}
const Node* endNode() const {
return (vertexes.last())->dstNode;
}
void appendVertex(Vertex* v) {
if(vertexes.empty())
{
......@@ -139,6 +189,7 @@ struct KoColorConversionSystem::Path {
referenceDepth = qMin( referenceDepth, v->dstNode->referenceDepth);
cost += v->dstNode->crossingCost;
}
// Compress path to hide the Engine node and correctly select the factory
typedef QPair<Node*, const KoColorConversionTransformationAbstractFactory* > node2factory;
QList< node2factory > compressedPath() const
......@@ -154,17 +205,19 @@ struct KoColorConversionSystem::Path {
previousFactory = n->engine;
} else {
nodes.push_back(
node2factory( n,
previousFactory ? previousFactory : vertex->factory() ) );
node2factory( n,
previousFactory ? previousFactory : vertex->factory() ) );
previousFactory = 0;
}
}
return nodes;
}
int length() const
{
return vertexes.size();
}
bool contains(Node* n) const
{
foreach(Vertex* v, vertexes)
......@@ -176,6 +229,7 @@ struct KoColorConversionSystem::Path {
}
return false;
}
QList<Vertex*> vertexes;
bool respectColorCorrectness;
int referenceDepth;
......@@ -196,20 +250,21 @@ uint qHash(const KoColorConversionSystem::NodeKey &key)
}
struct KoColorConversionSystem::Private {
QHash<NodeKey, Node*> graph;
QList<Vertex*> vertexes;
Node* alphaNode;
};
#define CHECK_ONE_AND_NOT_THE_OTHER(name) \
if(path1-> name and not path2-> name) \
{ \
return true; \
} \
if(not path1-> name and path2-> name) \
{ \
return false; \
}
if(path1-> name and not path2-> name) \
{ \
return true; \
} \
if(not path1-> name and path2-> name) \
{ \
return false; \
}
struct PathQualityChecker {
PathQualityChecker(int _referenceDepth, bool _ignoreHdr, bool _ignoreColorCorrectness) : referenceDepth(_referenceDepth), ignoreHdr(_ignoreHdr), ignoreColorCorrectness(_ignoreColorCorrectness) {}
......@@ -217,23 +272,23 @@ struct PathQualityChecker {
inline bool isGoodPath(KoColorConversionSystem::Path* path)
{
return ( path->respectColorCorrectness or ignoreColorCorrectness ) and
( path->referenceDepth >= referenceDepth) and
( path->keepDynamicRange or ignoreHdr );
( path->referenceDepth >= referenceDepth) and
( path->keepDynamicRange or ignoreHdr );
}
/**
* Compare two pathes.
*/
inline bool lessWorseThan(KoColorConversionSystem::Path* path1, KoColorConversionSystem::Path* path2)
{
// There is no point in comparing two pathes which doesn't start from the same node or doesn't end at the same node
// There is no point in comparing two pathes which doesn't start from the same node or doesn't end at the same node
if(not ignoreHdr)
{
CHECK_ONE_AND_NOT_THE_OTHER(keepDynamicRange)
}
}
if(not ignoreColorCorrectness)
{
CHECK_ONE_AND_NOT_THE_OTHER(respectColorCorrectness)
}
}
if( path1->referenceDepth == path2->referenceDepth)
{
return path1->cost < path2->cost; // if they have the same cost, well anyway you have to choose one, and there is no point in keeping one and not the other
......
......@@ -66,9 +66,11 @@ KoColorSpace::~KoColorSpace()
{
delete channel;
}
KoColorConversionCache* cache = KoColorSpaceRegistry::instance()->colorConversionCache();
if (cache) {
cache->colorSpaceIsDestroyed(this);
if (d->ownedByRegistry) {
KoColorConversionCache* cache = KoColorSpaceRegistry::instance()->colorConversionCache();
if (cache) {
cache->colorSpaceIsDestroyed(this);
}
}
delete d->mixColorsOp;
delete d->convolutionOp;
......
......@@ -18,7 +18,7 @@
*/
#include <KoColorSpaceEngine.h>
#include <kglobal.h>
#include <QString>
struct KoColorSpaceEngine::Private {
......@@ -47,15 +47,8 @@ const QString& KoColorSpaceEngine::name() const
return d->name;
}
struct KoColorSpaceEngineRegistry::Private {
static KoColorSpaceEngineRegistry* s_instance;
};
KoColorSpaceEngineRegistry* KoColorSpaceEngineRegistry::Private::s_instance = 0;
KoColorSpaceEngineRegistry::KoColorSpaceEngineRegistry() : d(new Private)
KoColorSpaceEngineRegistry::KoColorSpaceEngineRegistry()
{
}
KoColorSpaceEngineRegistry::~KoColorSpaceEngineRegistry()
......@@ -64,9 +57,6 @@ KoColorSpaceEngineRegistry::~KoColorSpaceEngineRegistry()
KoColorSpaceEngineRegistry* KoColorSpaceEngineRegistry::instance()
{
if( not Private::s_instance )
{
Private::s_instance = new KoColorSpaceEngineRegistry;
}
return Private::s_instance;
K_GLOBAL_STATIC(KoColorSpaceEngineRegistry, s_instance);
return s_instance;
}
......@@ -52,9 +52,6 @@ class PIGMENTCMS_EXPORT KoColorSpaceEngineRegistry : public KoGenericRegistry< K
KoColorSpaceEngineRegistry();
~KoColorSpaceEngineRegistry();
static KoColorSpaceEngineRegistry* instance();
private:
struct Private;
Private* const d;
};
#endif
......@@ -31,6 +31,7 @@
#include <klocale.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <kglobal.h>
#include "KoPluginLoader.h"
......@@ -49,26 +50,23 @@
#include "KoColorSpace_p.h"
struct KoColorSpaceRegistry::Private {
QHash<QString, KoColorProfile * > profileMap;
QHash<QString, const KoColorSpace * > csMap;
const KoColorSpace *alphaCs;
KoColorConversionSystem *colorConversionSystem;
KoColorConversionCache* colorConversionCache;
static KoColorSpaceRegistry *singleton;
const KoColorSpace *rgbU8sRGB;
const KoColorSpace *lab16sLAB;
};
KoColorSpaceRegistry *KoColorSpaceRegistry::Private::singleton = 0;
KoColorSpaceRegistry* KoColorSpaceRegistry::instance()
{
if (KoColorSpaceRegistry::Private::singleton == 0)
{
KoColorSpaceRegistry::Private::singleton = new KoColorSpaceRegistry();
KoColorSpaceRegistry::Private::singleton->init();
K_GLOBAL_STATIC(KoColorSpaceRegistry, s_instance);
if (!s_instance.exists()) {
s_instance->init();
}
return KoColorSpaceRegistry::Private::singleton;
return s_instance;
}
......@@ -115,16 +113,16 @@ void KoColorSpaceRegistry::init()
addProfile(labProfile);
add(new KoLabColorSpaceFactory());
KoHistogramProducerFactoryRegistry::instance()->add(
new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer>
(KoID("LABAHISTO", i18n("L*a*b* Histogram")), KoLabColorSpace::colorSpaceId()));
new KoBasicHistogramProducerFactory<KoBasicU16HistogramProducer>
(KoID("LABAHISTO", i18n("L*a*b* Histogram")), KoLabColorSpace::colorSpaceId()));
KoColorProfile *rgbProfile = KoLcmsColorProfileContainer::createFromLcmsProfile(cmsCreate_sRGBProfile());
addProfile(rgbProfile);
add(new KoRgbU16ColorSpaceFactory());
add(new KoRgbU8ColorSpaceFactory());
KoHistogramProducerFactoryRegistry::instance()->add(
new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer>
(KoID("RGB8HISTO", i18n("RGB8 Histogram")), KoRgbU8ColorSpace::colorSpaceId()) );
new KoBasicHistogramProducerFactory<KoBasicU8HistogramProducer>
(KoID("RGB8HISTO", i18n("RGB8 Histogram")), KoRgbU8ColorSpace::colorSpaceId()) );
......@@ -162,6 +160,8 @@ KoColorSpaceRegistry::KoColorSpaceRegistry() : d(new Private())
KoColorSpaceRegistry::~KoColorSpaceRegistry()
{
d->alphaCs->d->ownedByRegistry = false;
delete d->colorConversionSystem;
foreach( KoColorProfile* profile, d->profileMap) {
delete profile;
......@@ -175,7 +175,7 @@ KoColorSpaceRegistry::~KoColorSpaceRegistry()
// deleting colorspaces calls a function in the cache
delete d->colorConversionCache;
d->colorConversionCache = 0;
d->alphaCs->d->ownedByRegistry = false;
delete d->alphaCs;
// Do not explicitly delete d->rgbU8sRGB and d->lab16sLAB, since they are contained in the d->csMap
delete d;
......@@ -224,7 +224,7 @@ QList<const KoColorProfile *> KoColorSpaceRegistry::profilesFor(const KoColorSp
KoColorProfile * profile = it.value();
if(csf->profileIsCompatible(profile))
{
// if (profile->colorSpaceSignature() == csf->colorSpaceSignature()) {
// if (profile->colorSpaceSignature() == csf->colorSpaceSignature()) {
profiles.push_back(profile);
}
}
......@@ -251,15 +251,15 @@ QList<const KoColorProfile *> KoColorSpaceRegistry::profilesFor(const KoID& id)
void KoColorSpaceRegistry::addProfile(KoColorProfile *p)
{
if (p->valid()) {
d->profileMap[p->name()] = p;
d->colorConversionSystem->insertColorProfile( p );
}
if (p->valid()) {
d->profileMap[p->name()] = p;
d->colorConversionSystem->insertColorProfile( p );
}
}
void KoColorSpaceRegistry::addProfile(const KoColorProfile* profile)
{
addProfile( profile->clone() );
addProfile( profile->clone() );
}
bool KoColorSpaceRegistry::isCached(const QString & csId, const QString & profileName) const
......@@ -269,7 +269,7 @@ bool KoColorSpaceRegistry::isCached(const QString & csId, const QString & profil
QString KoColorSpaceRegistry::idsToCacheName(const QString & csId, const QString & profileName) const
{
return csId + "<comb>" + profileName;
return csId + "<comb>" + profileName;
}
const KoColorSpace * KoColorSpaceRegistry::colorSpace(const QString &csID, const QString &pName)
......@@ -342,7 +342,7 @@ const KoColorSpace * KoColorSpaceRegistry::colorSpace(const QString &csID, const
if( not d->profileMap.contains( profile->name() ) )
{
addProfile( profile );
addProfile( profile );
}
if(!cs)
......@@ -373,7 +373,7 @@ const KoColorSpace * KoColorSpaceRegistry::colorSpace(const QString &csID, const
const KoColorSpace * KoColorSpaceRegistry::alpha8()
{
return d->alphaCs;
return d->alphaCs;
}
const KoColorSpace * KoColorSpaceRegistry::rgb8(const QString &profileName)
......@@ -448,8 +448,8 @@ QList<KoID> KoColorSpaceRegistry::colorModelsList(ColorSpaceListVisibility optio
foreach(KoColorSpaceFactory* factory, factories)
{
if(!ids.contains(factory->colorModelId())
&& ( option == AllColorSpaces || factory->userVisible() ) )
{
&& ( option == AllColorSpaces || factory->userVisible() ) )
{
ids << factory->colorModelId();
}
}
......@@ -468,9 +468,9 @@ QList<KoID> KoColorSpaceRegistry::colorDepthList(const QString & colorModelId, C
foreach(KoColorSpaceFactory* factory, factories)
{
if(!ids.contains(KoID(factory->colorDepthId()))
&& factory->colorModelId().id() == colorModelId
&& ( option == AllColorSpaces || factory->userVisible() ))
{
&& factory->colorModelId().id() == colorModelId
&& ( option == AllColorSpaces || factory->userVisible() ))
{
ids << factory->colorDepthId();
}
}
......@@ -508,12 +508,12 @@ KoColorConversionCache* KoColorSpaceRegistry::colorConversionCache() const
const KoColorSpace* KoColorSpaceRegistry::permanentColorspace( const KoColorSpace* _colorSpace )
{
if(_colorSpace->d->ownedByRegistry) return _colorSpace;
else if(*_colorSpace == *d->alphaCs) return d->alphaCs;
else {
const KoColorSpace* cs = colorSpace(_colorSpace->id(), _colorSpace->profile());
Q_ASSERT(cs);
Q_ASSERT(*cs == *_colorSpace);
return cs;
}
if(_colorSpace->d->ownedByRegistry) return _colorSpace;
else if(*_colorSpace == *d->alphaCs) return d->alphaCs;
else {
const KoColorSpace* cs = colorSpace(_colorSpace->id(), _colorSpace->profile());
Q_ASSERT(cs);
Q_ASSERT(*cs == *_colorSpace);
return cs;
}
}
......@@ -29,7 +29,7 @@ struct KoColorSpace::Private {
QString id;
quint32 idNumber;
QString name;
QHash<QString, KoCompositeOp *> compositeOps;
QHash<QString, KoCompositeOp*> compositeOps;
QList<KoChannelInfo *> channels;
KoMixColorsOp* mixColorsOp;
KoConvolutionOp* convolutionOp;
......
......@@ -18,6 +18,8 @@
#include <QList>
#include <kglobal.h>
#include <KoID.h>
#include "KoHistogramProducer.h"
......@@ -25,22 +27,16 @@
#include "KoColorSpace.h"
KoHistogramProducerFactoryRegistry* KoHistogramProducerFactoryRegistry::m_singleton = 0;
KoHistogramProducerFactoryRegistry::KoHistogramProducerFactoryRegistry() {
Q_ASSERT(KoHistogramProducerFactoryRegistry::m_singleton == 0);
}
KoHistogramProducerFactoryRegistry::~KoHistogramProducerFactoryRegistry() {
}
KoHistogramProducerFactoryRegistry* KoHistogramProducerFactoryRegistry::instance() {
if(KoHistogramProducerFactoryRegistry::m_singleton == 0) {
KoHistogramProducerFactoryRegistry::m_singleton
= new KoHistogramProducerFactoryRegistry();
m_singleton->add( new KoGenericLabHistogramProducerFactory() );
}
return KoHistogramProducerFactoryRegistry::m_singleton;
K_GLOBAL_STATIC(KoHistogramProducerFactoryRegistry, s_instance);
return s_instance;
}
QList<KoID> KoHistogramProducerFactoryRegistry::listKeysCompatibleWith(
......
......@@ -123,8 +123,6 @@ private:
KoHistogramProducerFactoryRegistry();
KoHistogramProducerFactoryRegistry(const KoHistogramProducerFactoryRegistry&);
KoHistogramProducerFactoryRegistry operator=(const KoHistogramProducerFactoryRegistry&);
static KoHistogramProducerFactoryRegistry* m_singleton;
};
#endif // _KO_HISTOGRAM_PRODUCER
......@@ -24,43 +24,42 @@
#include <iso646.h>
#endif
#include <kglobal.h>
struct KoUniqueNumberForIdServer::Private
{
Private() : currentNumber(0) { }
QHash<QString, quint32 > id2Number;
quint32 currentNumber;
static KoUniqueNumberForIdServer* s_instance;
};
Private()
: currentNumber(0)
{}
KoUniqueNumberForIdServer* KoUniqueNumberForIdServer::Private::s_instance = 0;
QHash<QString, quint32 > id2Number;
quint32 currentNumber;
};
KoUniqueNumberForIdServer::KoUniqueNumberForIdServer() : d(new Private)
KoUniqueNumberForIdServer::KoUniqueNumberForIdServer()
: d(new Private)
{
}
KoUniqueNumberForIdServer::~KoUniqueNumberForIdServer()
{
delete d;
delete d;
}
KoUniqueNumberForIdServer* KoUniqueNumberForIdServer::instance()
{
if( not KoUniqueNumberForIdServer::Private::s_instance )
{
KoUniqueNumberForIdServer::Private::s_instance = new KoUniqueNumberForIdServer;
}
return KoUniqueNumberForIdServer::Private::s_instance;
K_GLOBAL_STATIC(KoUniqueNumberForIdServer, s_instance);
return s_instance;
}
quint32 KoUniqueNumberForIdServer::numberForId( const QString& _id )
{
QHash<QString, quint32>::iterator it = d->id2Number.find( _id );
if( it != d->id2Number.end() )
{
return it.value();
}
quint32 number = ++d->currentNumber;
d->id2Number[ _id ] = number;
return number;
QHash<QString, quint32>::iterator it = d->id2Number.find( _id );
if( it != d->id2Number.end() )
{
return it.value();
}
quint32 number = ++d->currentNumber;
d->id2Number[ _id ] = number;
return number;
}
......@@ -9,6 +9,12 @@
#include "KoRgbU16ColorSpace.h"
#include "KoLabColorSpace.h"
void TestKoColorSpaceRegistry::testConstruction()
{
KoColorSpaceRegistry* instance = KoColorSpaceRegistry::instance();
Q_ASSERT(instance);
}
void TestKoColorSpaceRegistry::testRgbU8()
{
QString colorSpaceId = KoColorSpaceRegistry::instance()->colorSpaceId(RGBAColorModelID,
......
......@@ -7,6 +7,7 @@ class TestKoColorSpaceRegistry : public QObject
{
Q_OBJECT
private slots:
void testConstruction();
void testRgbU8();
void testRgbU16();
void testLab();
......
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