KoColor.cpp 6.64 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
#include "kdebug.h"
23
#include "KoColor.h"
24 25
#include "KoColorProfile.h"
#include "KoColorSpace.h"
26
#include "KoColorSpaceRegistry.h"
27

Thomas Zander's avatar
Thomas Zander committed
28 29 30
class KoColor::Private {
public:
    Private() : data(0), colorSpace(0) {}
31

Thomas Zander's avatar
Thomas Zander committed
32
    ~Private() {
33 34
        if ( data )
            delete [] data;
Thomas Zander's avatar
Thomas Zander committed
35
    }
36

Thomas Zander's avatar
Thomas Zander committed
37 38 39 40
    quint8 * data;
    KoColorSpace * colorSpace;
};

41
KoColor::KoColor()
Thomas Zander's avatar
Thomas Zander committed
42
    : d(new Private())
43
{
Thomas Zander's avatar
Thomas Zander committed
44 45 46 47
    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);
48
}
49

50
KoColor::KoColor(KoColorSpace * colorSpace)
Thomas Zander's avatar
Thomas Zander committed
51
    : d(new Private())
52
{
Thomas Zander's avatar
Thomas Zander committed
53 54 55
    d->colorSpace = colorSpace;
    d->data = new quint8[d->colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());
56 57
}

58 59 60

KoColor::~KoColor()
{
Thomas Zander's avatar
Thomas Zander committed
61
    delete d;
62 63
}

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

Thomas Zander's avatar
Thomas Zander committed
71 72 73 74
    d->data = new quint8[colorSpace->pixelSize()];
    memset(d->data, 0, d->colorSpace->pixelSize());

    d->colorSpace->fromQColor(color, OPACITY_OPAQUE, d->data);
75 76 77 78
}


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

Thomas Zander's avatar
Thomas Zander committed
87
    d->colorSpace->fromQColor(color, alpha, d->data);
88 89 90
}

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


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

Thomas Zander's avatar
Thomas Zander committed
107
    src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace, 1);
108 109
}

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

KoColor & KoColor::operator=(const KoColor & rhs)
{
123 124
    if (this == &rhs) return *this;

Thomas Zander's avatar
Thomas Zander committed
125 126 127
    delete [] d->data;
    d->data = 0;
    d->colorSpace = rhs.colorSpace();
128

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

136 137
void KoColor::convertTo(KoColorSpace * cs)
{
Thomas Zander's avatar
Thomas Zander committed
138
    //kDebug(DBG_AREA_CMS) << "Our colormodel: " << d->colorSpace->id().name()
139 140
    //      << ", new colormodel: " << cs->id().name() << "\n";

Thomas Zander's avatar
Thomas Zander committed
141
    if (d->colorSpace == cs)
142 143
        return;

Thomas Zander's avatar
Thomas Zander committed
144 145
    quint8 * data = new quint8[cs->pixelSize()];
    memset(data, 0, cs->pixelSize());
146

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

Thomas Zander's avatar
Thomas Zander committed
149 150 151
    delete [] d->data;
    d->data = data;
    d->colorSpace = cs;
152 153 154 155 156
}


void KoColor::setColor(quint8 * data, KoColorSpace * colorSpace)
{
Thomas Zander's avatar
Thomas Zander committed
157 158 159 160
    delete [] d->data;
    d->data = new quint8[colorSpace->pixelSize()];
    memcpy(d->data, data, colorSpace->pixelSize());
    d->colorSpace = colorSpace;
161 162
}

163 164 165
// 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
166 167
    if (d->colorSpace && d->data) {
        d->colorSpace->toQColor(d->data, c);
168
    }
169 170 171 172
}

void KoColor::toQColor(QColor *c, quint8 *opacity) const
{
Thomas Zander's avatar
Thomas Zander committed
173 174
    if (d->colorSpace && d->data) {
        d->colorSpace->toQColor(d->data, c, opacity);
175
    }
176 177 178 179 180 181 182 183
}

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

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

void KoColor::fromQColor(const QColor& c, quint8 opacity) const
{
Thomas Zander's avatar
Thomas Zander committed
194 195
    if (d->colorSpace && d->data) {
        d->colorSpace->fromQColor(c, opacity, d->data);
196 197 198
    }
}

Thomas Zander's avatar
Thomas Zander committed
199
#ifndef NDEBUG
200 201
void KoColor::dump() const
{
Thomas Zander's avatar
Thomas Zander committed
202
    //kDebug(DBG_AREA_CMS) << "KoColor (" << this << "), " << d->colorSpace->id().name() << "\n";
Adrian Page's avatar
q3--  
Adrian Page committed
203
    QList<KoChannelInfo *> channels = d->colorSpace->channels();
204

Adrian Page's avatar
q3--  
Adrian Page committed
205 206
    QList<KoChannelInfo *>::const_iterator begin = channels.begin();
    QList<KoChannelInfo *>::const_iterator end = channels.end();
207

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

void KoColor::fromKoColor(const KoColor& src)
{
Thomas Zander's avatar
Thomas Zander committed
230
    src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace(), 1);
231
}
Cyrille Berger's avatar
Cyrille Berger committed
232 233 234

KoColorProfile *  KoColor::profile() const
{
Thomas Zander's avatar
Thomas Zander committed
235 236 237 238 239
    return d->colorSpace->profile();
}

quint8 * KoColor::data() const {
    return d->data;
Cyrille Berger's avatar
Cyrille Berger committed
240
}
Thomas Zander's avatar
Thomas Zander committed
241 242 243 244 245

KoColorSpace * KoColor::colorSpace() const {
    return d->colorSpace;
}