kis_gray_u16_colorspace.cc 21.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  Copyright (c) 2002 Patrick Julien  <freak@codepimps.org>
 *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <config.h>
#include <limits.h>
#include <stdlib.h>
Adrian Page's avatar
Adrian Page committed
23
#include <lcms.h>
24

25
#include <QImage>
26 27 28

#include <kdebug.h>
#include <klocale.h>
Gábor Lehel's avatar
Gábor Lehel committed
29
#include <kglobal.h>
30 31

#include "kis_gray_u16_colorspace.h"
32
#include "KoU16ColorSpaceTrait.h"
33
#include "kis_color_conversions.h"
34
#include "KoIntegerMaths.h"
35
#include "KoColorSpaceRegistry.h"
36 37

namespace {
Laurent Montel's avatar
Laurent Montel committed
38 39
    const qint32 MAX_CHANNEL_GRAY = 1;
    const qint32 MAX_CHANNEL_GRAYA = 2;
40 41
}

42
KisGrayU16ColorSpace::KisGrayU16ColorSpace(KoColorSpaceRegistry * parent, KoColorProfile *p) :
43 44 45
    KoColorSpace(KoID("GRAYA16", i18n("Grayscale (16-bit integer/channel)")), parent)
    , KoU16ColorSpaceTrait(PIXEL_ALPHA * sizeof(quint16))
    , KoLcmsColorSpaceTrait(TYPE_GRAYA_16, icSigGrayData, p)
46
{
47 48
    m_channels.push_back(new KoChannelInfo(i18n("Gray"), PIXEL_GRAY * sizeof(quint16), KoChannelInfo::COLOR, KoChannelInfo::UINT16, sizeof(quint16)));
    m_channels.push_back(new KoChannelInfo(i18n("Alpha"), PIXEL_ALPHA * sizeof(quint16), KoChannelInfo::ALPHA, KoChannelInfo::UINT16, sizeof(quint16)));
49

50
/*    LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2);
51 52
    cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma);
    cmsFreeGamma(Gamma);
53
*/
54 55 56 57 58 59 60 61

    init();
}

KisGrayU16ColorSpace::~KisGrayU16ColorSpace()
{
}

Laurent Montel's avatar
Laurent Montel committed
62
void KisGrayU16ColorSpace::mixColors(const quint8 **colors, const quint8 *weights, quint32 nColors, quint8 *dst) const
63
{
Laurent Montel's avatar
Laurent Montel committed
64
    quint32 totalGray = 0, newAlpha = 0;
65 66 67 68 69

    while (nColors--)
    {
        const Pixel *pixel = reinterpret_cast<const Pixel *>(*colors);

Laurent Montel's avatar
Laurent Montel committed
70 71
        quint32 alpha = pixel->alpha;
        quint32 alphaTimesWeight = UINT16_MULT(alpha, UINT8_TO_UINT16(*weights));
72

Adrian Page's avatar
Adrian Page committed
73
        totalGray += UINT16_MULT(pixel->gray, alphaTimesWeight);
74 75 76 77 78 79 80 81 82 83
        newAlpha += alphaTimesWeight;

        weights++;
        colors++;
    }

    Q_ASSERT(newAlpha <= U16_OPACITY_OPAQUE);

    Pixel *dstPixel = reinterpret_cast<Pixel *>(dst);

84
    dstPixel->alpha = newAlpha;
85 86 87 88 89

    if (newAlpha > 0) {
        totalGray = UINT16_DIVIDE(totalGray, newAlpha);
    }

Adrian Page's avatar
Adrian Page committed
90
    dstPixel->gray = totalGray;
91 92
}

93
void KisGrayU16ColorSpace::convolveColors(quint8** colors, qint32* kernelValues, KoChannelInfo::enumChannelFlags channelFlags, quint8 *dst,
Laurent Montel's avatar
Laurent Montel committed
94
                                          qint32 factor, qint32 offset, qint32 nColors) const
