summaryrefslogtreecommitdiffstats
path: root/krita/colorspaces/rgb_u8
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /krita/colorspaces/rgb_u8
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krita/colorspaces/rgb_u8')
-rw-r--r--krita/colorspaces/rgb_u8/Makefile.am33
-rw-r--r--krita/colorspaces/rgb_u8/composite.h868
-rw-r--r--krita/colorspaces/rgb_u8/kis_rgb_colorspace.cc1501
-rw-r--r--krita/colorspaces/rgb_u8/kis_rgb_colorspace.h116
-rw-r--r--krita/colorspaces/rgb_u8/kritargbplugin.desktop99
-rw-r--r--krita/colorspaces/rgb_u8/rgb_plugin.cc74
-rw-r--r--krita/colorspaces/rgb_u8/rgb_plugin.h37
-rw-r--r--krita/colorspaces/rgb_u8/rgbplugin.rc9
-rw-r--r--krita/colorspaces/rgb_u8/templates/.directory6
-rw-r--r--krita/colorspaces/rgb_u8/templates/Makefile.am8
-rw-r--r--krita/colorspaces/rgb_u8/templates/cr48-action-template_rgb_empty.pngbin0 -> 2363 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/crsc-action-template_rgb_empty.svgzbin0 -> 1818 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1024x768.desktop91
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1024x768.krabin0 -> 7141 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1280x1024.desktop92
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1280x1024.krabin0 -> 9806 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1600x1200.desktop97
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_1600x1200.krabin0 -> 13147 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_640x480.desktop92
-rw-r--r--krita/colorspaces/rgb_u8/templates/transparent_640x480.krabin0 -> 4947 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1024x768.desktop102
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1024x768.krabin0 -> 5323 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1280x1024.desktop95
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1280x1024.krabin0 -> 7988 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1600x1200.desktop95
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_1600x1200.krabin0 -> 11442 bytes
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_640x480.desktop102
-rw-r--r--krita/colorspaces/rgb_u8/templates/white_640x480.krabin0 -> 3164 bytes
-rw-r--r--krita/colorspaces/rgb_u8/tests/Makefile.am17
-rw-r--r--krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.cpp197
-rw-r--r--krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.h34
31 files changed, 3765 insertions, 0 deletions
diff --git a/krita/colorspaces/rgb_u8/Makefile.am b/krita/colorspaces/rgb_u8/Makefile.am
new file mode 100644
index 00000000..4d8ab87c
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/Makefile.am
@@ -0,0 +1,33 @@
+# Install the desktop file needed to detect the plugin
+kde_services_DATA = kritargbplugin.desktop
+
+INCLUDES = -I$(srcdir)/../../sdk \
+ -I$(srcdir)/../../kritacolor/color_strategy/ \
+ -I$(srcdir)/../../kritacolor/ \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+lib_LTLIBRARIES = libkritargb.la
+libkritargb_la_SOURCES = kis_rgb_colorspace.cc
+libkritargb_la_LDFLAGS = $(all_libraries)
+libkritargb_la_LIBADD = ../../kritacolor/libkritacolor.la
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = kritargbplugin.la
+
+# Srcs for the plugin
+kritargbplugin_la_SOURCES = rgb_plugin.cc
+noinst_HEADERS = rgb_plugin.h kis_rgb_colorspace.h
+
+kritargbplugin_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kritargbplugin_la_LIBADD = libkritargb.la ../../kritacolor/libkritacolor.la
+
+kritargbplugin_la_METASOURCES = AUTO
+#METASOURCES = AUTO # XXX: which of the two?
+
+if include_kunittest_tests
+TESTSDIR = tests
+endif
+
+SUBDIRS = . templates $(TESTSDIR)
+
diff --git a/krita/colorspaces/rgb_u8/composite.h b/krita/colorspaces/rgb_u8/composite.h
new file mode 100644
index 00000000..961130ba
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/composite.h
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2004 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.
+ *
+
+ Some code is derived from GraphicsMagick/magick/composite.c and is
+ subject to the following license and copyright:
+
+ Copyright (C) 2002 GraphicsMagick Group, an organization dedicated
+ to making software imaging solutions freely available.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ ("GraphicsMagick"), to deal in GraphicsMagick without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of GraphicsMagick,
+ and to permit persons to whom GraphicsMagick is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of GraphicsMagick.
+
+ The software is provided "as is", without warranty of any kind, express
+ or implied, including but not limited to the warranties of
+ merchantability, fitness for a particular purpose and noninfringement.
+ In no event shall GraphicsMagick Group be liable for any claim,
+ damages or other liability, whether in an action of contract, tort or
+ otherwise, arising from, out of or in connection with GraphicsMagick
+ or the use or other dealings in GraphicsMagick.
+
+ Except as contained in this notice, the name of the GraphicsMagick
+ Group shall not be used in advertising or otherwise to promote the
+ sale, use or other dealings in GraphicsMagick without prior written
+ authorization from the GraphicsMagick Group.
+
+ Other code is derived from gwenview/src/qxcfi.* - this is released under
+ the terms of the LGPL
+
+ */
+
+#ifndef COMPOSITE_H_
+#define COMPOSITE_H_
+
+#include <kdebug.h>
+
+#include <kis_global.h>
+
+/**
+ * Image composition functions that can be used by the colour strategies.
+ *
+ * XXX: perhaps each composition function ought to be a strategy of itself.
+ * Krita is still missing something like a capabilities database that ties
+ * together image formats, colour systems, composition functions etc., that
+ * determines which goes with which and defines user visible text for all this.
+ *
+ * For now, this is a quick hack; once things are working again, I'll investigate
+ * doing this nicely (famous last words...)
+ *
+ * XXX: Except for Over, none of the operators uses the opacity parameter
+ */
+
+
+// Straight from image.h
+
+#define PixelIntensity(pixel) ((unsigned int) \
+ (((double)306.0 * (pixel[PIXEL_RED]) + \
+ (double)601.0 * (pixel[PIXEL_GREEN]) + \
+ (double)117.0 * (pixel[PIXEL_BLUE)) \
+ / 1024.0))
+
+#define PixelIntensityToQuantum(pixel) ((Q_UINT8)PixelIntensity(pixel))
+
+#define PixelIntensityToDouble(pixel) ((double)PixelIntensity(pixel))
+
+#define RoundSignedToQuantum(value) ((Q_UINT8) (value < 0 ? 0 : \
+ (value > Q_UINT8_MAX) ? Q_UINT8_MAX : value + 0.5))
+
+#define RoundToQuantum(value) ((Q_UINT8) (value > Q_UINT8_MAX ? Q_UINT8_MAX : \
+ value + 0.5))
+
+// And from studio.h
+#define AbsoluteValue(x) ((x) < 0 ? -(x) : (x))
+
+void compositeIn(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+
+ if (s[PIXEL_ALPHA] == OPACITY_TRANSPARENT)
+ {
+ memcpy(d, s, pixelSize * sizeof(Q_UINT8));
+ continue;
+ }
+ if (d[PIXEL_ALPHA] == OPACITY_TRANSPARENT)
+ continue;
+
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ alpha=(double) (((double) UINT8_MAX - sAlpha) * (UINT8_MAX - dAlpha) / UINT8_MAX);
+ d[PIXEL_RED]=(Q_UINT8) (((double) UINT8_MAX - sAlpha) *
+ (UINT8_MAX-dAlpha) * s[PIXEL_RED] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_GREEN]=(Q_UINT8) (((double) UINT8_MAX - sAlpha)*
+ (UINT8_MAX-dAlpha) * s[PIXEL_GREEN] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_BLUE]=(Q_UINT8) (((double) UINT8_MAX - sAlpha)*
+ (UINT8_MAX - dAlpha) * s[PIXEL_BLUE] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_ALPHA]=(Q_UINT8) ((d[PIXEL_ALPHA] * (UINT8_MAX - alpha) / UINT8_MAX) + 0.5);
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeOut(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ if (s[PIXEL_ALPHA] == OPACITY_TRANSPARENT)
+ {
+ memcpy(d, s, pixelSize * sizeof(Q_UINT8));
+ break;
+ }
+ if (d[PIXEL_ALPHA] == OPACITY_OPAQUE)
+ {
+ d[PIXEL_ALPHA]=OPACITY_TRANSPARENT;
+ break;
+ }
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ alpha=(double) (UINT8_MAX - sAlpha) * d[PIXEL_ALPHA]/UINT8_MAX;
+ d[PIXEL_RED] = (Q_UINT8) (((double) UINT8_MAX - sAlpha) * dAlpha * s[PIXEL_RED] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_GREEN] = (Q_UINT8) (((double) UINT8_MAX - sAlpha) * dAlpha * s[PIXEL_GREEN] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_BLUE] = (Q_UINT8) (((double) UINT8_MAX - sAlpha) * dAlpha * s[PIXEL_BLUE] / UINT8_MAX / alpha + 0.5);
+ d[PIXEL_ALPHA]=(Q_UINT8) ((d[PIXEL_ALPHA] * (UINT8_MAX - alpha) / UINT8_MAX) + 0.5);
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeAtop(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha, red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ alpha = ((double)(UINT8_MAX - sAlpha) *
+ (UINT8_MAX - dAlpha) + (double) sAlpha *
+ (UINT8_MAX - dAlpha)) / UINT8_MAX;
+
+ red = ((double)(UINT8_MAX - sAlpha) * (UINT8_MAX - dAlpha) * s[PIXEL_RED] / UINT8_MAX +
+ (double) sAlpha * (UINT8_MAX-dAlpha) * d[PIXEL_RED]/UINT8_MAX) / alpha;
+ d[PIXEL_RED] = (Q_UINT8) (red > UINT8_MAX ? UINT8_MAX : red + 0.5);
+
+ green = ((double) (UINT8_MAX - sAlpha) * (UINT8_MAX - dAlpha) * s[PIXEL_GREEN] / UINT8_MAX +
+ (double) sAlpha * (UINT8_MAX-dAlpha) * d[PIXEL_GREEN]/UINT8_MAX)/alpha;
+ d[PIXEL_GREEN] = (Q_UINT8) (green > UINT8_MAX ? UINT8_MAX : green + 0.5);
+
+ blue = ((double) (UINT8_MAX - sAlpha) * (UINT8_MAX- dAlpha) * s[PIXEL_BLUE] / UINT8_MAX +
+ (double) sAlpha * (UINT8_MAX - dAlpha) * d[PIXEL_BLUE]/UINT8_MAX) / alpha;
+ d[PIXEL_BLUE] = (Q_UINT8) (blue > UINT8_MAX ? UINT8_MAX : blue + 0.5);
+ d[PIXEL_ALPHA]=(Q_UINT8) (UINT8_MAX - (alpha > UINT8_MAX ? UINT8_MAX : alpha) + 0.5);
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+}
+
+
+void compositeXor(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha, red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ alpha =((double) (UINT8_MAX -sAlpha)*
+ dAlpha+(double) (UINT8_MAX -dAlpha)*
+ sAlpha)/UINT8_MAX ;
+ red=((double) (UINT8_MAX -sAlpha)*dAlpha*
+ s[PIXEL_RED]/UINT8_MAX +(double) (UINT8_MAX -dAlpha)*
+ sAlpha*d[PIXEL_RED]/UINT8_MAX )/alpha ;
+ d[PIXEL_RED]=RoundSignedToQuantum(red);
+ green=((double) (UINT8_MAX -sAlpha)*dAlpha*
+ s[PIXEL_GREEN]/UINT8_MAX +(double) (UINT8_MAX -dAlpha)*
+ sAlpha*d[PIXEL_GREEN]/UINT8_MAX )/alpha ;
+ d[PIXEL_GREEN]=RoundSignedToQuantum(green);
+ blue=((double) (UINT8_MAX -sAlpha)*dAlpha*
+ s[PIXEL_BLUE]/UINT8_MAX +(double) (UINT8_MAX -dAlpha)*
+ sAlpha*d[PIXEL_BLUE]/UINT8_MAX )/alpha ;
+ d[PIXEL_BLUE]=RoundSignedToQuantum(blue);
+ d[PIXEL_ALPHA]=UINT8_MAX -RoundSignedToQuantum(alpha );
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+
+void compositePlus(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha, red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ red=((double) (UINT8_MAX -sAlpha)*s[PIXEL_RED]+(double)
+ (UINT8_MAX -dAlpha)*d[PIXEL_RED])/UINT8_MAX ;
+ d[PIXEL_RED]=RoundSignedToQuantum(red);
+ green=((double) (UINT8_MAX -sAlpha)*s[PIXEL_GREEN]+(double)
+ (UINT8_MAX -dAlpha)*d[PIXEL_GREEN])/UINT8_MAX ;
+ d[PIXEL_GREEN]=RoundSignedToQuantum(green);
+ blue=((double) (UINT8_MAX -sAlpha)*s[PIXEL_BLUE]+(double)
+ (UINT8_MAX -dAlpha)*d[PIXEL_BLUE])/UINT8_MAX ;
+ d[PIXEL_BLUE]=RoundSignedToQuantum(blue);
+ alpha =((double) (UINT8_MAX -sAlpha)+
+ (double) (UINT8_MAX -dAlpha))/UINT8_MAX ;
+ d[PIXEL_ALPHA]=UINT8_MAX -RoundSignedToQuantum(alpha );
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+}
+
+
+
+void compositeMinus(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double alpha, red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ red=((double) (UINT8_MAX -dAlpha)*d[PIXEL_RED]-
+ (double) (UINT8_MAX -sAlpha)*s[PIXEL_RED])/UINT8_MAX ;
+ d[PIXEL_RED]=RoundSignedToQuantum(red);
+ green=((double) (UINT8_MAX -dAlpha)*d[PIXEL_GREEN]-
+ (double) (UINT8_MAX -sAlpha)*s[PIXEL_GREEN])/UINT8_MAX ;
+ d[PIXEL_GREEN]=RoundSignedToQuantum(green);
+ blue=((double) (UINT8_MAX -dAlpha)*d[PIXEL_BLUE]-
+ (double) (UINT8_MAX -sAlpha)*s[PIXEL_BLUE])/UINT8_MAX ;
+ d[PIXEL_BLUE]=RoundSignedToQuantum(blue);
+ alpha =((double) (UINT8_MAX -dAlpha)-
+ (double) (UINT8_MAX -sAlpha))/UINT8_MAX ;
+ d[PIXEL_ALPHA]=UINT8_MAX -RoundSignedToQuantum(alpha );
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeAdd(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ double red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ red=(double) s[PIXEL_RED]+d[PIXEL_RED];
+ d[PIXEL_RED]=(Q_UINT8)
+ (red > UINT8_MAX ? red-=UINT8_MAX : red+0.5);
+ green=(double) s[PIXEL_GREEN]+d[PIXEL_GREEN];
+ d[PIXEL_GREEN]=(Q_UINT8)
+ (green > UINT8_MAX ? green-=UINT8_MAX : green+0.5);
+ blue=(double) s[PIXEL_BLUE]+d[PIXEL_BLUE];
+ d[PIXEL_BLUE]=(Q_UINT8)
+ (blue > UINT8_MAX ? blue-=UINT8_MAX : blue+0.5);
+ d[PIXEL_ALPHA]=OPACITY_OPAQUE;
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeSubtract(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double red, green, blue;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+
+ red=(double) s[PIXEL_RED]-d[PIXEL_RED];
+ d[PIXEL_RED]=(Q_UINT8)
+ (red < 0 ? red+=UINT8_MAX : red+0.5);
+ green=(double) s[PIXEL_GREEN]-d[PIXEL_GREEN];
+ d[PIXEL_GREEN]=(Q_UINT8)
+ (green < 0 ? green+=UINT8_MAX : green+0.5);
+ blue=(double) s[PIXEL_BLUE]-d[PIXEL_BLUE];
+ d[PIXEL_BLUE]=(Q_UINT8)
+ (blue < 0 ? blue+=UINT8_MAX : blue+0.5);
+ d[PIXEL_ALPHA]=OPACITY_OPAQUE;
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeDiff(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ d[PIXEL_RED]=(Q_UINT8)
+ AbsoluteValue(s[PIXEL_RED]-(double) d[PIXEL_RED]);
+ d[PIXEL_GREEN]=(Q_UINT8)
+ AbsoluteValue(s[PIXEL_GREEN]-(double) d[PIXEL_GREEN]);
+ d[PIXEL_BLUE]=(Q_UINT8)
+ AbsoluteValue(s[PIXEL_BLUE]-(double) d[PIXEL_BLUE]);
+ d[PIXEL_ALPHA]=UINT8_MAX - (Q_UINT8)
+ AbsoluteValue(sAlpha-(double) dAlpha);
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeBumpmap(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double intensity;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ // Is this correct? It's not this way in GM.
+ if (s[PIXEL_ALPHA] == OPACITY_TRANSPARENT)
+ continue;
+
+ // And I'm not sure whether this is correct, either.
+ intensity = ((double)306.0 * s[PIXEL_RED] +
+ (double)601.0 * s[PIXEL_GREEN] +
+ (double)117.0 * s[PIXEL_BLUE]) / 1024.0;
+
+ d[PIXEL_RED]=(Q_UINT8) (((double)
+ intensity * d[PIXEL_RED])/UINT8_MAX +0.5);
+ d[PIXEL_GREEN]=(Q_UINT8) (((double)
+ intensity * d[PIXEL_GREEN])/UINT8_MAX +0.5);
+ d[PIXEL_BLUE]=(Q_UINT8) (((double)
+ intensity * d[PIXEL_BLUE])/UINT8_MAX +0.5);
+ d[PIXEL_ALPHA]= (Q_UINT8) (((double)
+ intensity * d[PIXEL_ALPHA])/UINT8_MAX +0.5);
+
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeCopy(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 /*opacity*/ = OPACITY_OPAQUE)
+{
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+ d = dst;
+ s = src;
+ Q_UINT32 len = cols * pixelSize;
+
+ while (rows-- > 0) {
+ memcpy(d, s, len);
+ d += dstRowSize;
+ s += srcRowSize;
+ }
+}
+
+void compositeCopyChannel(Q_UINT8 pixel,
+ Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 /*opacity*/ = OPACITY_OPAQUE)
+{
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+ Q_INT32 i;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ d[pixel] = s[pixel];
+ }
+
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+void compositeCopyRed(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ compositeCopyChannel(PIXEL_RED, pixelSize, dst, dstRowSize, src, srcRowSize, rows, cols, opacity);
+}
+
+void compositeCopyGreen(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ compositeCopyChannel(PIXEL_GREEN, pixelSize, dst, dstRowSize, src, srcRowSize, rows, cols, opacity);
+}
+
+void compositeCopyBlue(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ compositeCopyChannel(PIXEL_BLUE, pixelSize, dst, dstRowSize, src, srcRowSize, rows, cols, opacity);
+}
+
+
+void compositeCopyOpacity(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+
+ // XXX: mess with intensity if there isn't an alpha channel, according to GM.
+ compositeCopyChannel(PIXEL_ALPHA, pixelSize, dst, dstRowSize, src, srcRowSize, rows, cols, opacity);
+
+}
+
+
+void compositeClear(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 /*srcRowSize*/,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 /*opacity*/ = OPACITY_OPAQUE)
+{
+
+ Q_INT32 linesize = pixelSize * sizeof(Q_UINT8) * cols;
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ d = dst;
+ s = src;
+
+ while (rows-- > 0) {
+ memset(d, 0, linesize);
+ d += dstRowSize;
+ }
+
+}
+
+
+void compositeDissolve(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ // XXX: correct?
+ if (s[PIXEL_ALPHA] == OPACITY_TRANSPARENT) continue;
+
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+ d[PIXEL_RED]=(Q_UINT8) (((double) sAlpha*s[PIXEL_RED]+
+ (UINT8_MAX -sAlpha)*d[PIXEL_RED])/UINT8_MAX +0.5);
+ d[PIXEL_GREEN]= (Q_UINT8) (((double) sAlpha*s[PIXEL_GREEN]+
+ (UINT8_MAX -sAlpha)*d[PIXEL_GREEN])/UINT8_MAX +0.5);
+ d[PIXEL_BLUE] = (Q_UINT8) (((double) sAlpha*s[PIXEL_BLUE]+
+ (UINT8_MAX -sAlpha)*d[PIXEL_BLUE])/UINT8_MAX +0.5);
+ d[PIXEL_ALPHA] = OPACITY_OPAQUE;
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+}
+
+
+void compositeDisplace(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 /*opacity*/ = OPACITY_OPAQUE)
+{
+ Q_INT32 linesize = pixelSize * sizeof(Q_UINT8) * cols;
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+ d = dst;
+ s = src;
+
+ while (rows-- > 0) {
+ memcpy(d, s, linesize);
+ d += dstRowSize;
+ s += srcRowSize;
+ }
+
+}
+
+#if 0
+void compositeModulate(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ if (opacity == OPACITY_TRANSPARENT)
+ return;
+
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+
+ Q_INT32 i;
+
+ double sAlpha, dAlpha;
+ long offset;
+
+ while (rows-- > 0) {
+ d = dst;
+ s = src;
+ for (i = cols; i > 0; i--, d += pixelSize, s += pixelSize) {
+ // XXX: correct?
+ if (s[PIXEL_ALPHA] == OPACITY_TRANSPARENT) continue;
+
+ sAlpha = UINT8_MAX - s[PIXEL_ALPHA];
+ dAlpha = UINT8_MAX - d[PIXEL_ALPHA];
+
+
+ offset=(long) (PixelIntensityToQuantum(&source)-midpoint);
+ if (offset == 0)
+ continue;
+ TransformHSL(d[PIXEL_RED],d[PIXEL_GREEN],d[PIXEL_BLUE],
+ &hue,&saturation,&brightness);
+ brightness+=(percent_brightness*offset)/midpoint;
+ if (brightness < 0.0)
+ brightness=0.0;
+ else
+ if (brightness > 1.0)
+ brightness=1.0;
+ HSLTransform(hue,saturation,brightness,&d[PIXEL_RED],
+ &d[PIXEL_GREEN],&d[PIXEL_BLUE]);
+
+
+ }
+ dst += dstRowSize;
+ src += srcRowSize;
+ }
+
+
+}
+
+
+void compositeThreshold(Q_INT32 pixelSize,
+ Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 opacity = OPACITY_OPAQUE)
+{
+ Q_INT32 linesize = pixelSize * sizeof(Q_UINT8) * cols;
+ Q_UINT8 *d;
+ const Q_UINT8 *s;
+ Q_UINT8 alpha;
+ Q_UINT8 invAlpha;
+ Q_INT32 i;
+
+}
+
+#endif
+
+void compositeColorize(Q_INT32,
+ Q_UINT8 *,
+ Q_INT32 ,
+ const Q_UINT8 *,
+ Q_INT32 ,
+ Q_INT32 ,
+ Q_INT32 ,
+ Q_UINT8 )
+{
+}
+
+
+void compositeLuminize(Q_INT32 ,
+ Q_UINT8 *,
+ Q_INT32 ,
+ const Q_UINT8 *,
+ Q_INT32 ,
+ Q_INT32 ,
+ Q_INT32 ,
+ Q_UINT8 )
+{
+
+}
+
+#endif
+
diff --git a/krita/colorspaces/rgb_u8/kis_rgb_colorspace.cc b/krita/colorspaces/rgb_u8/kis_rgb_colorspace.cc
new file mode 100644
index 00000000..61272e36
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/kis_rgb_colorspace.cc
@@ -0,0 +1,1501 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 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>
+#include LCMS_HEADER
+
+#include <qimage.h>
+#include <qcolor.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include "kis_rgb_colorspace.h"
+#include "kis_u8_base_colorspace.h"
+#include "kis_color_conversions.h"
+#include "kis_integer_maths.h"
+#include "kis_colorspace_factory_registry.h"
+
+#include "composite.h"
+
+#define downscale(quantum) (quantum) //((unsigned char) ((quantum)/257UL))
+#define upscale(value) (value) // ((Q_UINT8) (257UL*(value)))
+
+namespace {
+ const Q_INT32 MAX_CHANNEL_RGB = 3;
+ const Q_INT32 MAX_CHANNEL_RGBA = 4;
+}
+
+KisRgbColorSpace::KisRgbColorSpace(KisColorSpaceFactoryRegistry * parent, KisProfile *p) :
+ KisU8BaseColorSpace(KisID("RGBA", i18n("RGB (8-bit integer/channel)")), TYPE_BGRA_8, icSigRgbData, parent, p)
+{
+ m_channels.push_back(new KisChannelInfo(i18n("Red"), i18n("R"), 2, KisChannelInfo::COLOR, KisChannelInfo::UINT8, 1, QColor(255,0,0)));
+ m_channels.push_back(new KisChannelInfo(i18n("Green"), i18n("G"), 1, KisChannelInfo::COLOR, KisChannelInfo::UINT8, 1, QColor(0,255,0)));
+ m_channels.push_back(new KisChannelInfo(i18n("Blue"), i18n("B"), 0, KisChannelInfo::COLOR, KisChannelInfo::UINT8, 1, QColor(0,0,255)));
+ m_channels.push_back(new KisChannelInfo(i18n("Alpha"), i18n("A"), 3, KisChannelInfo::ALPHA, KisChannelInfo::UINT8));
+
+ m_alphaPos = PIXEL_ALPHA;
+ init();
+}
+
+KisRgbColorSpace::~KisRgbColorSpace()
+{
+}
+
+void KisRgbColorSpace::setPixel(Q_UINT8 *pixel, Q_UINT8 red, Q_UINT8 green, Q_UINT8 blue, Q_UINT8 alpha) const
+{
+ pixel[PIXEL_RED] = red;
+ pixel[PIXEL_GREEN] = green;
+ pixel[PIXEL_BLUE] = blue;
+ pixel[PIXEL_ALPHA] = alpha;
+}
+
+void KisRgbColorSpace::getPixel(const Q_UINT8 *pixel, Q_UINT8 *red, Q_UINT8 *green, Q_UINT8 *blue, Q_UINT8 *alpha) const
+{
+ *red = pixel[PIXEL_RED];
+ *green = pixel[PIXEL_GREEN];
+ *blue = pixel[PIXEL_BLUE];
+ *alpha = pixel[PIXEL_ALPHA];
+}
+
+void KisRgbColorSpace::mixColors(const Q_UINT8 **colors, const Q_UINT8 *weights, Q_UINT32 nColors, Q_UINT8 *dst) const
+{
+ Q_UINT32 totalRed = 0, totalGreen = 0, totalBlue = 0, totalAlpha = 0;
+
+ while (nColors--)
+ {
+ Q_UINT32 alpha = (*colors)[PIXEL_ALPHA];
+ // although we only mult by weight and not by weight*256/255
+ // we divide by the same amount later, so there is no need
+ Q_UINT32 alphaTimesWeight = alpha * *weights;
+
+ totalRed += (*colors)[PIXEL_RED] * alphaTimesWeight;
+ totalGreen += (*colors)[PIXEL_GREEN] * alphaTimesWeight;
+ totalBlue += (*colors)[PIXEL_BLUE] * alphaTimesWeight;
+ totalAlpha += alphaTimesWeight;
+
+ weights++;
+ colors++;
+ }
+
+ // note this is correct - if you look at the above calculation
+ if (totalAlpha > 255*255) totalAlpha = 255*255;
+
+ // Divide by 255.
+ dst[PIXEL_ALPHA] =(((totalAlpha + 0x80)>>8)+totalAlpha + 0x80) >>8;
+
+ if (totalAlpha > 0) {
+ totalRed = totalRed / totalAlpha;
+ totalGreen = totalGreen / totalAlpha;
+ totalBlue = totalBlue / totalAlpha;
+ } // else the values are already 0 too
+
+ Q_UINT32 dstRed = totalRed;
+ //Q_ASSERT(dstRed <= 255);
+ if (dstRed > 255) dstRed = 255;
+ dst[PIXEL_RED] = dstRed;
+
+ Q_UINT32 dstGreen = totalGreen;
+ //Q_ASSERT(dstGreen <= 255);
+ if (dstGreen > 255) dstGreen = 255;
+ dst[PIXEL_GREEN] = dstGreen;
+
+ Q_UINT32 dstBlue = totalBlue;
+ //Q_ASSERT(dstBlue <= 255);
+ if (dstBlue > 255) dstBlue = 255;
+ dst[PIXEL_BLUE] = dstBlue;
+}
+
+void KisRgbColorSpace::convolveColors(Q_UINT8** colors, Q_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, Q_UINT8 *dst, Q_INT32 factor, Q_INT32 offset, Q_INT32 nColors) const
+{
+ Q_INT64 totalRed = 0, totalGreen = 0, totalBlue = 0, totalAlpha = 0;
+ Q_INT32 totalWeight = 0, totalWeightTransparent = 0;
+ while (nColors--)
+ {
+ Q_INT32 weight = *kernelValues;
+
+ if (weight != 0) {
+ if((*colors)[PIXEL_ALPHA] == 0)
+ {
+ totalWeightTransparent += weight;
+ } else {
+ totalRed += (*colors)[PIXEL_RED] * weight;
+ totalGreen += (*colors)[PIXEL_GREEN] * weight;
+ totalBlue += (*colors)[PIXEL_BLUE] * weight;
+ }
+ totalAlpha += (*colors)[PIXEL_ALPHA] * weight;
+ totalWeight += weight;
+ }
+ colors++;
+ kernelValues++;
+ }
+ if(totalWeightTransparent == 0)
+ {
+ if (channelFlags & KisChannelInfo::FLAG_COLOR) {
+ dst[PIXEL_RED] = CLAMP((totalRed / factor) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_GREEN] = CLAMP((totalGreen / factor) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_BLUE] = CLAMP((totalBlue / factor) + offset, 0, Q_UINT8_MAX);
+ }
+ if (channelFlags & KisChannelInfo::FLAG_ALPHA) {
+ dst[PIXEL_ALPHA] = CLAMP((totalAlpha/ factor) + offset, 0, Q_UINT8_MAX);
+ }
+ } else if(totalWeightTransparent != totalWeight && (channelFlags & KisChannelInfo::FLAG_COLOR)) {
+ if(totalWeight == factor)
+ {
+ Q_INT64 a = ( totalWeight - totalWeightTransparent );
+ dst[PIXEL_RED] = CLAMP((totalRed / a) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_GREEN] = CLAMP((totalGreen / a) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_BLUE] = CLAMP((totalBlue / a) + offset, 0, Q_UINT8_MAX);
+ } else {
+ double a = totalWeight / ( factor * ( totalWeight - totalWeightTransparent ) ); // use double as it can saturate
+ dst[PIXEL_RED] = CLAMP( (Q_UINT8)(totalRed * a) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_GREEN] = CLAMP( (Q_UINT8)(totalGreen * a) + offset, 0, Q_UINT8_MAX);
+ dst[PIXEL_BLUE] = CLAMP( (Q_UINT8)(totalBlue * a) + offset, 0, Q_UINT8_MAX);
+ }
+ }
+ if (channelFlags & KisChannelInfo::FLAG_ALPHA) {
+ dst[PIXEL_ALPHA] = CLAMP((totalAlpha/ factor) + offset, 0, Q_UINT8_MAX);
+ }
+}
+
+
+void KisRgbColorSpace::invertColor(Q_UINT8 * src, Q_INT32 nPixels)
+{
+ Q_UINT32 psize = pixelSize();
+
+ while (nPixels--)
+ {
+ src[PIXEL_RED] = Q_UINT8_MAX - src[PIXEL_RED];
+ src[PIXEL_GREEN] = Q_UINT8_MAX - src[PIXEL_GREEN];
+ src[PIXEL_BLUE] = Q_UINT8_MAX - src[PIXEL_BLUE];
+
+ src += psize;
+ }
+}
+
+
+void KisRgbColorSpace::darken(const Q_UINT8 * src, Q_UINT8 * dst, Q_INT32 shade, bool compensate, double compensation, Q_INT32 nPixels) const
+{
+ Q_UINT32 pSize = pixelSize();
+
+ while (nPixels--) {
+ if (compensate) {
+ dst[PIXEL_RED] = (Q_INT8) QMIN(255,((src[PIXEL_RED] * shade) / (compensation * 255)));
+ dst[PIXEL_GREEN] = (Q_INT8) QMIN(255,((src[PIXEL_GREEN] * shade) / (compensation * 255)));
+ dst[PIXEL_BLUE] = (Q_INT8) QMIN(255,((src[PIXEL_BLUE] * shade) / (compensation * 255)));
+ }
+ else {
+ dst[PIXEL_RED] = (Q_INT8) QMIN(255, (src[PIXEL_RED] * shade / 255));
+ dst[PIXEL_BLUE] = (Q_INT8) QMIN(255, (src[PIXEL_BLUE] * shade / 255));
+ dst[PIXEL_GREEN] = (Q_INT8) QMIN(255, (src[PIXEL_GREEN] * shade / 255));
+ }
+ dst += pSize;
+ src += pSize;
+ }
+}
+
+Q_UINT8 KisRgbColorSpace::intensity8(const Q_UINT8 * src) const
+{
+ return (Q_UINT8)((src[PIXEL_RED] * 0.30 + src[PIXEL_GREEN] * 0.59 + src[PIXEL_BLUE] * 0.11) + 0.5);
+}
+
+QValueVector<KisChannelInfo *> KisRgbColorSpace::channels() const
+{
+ return m_channels;
+}
+
+Q_UINT32 KisRgbColorSpace::nChannels() const
+{
+ return MAX_CHANNEL_RGBA;
+}
+
+Q_UINT32 KisRgbColorSpace::nColorChannels() const
+{
+ return MAX_CHANNEL_RGB;
+}
+
+Q_UINT32 KisRgbColorSpace::pixelSize() const
+{
+ return MAX_CHANNEL_RGBA;
+}
+
+QImage KisRgbColorSpace::convertToQImage(const Q_UINT8 *data, Q_INT32 width, Q_INT32 height,
+ KisProfile * dstProfile,
+ Q_INT32 renderingIntent, float /*exposure*/)
+
+{
+ Q_ASSERT(data);
+ QImage img = QImage(const_cast<Q_UINT8 *>(data), width, height, 32, 0, 0, QImage::LittleEndian);
+ img.setAlphaBuffer(true);
+ // XXX: The previous version of this code used the quantum data directly
+ // as an optimisation. We're introducing a copy overhead here which could
+ // be factored out again if needed.
+ img = img.copy();
+
+ if (dstProfile != 0) {
+ KisColorSpace *dstCS = m_parent->getColorSpace(KisID("RGBA",""), dstProfile->productName());
+ convertPixelsTo(img.bits(),
+ img.bits(), dstCS,
+ width * height, renderingIntent);
+ }
+
+ return img;
+}
+
+
+
+
+void KisRgbColorSpace::compositeOver(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride,
+ const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride,
+ const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride,
+ Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ const Q_UINT8 *mask = maskRowStart;
+ Q_INT32 columns = numColumns;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(srcAlpha, opacity);
+ }
+
+ if (srcAlpha == OPACITY_OPAQUE) {
+ memcpy(dst, src, MAX_CHANNEL_RGBA * sizeof(Q_UINT8));
+ } else {
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ if (srcBlend == OPACITY_OPAQUE) {
+ memcpy(dst, src, MAX_CHANNEL_RGB * sizeof(Q_UINT8));
+ } else {
+ dst[PIXEL_RED] = UINT8_BLEND(src[PIXEL_RED], dst[PIXEL_RED], srcBlend);
+ dst[PIXEL_GREEN] = UINT8_BLEND(src[PIXEL_GREEN], dst[PIXEL_GREEN], srcBlend);
+ dst[PIXEL_BLUE] = UINT8_BLEND(src[PIXEL_BLUE], dst[PIXEL_BLUE], srcBlend);
+ }
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+
+void KisRgbColorSpace::compositeAlphaDarken(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride,
+ const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride,
+ const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride,
+ Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ const Q_UINT8 *mask = maskRowStart;
+ Q_INT32 columns = numColumns;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(srcAlpha, opacity);
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT && srcAlpha >= dstAlpha) {
+ dst[PIXEL_ALPHA] = srcAlpha;
+ memcpy(dst, src, MAX_CHANNEL_RGB * sizeof(Q_UINT8));
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+
+void KisRgbColorSpace::compositeMultiply(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ Q_UINT8 srcColor = src[PIXEL_RED];
+ Q_UINT8 dstColor = dst[PIXEL_RED];
+
+ srcColor = UINT8_MULT(srcColor, dstColor);
+
+ dst[PIXEL_RED] = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ srcColor = src[PIXEL_GREEN];
+ dstColor = dst[PIXEL_GREEN];
+
+ srcColor = UINT8_MULT(srcColor, dstColor);
+
+ dst[PIXEL_GREEN] = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ srcColor = src[PIXEL_BLUE];
+ dstColor = dst[PIXEL_BLUE];
+
+ srcColor = UINT8_MULT(srcColor, dstColor);
+
+ dst[PIXEL_BLUE] = UINT8_BLEND(srcColor, dstColor, srcBlend);
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeDivide(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = QMIN((dstColor * (UINT8_MAX + 1u) + (srcColor / 2u)) / (1u + srcColor), UINT8_MAX);
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeScreen(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = UINT8_MAX - UINT8_MULT(UINT8_MAX - dstColor, UINT8_MAX - srcColor);
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeOverlay(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = UINT8_MULT(dstColor, dstColor + UINT8_MULT(2 * srcColor, UINT8_MAX - dstColor));
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeDodge(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = QMIN((dstColor * (UINT8_MAX + 1)) / (UINT8_MAX + 1 - srcColor), UINT8_MAX);
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeBurn(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = QMIN(((UINT8_MAX - dstColor) * (UINT8_MAX + 1)) / (srcColor + 1), UINT8_MAX);
+ if (UINT8_MAX - srcColor > UINT8_MAX) srcColor = UINT8_MAX;
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeDarken(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = QMIN(srcColor, dstColor);
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeLighten(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
+
+ Q_UINT8 srcColor = src[channel];
+ Q_UINT8 dstColor = dst[channel];
+
+ srcColor = QMAX(srcColor, dstColor);
+
+ Q_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend);
+
+ dst[channel] = newColor;
+ }
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeHue(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ int dstRed = dst[PIXEL_RED];
+ int dstGreen = dst[PIXEL_GREEN];
+ int dstBlue = dst[PIXEL_BLUE];
+
+ int srcHue;
+ int srcSaturation;
+ int srcValue;
+ int dstHue;
+ int dstSaturation;
+ int dstValue;
+
+ rgb_to_hsv(src[PIXEL_RED], src[PIXEL_GREEN], src[PIXEL_BLUE], &srcHue, &srcSaturation, &srcValue);
+ rgb_to_hsv(dstRed, dstGreen, dstBlue, &dstHue, &dstSaturation, &dstValue);
+
+ int srcRed;
+ int srcGreen;
+ int srcBlue;
+
+ hsv_to_rgb(srcHue, dstSaturation, dstValue, &srcRed, &srcGreen, &srcBlue);
+
+ dst[PIXEL_RED] = UINT8_BLEND(srcRed, dstRed, srcBlend);
+ dst[PIXEL_GREEN] = UINT8_BLEND(srcGreen, dstGreen, srcBlend);
+ dst[PIXEL_BLUE] = UINT8_BLEND(srcBlue, dstBlue, srcBlend);
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeSaturation(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ int dstRed = dst[PIXEL_RED];
+ int dstGreen = dst[PIXEL_GREEN];
+ int dstBlue = dst[PIXEL_BLUE];
+
+ int srcHue;
+ int srcSaturation;
+ int srcValue;
+ int dstHue;
+ int dstSaturation;
+ int dstValue;
+
+ rgb_to_hsv(src[PIXEL_RED], src[PIXEL_GREEN], src[PIXEL_BLUE], &srcHue, &srcSaturation, &srcValue);
+ rgb_to_hsv(dstRed, dstGreen, dstBlue, &dstHue, &dstSaturation, &dstValue);
+
+ int srcRed;
+ int srcGreen;
+ int srcBlue;
+
+ hsv_to_rgb(dstHue, srcSaturation, dstValue, &srcRed, &srcGreen, &srcBlue);
+
+ dst[PIXEL_RED] = UINT8_BLEND(srcRed, dstRed, srcBlend);
+ dst[PIXEL_GREEN] = UINT8_BLEND(srcGreen, dstGreen, srcBlend);
+ dst[PIXEL_BLUE] = UINT8_BLEND(srcBlue, dstBlue, srcBlend);
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeValue(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ int dstRed = dst[PIXEL_RED];
+ int dstGreen = dst[PIXEL_GREEN];
+ int dstBlue = dst[PIXEL_BLUE];
+
+ int srcHue;
+ int srcSaturation;
+ int srcValue;
+ int dstHue;
+ int dstSaturation;
+ int dstValue;
+
+ rgb_to_hsv(src[PIXEL_RED], src[PIXEL_GREEN], src[PIXEL_BLUE], &srcHue, &srcSaturation, &srcValue);
+ rgb_to_hsv(dstRed, dstGreen, dstBlue, &dstHue, &dstSaturation, &dstValue);
+
+ int srcRed;
+ int srcGreen;
+ int srcBlue;
+
+ hsv_to_rgb(dstHue, dstSaturation, srcValue, &srcRed, &srcGreen, &srcBlue);
+
+ dst[PIXEL_RED] = UINT8_BLEND(srcRed, dstRed, srcBlend);
+ dst[PIXEL_GREEN] = UINT8_BLEND(srcGreen, dstGreen, srcBlend);
+ dst[PIXEL_BLUE] = UINT8_BLEND(srcBlue, dstBlue, srcBlend);
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeColor(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity)
+{
+ while (rows > 0) {
+
+ const Q_UINT8 *src = srcRowStart;
+ Q_UINT8 *dst = dstRowStart;
+ Q_INT32 columns = numColumns;
+ const Q_UINT8 *mask = maskRowStart;
+
+ while (columns > 0) {
+
+ Q_UINT8 srcAlpha = src[PIXEL_ALPHA];
+ Q_UINT8 dstAlpha = dst[PIXEL_ALPHA];
+
+ srcAlpha = QMIN(srcAlpha, dstAlpha);
+
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_MULT(srcAlpha, *mask);
+ mask++;
+ }
+
+ if (srcAlpha != OPACITY_TRANSPARENT) {
+
+ if (opacity != OPACITY_OPAQUE) {
+ srcAlpha = UINT8_MULT(src[PIXEL_ALPHA], opacity);
+ }
+
+ Q_UINT8 srcBlend;
+
+ if (dstAlpha == OPACITY_OPAQUE) {
+ srcBlend = srcAlpha;
+ } else {
+ Q_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
+ dst[PIXEL_ALPHA] = newAlpha;
+
+ if (newAlpha != 0) {
+ srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
+ } else {
+ srcBlend = srcAlpha;
+ }
+ }
+
+ int dstRed = dst[PIXEL_RED];
+ int dstGreen = dst[PIXEL_GREEN];
+ int dstBlue = dst[PIXEL_BLUE];
+
+ int srcHue;
+ int srcSaturation;
+ int srcLightness;
+ int dstHue;
+ int dstSaturation;
+ int dstLightness;
+
+ rgb_to_hls(src[PIXEL_RED], src[PIXEL_GREEN], src[PIXEL_BLUE], &srcHue, &srcLightness, &srcSaturation);
+ rgb_to_hls(dstRed, dstGreen, dstBlue, &dstHue, &dstLightness, &dstSaturation);
+
+ Q_UINT8 srcRed;
+ Q_UINT8 srcGreen;
+ Q_UINT8 srcBlue;
+
+ hls_to_rgb(srcHue, dstLightness, srcSaturation, &srcRed, &srcGreen, &srcBlue);
+
+ dst[PIXEL_RED] = UINT8_BLEND(srcRed, dstRed, srcBlend);
+ dst[PIXEL_GREEN] = UINT8_BLEND(srcGreen, dstGreen, srcBlend);
+ dst[PIXEL_BLUE] = UINT8_BLEND(srcBlue, dstBlue, srcBlend);
+ }
+
+ columns--;
+ src += MAX_CHANNEL_RGBA;
+ dst += MAX_CHANNEL_RGBA;
+ }
+
+ rows--;
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ if(maskRowStart)
+ maskRowStart += maskRowStride;
+ }
+}
+
+void KisRgbColorSpace::compositeErase(Q_UINT8 *dst,
+ Q_INT32 dstRowSize,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowSize,
+ const Q_UINT8 *srcAlphaMask,
+ Q_INT32 maskRowStride,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ Q_UINT8 /*opacity*/)
+{
+ Q_INT32 i;
+ Q_UINT8 srcAlpha;
+
+ while (rows-- > 0)
+ {
+ const Q_UINT8 *s = src;
+ Q_UINT8 *d = dst;
+ const Q_UINT8 *mask = srcAlphaMask;
+
+ for (i = cols; i > 0; i--, s+=MAX_CHANNEL_RGBA, d+=MAX_CHANNEL_RGBA)
+ {
+ srcAlpha = s[PIXEL_ALPHA];
+ // apply the alphamask
+ if(mask != 0)
+ {
+ if(*mask != OPACITY_OPAQUE)
+ srcAlpha = UINT8_BLEND(srcAlpha, OPACITY_OPAQUE, *mask);
+ mask++;
+ }
+ d[PIXEL_ALPHA] = UINT8_MULT(srcAlpha, d[PIXEL_ALPHA]);
+ }
+
+ dst += dstRowSize;
+ if(srcAlphaMask)
+ srcAlphaMask += maskRowStride;
+ src += srcRowSize;
+ }
+}
+
+void KisRgbColorSpace::bitBlt(Q_UINT8 *dst,
+ Q_INT32 dstRowStride,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowStride,
+ const Q_UINT8 *mask,
+ Q_INT32 maskRowStride,
+ Q_UINT8 opacity,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ const KisCompositeOp& op)
+{
+
+ 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_ALPHA_DARKEN:
+ compositeAlphaDarken(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
+ break;
+ case COMPOSITE_IN:
+ compositeIn(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
+ break;
+ 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:
+ compositeCopy(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
+ 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;
+ }
+}
+
+KisCompositeOpList KisRgbColorSpace::userVisiblecompositeOps() const
+{
+ KisCompositeOpList list;
+
+ list.append(KisCompositeOp(COMPOSITE_OVER));
+ list.append(KisCompositeOp(COMPOSITE_ALPHA_DARKEN));
+ list.append(KisCompositeOp(COMPOSITE_MULT));
+ list.append(KisCompositeOp(COMPOSITE_BURN));
+ list.append(KisCompositeOp(COMPOSITE_DODGE));
+ list.append(KisCompositeOp(COMPOSITE_DIVIDE));
+ list.append(KisCompositeOp(COMPOSITE_SCREEN));
+ list.append(KisCompositeOp(COMPOSITE_OVERLAY));
+ list.append(KisCompositeOp(COMPOSITE_DARKEN));
+ list.append(KisCompositeOp(COMPOSITE_LIGHTEN));
+ list.append(KisCompositeOp(COMPOSITE_HUE));
+ list.append(KisCompositeOp(COMPOSITE_SATURATION));
+ list.append(KisCompositeOp(COMPOSITE_VALUE));
+ list.append(KisCompositeOp(COMPOSITE_COLOR));
+ list.append(KisCompositeOp(COMPOSITE_PLUS));
+ list.append(KisCompositeOp(COMPOSITE_MINUS));
+ list.append(KisCompositeOp(COMPOSITE_SUBTRACT));
+ list.append(KisCompositeOp(COMPOSITE_ADD));
+
+ return list;
+}
diff --git a/krita/colorspaces/rgb_u8/kis_rgb_colorspace.h b/krita/colorspaces/rgb_u8/kis_rgb_colorspace.h
new file mode 100644
index 00000000..40718251
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/kis_rgb_colorspace.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.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.
+ */
+#ifndef KIS_STRATEGY_COLORSPACE_RGB_H_
+#define KIS_STRATEGY_COLORSPACE_RGB_H_
+
+#include "klocale.h"
+
+#include "kis_global.h"
+#include "kis_u8_base_colorspace.h"
+#include "koffice_export.h"
+
+const Q_UINT8 PIXEL_BLUE = 0;
+const Q_UINT8 PIXEL_GREEN = 1;
+const Q_UINT8 PIXEL_RED = 2;
+const Q_UINT8 PIXEL_ALPHA = 3;
+
+class KRITATOOL_EXPORT KisRgbColorSpace : public KisU8BaseColorSpace {
+public:
+ KisRgbColorSpace(KisColorSpaceFactoryRegistry * parent, KisProfile *p);
+ virtual ~KisRgbColorSpace();
+
+ virtual bool willDegrade(ColorSpaceIndependence)
+ {
+ return false;
+ };
+
+
+public:
+ void setPixel(Q_UINT8 *pixel, Q_UINT8 red, Q_UINT8 green, Q_UINT8 blue, Q_UINT8 alpha) const;
+ void getPixel(const Q_UINT8 *pixel, Q_UINT8 *red, Q_UINT8 *green, Q_UINT8 *blue, Q_UINT8 *alpha) const;
+
+ virtual void mixColors(const Q_UINT8 **colors, const Q_UINT8 *weights, Q_UINT32 nColors, Q_UINT8 *dst) const;
+ virtual void convolveColors(Q_UINT8** colors, Q_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, Q_UINT8 *dst, Q_INT32 factor, Q_INT32 offset, Q_INT32 nColors) const;
+ virtual void invertColor(Q_UINT8 * src, Q_INT32 nPixels);
+ virtual void darken(const Q_UINT8 * src, Q_UINT8 * dst, Q_INT32 shade, bool compensate, double compensation, Q_INT32 nPixels) const;
+ virtual Q_UINT8 intensity8(const Q_UINT8 * src) const;
+
+ virtual QValueVector<KisChannelInfo *> channels() const;
+ virtual Q_UINT32 nChannels() const;
+ virtual Q_UINT32 nColorChannels() const;
+ virtual Q_UINT32 pixelSize() const;
+
+ virtual QImage convertToQImage(const Q_UINT8 *data, Q_INT32 width, Q_INT32 height,
+ KisProfile * dstProfile = 0,
+ Q_INT32 renderingIntent = INTENT_PERCEPTUAL,
+ float exposure = 0.0f);
+
+ virtual KisCompositeOpList userVisiblecompositeOps() const;
+
+protected:
+
+ virtual void bitBlt(Q_UINT8 *dst,
+ Q_INT32 dstRowStride,
+ const Q_UINT8 *src,
+ Q_INT32 srcRowStride,
+ const Q_UINT8 *srcAlphaMask,
+ Q_INT32 maskRowStride,
+ Q_UINT8 opacity,
+ Q_INT32 rows,
+ Q_INT32 cols,
+ const KisCompositeOp& op);
+
+ void compositeOver(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeAlphaDarken(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeMultiply(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeDivide(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeScreen(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeOverlay(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeDodge(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeBurn(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeDarken(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeLighten(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeHue(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeSaturation(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeValue(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeColor(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+ void compositeErase(Q_UINT8 *dst, Q_INT32 dstRowStride, const Q_UINT8 *src, Q_INT32 srcRowStride, const Q_UINT8 *mask, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 columns, Q_UINT8 opacity);
+};
+
+class KisRgbColorSpaceFactory : public KisColorSpaceFactory
+{
+public:
+ /**
+ * Krita definition for use in .kra files and internally: unchanging name +
+ * i18n'able description.
+ */
+ virtual KisID id() const { return KisID("RGBA", i18n("RGB (8-bit integer/channel)")); };
+
+ /**
+ * lcms colorspace type definition.
+ */
+ virtual Q_UINT32 colorSpaceType() { return TYPE_BGRA_8; };
+
+ virtual icColorSpaceSignature colorSpaceSignature() { return icSigRgbData; };
+
+ virtual KisColorSpace *createColorSpace(KisColorSpaceFactoryRegistry * parent, KisProfile * p) { return new KisRgbColorSpace(parent, p); };
+
+ virtual QString defaultProfile() { return "sRGB built-in - (lcms internal)"; };
+};
+
+#endif // KIS_STRATEGY_COLORSPACE_RGB_H_
diff --git a/krita/colorspaces/rgb_u8/kritargbplugin.desktop b/krita/colorspaces/rgb_u8/kritargbplugin.desktop
new file mode 100644
index 00000000..a8f5c30d
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/kritargbplugin.desktop
@@ -0,0 +1,99 @@
+[Desktop Entry]
+Name=RGB Color Model
+Name[bg]=Цветови модел RGB
+Name[br]=Gobari al livioù RGB
+Name[ca]=Model de color RGB
+Name[cy]=Model Lliw RGB
+Name[da]=RGB-farvemodel
+Name[de]=RGB-Farbmodell
+Name[el]=Χρωματικό μοντέλο RGB
+Name[en_GB]=RGB Colour Model
+Name[eo]=RGB-kolormodelo
+Name[es]=Modelo de color RGB
+Name[et]=RGB värvimudel
+Name[eu]=RGB kolore-eredua
+Name[fa]=مدل رنگ RGB
+Name[fi]=RGB-värimalli
+Name[fr]=Modèle de couleurs RVB
+Name[fy]=RGB-kleurmodel
+Name[gl]=Modelo de Cores RGB
+Name[he]=מודל צבעים RGB
+Name[hi]=आरजीबी रंग नमूना
+Name[hu]=RGB színmodell
+Name[is]=RGB litategund
+Name[it]=Modello di colore RGB
+Name[ja]=RGB カラーモデル
+Name[km]=គំរូ​ពណ៌ RGB
+Name[lt]=RGB spalvų modelis
+Name[lv]=RGB krāsu modelis
+Name[ms]=Model Warna RGB
+Name[nb]=RGB-fargemodell
+Name[nds]=RGB-Klöörmodell
+Name[ne]=RGB रङ मोडेल
+Name[nl]=RGB-kleurmodel
+Name[nn]=RGB-fargemodell
+Name[pl]=Przestrzeń barw RGB
+Name[pt]=Modelo de Cor RGB
+Name[pt_BR]=Modelo de Cor RGB
+Name[ru]=RGB
+Name[se]=RGB-ivdnemálle
+Name[sk]=Model farieb RGB
+Name[sl]=Barvni model RGB
+Name[sr]=RGB модел боја
+Name[sr@Latn]=RGB model boja
+Name[sv]=RGB-färgmodell
+Name[ta]=RGB வண்ண மாதிரி
+Name[tr]=RGB Renk Modeli
+Name[uk]=Модель кольору RGB
+Name[uz]=RGB rang usuli
+Name[uz@cyrillic]=RGB ранг усули
+Name[zh_CN]=RGB 色彩模型
+Name[zh_TW]=RGB 色彩模型
+Comment=Color model for 8-bit/channel RGB images
+Comment[bg]=Цветови модел за 8 битови изображения RGB
+Comment[ca]=Model de color per a 8 bits/canal d'imatges RGB
+Comment[cy]=Model lliw ar gyfer delweddau RGB 8-did/sianel
+Comment[da]=Farvemodel for 8-bit/kanal RGB-billeder
+Comment[de]=Farbmodell für 8-bit pro Kanal RGB-Bilder
+Comment[el]=Χρωματικό μοντέλο για 8-bit/κανάλι RGB εικόνες
+Comment[en_GB]=Colour model for 8-bit/channel RGB images
+Comment[es]=Modelo de color para imágenes de 8 bits/canal RGB
+Comment[et]=8-bitiste kanalitega RGB-piltide värvimudel
+Comment[eu]=8-bit/kanaleko RGB irudien kolore-eredua
+Comment[fa]=مدل رنگ برای تصاویر ۸ بیتی/RGB مجرا
+Comment[fi]=Värimalli 8-bittisille/kanavaisille RGB-kuville
+Comment[fr]=Modèle de couleurs pour des images RVB en 8 bits/plage
+Comment[fy]=Kleurmodel foar 8-bit/kanaal RGB-ôfbyldings
+Comment[gl]=Modelo de Cores para imaxe RGB de 8-bit/canal
+Comment[he]=מודל צבעים עבור תמונות RGB של 8 סיביות/ערוצים
+Comment[hi]=8-बिट/चैनल आरजीबी छवियों के लिए रंग नमूना
+Comment[hu]=Színmodell 8 bit/csatorna RGB képekhez
+Comment[is]=Litategund fyrir 8-bita/rás RGB myndir
+Comment[it]=Modello di colore per immagini RGB a canale di 8 bit
+Comment[ja]=8 ビット/チャンネル RGB 画像のためのカラーモデル
+Comment[km]=គំរូ​ពណ៌​សម្រាប់​រូបភាព RGB ៨ ប៊ីត/មួយ​ឆានែល
+Comment[ms]=Model warna imej RGB 8-bit/saluran
+Comment[nb]=Fargemodell for RGB-bilde med 8 bit per kanal
+Comment[nds]=Klöörmodell för RGB-Biller mit 8-Bit per Kanaal
+Comment[ne]=८-बिट/च्यानल RGB छविहरूका लागि रङ मोडेल
+Comment[nl]=Kleurmodel voor 8-bit/kanaal RGB-afbeeldingen
+Comment[nn]=Fargemodell for RGB-bilete med 8 bit per kanal
+Comment[pl]=Przestrzeń barw dla obrazków RGB 8-bitów/kanał
+Comment[pt]=Modelo de cor para imagens RGB com 8 bits por canal
+Comment[pt_BR]=Modelo de cor para imagens com 8-bits de canal RGB
+Comment[ru]=Цветовое пространство RGB (8-бит/канал)
+Comment[sk]=Model farieb pre RGB obrázky s 8-bitovými číslami na kanál
+Comment[sl]=Barvni model za slike RGB z 8 biti/kanal
+Comment[sr]=Модел боја за RGB слике са 8 битова/каналу
+Comment[sr@Latn]=Model boja za RGB slike sa 8 bitova/kanalu
+Comment[sv]=Färgmodell för 8-bitar/kanal RGB-bilder
+Comment[ta]=8/பிட்/வழி RGB பிம்பங்களுக்கான வண்ண முறை
+Comment[tg]=Mодели ранга барои 8-бит /канал тасвирҳои RGB
+Comment[tr]=8-bit/kanal RGB görüntüler için renk modeli.
+Comment[uk]=Модель кольорів для зображень RGB з 8-бітами/канал
+Comment[zh_CN]=8 位/通道 RGB 图像的色彩模型
+Comment[zh_TW]=8-bit/色頻 RGB 圖片的色彩模型
+ServiceTypes=Krita/ColorSpace
+Type=Service
+X-KDE-Library=kritargbplugin
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/rgb_plugin.cc b/krita/colorspaces/rgb_u8/rgb_plugin.cc
new file mode 100644
index 00000000..018c1491
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/rgb_plugin.cc
@@ -0,0 +1,74 @@
+/*
+* rgb_plugin.cc -- Part of Krita
+*
+* Copyright (c) 2004 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 <stdlib.h>
+#include <vector>
+
+#include <qpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+#include <kis_debug_areas.h>
+
+#include <kis_debug_areas.h>
+#include <kis_colorspace_factory_registry.h>
+#include <kis_basic_histogram_producers.h>
+
+#include "rgb_plugin.h"
+#include "kis_rgb_colorspace.h"
+
+typedef KGenericFactory<RGBPlugin> RGBPluginFactory;
+K_EXPORT_COMPONENT_FACTORY( kritargbplugin, RGBPluginFactory( "krita" ) )
+
+
+RGBPlugin::RGBPlugin(QObject *parent, const char *name, const QStringList &)
+ : KParts::Plugin(parent, name)
+{
+ setInstance(RGBPluginFactory::instance());
+
+ if ( parent->inherits("KisColorSpaceFactoryRegistry") )
+ {
+ KisColorSpaceFactoryRegistry * f = dynamic_cast<KisColorSpaceFactoryRegistry*>(parent);
+
+ KisProfile *defProfile = new KisProfile(cmsCreate_sRGBProfile());
+ f->addProfile(defProfile);
+
+
+ KisColorSpaceFactory * csFactory = new KisRgbColorSpaceFactory();
+ f->add(csFactory);
+
+ KisColorSpace * colorSpaceRGBA = new KisRgbColorSpace(f, 0);
+ KisHistogramProducerFactoryRegistry::instance()->add(
+ new KisBasicHistogramProducerFactory<KisBasicU8HistogramProducer>
+ (KisID("RGB8HISTO", i18n("RGB8")), colorSpaceRGBA) );
+ }
+
+}
+
+RGBPlugin::~RGBPlugin()
+{
+}
+
+#include "rgb_plugin.moc"
diff --git a/krita/colorspaces/rgb_u8/rgb_plugin.h b/krita/colorspaces/rgb_u8/rgb_plugin.h
new file mode 100644
index 00000000..262d0bb4
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/rgb_plugin.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2003 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.
+ */
+
+#ifndef RGB_PLUGIN_H_
+#define RGB_PLUGIN_H_
+
+#include <kparts/plugin.h>
+
+/**
+ * A plugin wrapper around the RGB colour space strategy.
+ */
+class RGBPlugin : public KParts::Plugin
+{
+ Q_OBJECT
+public:
+ RGBPlugin(QObject *parent, const char *name, const QStringList &);
+ virtual ~RGBPlugin();
+
+};
+
+
+#endif // RGB_PLUGIN_H_
diff --git a/krita/colorspaces/rgb_u8/rgbplugin.rc b/krita/colorspaces/rgb_u8/rgbplugin.rc
new file mode 100644
index 00000000..cc618164
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/rgbplugin.rc
@@ -0,0 +1,9 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui library="kritargbplugin" version="1">
+<Menu name="Image"><text>&amp;Image</text>
+ <Menu name="Mode"><text>&amp;Mode</text>
+ <Action name="convert to RGB(A)"/>
+ </Menu>
+</Menu>
+
+</kpartgui>
diff --git a/krita/colorspaces/rgb_u8/templates/.directory b/krita/colorspaces/rgb_u8/templates/.directory
new file mode 100644
index 00000000..4b475643
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/.directory
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Name=RGB
+Name[cy]=CGwGl (RGB)
+Name[fr]=RVB
+Name[hi]=आरजीबी
+X-KDE-DefaultTab=true
diff --git a/krita/colorspaces/rgb_u8/templates/Makefile.am b/krita/colorspaces/rgb_u8/templates/Makefile.am
new file mode 100644
index 00000000..29c87939
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/Makefile.am
@@ -0,0 +1,8 @@
+templates_DATA = .directory transparent_1024x768.desktop transparent_1280x1024.desktop transparent_1600x1200.desktop transparent_640x480.desktop white_1024x768.desktop white_1280x1024.desktop white_1600x1200.desktop white_640x480.desktop
+templatesdir = $(kde_datadir)/krita/templates/rgb
+
+templatesrc_DATA = transparent_1024x768.kra transparent_1280x1024.kra transparent_1600x1200.kra transparent_640x480.kra white_1024x768.kra white_1280x1024.kra white_1600x1200.kra white_640x480.kra
+templatesrcdir = $(kde_datadir)/krita/templates/rgb/.source
+
+templatesicon_ICON = AUTO
+templatesicondir = $(kde_datadir)/krita/icons
diff --git a/krita/colorspaces/rgb_u8/templates/cr48-action-template_rgb_empty.png b/krita/colorspaces/rgb_u8/templates/cr48-action-template_rgb_empty.png
new file mode 100644
index 00000000..ec4d6ddc
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/cr48-action-template_rgb_empty.png
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/crsc-action-template_rgb_empty.svgz b/krita/colorspaces/rgb_u8/templates/crsc-action-template_rgb_empty.svgz
new file mode 100644
index 00000000..3ea7b854
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/crsc-action-template_rgb_empty.svgz
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1024x768.desktop b/krita/colorspaces/rgb_u8/templates/transparent_1024x768.desktop
new file mode 100644
index 00000000..d22ad3e3
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1024x768.desktop
@@ -0,0 +1,91 @@
+[Desktop Entry]
+Type=Link
+URL=.source/transparent_1024x768.kra
+Icon=template_rgb_empty
+Name=Transparent 1024 x 768
+Name[bg]=Прозрачно 1024x768
+Name[br]=Treuzwelus 1024 x 768
+Name[cy]=Tryloyw 1024 x 768
+Name[da]=Gennemsigtig 1024 x 768
+Name[el]=Διαφανής 1024 x 768
+Name[es]=1024 x 768 transparente
+Name[et]=Läbipaistev 1024 x 768
+Name[eu]=Gardena 1024 x 768
+Name[fa]=شفاف ۷۶۸ × ۱۰۲۴
+Name[fi]=Läpinäkyvä 1024x768
+Name[fr]=Image transparente 1024 x 768
+Name[fy]=Trochsichtich 1024 x 768
+Name[gl]=Transparente 1024 x 768
+Name[he]=‏1024‎ x 768 שקוף
+Name[hu]=Áttetsző 1024 x 768
+Name[is]=Gegnsæ 1024 x 768
+Name[it]=Trasparente 1024 × 768
+Name[ja]=透明 1024 x 768
+Name[km]=ថ្លា 1024 x 768
+Name[lt]=Permatomas 1024 x 768
+Name[lv]=Caurspīdīgs 1024 x 768
+Name[ms]=Lutsinar 1024 x 768
+Name[nb]=Gjennomsiktig 1024 × 768
+Name[nds]=Dörsichtig 1024 x 768
+Name[ne]=पारदर्शी १०२४ x ७६८
+Name[nn]=Gjennomsiktig 1024 × 768
+Name[pl]=Przezroczysty 1024 x 768
+Name[pt]=Transparente 1024 x 768
+Name[pt_BR]=Transparente de 1024 x 768
+Name[ru]=Рисунок 1024x768, прозрачный фон
+Name[se]=Čađačuovgi 1024 × 768
+Name[sk]=Priehľadný 1024 x 768
+Name[sl]=Prosojna 1024 x 768
+Name[sr]=Провидна 1024 x 768
+Name[sr@Latn]=Providna 1024 x 768
+Name[sv]=Genomskinlig 1024 x 768
+Name[uk]=Прозоре 1024 x 768
+Name[uz]=Shaffof 1024 x 768
+Name[uz@cyrillic]=Шаффоф 1024 x 768
+Name[zh_CN]=透明 1024 x 768
+Name[zh_TW]=透明 1024 x 768
+Comment=Creates a transparent image of 1024 x 768 pixels.
+Comment[bg]=Създава прозрачно изображение с размери 1024x768 пиксела.
+Comment[ca]=Crea una imatge transparent de 1024 x 768 píxels.
+Comment[cy]=Creu delwedd dryloyw o 1024 x 768 picsel.
+Comment[da]=Laver et gennemsigtigt billede på 1024 x 768 billedpunkter.
+Comment[de]=Erstellt ein transparentes Bild mit 1024 x 768 Pixeln.
+Comment[el]=Δημιουργεί μία διαφανή εικόνα μεγέθους 1024 x 768 εικονοστοιχείων.
+Comment[eo]=Kreas travideblan bildon el 1024 x 768 rastrumeroj.
+Comment[es]=Crea una imagen transparente de 1024 x 768 píxeles.
+Comment[et]=Loob läbipaistva pildi mõõtmetega 1024 x 768 pikslit.
+Comment[eu]=1024 x 768 pixeleko irudi garden bat sortzen du.
+Comment[fa]=یک تصویر شفاف ۷۶۸ × ۱۰۲۴ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo läpinäkyvän 1024x768 pikselin kuvan.
+Comment[fr]=Crée une image transparente de 1024 x 768 pixels.
+Comment[fy]=Makket in trochsichtige ôfbylding oan fan 1024 x 768 byldpunten.
+Comment[gl]=Cria unha imaxe transparente de 1024 x 768 pixels.
+Comment[he]=יצירת תמונה שקופה בגודל ‎1024 x 768 פיקסלים
+Comment[hu]=Létrehoz egy 1024 x 768 képpontos áttetsző képet.
+Comment[is]=Býr til gegnsæja mynd í hlutföllunum 1024 x 768 punktar.
+Comment[it]=Crea un'immagine trasparente di 1024 × 768 pixel.
+Comment[ja]=1024 x 768 ピクセルの透視画像を作成
+Comment[km]=បង្កើត​រូបភាព​ថ្លា​ទំហំ 1024 x 768 ភីកសែល ។
+Comment[lt]=Sukuria permatomą 1024 x 768 pikselių paveiksliuką.
+Comment[ms]=Cipta imej lutsinar 1024 x 768 piksel.
+Comment[nb]=Lager et gjennomsiktig bilde på 1024 x 768 piksler.
+Comment[nds]=Stellt en dörsichtig Bild mit 1024 x 768 Pixels op.
+Comment[ne]=१०२४ x ७६८ पिक्सेलको पारदर्शी छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een transparante afbeelding aan van 1024 x 768 pixels.
+Comment[nn]=Lagar eit gjennomsiktig bilete på 1024 × 768 pikslar.
+Comment[pl]=Tworzy przezroczysty obrazek o rozmiarach 1024 x 768 pikseli.
+Comment[pt]=Cria uma imagem transparente com 1024 x 768 pontos.
+Comment[pt_BR]=Cria uma imagem transparente de 1024 x 768 pixels.
+Comment[ru]=Рисунок 1024x768, прозрачный фон
+Comment[se]=Ráhkada čađačuovgi gova mas t 1024 × 768 govvačuoggá
+Comment[sk]=Vytvorí obrázok s rozmermi 1024 x 768 pixelov a priehľadným pozadím.
+Comment[sl]=Ustvari prosojno sliko velikosti 1024 x 768 pik.
+Comment[sr]=Прави провидну слику са 1024 x 768 пиксела.
+Comment[sr@Latn]=Pravi providnu sliku sa 1024 x 768 piksela.
+Comment[sv]=Skapar en genomskinlig bild med 1024 x 768 bildpunkter.
+Comment[uk]=Створює прозоре зображення 1024 x 768 пікселів.
+Comment[uz]=Oʻlchami 1024 x 768 nuqta boʻlgan shaffof rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1024 x 768 нуқта бўлган шаффоф расмни яратиш.
+Comment[zh_CN]=创建 1024 x 768 像素的透明图像。
+Comment[zh_TW]=建立一個 1024 x 768 像素的透明圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1024x768.kra b/krita/colorspaces/rgb_u8/templates/transparent_1024x768.kra
new file mode 100644
index 00000000..eb026588
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1024x768.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.desktop b/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.desktop
new file mode 100644
index 00000000..58469cc6
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Type=Link
+URL=.source/transparent_1280x1024.kra
+Icon=template_rgb_empty
+Name=Transparent 1280 x 1024
+Name[bg]=Прозрачно 1280x1204
+Name[br]=Treuzwelus 1280 x 1024
+Name[cy]=Tryloyw 1280 x 1024
+Name[da]=Gennemsigtig 1280 x 1024
+Name[el]=Διαφανής 1280 x 1024
+Name[eo]=Travidebla 1280 x 1024
+Name[es]=1280 x 1024 transparente
+Name[et]=Läbipaistev 1280 x 1024
+Name[eu]=Gardena 1280 x 1024
+Name[fa]=شفاف ۱۰۲۴ × ۱۲۸۰
+Name[fi]=Läpinäkyvä 1280x1024
+Name[fr]=Image transparente 1280 x 1024
+Name[fy]=Trochsichtich 1280 x 1024
+Name[gl]=Transparente 1280 x 1024
+Name[he]=‏1280‎ x 1024 שקוף
+Name[hu]=Áttetsző 1280 x 1024
+Name[is]=Gegnsæ 1280 x 1024
+Name[it]=Trasparente 1280 × 1024
+Name[ja]=透明 1280 x 1024
+Name[km]=ថ្លា 1280 x 1024
+Name[lt]=Permatomas 1280 x 1024
+Name[lv]=Caurspīdīgs 1280 x 1024
+Name[ms]=Lutsinar 1280 x 1024
+Name[nb]=Gjennomsiktig 1280 x 1024
+Name[nds]=Dörsichtig 1280 x 1024
+Name[ne]=पारदर्शी १२८० x १०२४
+Name[nn]=Gjennomsiktig 1280 × 1024
+Name[pl]=Przezroczysty 1280 x 1024
+Name[pt]=Transparente 1280 x 1024
+Name[pt_BR]=Transparente de 1280 x 1024
+Name[ru]=Рисунок 1280x1024, прозрачный фон
+Name[se]=Čađačuovgi 1280 × 1024
+Name[sk]=Priehľadný 1280 x 1024
+Name[sl]=Prosojna 1280 x 1024
+Name[sr]=Провидна 1280 x 1024
+Name[sr@Latn]=Providna 1280 x 1024
+Name[sv]=Genomskinlig 1280 x 1024
+Name[uk]=Прозоре 1280 x 1024
+Name[uz]=Shaffof 1280 x 1024
+Name[uz@cyrillic]=Шаффоф 1280 x 1024
+Name[zh_CN]=透明 1280 x 1024
+Name[zh_TW]=透明 1280 x 1024
+Comment=Creates a transparent image of 1280 x 1024 pixels.
+Comment[bg]=Създава прозрачно изображение с размери 1280x1024 пиксела.
+Comment[ca]=Crea una imatge transparent de 1280 x 1024 píxels.
+Comment[cy]=Creu delwedd dryloyw o 1280 x 1024 picsel.
+Comment[da]=Laver et gennemsigtigt billede på 1280 x 1024 billedpunkter.
+Comment[de]=Erstellt ein transparentes Bild mit 1280 x 1024 Pixeln.
+Comment[el]=Δημιουργεί μία διαφανή εικόνα μεγέθους 1280 x 1024 εικονοστοιχείων.
+Comment[eo]=Kreas travideblan bildon el 1280 x 1024 rastrumeroj.
+Comment[es]=Crea una imagen transparente de 1280 x 1024 píxeles.
+Comment[et]=Loob läbipaistva pildi mõõtmetega 1280 x 1024 pikslit.
+Comment[eu]=1280 x 1024 pixeleko irudi garden bat sortzen du.
+Comment[fa]=یک تصویر شفاف ۱۰۲۴ × ۱۲۸۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo läpinäkyvän 1280x1024 pikselin kuvan.
+Comment[fr]=Crée une image transparente de 1280 x 1024 pixels.
+Comment[fy]=Makket in trochsichtige ôfbylding oan fan 1280 x 1024 byldpunten.
+Comment[gl]=Cria unha imaxe transparente de 1280 x 1024 pixels.
+Comment[he]=יצירת תמונה שקופה בגודל ‎1280 x 1024 פיקסלים
+Comment[hu]=Létrehoz egy 1280 x 1024 képpontos áttetsző képet.
+Comment[is]=Býr til gegnsæja mynd í hlutföllunum 1280 x 1024 punktar.
+Comment[it]=Crea un'immagine trasparente di 1280 × 1024 pixel.
+Comment[ja]=1280 x 1024 ピクセルの透視画像を作成
+Comment[km]=បង្កើត​រូបភាព​ថ្លា​ទំហំ 1280 x 1024 ភីកសែល ។
+Comment[lt]=Sukuria permatomą 1280 x 1024 pikselių paveiksliuką.
+Comment[ms]=Cipta imej lutsinar 1280 x 1024 piksel.
+Comment[nb]=Lager et gjennomsiktig bilde på 1280 x 1024 piksler.
+Comment[nds]=Stellt en dörsichtig Bild mit 1280 x 1024 Pixels op.
+Comment[ne]=१२८० x १०२४ पिक्सेलको पारदर्शी छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een transparante afbeelding aan van 1280 x 1024 pixels.
+Comment[nn]=Lagar eit gjennomsiktig bilete på 1280 × 1024 pikslar.
+Comment[pl]=Tworzy przezroczysty obrazek o rozmiarach 1280 x 1024 pikseli.
+Comment[pt]=Cria uma imagem transparente com 1280 x 1024 pontos.
+Comment[pt_BR]=Cria uma imagem transparente de 1280 x 1024 pixels.
+Comment[ru]=Рисунок 1280x1024, прозрачный фон
+Comment[se]=Ráhkada čađačuovgi gova mas lea 1280 × 1024 govvačuoggá
+Comment[sk]=Vytvorí obrázok s rozmermi 1280 x 1024 pixelov a priehľadným pozadím.
+Comment[sl]=Ustvari prosojno sliko velikosti 1280 x 1024 pik.
+Comment[sr]=Прави провидну слику са 1280 x 1024 пиксела.
+Comment[sr@Latn]=Pravi providnu sliku sa 1280 x 1024 piksela.
+Comment[sv]=Skapar en genomskinlig bild med 1280 x 1024 bildpunkter.
+Comment[uk]=Створює прозоре зображення 1280 x 1024 пікселів.
+Comment[uz]=Oʻlchami 1280 x 1024 nuqta boʻlgan shaffof rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1280 x 1024 нуқта бўлган шаффоф расмни яратиш.
+Comment[zh_CN]=创建 1280x 1024 像素的透明图像。
+Comment[zh_TW]=建立一個 1280 x 1024 像素的透明圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.kra b/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.kra
new file mode 100644
index 00000000..be96fb23
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1280x1024.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.desktop b/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.desktop
new file mode 100644
index 00000000..c4937805
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.desktop
@@ -0,0 +1,97 @@
+[Desktop Entry]
+Type=Link
+URL=.source/transparent_1600x1200.kra
+Icon=template_rgb_empty
+Name=Transparent 1600 x 1200
+Name[bg]=Прозрачно 1600x1200
+Name[br]=Treuzwelus 1600 x 1200
+Name[cy]=Tryloyw 1600 x 1200
+Name[da]=Gennemsigtig 1600 x 1200
+Name[el]=Διαφανής 1600 x 1200
+Name[es]=1600 x 1200 transparente
+Name[et]=Läbipaistev 1600 x 1200
+Name[eu]=Gardena 1600 x 1200
+Name[fa]=شفاف ۱۲۰۰ × ۱۶۰۰
+Name[fi]=Läpinäkyvä 1600x1200
+Name[fr]=Image transparente 1600 x 1200
+Name[fy]=Trochsichtich 1600 x 1200
+Name[gl]=Transparente 1600 x 1200
+Name[he]=‏1600‎ x 1200 שקוף
+Name[hi]=पारदर्शी 1600 x 1200
+Name[hu]=Áttetsző 1600 x 1200
+Name[is]=Gegnsæ 1600 x 1200
+Name[it]=Trasparente 1600 × 1200
+Name[ja]=透明 1600 x 1200
+Name[km]=ថ្លា 1600 x 1200
+Name[lt]=Permatomas 1600 x 1200
+Name[lv]=Caurspīdīgs 1600 x 1200
+Name[ms]=Lutsinar 1600 x 1200
+Name[nb]=Gjennomsiktig 1600 × 1200
+Name[nds]=Dörsichtig 1600 x 1200
+Name[ne]=पारदर्शी १६०० x १२००
+Name[nl]=Transparant 1600 x 1200
+Name[nn]=Gjennomsiktig 1600 × 1200
+Name[pl]=Przezroczysty 1600 x 1200
+Name[pt]=Transparente 1600 x 1200
+Name[pt_BR]=Transparente de 1600 x 1200
+Name[ru]=Рисунок 1600x1200, прозрачный фон
+Name[se]=Čađačuovgi 1600 × 1200
+Name[sk]=Priehľadný 1600 x 1200
+Name[sl]=Prosojna 1600 x 1200
+Name[sr]=Провидна 1600 x 1200
+Name[sr@Latn]=Providna 1600 x 1200
+Name[sv]=Genomskinlig 1600 x 1200
+Name[ta]=தெரியக்கூடிய 1600 x 1200
+Name[tr]=Saydam 1600 x 1200
+Name[uk]=Прозоре 1600 x 1200
+Name[uz]=Shaffof 1600 x 1200
+Name[uz@cyrillic]=Шаффоф 1600 x 1200
+Name[zh_CN]=透明 1600 x 1200
+Name[zh_TW]=透明 1600 x 1200
+Comment=Creates a transparent image of 1600 x 1200 pixels.
+Comment[bg]=Създаване на прозрачно изображение с размери 1600x1200 пиксела.
+Comment[ca]=Crea una imatge transparent de 1600 x 1200 píxels.
+Comment[cy]=Creu delwedd dryloyw o 1600 x 1200 picsel.
+Comment[da]=Laver et gennemsigtigt billede på 1600 x 1200 billedpunkter.
+Comment[de]=Erstellt ein transparentes Bild mit 1600 x 1200 Pixeln.
+Comment[el]=Δημιουργεί μία διαφανή εικόνα μεγέθους 1600 x 1200 εικονοστοιχείων.
+Comment[es]=Crea una imagen transparente de 1600 x 1200 píxeles.
+Comment[et]=Loob läbipaistva pildi mõõtmetega 1600 x 1200 pikslit.
+Comment[eu]=1600 x 1200 pixeleko irudi garden bat sortzen du.
+Comment[fa]=یک تصویر شفاف ۱۲۰۰ × ۱۶۰۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo läpinäkyvän 1600x1200 pikselin kuvan.
+Comment[fr]=Crée une image transparente de 1600 x 1200 pixels.
+Comment[fy]=Makket in trochsichtige ôfbylding oan fan 11600 x 1200 byldpunten.
+Comment[gl]=Cria unha imaxe transparente de 1600 x 1200 pixels.
+Comment[he]=יצירת תמונה שקופה בגודל ‎1600 x 1200 פיקסלים
+Comment[hi]=1600 x 1200 पिक्सेल की पारदर्शी छवि बनाता है.
+Comment[hu]=Létrehoz egy 1600 x 1200 képpontos áttetsző képet.
+Comment[is]=Býr til gegnsæja mynd í hlutföllunum 1600 x 1200 punktar.
+Comment[it]=Crea un'immagine trasparente di 1600 × 1200 pixel.
+Comment[ja]=1600 x 1200 ピクセルの透視画像を作成
+Comment[km]=បង្កើត​រូបភាព​ថ្លា​ទំហំ 1600 x 1200 ភីកសែល ។
+Comment[lt]=Sukuria permatomą 1600 x 1200 pikselių paveiksliuką.
+Comment[ms]=Cipta imej lutsinar 1600 x 1200 piksel.
+Comment[nb]=Lager et gjennomsiktig bilde på 1600 x 1200 piksler.
+Comment[nds]=Stellt en dörsichtig Bild mit 1600 x 1200 Pixels op.
+Comment[ne]=१६०० x १२०० पिक्सेलको पारदर्शी छवि सिर्जना गर्दछ।
+Comment[nl]=Maakt een transparante afbeelding aan van 1600 x 1200 pixels.
+Comment[nn]=Lagar eit gjennomsiktig bilete på 1600 × 1200 pikslar.
+Comment[pl]=Tworzy przezroczysty obrazek o rozmiarach 1600 x 1200 pikseli.
+Comment[pt]=Cria uma imagem transparente com 1600 x 1200 pontos.
+Comment[pt_BR]=Cria uma imagem transparente de 1600 x 1200 pixéis.
+Comment[ru]=Рисунок 1600x1200, прозрачный фон
+Comment[se]=Ráhkada čađačuovgi gova mas lea 1600 × 1200 govvačuoggá.
+Comment[sk]=Vytvorí obrázok s rozmermi 1600 x 1200 pixelov a priehľadným pozadím.
+Comment[sl]=Ustvari prosojno sliko velikosti 1600 x 1200 pik.
+Comment[sr]=Прави провидну слику са 1600 x 1200 пиксела.
+Comment[sr@Latn]=Pravi providnu sliku sa 1600 x 1200 piksela.
+Comment[sv]=Skapar en genomskinlig bild med 1600 x 1200 bildpunkter.
+Comment[ta]=1600 x 1200 படத்துணுக்குகளில் ஒரு தெரியக்கூடிய பிம்பத்தை உருவாக்குகிறது.
+Comment[tr]=1600 x 1200 piksel ebadında transparan bir görüntü oluşturur.
+Comment[uk]=Створює прозоре зображення 1600 x 1200 пікселів.
+Comment[uz]=Oʻlchami 1600 x 1200 nuqta boʻlgan shaffof rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1600 x 1200 нуқта бўлган шаффоф расмни яратиш.
+Comment[zh_CN]=创建 1600 x 1200 像素的透明图像。
+Comment[zh_TW]=建立一個 1600 x 1200 像素的透明圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.kra b/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.kra
new file mode 100644
index 00000000..b01685a9
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_1600x1200.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_640x480.desktop b/krita/colorspaces/rgb_u8/templates/transparent_640x480.desktop
new file mode 100644
index 00000000..7dec238a
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_640x480.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Type=Link
+URL=.source/transparent_640x480.kra
+Icon=template_rgb_empty
+Name=Transparent 640 x 480
+Name[bg]=Прозрачно 640x480
+Name[br]=Treuzwelus 640 x 480
+Name[cy]=Tryloyw 640 x 480
+Name[da]=Gennemsigtig 640 x 480
+Name[el]=Διαφανής 640 x 480
+Name[eo]=Travidebla 640 x 480
+Name[es]=640 x 480 transparente
+Name[et]=Läbipaistev 640 x 480
+Name[eu]=Gardena 640 x 480
+Name[fa]=شفاف ۴۸۰ × ۶۴۰
+Name[fi]=Läpinäkyvä 640x480
+Name[fr]=Image transparente 640 x 480
+Name[fy]=Trochsichtich 640 x 480
+Name[gl]=Transparente 640 x 480
+Name[he]=‏640 x 480 שקוף
+Name[hu]=Áttetsző 640 x 480
+Name[is]=Gegnsæ 640 x 480
+Name[it]=Trasparente 640 × 480
+Name[ja]=透明 640 x 480
+Name[km]=ថ្លា 640 x 480
+Name[lt]=Permatomas 640 x 480
+Name[lv]=Caurspīdīgs 640 x 480
+Name[ms]=Lutsinar 640 x 480
+Name[nb]=Gjennomsiktig 640 x 480
+Name[nds]=Dörsichtig 640 x 480
+Name[ne]=पारदर्शी ६४० x ४८०
+Name[nn]=Gjennomsiktig 640 × 480
+Name[pl]=Przezroczysty 640 x 480
+Name[pt]=Transparente 640 x 480
+Name[pt_BR]=Transparente de 640 x 480
+Name[ru]=Рисунок 640x480, прозрачный фон
+Name[se]=Čađačuovgi 640 × 480
+Name[sk]=Priehľadný 640 x 480
+Name[sl]=Prosojna 640 x 480
+Name[sr]=Провидна 640 x 480
+Name[sr@Latn]=Providna 640 x 480
+Name[sv]=Genomskinlig 640 x 480
+Name[uk]=Прозоре 640 x 480
+Name[uz]=Shaffof 640 x 480
+Name[uz@cyrillic]=Шаффоф 640 x 480
+Name[zh_CN]=透明 640 x 480
+Name[zh_TW]=透明 640 x 480
+Comment=Creates a transparent image of 640 x 480 pixels.
+Comment[bg]=Създаване на прозрачно изображение с размери 640x480 пиксела.
+Comment[ca]=Crea una imatge transparent de 640 x 480 píxels.
+Comment[cy]=Creu delwedd dryloyw o 640 x 480 picsel.
+Comment[da]=Laver et gennemsigtigt billede på 640 x 480 billedpunkter.
+Comment[de]=Erstellt ein transparentes Bild mit 640 x 480 Pixeln.
+Comment[el]=Δημιουργεί μία διαφανή εικόνα μεγέθους 640 x 480 εικονοστοιχείων.
+Comment[eo]=Kreas travideblan bildon el 640 x 480 rastrumeroj.
+Comment[es]=Crea una imagen transparente de 640 x 480 píxeles.
+Comment[et]=Loob läbipaistva pildi mõõtmetega 640 x 480 pikslit.
+Comment[eu]=640 x 480 pixeleko irudi garden bat sortzen du.
+Comment[fa]=یک تصویر شفاف ۴۸۰ × ۶۴۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo läpinäkyvän 640x480 pikselin kuvan.
+Comment[fr]=Crée une image transparente de 640 x 480 pixels.
+Comment[fy]=Makket in trochsichtige ôfbylding oan fan 640 x 480 byldpunten.
+Comment[gl]=Cria unha imaxe transparente de 640 x 480 pixels.
+Comment[he]=יצירת תמונה שקופה בגודל ‎640 x 480 פיקסלים
+Comment[hu]=Létrehoz egy 640 x 480 képpontos áttetsző képet.
+Comment[is]=Býr til gegnsæja mynd í hlutföllunum 640 x 480 punktar.
+Comment[it]=Crea un'immagine trasparente di 640 × 480 pixel.
+Comment[ja]=640 x 480 ピクセルの透視画像を作成
+Comment[km]=បង្កើត​រូបភាព​ថ្លា​ទំហំ 640 x 480 ភីកសែល ។
+Comment[lt]=Sukuria permatomą 640 x 480 pikselių paveiksliuką.
+Comment[ms]=Cipta imej lutsinar 640 x 480 piksel.
+Comment[nb]=Lager et gjennomsiktig bilde på 640 x 480 piksler.
+Comment[nds]=Stellt en dörsichtig Bild mit 640 x 480 Pixels op.
+Comment[ne]=६४० x ४८० पिक्सेलको पारदर्शी सिर्जना गर्दछ ।
+Comment[nl]=Maakt een transparante afbeelding aan van 640 x 480 pixels.
+Comment[nn]=Lagar eit gjennomsiktig bilete på 640 × 480 pikslar.
+Comment[pl]=Tworzy przezroczysty obrazek o rozmiarach 640 x 480 pikseli.
+Comment[pt]=Cria uma imagem transparente com 640 x 480 pontos.
+Comment[pt_BR]=Cria uma imagem transparente de 640 x 480 pixels.
+Comment[ru]=Рисунок 640x480, прозрачный фон
+Comment[se]=Ráhkada čađačuovgi gova mas lea 640 × 480 govvačuoggá.
+Comment[sk]=Vytvorí obrázok s rozmermi 640 x 480 pixelov a priehľadným pozadím.
+Comment[sl]=Ustvari prosojno sliko velikosti 640 x 480 pik.
+Comment[sr]=Прави провидну слику са 640 x 480 пиксела.
+Comment[sr@Latn]=Pravi providnu sliku sa 640 x 480 piksela.
+Comment[sv]=Skapar en genomskinlig bild med 640 x 480 bildpunkter.
+Comment[uk]=Створює прозоре зображення 640 x 480 пікселів.
+Comment[uz]=Oʻlchami 640 x 480 nuqta boʻlgan shaffof rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 640 x 480 нуқта бўлган шаффоф расмни яратиш.
+Comment[zh_CN]=创建 640 x 480 像素的透明图像。
+Comment[zh_TW]=建立一個 640 x 480 像素的透明圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/transparent_640x480.kra b/krita/colorspaces/rgb_u8/templates/transparent_640x480.kra
new file mode 100644
index 00000000..59777c92
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/transparent_640x480.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/white_1024x768.desktop b/krita/colorspaces/rgb_u8/templates/white_1024x768.desktop
new file mode 100644
index 00000000..57f097bf
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1024x768.desktop
@@ -0,0 +1,102 @@
+[Desktop Entry]
+Type=Link
+URL=.source/white_1024x768.kra
+Icon=template_rgb_empty
+Name=White 1024 x 768
+Name[bg]=Бяло 1024x768
+Name[br]=Gwenn 1024 x 768
+Name[ca]=Blanc 1024 x 768
+Name[cy]=Gwyn 1024 x 768
+Name[da]=Hvidt 1024 x 768
+Name[de]=Weiß 1024 x 768
+Name[el]=Λευκή 1024 x 768
+Name[eo]=Blanka 1024 x 768
+Name[es]=1024 x 768 blanco
+Name[et]=Valge 1024 x 768
+Name[eu]=Zuria 1024 x 768
+Name[fa]=سفید ۷۶۸ × ۱۰۲۴
+Name[fi]=Valkoinen 1024x768
+Name[fr]=Image blanche 1024 x 768
+Name[fy]=Wyt 1024 x 768
+Name[ga]=Bán 1024×768
+Name[gl]=Branca 1024 x 768
+Name[he]=לבן ‎1024 x 768
+Name[hi]=सफेद 1024 x 768
+Name[hu]=Fehér 1024 x 768
+Name[is]=Hvít 1024 x 768
+Name[it]=Bianco 1024 × 768
+Name[ja]=白 1024 x 768
+Name[km]=ពណ៌ស 1024 x 768
+Name[lt]=Baltas 1024 x 768
+Name[lv]=Balts 1024 x 768
+Name[ms]=Putih 1024 x 768
+Name[nb]=Hvitt 1024 x 768
+Name[nds]=Witt 1024 x 768
+Name[ne]=सेतो १०२४ x ७६८
+Name[nl]=Wit 1024 x 768
+Name[nn]=Kvitt 1024 × 768
+Name[pl]=Biały 1024 x 768
+Name[pt]=Branca 1024 x 768
+Name[pt_BR]=1024 x 768 em Branco
+Name[ru]=Рисунок 1024x768, белый фон
+Name[se]=Vilges 1024 × 768
+Name[sk]=Biely 1024 x 768
+Name[sl]=Bela 1024 x 768
+Name[sr]=Бела 1024 x 768
+Name[sr@Latn]=Bela 1024 x 768
+Name[sv]=Vit 1024 x 768
+Name[ta]=வெள்ளை 1024 x 768
+Name[tr]=Beyaz 1024 x 768
+Name[uk]=Біле 1024 x 768
+Name[uz]=Oq 1024 x 768
+Name[uz@cyrillic]=Оқ 1024 x 768
+Name[zh_CN]=白色 1024 x 768
+Name[zh_TW]=白色 1024 x 768
+Comment=Creates a white RGB image of 1024 x 768 pixels.
+Comment[bg]=Създаване на бяло изображение RGB с размери 1024x768 пиксела.
+Comment[ca]=Crea una imatge blanca RGB de 1024 x 768 píxels.
+Comment[cy]=Creu delwedd RGB wen o 1024 x 768 picsel.
+Comment[da]=Laver et hvidt RGB-billede på 1024 x 768 billedpunkter.
+Comment[de]=Erstellt ein weißes RGB-Bild mit 1024 x 768 Pixeln.
+Comment[el]=Δημιουργεί μία λευκή RGB εικόνα μεγέθους 1024 x 768 εικονοστοιχείων.
+Comment[eo]=Kreas blankan RGB-bildon el 1024 x 768 rastrumeroj.
+Comment[es]=Crea una imagen RGB de 1024 x 768 píxeles.
+Comment[et]=Loob valge RGB-pildi mõõtmetega 1024 x 768 pikslit.
+Comment[eu]=1024 x 768 pixeleko RGB irudi zuri bat sortzen du.
+Comment[fa]=یک تصویر RGB سفید ۷۶۸ × ۱۰۲۴ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo valkoisen 1024x768 pikselin RGB-kuvan.
+Comment[fr]=Crée une image blanche RVB de 1024 x 768 pixels.
+Comment[fy]=Makket in wite RGB-ôfbylding oan fan 1024 x 768 byldpunten.
+Comment[gl]=Cria unha imaxe RGB branca de 1024 x 768 pixels.
+Comment[he]=יצירת תמונת RGB לבנה בגודל ‎1024 x 768 פיקסלים
+Comment[hi]=1024 x 768 पिक्सेल की सफेद आरजीबी छवि बनाता है.
+Comment[hu]=Létrehoz egy 1024 x 768 képpontos fehér RGB képet.
+Comment[is]=Býr til hvíta RGB mynd í hlutföllunum 1024 x 768 punktar.
+Comment[it]=Crea un'immagine RGB bianca di 1024 × 768 pixel.
+Comment[ja]=1024 x 768 ピクセルの RGB 画像を作成
+Comment[km]=បង្កើត​រូបភាព RGB ពណ៌​ស​ទំហំ 1024 x 768 ភីកសែល ។
+Comment[lt]=Sukuria baltą 1024 x 768 pikselių RGB paveiksliuką.
+Comment[ms]=Cipta imej RGB putih 1024 x 768 piksel.
+Comment[nb]=Lager et hvitt RGB-bilde på 1024 x 768 piksler.
+Comment[nds]=Stellt en witt RGB-Bild mit 1024 x 768 Pixels op.
+Comment[ne]=१०२४ x ७६८ पिक्सेलको सेतो RGB छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een witte RGB-afbeelding aan van 1024 x 768 pixels.
+Comment[nn]=Lagar eit kvitt RGB-bilete på 1024 × 768 pikslar.
+Comment[pl]=Tworzy biały obrazek RGB o rozmiarach 1024 x 768 pikseli.
+Comment[pt]=Cria uma imagem RGB branca com 1024 x 768 pontos.
+Comment[pt_BR]=Cria uma imagem RGB em branco de 1024 x 768 pixéis.
+Comment[ru]=Рисунок RGB 1024x768, белый фон
+Comment[se]=Ráhkada vilges RGB-gova mas lea 1024 × 768 govvačuoggá.
+Comment[sk]=Vytvorí RGB obrázok s rozmermi 1024 x 768 pixelov a bielym pozadím.
+Comment[sl]=Ustvari belo sliko RGB velikosti 1024 x 768 pik.
+Comment[sr]=Прави белу RGB слику са 1024 x 768 пиксела.
+Comment[sr@Latn]=Pravi belu RGB sliku sa 1024 x 768 piksela.
+Comment[sv]=Skapar en vit RGB-bild med 1024 x 768 bildpunkter.
+Comment[ta]=1024 x 768 படத்துணுக்குகளில் ஒரு வெள்ளை RGB பிம்பத்தை உருவாக்குகிறது.
+Comment[tr]=1024 x 768 piksel ebadında beyaz bir RGB görüntü oluşturur.
+Comment[uk]=Створює біле зображення у форматі RGB, 640 x 480 пікселів.
+Comment[uz]=Oʻlchami 1024 x 768 nuqta boʻlgan oq RGB rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1024 x 768 нуқта бўлган оқ RGB расмни яратиш.
+Comment[zh_CN]=创建 1024 x 768 像素的 RGB 白色背景图像。
+Comment[zh_TW]=建立一個 1024 x 768 像素的白色 RGB 圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/white_1024x768.kra b/krita/colorspaces/rgb_u8/templates/white_1024x768.kra
new file mode 100644
index 00000000..0a7702ad
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1024x768.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/white_1280x1024.desktop b/krita/colorspaces/rgb_u8/templates/white_1280x1024.desktop
new file mode 100644
index 00000000..a6363424
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1280x1024.desktop
@@ -0,0 +1,95 @@
+[Desktop Entry]
+Type=Link
+URL=.source/white_1280x1024.kra
+Icon=template_rgb_empty
+Name=White 1280 x 1024
+Name[bg]=Бяло 1280x1024
+Name[br]=Gwenn 1280 x 1024
+Name[ca]=Blanc 1280 x 1024
+Name[cy]=Gwyn 1280 x 1024
+Name[da]=Hvidt 1280 x 1024
+Name[de]=Weiß 1280 x 1024
+Name[el]=Λευκή 1280 x 1024
+Name[eo]=Blanka 1280 x 1024
+Name[es]=1280 x 1024 blanco
+Name[et]=Valge 1280 x 1024
+Name[eu]=Zuria 1280 x 1024
+Name[fa]=سفید ۱۰۲۴ × ۱۲۸۰
+Name[fi]=Valkoinen 1280x1024
+Name[fr]=Image blanche 1280 x 1024
+Name[fy]=Wyt 1280 x 1024
+Name[ga]=Bán 1280×1024
+Name[gl]=Branca 1280 x 1024
+Name[he]=לבן ‎1280 x 1024
+Name[hu]=Fehér 1280 x 1024
+Name[is]=Hvít 1280 x 1024
+Name[it]=Bianco 1280 × 1024
+Name[ja]=白 1280 x 1024
+Name[km]=ពណ៌ស 1280 x 1024
+Name[lt]=Baltas 1280 x 1024
+Name[lv]=Balts 1280 x 1024
+Name[ms]=Putih 1280 x 1024
+Name[nb]=Hvit 1280 x 1024
+Name[nds]=Witt 1280 x 1024
+Name[ne]=सेतो १२८० x १०२४
+Name[nn]=Kvitt 1280 × 1024
+Name[pl]=Biały 1280 x 1024
+Name[pt]=Branca 1280 x 1024
+Name[pt_BR]=1280 x 1024 em Branco
+Name[ru]=Рисунок 1280x1024, белый фон
+Name[se]=Vilges 1280 × 1024
+Name[sk]=Biely 1280 x 1024
+Name[sl]=Bela 1280 x 1024
+Name[sr]=Бела 1280 x 1024
+Name[sr@Latn]=Bela 1280 x 1024
+Name[sv]=Vit 1280 x 1024
+Name[uk]=Біле 1280 x 1024
+Name[uz]=Oq 1280 x 1024
+Name[uz@cyrillic]=Оқ 1280 x 1024
+Name[zh_CN]=白色 1280 x 1024
+Name[zh_TW]=白色 1280 x 1024
+Comment=Creates a white RGB image of 1280 x 1024 pixels.
+Comment[bg]=Създаване на бяло изображение RGB с размери 1280x1024 пиксела.
+Comment[ca]=Crea una imatge blanca RGB de 1280 x 1024 píxels.
+Comment[cy]=Creu delwedd RGB wen o 1280 x 1024 picsel.
+Comment[da]=Laver et hvidt RGB-billede på 1280 x 1024 billedpunkter.
+Comment[de]=Erstellt ein weißes RGB-Bild mit 1280 x 1024 Pixeln.
+Comment[el]=Δημιουργεί μία λευκή RGB εικόνα μεγέθους 1280 x 1024 εικονοστοιχείων.
+Comment[eo]=Kreas blankan RGB-bildon el 1280 x 1024 rastrumeroj.
+Comment[es]=Crea una imagen RGB de 1280 x 1024 píxeles.
+Comment[et]=Loob valge RGB-pildi mõõtmetega 61280 x 1024 pikslit.
+Comment[eu]=1280 x 1024 pixeleko RGB irudi zuri bat sortzen du.
+Comment[fa]=یک تصویر RGB سفید ۱۰۲۴ × ۱۲۸۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo valkoisen 1280x1024 pikselin RGB-kuvan.
+Comment[fr]=Crée une image blanche RVB de 1280 x 1024 pixels.
+Comment[fy]=Makket in wite RGB-ôfbylding oan fan 1280 x 768 byldpunten.
+Comment[gl]=Cria unha imaxe RGB branca de 1280 x 1024 pixels.
+Comment[he]=יצירת תמונת RGB לבנה בגודל ‎1280 x 1024 פיקסלים
+Comment[hu]=Létrehoz egy 1280 x 1024 képpontos fehér RGB képet.
+Comment[is]=Býr til hvíta RGB mynd í hlutföllunum 1280 x 1024 punktar.
+Comment[it]=Crea un'immagine RGB bianca di 1280 × 1024 pixel.
+Comment[ja]=1280 x 1024 ピクセルの RGB 画像を作成
+Comment[km]=បង្កើត​រូបភាព RGB ពណ៌ស​ទំហំ 1280 x 1024 ភីកសែល ។
+Comment[lt]=Sukuria baltą 1280 x 1024 pikselių RGB paveiksliuką.
+Comment[ms]=Cipta imej RGB putih 1280 x 1024 piksel.
+Comment[nb]=Lager et hvitt bilde på 1280 x 1024 piksler.
+Comment[nds]=Stellt en witt RGB-Bild mit 1280 x 1024 Pixels op.
+Comment[ne]=१२८० x १०२४ पिक्सेलको सेतो RGB छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een witte RGB-afbeelding aan van 1280 x 1024 pixels.
+Comment[nn]=Lagar eit kvitt RGB-bilete på 1280 × 1024 pikslar.
+Comment[pl]=Tworzy biały obrazek RGB o rozmiarach 1280 x 1024 pikseli.
+Comment[pt]=Cria uma imagem RGB branca com 1280 x 1024 pontos.
+Comment[pt_BR]=Cria uma imagem RGB em branco de 1280 x 1024 pixels.
+Comment[ru]=Рисунок RGB 1280x1024, белый фон
+Comment[se]=Ráhkada vilges RGB-gova mas lea 1280 × 1024 govvačuoggá.
+Comment[sk]=Vytvorí RGB obrázok s rozmermi 1280 x 1024 pixelov a bielym pozadím.
+Comment[sl]=Ustvari belo sliko RGB velikosti 1280 x 1024 pik.
+Comment[sr]=Прави белу RGB слику са 1280 x 1024 пиксела.
+Comment[sr@Latn]=Pravi belu RGB sliku sa 1280 x 1024 piksela.
+Comment[sv]=Skapar en vit RGB-bild med 1280 x 1024 bildpunkter.
+Comment[uk]=Створює біле зображення у форматі RGB, 1280 x 1024 пікселів.
+Comment[uz]=Oʻlchami 1280 x 1024 nuqta boʻlgan oq RGB rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1280 x 1024 нуқта бўлган оқ RGB расмни яратиш.
+Comment[zh_CN]=创建 1080 x 1024 像素的 RGB 白色背景图像。
+Comment[zh_TW]=建立一個 1280 x 1024 像素的白色 RGB 圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/white_1280x1024.kra b/krita/colorspaces/rgb_u8/templates/white_1280x1024.kra
new file mode 100644
index 00000000..8d552419
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1280x1024.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/white_1600x1200.desktop b/krita/colorspaces/rgb_u8/templates/white_1600x1200.desktop
new file mode 100644
index 00000000..bb43573f
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1600x1200.desktop
@@ -0,0 +1,95 @@
+[Desktop Entry]
+Type=Link
+URL=.source/white_1600x1200.kra
+Icon=template_rgb_empty
+Name=White 1600 x 1200
+Name[bg]=Бяло 1600x1200
+Name[br]=Gwenn 1600 x 1200
+Name[ca]=Blanc 1600 x 1200
+Name[cy]=Gwyn 1600 x 1200
+Name[da]=Hvidt 1600 x 1200
+Name[de]=Weiß 1600 x 1200
+Name[el]=Λευκή 1600 x 1200
+Name[eo]=Blanka 1600 x 1200
+Name[es]=1600 x 1200 blanco
+Name[et]=Valge 1600 x 1200
+Name[eu]=Zuria 1600 x 1200
+Name[fa]=سفید ۱۲۰۰ × ۱۶۰۰
+Name[fi]=Valkoinen 1600x1200
+Name[fr]=Image blanche 1600 x 1200
+Name[fy]=Wyt 1600 x 1200
+Name[ga]=Bán 1600×1200
+Name[gl]=Branca 1600 x 1200
+Name[he]=לבן ‎1600 x 1200
+Name[hu]=Fehér 1600 x 1200
+Name[is]=Hvít 1600 x 1200
+Name[it]=Bianco 1600 × 1200
+Name[ja]=白 1600 x 1200
+Name[km]=ពណ៌ស 1600 x 1200
+Name[lt]=Baltas 1600 x 1200
+Name[lv]=Balts 1600 x 1200
+Name[ms]=Putih 1600 x 1200
+Name[nb]=Hvit 1600 x 1200
+Name[nds]=Witt 1600 x 1200
+Name[ne]=सेतो १६०० x १२००
+Name[nn]=Kvitt 1600 × 1200
+Name[pl]=Biały 1600 x 1200
+Name[pt]=Branca 1600 x 1200
+Name[pt_BR]=1600 x 1200 em Branco
+Name[ru]=Рисунок 1600x1200, белый фон
+Name[se]=Vilges 1600 × 1200
+Name[sk]=Biely 1600 x 1200
+Name[sl]=Bela 1600 x 1200
+Name[sr]=Бела 1600 x 1200
+Name[sr@Latn]=Bela 1600 x 1200
+Name[sv]=Vit 1600 x 1200
+Name[uk]=Біле 1600 x 1200
+Name[uz]=Oq 1600 x 1200
+Name[uz@cyrillic]=Оқ 1600 x 1200
+Name[zh_CN]=白色 1600 x 1200
+Name[zh_TW]=白色 1600 x 1200
+Comment=Creates a white RGB image of 1600 x 1200 pixels.
+Comment[bg]=Създаване на бяло изображение RGB с размери 1600x1200 пиксела.
+Comment[ca]=Crea una imatge blanca RGB de 1600 x 1200 píxels.
+Comment[cy]=Creu delwedd RGB wen o 1600 x 1200 picsel.
+Comment[da]=Laver et hvidt RGB-billede på 1600 x 1200 billedpunkter.
+Comment[de]=Erstellt ein weißes RGB-Bild mit 1600 x 1200 Pixeln.
+Comment[el]=Δημιουργεί μία λευκή RGB εικόνα μεγέθους 1600 x 1200 εικονοστοιχείων.
+Comment[eo]=Kreas blankan RGB-bildon el 1600 x 1200 rastrumeroj.
+Comment[es]=Crea una imagen RGB de 1600 x 1200 píxeles.
+Comment[et]=Loob valge RGB-pildi mõõtmetega 1600 x 1200 pikslit.
+Comment[eu]=1600 x 1200 pixeleko RGB irudi zuri bat sortzen du.
+Comment[fa]=یک تصویر RGB سفید ۱۲۰۰ × ۱۶۰۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo valkoisen 1600x1200 pikselin RGB-kuvan.
+Comment[fr]=Crée une image blanche RVB de 1600 x 1200 pixels.
+Comment[fy]=Makket in wite RGB-ôfbylding oan fan 1600 x 1200 byldpunten.
+Comment[gl]=Cria unha imaxe RGB branca de 1600 x 1200 pixels.
+Comment[he]=יצירת תמונת RGB לבנה בגודל ‎1600 x 1200 פיקסלים
+Comment[hu]=Létrehoz egy 1600 x 1200 képpontos fehér RGB képet.
+Comment[is]=Býr til hvíta RGB mynd í hlutföllunum 1600 x 1200 punktar.
+Comment[it]=Crea un'immagine RGB bianca di 1600 × 1200 pixel.
+Comment[ja]=1600 x 1200 ピクセルの RGB 画像を作成
+Comment[km]=បង្កើត​រូបភាព RGB ពណ៌ស​ទំហំ 1600 x 1200 ភីកសែល ។
+Comment[lt]=Sukuria baltą 1600 x 1200 pikselių RGB paveiksliuką.
+Comment[ms]=Cipta imej RGB putih 1600 x 1200 piksel.
+Comment[nb]=Lager et hvitt bilde på 1600 x 1200 piksler.
+Comment[nds]=Stellt en witt RGB-Bild mit 1600 x 1200 Pixels op
+Comment[ne]=१६०० x १२०० पिक्सेलको सेतो RGB छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een witte RGB-afbeelding aan van 1600 x 1200 pixels.
+Comment[nn]=Lagar eit kvitt RGB-bilete på 1600 × 1200 pikslar.
+Comment[pl]=Tworzy biały obrazek RGB o rozmiarach 1600 x1200 pikseli.
+Comment[pt]=Cria uma imagem RGB branca com 1600 x 1200 pontos.
+Comment[pt_BR]=Cria uma imagem RGB em branco de 1600 x 1200 pixels.
+Comment[ru]=Рисунок RGB 1600x1200, белый фон
+Comment[se]=Ráhkada vilges RGB-gova mas lea 1600 × 1200 govvačuoggá.
+Comment[sk]=Vytvorí RGB obrázok s rozmermi 1600 x 1200 pixelov a bielym pozadím.
+Comment[sl]=Ustvari belo sliko RGB velikosti 1600 x 1200 pik.
+Comment[sr]=Прави белу RGB слику са 1600 x 1200 пиксела.
+Comment[sr@Latn]=Pravi belu RGB sliku sa 1600 x 1200 piksela.
+Comment[sv]=Skapar en vit RGB-bild med 1600 x 1200 bildpunkter.
+Comment[uk]=Створює біле зображення у форматі RGB, 1600 x 1200 пікселів.
+Comment[uz]=Oʻlchami 1600 x 1200 nuqta boʻlgan oq RGB rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 1600 x 1200 нуқта бўлган оқ RGB расмни яратиш.
+Comment[zh_CN]=创建 1600 x 1200 像素的 RGB 白色背景图像。
+Comment[zh_TW]=建立一個 1600 x 1200 像素的白色 RGB 圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/white_1600x1200.kra b/krita/colorspaces/rgb_u8/templates/white_1600x1200.kra
new file mode 100644
index 00000000..7c037d9e
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_1600x1200.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/templates/white_640x480.desktop b/krita/colorspaces/rgb_u8/templates/white_640x480.desktop
new file mode 100644
index 00000000..2babefbf
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_640x480.desktop
@@ -0,0 +1,102 @@
+[Desktop Entry]
+Type=Link
+URL=.source/white_640x480.kra
+Icon=template_rgb_empty
+Name=White 640x480
+Name[bg]=Бяло 640x480
+Name[br]=Gwenn 640x480
+Name[ca]=Blanc 640x480
+Name[cy]=Gwyn 640 x 480
+Name[da]=Hvidt 640x480
+Name[de]=Weiß 640x480
+Name[el]=Λευκή 640x480
+Name[eo]=Blanka 640x480
+Name[es]=640x480 blanco
+Name[et]=Valge 640x480
+Name[eu]=Zuria 640x480
+Name[fa]=سفید ۴۸۰ × ۶۴۰
+Name[fi]=Valkoinen 640x480
+Name[fr]=Image blanche 640 x 480
+Name[fy]=Wyt 640x480
+Name[ga]=Bán 640×480
+Name[gl]=Branca 640x480
+Name[he]=לבן 640x480
+Name[hi]=सफेद 640x480
+Name[hu]=Fehér 640 x 480
+Name[is]=Hvít 640x480
+Name[it]=Bianco 640×480
+Name[ja]=白 640 x 480
+Name[km]=ពណ៌​ស​640 x 480
+Name[lt]=Baltas 640x480
+Name[lv]=Balts 640x480
+Name[ms]=Putih 640x480
+Name[nb]=Hvitt 640 x 480
+Name[nds]=Witt 640x480
+Name[ne]=सेतो ६४०x४८०
+Name[nl]=Wit 640 x 480
+Name[nn]=Kvitt 640 × 480
+Name[pl]=Biały 640x480
+Name[pt]=Branca 640x480
+Name[pt_BR]=640x480 em Branco
+Name[ru]=Рисунок 640x480, белый фон
+Name[se]=Vilges 640 × 480
+Name[sk]=Biely 640x480
+Name[sl]=Bela 640x480
+Name[sr]=Бела 640x480
+Name[sr@Latn]=Bela 640x480
+Name[sv]=Vit 640x480
+Name[ta]=வெள்ளை 640x480
+Name[tr]=Beyaz 640x480
+Name[uk]=Біле 640x480
+Name[uz]=Oq 640 x 480
+Name[uz@cyrillic]=Оқ 640 x 480
+Name[zh_CN]=白色 640 x 480
+Name[zh_TW]=白色 640x480
+Comment=Creates a white RGB image of 640 x 480 pixels.
+Comment[bg]=Създаване на бяло изображение RGB с размери 640x480 пиксела.
+Comment[ca]=Crea una imatge blanca RGB de 640 x 480 píxels.
+Comment[cy]=Creu delwedd RGB wen o 640 x 480 picsel.
+Comment[da]=Laver et hvidt RGB-billede på 640 x 480 billedpunkter.
+Comment[de]=Erstellt ein weißes RGB-Bild mit 640 x 480 Pixeln.
+Comment[el]=Δημιουργεί μία λευκή RGB εικόνα μεγέθους 640 x 480 εικονοστοιχείων.
+Comment[eo]=Kreas blankan RGB-bildon el 640 x 480 rastrumeroj.
+Comment[es]=Crea una imagen RGB de 640 x 480 píxeles.
+Comment[et]=Loob valge RGB pildi mõõtmetega 640 x 480 pikslit.
+Comment[eu]=640 x 480 pixeleko RGB irudi zuri bat sortzen du.
+Comment[fa]=یک تصویر RGB سفید ۴۸۰ × ۶۴۰ تصویردانه‌ای ایجاد می‌کند.
+Comment[fi]=Luo valkoisen 640x480 pikselin RGB-kuvan.
+Comment[fr]=Crée une image blanche RVB de 640 x 480 pixels.
+Comment[fy]=Makket in wite RGB-ôfbylding oan fan 640 x 480 byldpunten.
+Comment[gl]=Cria unha imaxe RGB branca de 640 x 480 pixels.
+Comment[he]=יצירת תמונת RGB לבנה בגודל ‎640 x 480 פיקסלים
+Comment[hi]=640 x 480 पिक्सेल का, सफेद आरजीबी छवि बनाता है
+Comment[hu]=Létrehoz egy 640 x 480 képpontos fehér RGB képet.
+Comment[is]=Býr til hvíta RGB mynd í hlutföllunum 640 x 480 punktar.
+Comment[it]=Crea un'immagine RGB bianca di 640 × 480 pixel.
+Comment[ja]=640 x 480 ピクセルの RGB 画像を作成
+Comment[km]=បង្កើត​រូបភាព RGB ពណ៌ស​ទំហំ 640 x 480 ភីកសែល ។
+Comment[lt]=Sukuria baltą 640 x 480 pikselių RGB paveiksliuką.
+Comment[ms]=Cipta imej RGB putih 640 x 480 piksel.
+Comment[nb]=Lager et hvitt bilde på 640 x 480 piksler.
+Comment[nds]=Stellt en witt RGB-Bild mit 640 x 480 Pixels op.
+Comment[ne]=६४० x ४८० पिक्सेलको सेतो RGB छवि सिर्जना गर्दछ ।
+Comment[nl]=Maakt een witte RGB-afbeelding aan van 640 x 480 pixels.
+Comment[nn]=Lagar eit kvitt RGB-bilete på 640 × 480 pikslar.
+Comment[pl]=Tworzy biały obrazek RGB o rozmiarach 640 x 480 pikseli.
+Comment[pt]=Cria uma imagem RGB branca com 640 x 480 pontos.
+Comment[pt_BR]=Cria uma imagem RGB em branco de 640 x 480 pixéis.
+Comment[ru]=Рисунок RGB 640x480, белый фон
+Comment[se]=Ráhkada vilges RGB-gova mas lea 640 × 480 govvačuoggá.
+Comment[sk]=Vytvorí RGB obrázok s rozmermi 640 x 480 pixelov a bielym pozadím.
+Comment[sl]=Ustvari belo sliko RGB velikosti 640 x 480 pik.
+Comment[sr]=Прави белу RGB слику са 640 x 480 пиксела.
+Comment[sr@Latn]=Pravi belu RGB sliku sa 640 x 480 piksela.
+Comment[sv]=Skapar en vit RGB-bild med 640 x 480 bildpunkter.
+Comment[ta]=640 x 480 படத்துணுக்குகளில் ஒரு வெள்ளை RGB பிம்பத்தை உருவாக்குகிறது.
+Comment[tr]=640 x 480 piksel ebadında beyaz bir RGB görüntü oluşturur.
+Comment[uk]=Створює біле зображення у форматі RGB, 640 x 480 пікселів.
+Comment[uz]=Oʻlchami 640 x 480 nuqta boʻlgan oq RGB rasmni yaratish.
+Comment[uz@cyrillic]=Ўлчами 640 x 480 нуқта бўлган оқ RGB расмни яратиш.
+Comment[zh_CN]=创建 640 x 480 像素的 RGB 白色背景图像。
+Comment[zh_TW]=建立一個 640 x 480 像素的白色 RGB 圖片。
+X-Krita-Version=2
diff --git a/krita/colorspaces/rgb_u8/templates/white_640x480.kra b/krita/colorspaces/rgb_u8/templates/white_640x480.kra
new file mode 100644
index 00000000..2a0265d0
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/templates/white_640x480.kra
Binary files differ
diff --git a/krita/colorspaces/rgb_u8/tests/Makefile.am b/krita/colorspaces/rgb_u8/tests/Makefile.am
new file mode 100644
index 00000000..65832896
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/tests/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/.. \
+ -I$(srcdir)/../../../kritacolor/color_strategy/ \
+ -I$(srcdir)/../../../color_strategy/ \
+ $(all_includes)
+
+# The check_ target makes sure we don't install the modules,
+# $(KDE_CHECK_PLUGIN) assures a shared library is created.
+check_LTLIBRARIES = kunittest_kis_strategy_colorspace_rgb_tester.la
+
+kunittest_kis_strategy_colorspace_rgb_tester_la_SOURCES = kis_strategy_colorspace_rgb_tester.cpp
+kunittest_kis_strategy_colorspace_rgb_tester_la_LIBADD = -lkunittest ../libkritargb.la
+kunittest_kis_strategy_colorspace_rgb_tester_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN) $(all_libraries)
+
+check-local: kunittest_kis_strategy_colorspace_rgb_tester.la
+ kunittestmodrunner
+
diff --git a/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.cpp b/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.cpp
new file mode 100644
index 00000000..7ad4cfae
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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 <kunittest/runner.h>
+#include <kunittest/module.h>
+
+#include "kis_factory.h"
+#include "kis_strategy_colorspace_rgb_tester.h"
+#include "kis_rgb_colorspace.h"
+
+using namespace KUnitTest;
+
+KUNITTEST_MODULE( kunittest_kis_strategy_colorspace_rgb_tester, "RGB ColorSpace Tester" );
+KUNITTEST_MODULE_REGISTER_TESTER( KisRgbColorSpaceTester );
+
+void KisRgbColorSpaceTester::allTests()
+{
+ // We need this so that the colour profile loading can operate without crashing.
+ KisFactory *factory = new KisFactory();
+
+ testBasics();
+ testMixColors();
+
+ delete factory;
+}
+
+#define NUM_CHANNELS 4
+
+#define RED_CHANNEL 0
+#define GREEN_CHANNEL 1
+#define BLUE_CHANNEL 2
+#define ALPHA_CHANNEL 3
+
+void KisRgbColorSpaceTester::testBasics()
+{
+ KisProfile *defProfile = new KisProfile(cmsCreate_sRGBProfile());
+ KisRgbColorSpace *cs = new KisRgbColorSpace(defProfile);
+
+ Q_UINT8 pixel[NUM_CHANNELS];
+
+ pixel[PIXEL_RED] = 255;
+ pixel[PIXEL_GREEN] = 128;
+ pixel[PIXEL_BLUE] = 64;
+ pixel[PIXEL_ALPHA] = 0;
+
+ QString valueText = cs->channelValueText(pixel, RED_CHANNEL);
+ CHECK(valueText, QString("255"));
+
+ valueText = cs->channelValueText(pixel, GREEN_CHANNEL);
+ CHECK(valueText, QString("128"));
+
+ valueText = cs->channelValueText(pixel, BLUE_CHANNEL);
+ CHECK(valueText, QString("64"));
+
+ valueText = cs->channelValueText(pixel, ALPHA_CHANNEL);
+ CHECK(valueText, QString("0"));
+
+ valueText = cs->normalisedChannelValueText(pixel, RED_CHANNEL);
+ CHECK(valueText, QString().setNum(1.0));
+
+ valueText = cs->normalisedChannelValueText(pixel, GREEN_CHANNEL);
+ CHECK(valueText, QString().setNum(128.0 / 255.0));
+
+ valueText = cs->normalisedChannelValueText(pixel, BLUE_CHANNEL);
+ CHECK(valueText, QString().setNum(64.0 / 255.0));
+
+ valueText = cs->normalisedChannelValueText(pixel, ALPHA_CHANNEL);
+ CHECK(valueText, QString().setNum(0.0));
+
+ cs->setPixel(pixel, 128, 192, 64, 99);
+ CHECK((uint)pixel[PIXEL_RED], 128u);
+ CHECK((uint)pixel[PIXEL_GREEN], 192u);
+ CHECK((uint)pixel[PIXEL_BLUE], 64u);
+ CHECK((uint)pixel[PIXEL_ALPHA], 99u);
+
+ Q_UINT8 red;
+ Q_UINT8 green;
+ Q_UINT8 blue;
+ Q_UINT8 alpha;
+
+ cs->getPixel(pixel, &red, &green, &blue, &alpha);
+ CHECK((uint)red, 128u);
+ CHECK((uint)green, 192u);
+ CHECK((uint)blue, 64u);
+ CHECK((uint)alpha, 99u);
+}
+
+void KisRgbColorSpaceTester::testMixColors()
+{
+ KisProfile *defProfile = new KisProfile(cmsCreate_sRGBProfile());
+ KisRgbColorSpace *cs = new KisRgbColorSpace(defProfile);
+
+
+ // Test mixColors.
+ Q_UINT8 pixel1[4];
+ Q_UINT8 pixel2[4];
+ Q_UINT8 outputPixel[4];
+
+ pixel1[PIXEL_RED] = 255;
+ pixel1[PIXEL_GREEN] = 255;
+ pixel1[PIXEL_BLUE] = 255;
+ pixel1[PIXEL_ALPHA] = 255;
+
+ pixel2[PIXEL_RED] = 0;
+ pixel2[PIXEL_GREEN] = 0;
+ pixel2[PIXEL_BLUE] = 0;
+ pixel2[PIXEL_ALPHA] = 0;
+
+ const Q_UINT8 *pixelPtrs[2];
+ Q_UINT8 weights[2];
+
+ pixelPtrs[0] = pixel1;
+ pixelPtrs[1] = pixel2;
+
+ weights[0] = 255;
+ weights[1] = 0;
+
+ cs->mixColors(pixelPtrs, weights, 2, outputPixel);
+
+ CHECK((int)outputPixel[PIXEL_RED], 255);
+ CHECK((int)outputPixel[PIXEL_GREEN], 255);
+ CHECK((int)outputPixel[PIXEL_BLUE], 255);
+ CHECK((int)outputPixel[PIXEL_ALPHA], 255);
+
+ weights[0] = 0;
+ weights[1] = 255;
+
+ cs->mixColors(pixelPtrs, weights, 2, outputPixel);
+
+ CHECK((int)outputPixel[PIXEL_RED], 0);
+ CHECK((int)outputPixel[PIXEL_GREEN], 0);
+ CHECK((int)outputPixel[PIXEL_BLUE], 0);
+ CHECK((int)outputPixel[PIXEL_ALPHA], 0);
+
+ weights[0] = 128;
+ weights[1] = 127;
+
+ cs->mixColors(pixelPtrs, weights, 2, outputPixel);
+
+ CHECK((int)outputPixel[PIXEL_RED], 255);
+ CHECK((int)outputPixel[PIXEL_GREEN], 255);
+ CHECK((int)outputPixel[PIXEL_BLUE], 255);
+ CHECK((int)outputPixel[PIXEL_ALPHA], 128);
+
+ pixel1[PIXEL_RED] = 200;
+ pixel1[PIXEL_GREEN] = 100;
+ pixel1[PIXEL_BLUE] = 50;
+ pixel1[PIXEL_ALPHA] = 255;
+
+ pixel2[PIXEL_RED] = 100;
+ pixel2[PIXEL_GREEN] = 200;
+ pixel2[PIXEL_BLUE] = 20;
+ pixel2[PIXEL_ALPHA] = 255;
+
+ cs->mixColors(pixelPtrs, weights, 2, outputPixel);
+
+ CHECK((int)outputPixel[PIXEL_RED], 150);
+ CHECK((int)outputPixel[PIXEL_GREEN], 150);
+ CHECK((int)outputPixel[PIXEL_BLUE], 35);
+ CHECK((int)outputPixel[PIXEL_ALPHA], 255);
+
+ pixel1[PIXEL_RED] = 0;
+ pixel1[PIXEL_GREEN] = 0;
+ pixel1[PIXEL_BLUE] = 0;
+ pixel1[PIXEL_ALPHA] = 0;
+
+ pixel2[PIXEL_RED] = 255;
+ pixel2[PIXEL_GREEN] = 255;
+ pixel2[PIXEL_BLUE] = 255;
+ pixel2[PIXEL_ALPHA] = 254;
+
+ weights[0] = 89;
+ weights[1] = 166;
+
+ cs->mixColors(pixelPtrs, weights, 2, outputPixel);
+
+ CHECK((int)outputPixel[PIXEL_RED], 255);
+ CHECK((int)outputPixel[PIXEL_GREEN], 255);
+ CHECK((int)outputPixel[PIXEL_BLUE], 255);
+ CHECK((int)outputPixel[PIXEL_ALPHA], 165);
+}
+
diff --git a/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.h b/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.h
new file mode 100644
index 00000000..16fc4e83
--- /dev/null
+++ b/krita/colorspaces/rgb_u8/tests/kis_strategy_colorspace_rgb_tester.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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.
+ */
+
+
+#ifndef KIS_STRATEGY_COLORSPACE_RGB_TESTER_H
+#define KIS_STRATEGY_COLORSPACE_RGB_TESTER_H
+
+#include <kunittest/tester.h>
+
+class KisRgbColorSpaceTester : public KUnitTest::Tester
+{
+public:
+ void allTests();
+ void testBasics();
+ void testMixColors();
+};
+
+#endif
+