KoColor.cpp 7.19 KB
Newer Older
1 2
/*
 *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
Thomas Zander's avatar
Thomas Zander committed
3
 *  Copyright (C) 2007 Thomas Zander <zander@kde.org>
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7 8
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
9
 *
10 11 12
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16 17 18 19
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/
20
#include <QColor>
Thomas Zander's avatar
Thomas Zander committed
21

22 23
#include <QDomDocument>

24
#include "kdebug.h"
25
#include "KoColor.h"
26 27
#include "KoColorProfile.h"
#include "KoColorSpace.h"
28
#include "KoColorSpaceRegistry.h"
29

30 31


Thomas Zander's avatar
Thomas Zander committed
32 33 34
class KoColor::Private {
public:
    Private() : data(0), colorSpace(0) {}
35

Thomas Zander's avatar
Thomas Zander committed
36
    ~Private() {
37 38
        if ( data )
            delete [] data;
Thomas Zander's avatar
Thomas Zander committed
39
    }
40

Thomas Zander's avatar
Thomas Zander committed
41
    quint8 * data;
42
    const KoColorSpace * colorSpace;
Thomas Zander's avatar
Thomas Zander committed
43 44
};

45
KoColor::KoColor()
Thomas Zander's avatar
Thomas Zander committed
46
    : d(new Private())
47
{
Thomas Zander's avatar
Thomas Zander committed
48 49 50 51
    d->colorSpace = KoColorSpaceRegistry::instance()->colorSpace("LABA",0);
    d->data = new quint8[d->colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
    d->colorSpace->setAlpha(d->data, OPACITY_OPAQUE, 1);
52
}
53

54
KoColor::KoColor(const KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
55
    : d(new Private())
56
{
Thomas Zander's avatar
Thomas Zander committed
57 58 59
    d->colorSpace = colorSpace;
    d->data = new quint8[d->colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
60 61
}

62 63 64

KoColor::~KoColor()
{
Thomas Zander's avatar
Thomas Zander committed
65
    delete d;
66 67
}

68
KoColor::KoColor(const QColor & color, const KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
69
    : d(new Private())
70
{
Thomas Zander's avatar
Thomas Zander committed
71
    d->colorSpace = colorSpace;
72 73 74
    Q_ASSERT(color.isValid());
    Q_ASSERT(colorSpace);

Thomas Zander's avatar
Thomas Zander committed
75 76 77 78
    d->data = new quint8[colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());

    d->colorSpace->fromQColor(color, OPACITY_OPAQUE, d->data);
79 80 81
}


82
KoColor::KoColor(const QColor & color, quint8 alpha, const KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
83
    : d(new Private())
84
{
Thomas Zander's avatar
Thomas Zander committed
85
    d->colorSpace = colorSpace;
86 87
    Q_ASSERT(color.isValid());
    Q_ASSERT(colorSpace);
Thomas Zander's avatar
Thomas Zander committed
88 89
    d->data = new quint8[colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
90

Thomas Zander's avatar
Thomas Zander committed
91
    d->colorSpace->fromQColor(color, alpha, d->data);
92 93
}

94
KoColor::KoColor(const quint8 * data, const KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
95
    : d(new Private())
96
{
Thomas Zander's avatar
Thomas Zander committed
97 98 99 100
    d->colorSpace = colorSpace;
    d->data = new quint8[colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
    memmove(d->data, data, colorSpace->pixelSize());
101 102 103
}


104
KoColor::KoColor(const KoColor &src, const KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
105
    : d(new Private())
106
{
Thomas Zander's avatar
Thomas Zander committed
107 108 109
    d->colorSpace = colorSpace;
    d->data = new quint8[colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
110

Thomas Zander's avatar
Thomas Zander committed
111
    src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace, 1);
112 113
}

114
KoColor::KoColor(const KoColor & rhs)
Thomas Zander's avatar
Thomas Zander committed
115
    : d(new Private())
116
{
Thomas Zander's avatar
Thomas Zander committed
117 118
    d->colorSpace = rhs.colorSpace();
    if(d->colorSpace && rhs.d->data)
119
    {
Thomas Zander's avatar
Thomas Zander committed
120 121
        d->data = new quint8[d->colorSpace->pixelSize()];
        memcpy(d->data, rhs.d->data, d->colorSpace->pixelSize());
122
    }
123 124 125 126
}

KoColor & KoColor::operator=(const KoColor & rhs)
{
127 128
    if (this == &rhs) return *this;

Thomas Zander's avatar
Thomas Zander committed
129 130 131
    delete [] d->data;
    d->data = 0;
    d->colorSpace = rhs.colorSpace();
132

Thomas Zander's avatar
Thomas Zander committed
133 134 135
    if (rhs.d->colorSpace && rhs.d->data) {
        d->data = new quint8[d->colorSpace->pixelSize()];
        memcpy(d->data, rhs.d->data, d->colorSpace->pixelSize());
136
    }
137 138 139
    return * this;
}

140
bool KoColor::operator==(const KoColor &other) const
141 142 143 144 145
{
    if(colorSpace() != other.colorSpace()) return false;
    return memcmp(d->data, other.d->data, d->colorSpace->pixelSize()) == 0;
}

146
void KoColor::convertTo(const KoColorSpace * cs)
147
{
148
    //kDebug(DBG_AREA_CMS) <<"Our colormodel:" << d->colorSpace->id().name()
149 150
    //      << ", new colormodel: " << cs->id().name() << "\n";

Thomas Zander's avatar
Thomas Zander committed
151
    if (d->colorSpace == cs)
152 153
        return;

Thomas Zander's avatar
Thomas Zander committed
154 155
    quint8 * data = new quint8[cs->pixelSize()];
    memset(data, 0, cs->pixelSize());
156

Thomas Zander's avatar
Thomas Zander committed
157
    d->colorSpace->convertPixelsTo(d->data, data, cs, 1);
158

Thomas Zander's avatar
Thomas Zander committed
159 160 161
    delete [] d->data;
    d->data = data;
    d->colorSpace = cs;
162 163 164
}


165
void KoColor::setColor(quint8 * data, const KoColorSpace * colorSpace)
166
{
Thomas Zander's avatar
Thomas Zander committed
167 168 169 170
    delete [] d->data;
    d->data = new quint8[colorSpace->pixelSize()];
    memcpy(d->data, data, colorSpace->pixelSize());
    d->colorSpace = colorSpace;
171 172
}

173 174 175
// To save the user the trouble of doing color->colorSpace()->toQColor(color->data(), &c, &a, profile
void KoColor::toQColor(QColor *c) const
{
Thomas Zander's avatar
Thomas Zander committed
176 177
    if (d->colorSpace && d->data) {
        d->colorSpace->toQColor(d->data, c);
178
    }
179 180 181 182
}

void KoColor::toQColor(QColor *c, quint8 *opacity) const
{
Thomas Zander's avatar
Thomas Zander committed
183 184
    if (d->colorSpace && d->data) {
        d->colorSpace->toQColor(d->data, c, opacity);
185
    }
186 187 188 189 190 191 192 193
}

QColor KoColor::toQColor() const
{
    QColor c;
    toQColor(&c);
    return c;
}
194

195 196
void KoColor::fromQColor(const QColor& c) const
{
Thomas Zander's avatar
Thomas Zander committed
197 198
    if (d->colorSpace && d->data) {
        d->colorSpace->fromQColor(c, d->data);
199 200 201 202 203
    }
}

void KoColor::fromQColor(const QColor& c, quint8 opacity) const
{
Thomas Zander's avatar
Thomas Zander committed
204 205
    if (d->colorSpace && d->data) {
        d->colorSpace->fromQColor(c, opacity, d->data);
206 207 208
    }
}

Thomas Zander's avatar
Thomas Zander committed
209
#ifndef NDEBUG
210 211
void KoColor::dump() const
{
212
    //kDebug(DBG_AREA_CMS) <<"KoColor (" << this <<")," << d->colorSpace->id().name() <<"";
Adrian Page's avatar
q3--  
Adrian Page committed
213
    QList<KoChannelInfo *> channels = d->colorSpace->channels();
214

Adrian Page's avatar
q3--  
Adrian Page committed
215 216
    QList<KoChannelInfo *>::const_iterator begin = channels.begin();
    QList<KoChannelInfo *>::const_iterator end = channels.end();
217

Adrian Page's avatar
q3--  
Adrian Page committed
218
    for (QList<KoChannelInfo *>::const_iterator it = begin; it != end; ++it)
219 220 221 222 223
    {
        KoChannelInfo * ch = (*it);
        // XXX: setNum always takes a byte.
        if (ch->size() == sizeof(quint8)) {
            // Byte
224
            //kDebug(DBG_AREA_CMS) <<"Channel (byte):" << ch->name() <<":" << QString().setNum(d->data[ch->pos()]) <<"";
225 226 227
        }
        else if (ch->size() == sizeof(quint16)) {
            // Short (may also by an nvidia half)
228
            //kDebug(DBG_AREA_CMS) <<"Channel (short):" << ch->name() <<":" << QString().setNum(*((const quint16 *)(d->data+ch->pos())))  <<"";
229 230 231
        }
        else if (ch->size() == sizeof(quint32)) {
            // Integer (may also be float... Find out how to distinguish these!)
232
            //kDebug(DBG_AREA_CMS) <<"Channel (int):" << ch->name() <<":" << QString().setNum(*((const quint32 *)(d->data+ch->pos())))  <<"";
233 234 235
        }
    }
}
Thomas Zander's avatar
Thomas Zander committed
236
#endif
237 238 239

void KoColor::fromKoColor(const KoColor& src)
{
Thomas Zander's avatar
Thomas Zander committed
240
    src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace(), 1);
241
}
Cyrille Berger's avatar
Cyrille Berger committed
242

243
const KoColorProfile *  KoColor::profile() const
Cyrille Berger's avatar
Cyrille Berger committed
244
{
Thomas Zander's avatar
Thomas Zander committed
245 246 247
    return d->colorSpace->profile();
}

Thomas Zander's avatar
Thomas Zander committed
248 249 250 251 252
quint8 * KoColor::data() {
    return d->data;
}

const quint8 * KoColor::data() const {
Thomas Zander's avatar
Thomas Zander committed
253
    return d->data;
Cyrille Berger's avatar
Cyrille Berger committed
254
}
Thomas Zander's avatar
Thomas Zander committed
255

256
const KoColorSpace * KoColor::colorSpace() const {
Thomas Zander's avatar
Thomas Zander committed
257 258 259
    return d->colorSpace;
}

260 261 262 263 264 265 266 267 268
void KoColor::toXML(QDomDocument& doc, QDomElement& colorElt) const
{
    d->colorSpace->colorToXML( d->data, doc, colorElt);
}

KoColor KoColor::fromXML(const QDomElement& elt, QString bitDepthId, QHash<QString, QString> aliases)
{
    return KoColor();
}