95
{
Laurent Montel's avatar
Laurent Montel committed
96
    qint32 totalGray = 0, totalAlpha = 0;
97 98 99 100 101

    while (nColors--)
    {
        const Pixel * pixel = reinterpret_cast<const Pixel *>( *colors );

Laurent Montel's avatar
Laurent Montel committed
102
        qint32 weight = *kernelValues;
103 104

        if (weight != 0) {
Adrian Page's avatar
Adrian Page committed
105
            totalGray += pixel->gray * weight;
106 107 108 109 110 111 112 113
            totalAlpha += pixel->alpha * weight;
        }
        colors++;
        kernelValues++;
    }

    Pixel * p = reinterpret_cast< Pixel *>( dst );

114
    if (channelFlags & KoChannelInfo::FLAG_COLOR) {
Adrian Page's avatar
Adrian Page committed
115
        p->gray = CLAMP( ( totalGray / factor) + offset, 0, quint16_MAX);
116
    }
117
    if (channelFlags & KoChannelInfo::FLAG_ALPHA) {
Laurent Montel's avatar
Laurent Montel committed
118
        p->alpha = CLAMP((totalAlpha/ factor) + offset, 0, quint16_MAX);
119 120 121 122
    }
}


Laurent Montel's avatar
Laurent Montel committed
123
void KisGrayU16ColorSpace::invertColor(quint8 * src, qint32 nPixels)
124
{
Laurent Montel's avatar
Laurent Montel committed
125
    quint32 psize = pixelSize();
126 127 128 129

    while (nPixels--)
    {
        Pixel * p = reinterpret_cast< Pixel *>( src );
Adrian Page's avatar
Adrian Page committed
130
        p->gray = quint16_MAX - p->gray;
131 132 133 134 135 136
        src += psize;
    }
}



Laurent Montel's avatar
Laurent Montel committed
137
quint8 KisGrayU16ColorSpace::intensity8(const quint8 * src) const
138 139
{
    const Pixel * p = reinterpret_cast<const Pixel *>( src );
Adrian Page's avatar
Adrian Page committed
140
    return UINT16_TO_UINT8(p->gray);
141 142 143
}


144
Q3ValueVector<KoChannelInfo *> KisGrayU16ColorSpace::channels() const
145 146 147 148
{
    return m_channels;
}

Laurent Montel's avatar
Laurent Montel committed
149
quint32 KisGrayU16ColorSpace::nChannels() const
150 151 152 153
{
    return MAX_CHANNEL_GRAYA;
}

Laurent Montel's avatar
Laurent Montel committed
154
quint32 KisGrayU16ColorSpace::nColorChannels() const
155 156 157 158
{
    return MAX_CHANNEL_GRAY;
}

Laurent Montel's avatar
Laurent Montel committed
159
quint32 KisGrayU16ColorSpace::pixelSize() const
160
{
Laurent Montel's avatar
Laurent Montel committed
161
    return MAX_CHANNEL_GRAYA * sizeof(quint16);
162 163
}

Laurent Montel's avatar
Laurent Montel committed
164
void KisGrayU16ColorSpace::compositeOver(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
165 166 167
{
    while (rows > 0) {

Laurent Montel's avatar
Laurent Montel committed
168 169 170 171
        const quint16 *src = reinterpret_cast<const quint16 *>(srcRowStart);
        quint16 *dst = reinterpret_cast<quint16 *>(dstRowStart);
        const quint8 *mask = maskRowStart;
        qint32 columns = numColumns;
172 173 174

        while (columns > 0) {

Laurent Montel's avatar
Laurent Montel committed
175
            quint16 srcAlpha = src[PIXEL_ALPHA];
176 177 178

            // apply the alphamask
            if (mask != 0) {
Laurent Montel's avatar
Laurent Montel committed
179
                quint8 U8_mask = *mask;
180 181 182 183 184 185 186 187 188 189 190 191 192 193

                if (U8_mask != OPACITY_OPAQUE) {
                    srcAlpha = UINT16_MULT(srcAlpha, UINT8_TO_UINT16(U8_mask));
                }
                mask++;
            }

            if (srcAlpha != U16_OPACITY_TRANSPARENT) {

                if (opacity != U16_OPACITY_OPAQUE) {
                    srcAlpha = UINT16_MULT(srcAlpha, opacity);
                }

                if (srcAlpha == U16_OPACITY_OPAQUE) {
Laurent Montel's avatar
Laurent Montel committed
194
                    memcpy(dst, src, MAX_CHANNEL_GRAYA * sizeof(quint16));
195
                } else {
Laurent Montel's avatar
Laurent Montel committed
196
                    quint16 dstAlpha = dst[PIXEL_ALPHA];
197

Laurent Montel's avatar
Laurent Montel committed
198
                    quint16 srcBlend;
199 200 201 202

                    if (dstAlpha == U16_OPACITY_OPAQUE) {
                        srcBlend = srcAlpha;
                    } else {
Laurent Montel's avatar
Laurent Montel committed
203
                        quint16 newAlpha = dstAlpha + UINT16_MULT(U16_OPACITY_OPAQUE - dstAlpha, srcAlpha);
204 205 206 207 208 209 210 211 212 213
                        dst[PIXEL_ALPHA] = newAlpha;

                        if (newAlpha != 0) {
                            srcBlend = UINT16_DIVIDE(srcAlpha, newAlpha);
                        } else {
                            srcBlend = srcAlpha;
                        }
                    }

                    if (srcBlend == U16_OPACITY_OPAQUE) {
Laurent Montel's avatar
Laurent Montel committed
214
                        memcpy(dst, src, MAX_CHANNEL_GRAY * sizeof(quint16));
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
                    } else {
                        dst[PIXEL_GRAY] = UINT16_BLEND(src[PIXEL_GRAY], dst[PIXEL_GRAY], srcBlend);
                    }
                }
            }

            columns--;
            src += MAX_CHANNEL_GRAYA;
            dst += MAX_CHANNEL_GRAYA;
        }

        rows--;
        srcRowStart += srcRowStride;
        dstRowStart += dstRowStride;
        if(maskRowStart) {
            maskRowStart += maskRowStride;
        }
    }
}

#define COMMON_COMPOSITE_OP_PROLOG() \
    while (rows > 0) { \
    \
Laurent Montel's avatar
Laurent Montel committed
238 239 240 241
        const quint16 *src = reinterpret_cast<const quint16 *>(srcRowStart); \
        quint16 *dst = reinterpret_cast<quint16 *>(dstRowStart); \
        qint32 columns = numColumns; \
        const quint8 *mask = maskRowStart; \
242 243 244
    \
        while (columns > 0) { \
    \
Laurent Montel's avatar
Laurent Montel committed
245 246
            quint16 srcAlpha = src[PIXEL_ALPHA]; \
            quint16 dstAlpha = dst[PIXEL_ALPHA]; \
247
    \
Laurent Montel's avatar
Laurent Montel committed
248
            srcAlpha = qMin(srcAlpha, dstAlpha); \
249 250
    \
            if (mask != 0) { \
Laurent Montel's avatar
Laurent Montel committed
251
                quint8 U8_mask = *mask; \
252 253 254 255 256 257 258 259 260 261 262 263 264
    \
                if (U8_mask != OPACITY_OPAQUE) { \
                    srcAlpha = UINT16_MULT(srcAlpha, UINT8_TO_UINT16(U8_mask)); \
                } \
                mask++; \
            } \
    \
            if (srcAlpha != U16_OPACITY_TRANSPARENT) { \
    \
                if (opacity != U16_OPACITY_OPAQUE) { \
                    srcAlpha = UINT16_MULT(srcAlpha, opacity); \
                } \
    \
Laurent Montel's avatar
Laurent Montel committed
265
                quint16 srcBlend; \
266 267 268 269
    \
                if (dstAlpha == U16_OPACITY_OPAQUE) { \
                    srcBlend = srcAlpha; \
                } else { \
Laurent Montel's avatar
Laurent Montel committed
270
                    quint16 newAlpha = dstAlpha + UINT16_MULT(U16_OPACITY_OPAQUE - dstAlpha, srcAlpha); \
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
                    dst[PIXEL_ALPHA] = newAlpha; \
    \
                    if (newAlpha != 0) { \
                        srcBlend = UINT16_DIVIDE(srcAlpha, newAlpha); \
                    } else { \
                        srcBlend = srcAlpha; \
                    } \
                }

#define COMMON_COMPOSITE_OP_EPILOG() \
            } \
    \
            columns--; \
            src += MAX_CHANNEL_GRAYA; \
            dst += MAX_CHANNEL_GRAYA; \
        } \
    \
        rows--; \
        srcRowStart += srcRowStride; \
        dstRowStart += dstRowStride; \
        if(maskRowStart) { \
            maskRowStart += maskRowStride; \
        } \
    }

Laurent Montel's avatar
Laurent Montel committed
296
void KisGrayU16ColorSpace::compositeMultiply(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
297 298 299 300
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
Laurent Montel's avatar
Laurent Montel committed
301 302
        quint16 srcColor = src[PIXEL_GRAY];
        quint16 dstColor = dst[PIXEL_GRAY];
303 304 305 306 307 308 309 310 311 312

        srcColor = UINT16_MULT(srcColor, dstColor);

        dst[PIXEL_GRAY] = UINT16_BLEND(srcColor, dstColor, srcBlend);

    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
313
void KisGrayU16ColorSpace::compositeDivide(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
314 315 316 317 318 319
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
320 321
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
322

Laurent Montel's avatar
Laurent Montel committed
323
            srcColor = qMin((dstColor * (UINT16_MAX + 1u) + (srcColor / 2u)) / (1u + srcColor), UINT16_MAX);
324

Laurent Montel's avatar
Laurent Montel committed
325
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
326 327 328 329 330 331 332 333

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
334
void KisGrayU16ColorSpace::compositeScreen(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
335 336 337 338 339 340
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
341 342
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
343 344 345

            srcColor = UINT16_MAX - UINT16_MULT(UINT16_MAX - dstColor, UINT16_MAX - srcColor);

Laurent Montel's avatar
Laurent Montel committed
346
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
347 348 349 350 351 352 353 354

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
355
void KisGrayU16ColorSpace::compositeOverlay(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
356 357 358 359 360 361
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
362 363
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
364 365 366

            srcColor = UINT16_MULT(dstColor, dstColor + 2u * UINT16_MULT(srcColor, UINT16_MAX - dstColor));

Laurent Montel's avatar
Laurent Montel committed
367
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
368 369 370 371 372 373 374 375

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
376
void KisGrayU16ColorSpace::compositeDodge(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
377 378 379 380 381 382
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
383 384
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
385

Laurent Montel's avatar
Laurent Montel committed
386
            srcColor = qMin((dstColor * (UINT16_MAX + 1u)) / (UINT16_MAX + 1u - srcColor), UINT16_MAX);
387

Laurent Montel's avatar
Laurent Montel committed
388
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
389 390 391 392 393 394 395 396

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
397
void KisGrayU16ColorSpace::compositeBurn(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
398 399 400 401 402 403
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
404 405
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
406

Laurent Montel's avatar
Laurent Montel committed
407
            srcColor = qMin(((UINT16_MAX - dstColor) * (UINT16_MAX + 1u)) / (srcColor + 1u), UINT16_MAX);
Adrian Page's avatar
Adrian Page committed
408
            srcColor = qBound(0u, UINT16_MAX - srcColor, UINT16_MAX);
409

Laurent Montel's avatar
Laurent Montel committed
410
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
411 412 413 414 415 416 417 418

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
419
void KisGrayU16ColorSpace::compositeDarken(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
420 421 422 423 424 425
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
426 427
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
428

Laurent Montel's avatar
Laurent Montel committed
429
            srcColor = qMin(srcColor, dstColor);
430

Laurent Montel's avatar
Laurent Montel committed
431
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
432 433 434 435 436 437 438 439

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}

Laurent Montel's avatar
Laurent Montel committed
440
void KisGrayU16ColorSpace::compositeLighten(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, quint16 opacity)
441 442 443 444 445 446
{
    COMMON_COMPOSITE_OP_PROLOG();

    {
        for (int channel = 0; channel < MAX_CHANNEL_GRAY; channel++) {

Laurent Montel's avatar
Laurent Montel committed
447 448
            quint16 srcColor = src[channel];
            quint16 dstColor = dst[channel];
449

Laurent Montel's avatar
Laurent Montel committed
450
            srcColor = qMax(srcColor, dstColor);
451

Laurent Montel's avatar
Laurent Montel committed
452
            quint16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
453 454 455 456 457 458 459 460 461

            dst[channel] = newColor;
        }
    }

    COMMON_COMPOSITE_OP_EPILOG();
}


Laurent Montel's avatar
Laurent Montel committed
462 463 464 465 466 467 468 469 470
void KisGrayU16ColorSpace::compositeErase(quint8 *dst,
            qint32 dstRowSize,
            const quint8 *src,
            qint32 srcRowSize,
            const quint8 *srcAlphaMask,
            qint32 maskRowStride,
            qint32 rows,
            qint32 cols,
            quint16 /*opacity*/)
471 472 473 474 475
{
    while (rows-- > 0)
    {
        const Pixel *s = reinterpret_cast<const Pixel *>(src);
        Pixel *d = reinterpret_cast<Pixel *>(dst);
Laurent Montel's avatar
Laurent Montel committed
476
        const quint8 *mask = srcAlphaMask;
477

Laurent Montel's avatar
Laurent Montel committed
478
        for (qint32 i = cols; i > 0; i--, s++, d++)
479
        {
Laurent Montel's avatar
Laurent Montel committed
480
            quint16 srcAlpha = s->alpha;
481 482 483

            // apply the alphamask
            if (mask != 0) {
Laurent Montel's avatar
Laurent Montel committed
484
                quint8 U8_mask = *mask;
485 486 487 488 489 490

                if (U8_mask != OPACITY_OPAQUE) {
                    srcAlpha = UINT16_BLEND(srcAlpha, U16_OPACITY_OPAQUE, UINT8_TO_UINT16(U8_mask));
                }
                mask++;
            }
491
            d->alpha = UINT16_MULT(srcAlpha, d->alpha);
492 493 494 495 496 497 498 499 500 501
        }

        dst += dstRowSize;
        src += srcRowSize;
        if(srcAlphaMask) {
            srcAlphaMask += maskRowStride;
        }
    }
}

Laurent Montel's avatar
Laurent Montel committed
502 503 504 505 506 507 508 509 510
void KisGrayU16ColorSpace::bitBlt(quint8 *dst,
                      qint32 dstRowStride,
                      const quint8 *src,
                      qint32 srcRowStride,
                      const quint8 *mask,
                      qint32 maskRowStride,
                      quint8 U8_opacity,
                      qint32 rows,
                      qint32 cols,
511
                      const KoCompositeOp& op)
512
{
Laurent Montel's avatar
Laurent Montel committed
513
    quint16 opacity = UINT8_TO_UINT16(U8_opacity);
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557

    switch (op.op()) {
    case COMPOSITE_UNDEF:
        // Undefined == no composition
        break;
    case COMPOSITE_OVER:
        compositeOver(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_IN:
        //compositeIn(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
    case COMPOSITE_OUT:
        //compositeOut(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_ATOP:
        //compositeAtop(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_XOR:
        //compositeXor(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_PLUS:
        //compositePlus(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_MINUS:
        //compositeMinus(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_ADD:
        //compositeAdd(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_SUBTRACT:
        //compositeSubtract(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_DIFF:
        //compositeDiff(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_MULT:
        compositeMultiply(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_DIVIDE:
        compositeDivide(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_BUMPMAP:
        //compositeBumpmap(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COPY:
558
        compositeCopy(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, U8_opacity);
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
        break;
    case COMPOSITE_COPY_RED:
        //compositeCopyRed(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COPY_GREEN:
        //compositeCopyGreen(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COPY_BLUE:
        //compositeCopyBlue(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COPY_OPACITY:
        //compositeCopyOpacity(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_CLEAR:
        //compositeClear(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_DISSOLVE:
        //compositeDissolve(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_DISPLACE:
        //compositeDisplace(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
#if 0
    case COMPOSITE_MODULATE:
        compositeModulate(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_THRESHOLD:
        compositeThreshold(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
#endif
    case COMPOSITE_NO:
        // No composition.
        break;
    case COMPOSITE_DARKEN:
        compositeDarken(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_LIGHTEN:
        compositeLighten(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_HUE:
        //compositeHue(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_SATURATION:
        //compositeSaturation(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_VALUE:
        //compositeValue(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COLOR:
        //compositeColor(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_COLORIZE:
        //compositeColorize(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_LUMINIZE:
        //compositeLuminize(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_SCREEN:
        compositeScreen(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_OVERLAY:
        compositeOverlay(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_ERASE:
        compositeErase(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_DODGE:
        compositeDodge(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    case COMPOSITE_BURN:
        compositeBurn(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
        break;
    default:
        break;
    }
}

636
KoCompositeOpList KisGrayU16ColorSpace::userVisiblecompositeOps() const
637
{
638 639 640 641 642 643 644 645 646 647 648
    KoCompositeOpList list;

    list.append(KoCompositeOp(COMPOSITE_OVER));
    list.append(KoCompositeOp(COMPOSITE_MULT));
    list.append(KoCompositeOp(COMPOSITE_BURN));
    list.append(KoCompositeOp(COMPOSITE_DODGE));
    list.append(KoCompositeOp(COMPOSITE_DIVIDE));
    list.append(KoCompositeOp(COMPOSITE_SCREEN));
    list.append(KoCompositeOp(COMPOSITE_OVERLAY));
    list.append(KoCompositeOp(COMPOSITE_DARKEN));
    list.append(KoCompositeOp(COMPOSITE_LIGHTEN));
649 650 651

    return list;
}