diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:41:16 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:41:16 +0000 |
commit | 698569f8428ca088f764d704034a1330517b98c0 (patch) | |
tree | bf45be6946ebbbee9cce5a5bcf838f4c952d87e6 /chalk/colorspaces/gray_u8 | |
parent | 2785103a6bd4de55bd26d79e34d0fdd4b329a73a (diff) | |
download | koffice-698569f8428ca088f764d704034a1330517b98c0.tar.gz koffice-698569f8428ca088f764d704034a1330517b98c0.zip |
Finish rebranding of Krita as Chalk
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238363 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'chalk/colorspaces/gray_u8')
16 files changed, 1721 insertions, 0 deletions
diff --git a/chalk/colorspaces/gray_u8/Makefile.am b/chalk/colorspaces/gray_u8/Makefile.am new file mode 100644 index 00000000..adce3031 --- /dev/null +++ b/chalk/colorspaces/gray_u8/Makefile.am @@ -0,0 +1,31 @@ +kde_services_DATA = chalkgrayplugin.desktop + +INCLUDES = -I$(srcdir)/../../sdk \ + -I$(srcdir)/../../chalkcolor/color_strategy/ \ + -I$(srcdir)/../../chalkcolor/ \ + -I$(interfacedir) \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + + +lib_LTLIBRARIES = libchalkgrayscale.la +libchalkgrayscale_la_SOURCES = kis_gray_colorspace.cc +libchalkgrayscale_la_LDFLAGS = $(all_libraries) +libchalkgrayscale_la_LIBADD = ../../chalkcolor/libchalkcolor.la + +kde_module_LTLIBRARIES = chalkgrayplugin.la + +chalkgrayplugin_la_SOURCES = gray_plugin.cc +noinst_HEADERS = gray_plugin.h kis_gray_colorspace.h + +chalkgrayplugin_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -llcms +chalkgrayplugin_la_LIBADD = libchalkgrayscale.la ../../chalkcolor/libchalkcolor.la + +chalkgrayplugin_la_METASOURCES = AUTO + +if include_kunittest_tests +TESTSDIR = tests +endif + +SUBDIRS = . templates $(TESTSDIR) + diff --git a/chalk/colorspaces/gray_u8/chalkgrayplugin.desktop b/chalk/colorspaces/gray_u8/chalkgrayplugin.desktop new file mode 100644 index 00000000..58a6d992 --- /dev/null +++ b/chalk/colorspaces/gray_u8/chalkgrayplugin.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Name=Grayscale Color Model +Name[bg]=Цветови модел със степени на сивото +Name[ca]=Model de color d'escala de grisos +Name[cy]=Model Lliw Graddlwyd +Name[da]=Farvemodel med gråskala +Name[de]=Graustufen-Farbmodell +Name[el]=Χρωματικό μοντέλο διαβαθμίσεων του γκρι +Name[en_GB]=Greyscale Colour Model +Name[eo]=Grizoskala kolormodelo +Name[es]=Modelo de color de escala de grises +Name[et]=Halltooni värvimudel +Name[eu]=Gris-eskala kolore-eredua +Name[fa]=مدل رنگ مقیاس خاکستری +Name[fi]=Harmaasävyvärimalli +Name[fr]=Modèle de couleurs en niveaux de gris +Name[fy]=Griiswearden kleurmodel +Name[gl]=Modelo de Cores en Escala de Gris +Name[he]=מודל צבעים של גווני אפור +Name[hi]=श्वेत-श्याम रंग नमूना +Name[hu]=Szürkeárnyalatos színmodell +Name[is]=Gráskala litategund +Name[it]=Modello di colore in scala di grigio +Name[ja]=グレースケール カラーモデル +Name[km]=គំរូពណ៌មាត្រដ្ឋានប្រផេះ +Name[lv]=Pelēktoņu krāsu modelis +Name[ms]=Model Warna Skala Kelabu +Name[nb]=Fargemodell med gråtoner +Name[nds]=Griestöön-Klöörmodell +Name[ne]=ग्रेस्केल रङ मोडेल +Name[nl]=Grijswaarden kleurmodel +Name[nn]=Fargemodell med gråtonar +Name[pl]=Skala szarości +Name[pt]=Modelo de Cor de Tons de Cinzento +Name[pt_BR]=Modelo de Cor em Tons de Cinza +Name[ru]=Градации серого +Name[se]=Ránesivnniid ivdnemálle +Name[sk]=Model farieb ČB/šedý +Name[sl]=Sivinski barvni model +Name[sr]=Модел боја за сиве нијансе +Name[sr@Latn]=Model boja za sive nijanse +Name[sv]=Gråskalefärgmodell +Name[ta]=பழுப்புநிற வண்ண மாதிரி +Name[tr]=Griton Renk Modeli +Name[uk]=Модель кольору "відтінки сірого" +Name[uz]=Kul rang usuli +Name[uz@cyrillic]=Кул ранг усули +Name[zh_CN]=灰度色彩模型 +Name[zh_TW]=灰階色彩模型 +Comment=Color model for 8-bit grayscale images +Comment[bg]=Цветови модел за 8 битови сиви изображения +Comment[ca]=Model de color d'escala de grisos de 8 bits +Comment[cy]=Model lliw ar gyfer delweddau graddlwyd 8-did +Comment[da]=Farvemodel for 8-bit gråskala-billeder +Comment[de]=Farbmodell für 8-bit Graustufenbilder +Comment[el]=Χρωματικό μοντέλο για 8-bit με διαβαθμίσεις του γκρι εικόνες +Comment[en_GB]=Colour model for 8-bit greyscale images +Comment[eo]=Kolormodelo por 8-bitaj grizoskalaj bildoj +Comment[es]=Modelo de color de imágenes de escala de grises para 8 bits +Comment[et]=8-bitiste halltoonis piltide värvimudel +Comment[eu]=8 bit/kanaleko gris-eskalako irudien kolore-eredua +Comment[fa]=مدل رنگ برای تصاویر مقیاس خاکستری ۸ بیتی +Comment[fi]=Värimalli 8-bittisille harmaasävykuville +Comment[fr]=Modèle de couleurs pour des images en niveaux de gris 8 bits +Comment[fy]=Kleurmodel foar ôfbeeldings yn 8-bit griiswearden +Comment[gl]=Modelo de Cores de escala de gris de for 8-bit +Comment[he]=מודל צבעים עבור תמונות של 8 סיביות בגווני אפור +Comment[hi]=8-बिट श्वेत-श्याम छवियों के लिए रंग नमूना +Comment[hu]=Színmodell 8 bites szürkeárnyalatos képekhez +Comment[is]=Litategund fyrir 8-bita gráskala myndir +Comment[it]=Modello di colore per immagini a 8 bit in scala di grigio +Comment[ja]=8 ビット グレースケール画像のためのカラーモデル +Comment[km]=គំរូពណ៌សម្រាប់រូបភាពមាត្រដ្ឋានប្រផេះ ៨ ប៊ីត +Comment[ms]=Model warna bagi imej skala kelabu 8-bit +Comment[nb]=Fargemodell for 8-bits gråtonebilder +Comment[nds]=Klöörmodell för Griestöön-Biller mit 8-Bit Heeltall +Comment[ne]=८-बिट ग्रेस्केल छविहरूका लागि रङ मोडेल +Comment[nl]=Kleurmodel voor afbeeldingen in 8-bit grijswaarden +Comment[nn]=Fargemodell for 8-bits gråtonebilete +Comment[pl]=Przestrzeń braw dla 8-bitowych obrazków w skali szarości +Comment[pt]=Modelo de cor para imagens de tons de cinzento com 8 bits +Comment[pt_BR]=Modelo de cor para imagens com 8-bits de tons de cinza +Comment[ru]=Цветовое пространство градаций серого (8-бит) +Comment[sk]=Model farieb pre ČB/šedé obrázky s 8 bitmi na kanál +Comment[sl]=Barvni model za 8 bitne sivinske slike +Comment[sr]=Модел боја за слике у 8-битним сивим нијансама +Comment[sr@Latn]=Model boja za slike u 8-bitnim sivim nijansama +Comment[sv]=Färgmodell för 8-bitars gråskalebilder +Comment[ta]=8-பிட் பழுப்புநிற பிம்பங்களுக்கு வண்ண மாதிரி +Comment[tr]=8-bit griton görüntüler için renk modeli. +Comment[uk]=Модель кольору зображень відтінків сірого (8-бітів) +Comment[zh_CN]=8 位灰度图像的色彩模型 +Comment[zh_TW]=8-bit 灰階圖片的色彩模型 +ServiceTypes=Chalk/ColorSpace +Type=Service +X-KDE-Library=chalkgrayplugin +X-Chalk-Version=2 diff --git a/chalk/colorspaces/gray_u8/gray_plugin.cc b/chalk/colorspaces/gray_u8/gray_plugin.cc new file mode 100644 index 00000000..0028c597 --- /dev/null +++ b/chalk/colorspaces/gray_u8/gray_plugin.cc @@ -0,0 +1,77 @@ +/* + * gray_plugin.cc -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt ([email protected]) + * + * 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 <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_colorspace_factory_registry.h> +#include <kis_basic_histogram_producers.h> + +#include "gray_plugin.h" +#include "kis_gray_colorspace.h" + +typedef KGenericFactory<GrayPlugin> GrayPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkgrayplugin, GrayPluginFactory( "chalkcore" ) ) + + +GrayPlugin::GrayPlugin(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + setInstance(GrayPluginFactory::instance()); + + // This is not a gui plugin; only load it when the doc is created. + if ( tqparent->inherits("KisColorSpaceFactoryRegistry") ) + { + + KisColorSpaceFactoryRegistry * f = dynamic_cast<KisColorSpaceFactoryRegistry*>( tqparent ); + + // .22 gamma grayscale or something like that. Taken from the lcms tutorial... + LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); + cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); + cmsFreeGamma(Gamma); + KisProfile *defProfile = new KisProfile(hProfile); + + f->addProfile(defProfile); + + KisColorSpace * colorSpaceGrayA = new KisGrayColorSpace(f, 0); + + KisColorSpaceFactory * csf = new KisGrayColorSpaceFactory(); + Q_CHECK_PTR(colorSpaceGrayA); + + f->add(csf); + + KisHistogramProducerFactoryRegistry::instance()->add( + new KisBasicHistogramProducerFactory<KisBasicU8HistogramProducer> + (KisID("GRAYA8HISTO", i18n("GRAY/Alpha8")), colorSpaceGrayA) ); + } + +} + +GrayPlugin::~GrayPlugin() +{ +} + +#include "gray_plugin.moc" diff --git a/chalk/colorspaces/gray_u8/gray_plugin.h b/chalk/colorspaces/gray_u8/gray_plugin.h new file mode 100644 index 00000000..f18bf77c --- /dev/null +++ b/chalk/colorspaces/gray_u8/gray_plugin.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 Boudewijn Rempt ([email protected]) + * + * 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 GRAY_PLUGIN_H_ +#define GRAY_PLUGIN_H_ + +#include <kparts/plugin.h> + +/** + * A plugin wrapper around the GRAY colour space strategy. + */ +class GrayPlugin : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + GrayPlugin(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~GrayPlugin(); + +}; + +#endif // GRAY_PLUGIN_H_ diff --git a/chalk/colorspaces/gray_u8/grayplugin.rc b/chalk/colorspaces/gray_u8/grayplugin.rc new file mode 100644 index 00000000..8d4562cd --- /dev/null +++ b/chalk/colorspaces/gray_u8/grayplugin.rc @@ -0,0 +1,7 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkgrayplugin" version="1"> +<Menu name="Image"><text>&Image</text> + <Menu name="Mode"><text>&Mode</text> + <Action name="convert to Gray(A)"/> + </Menu> +</Menu></kpartgui> diff --git a/chalk/colorspaces/gray_u8/kis_gray_colorspace.cc b/chalk/colorspaces/gray_u8/kis_gray_colorspace.cc new file mode 100644 index 00000000..dbd475df --- /dev/null +++ b/chalk/colorspaces/gray_u8/kis_gray_colorspace.cc @@ -0,0 +1,997 @@ +/* + * Copyright (c) 2002 Patrick Julien <[email protected]> + * Copyright (c) 2004 Cyrille Berger + * Copyright (c) 2004 Boudewijn Rempt <[email protected]> + * + * 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 <limits.h> +#include <stdlib.h> + +#include <config.h> +#include LCMS_HEADER + +#include <tqimage.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kglobal.h> + +#include "kis_abstract_colorspace.h" +#include "kis_u8_base_colorspace.h" +#include "kis_gray_colorspace.h" +#include "kis_integer_maths.h" + +#define downscale(quantum) (quantum) //((unsigned char) ((quantum)/257UL)) +#define upscale(value) (value) // ((TQ_UINT8) (257UL*(value))) + +namespace { + const TQ_INT32 MAX_CHANNEL_GRAYSCALE = 1; + const TQ_INT32 MAX_CHANNEL_GRAYSCALEA = 2; +} + +KisGrayColorSpace::KisGrayColorSpace(KisColorSpaceFactoryRegistry * tqparent, KisProfile *p) : + KisU8BaseColorSpace(KisID("GRAYA", i18n("Grayscale")), TYPE_GRAYA_8, icSigGrayData, tqparent, p) +{ + m_channels.push_back(new KisChannelInfo(i18n("Gray"), i18n("G"), 0, KisChannelInfo::COLOR, KisChannelInfo::UINT8)); + m_channels.push_back(new KisChannelInfo(i18n("Alpha"), i18n("A"), 1, KisChannelInfo::ALPHA, KisChannelInfo::UINT8)); + + m_alphaPos = PIXEL_GRAY_ALPHA; + + init(); +} + + +KisGrayColorSpace::~KisGrayColorSpace() +{ +} + +void KisGrayColorSpace::setPixel(TQ_UINT8 *pixel, TQ_UINT8 gray, TQ_UINT8 alpha) const +{ + pixel[PIXEL_GRAY] = gray; + pixel[PIXEL_GRAY_ALPHA] = alpha; +} + +void KisGrayColorSpace::getPixel(const TQ_UINT8 *pixel, TQ_UINT8 *gray, TQ_UINT8 *alpha) const +{ + *gray = pixel[PIXEL_GRAY]; + *alpha = pixel[PIXEL_GRAY_ALPHA]; +} + +void KisGrayColorSpace::getAlpha(const TQ_UINT8 *pixel, TQ_UINT8 *alpha) const +{ + *alpha = pixel[PIXEL_GRAY_ALPHA]; +} + +void KisGrayColorSpace::setAlpha(TQ_UINT8 *pixels, TQ_UINT8 alpha, TQ_INT32 nPixels) const +{ + while (nPixels > 0) { + pixels[PIXEL_GRAY_ALPHA] = alpha; + --nPixels; + pixels += MAX_CHANNEL_GRAYSCALEA; + } +} + +void KisGrayColorSpace::mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const +{ + TQ_UINT32 totalGray = 0, newAlpha = 0; + + while (nColors--) + { + TQ_UINT32 alpha = (*colors)[PIXEL_GRAY_ALPHA]; + TQ_UINT32 alphaTimesWeight = UINT8_MULT(alpha, *weights); + + totalGray += (*colors)[PIXEL_GRAY] * alphaTimesWeight; + newAlpha += alphaTimesWeight; + + weights++; + colors++; + } + + Q_ASSERT(newAlpha <= 255); + + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha > 0) { + totalGray = UINT8_DIVIDE(totalGray, newAlpha); + } + + // Divide by 255. + totalGray += 0x80; + TQ_UINT32 dstGray = ((totalGray >> 8) + totalGray) >> 8; + Q_ASSERT(dstGray <= 255); + dst[PIXEL_GRAY] = dstGray; +} + +void KisGrayColorSpace::convolveColors(TQ_UINT8** colors, TQ_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, TQ_UINT8 *dst, TQ_INT32 factor, TQ_INT32 offset, TQ_INT32 nColors) const +{ + TQ_INT32 totalGray = 0, totalAlpha = 0; + + while (nColors--) + { + TQ_INT32 weight = *kernelValues; + + if (weight != 0) { + totalGray += (*colors)[PIXEL_GRAY] * weight; + totalAlpha += (*colors)[PIXEL_GRAY_ALPHA] * weight; + } + colors++; + kernelValues++; + } + + + if (channelFlags & KisChannelInfo::FLAG_COLOR) { + dst[PIXEL_GRAY] = CLAMP((totalGray / factor) + offset, 0, TQ_UINT8_MAX); + } + if (channelFlags & KisChannelInfo::FLAG_ALPHA) { + dst[PIXEL_GRAY_ALPHA] = CLAMP((totalAlpha/ factor) + offset, 0, TQ_UINT8_MAX); + } + +} + + +void KisGrayColorSpace::invertColor(TQ_UINT8 * src, TQ_INT32 nPixels) +{ + TQ_UINT32 psize = pixelSize(); + + while (nPixels--) + { + src[PIXEL_GRAY] = TQ_UINT8_MAX - src[PIXEL_GRAY]; + src += psize; + } +} + +void KisGrayColorSpace::darken(const TQ_UINT8 * src, TQ_UINT8 * dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const +{ + TQ_UINT32 pSize = pixelSize(); + + while (nPixels--) { + if (compensate) { + dst[PIXEL_GRAY] = (TQ_INT8) TQMIN(255,((src[PIXEL_GRAY] * shade) / (compensation * 255))); + } + else { + dst[PIXEL_GRAY] = (TQ_INT8) TQMIN(255, (src[PIXEL_GRAY] * shade / 255)); + } + dst += pSize; + src += pSize; + } +} + +TQ_UINT8 KisGrayColorSpace::intensity8(const TQ_UINT8 * src) const +{ + return src[PIXEL_GRAY]; +} + +TQValueVector<KisChannelInfo *> KisGrayColorSpace::channels() const +{ + return m_channels; +} + +TQ_UINT32 KisGrayColorSpace::nChannels() const +{ + return MAX_CHANNEL_GRAYSCALEA; +} + +TQ_UINT32 KisGrayColorSpace::nColorChannels() const +{ + return MAX_CHANNEL_GRAYSCALE; +} + +TQ_UINT32 KisGrayColorSpace::pixelSize() const +{ + return MAX_CHANNEL_GRAYSCALEA; +} + +void KisGrayColorSpace::bitBlt(TQ_UINT8 *dst, + TQ_INT32 dstRowStride, + const TQ_UINT8 *src, + TQ_INT32 srcRowStride, + const TQ_UINT8 *tqmask, + TQ_INT32 tqmaskRowStride, + TQ_UINT8 opacity, + TQ_INT32 rows, + TQ_INT32 cols, + const KisCompositeOp& op) +{ + switch (op.op()) { + case COMPOSITE_OVER: + compositeOver(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_MULT: + compositeMultiply(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_DIVIDE: + compositeDivide(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_DARKEN: + compositeDarken(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_LIGHTEN: + compositeLighten(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_SCREEN: + compositeScreen(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_OVERLAY: + compositeOverlay(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_DODGE: + compositeDodge(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_BURN: + compositeBurn(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_ERASE: + compositeErase(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_COPY: + compositeCopy(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + case COMPOSITE_CLEAR: { + TQ_UINT8 *d; + TQ_INT32 linesize; + + linesize = MAX_CHANNEL_GRAYSCALEA*sizeof(TQ_UINT8) * cols; + d = dst; + while (rows-- > 0) { + memset(d, 0, linesize); + d += dstRowStride; + } + } + break; + case COMPOSITE_ALPHA_DARKEN: + compositeAlphaDarken(dst, dstRowStride, src, srcRowStride, tqmask, tqmaskRowStride, rows, cols, opacity); + break; + + default: + break; + } +} + +KisCompositeOpList KisGrayColorSpace::userVisiblecompositeOps() const +{ + KisCompositeOpList list; + + list.append(KisCompositeOp(COMPOSITE_OVER)); + 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)); + + return list; +} + +void KisGrayColorSpace::compositeOver(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(srcAlpha, opacity); + } + + if (srcAlpha == OPACITY_OPAQUE) { + memcpy(dst, src, MAX_CHANNEL_GRAYSCALEA * sizeof(TQ_UINT8)); + } else { + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + if (srcBlend == OPACITY_OPAQUE) { + memcpy(dst, src, MAX_CHANNEL_GRAYSCALE * sizeof(TQ_UINT8)); + } else { + dst[PIXEL_GRAY] = UINT8_BLEND(src[PIXEL_GRAY], dst[PIXEL_GRAY], srcBlend); + } + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeMultiply(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + TQ_UINT8 srcColor = src[PIXEL_GRAY]; + TQ_UINT8 dstColor = dst[PIXEL_GRAY]; + + srcColor = UINT8_MULT(srcColor, dstColor); + + dst[PIXEL_GRAY] = UINT8_BLEND(srcColor, dstColor, srcBlend); + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeDivide(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = TQMIN((dstColor * (UINT8_MAX + 1)) / (1 + srcColor), UINT8_MAX); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeScreen(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = UINT8_MAX - UINT8_MULT(UINT8_MAX - dstColor, UINT8_MAX - srcColor); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeOverlay(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = UINT8_MULT(dstColor, dstColor + UINT8_MULT(2 * srcColor, UINT8_MAX - dstColor)); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeDodge(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = TQMIN((dstColor * (UINT8_MAX + 1)) / (UINT8_MAX + 1 - srcColor), UINT8_MAX); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeBurn(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = kMin(((UINT8_MAX - dstColor) * (UINT8_MAX + 1)) / (srcColor + 1), UINT8_MAX); + srcColor = kClamp(UINT8_MAX - srcColor, 0u, UINT8_MAX); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeDarken(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = TQMIN(srcColor, dstColor); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeLighten(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + TQ_INT32 columns = numColumns; + const TQ_UINT8 *tqmask = tqmaskRowStart; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + srcAlpha = TQMIN(srcAlpha, dstAlpha); + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (srcAlpha != OPACITY_TRANSPARENT) { + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(src[PIXEL_GRAY_ALPHA], opacity); + } + + TQ_UINT8 srcBlend; + + if (dstAlpha == OPACITY_OPAQUE) { + srcBlend = srcAlpha; + } else { + TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha); + dst[PIXEL_GRAY_ALPHA] = newAlpha; + + if (newAlpha != 0) { + srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha); + } else { + srcBlend = srcAlpha; + } + } + + for (int channel = 0; channel < MAX_CHANNEL_GRAYSCALE; channel++) { + + TQ_UINT8 srcColor = src[channel]; + TQ_UINT8 dstColor = dst[channel]; + + srcColor = TQMAX(srcColor, dstColor); + + TQ_UINT8 newColor = UINT8_BLEND(srcColor, dstColor, srcBlend); + + dst[channel] = newColor; + } + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} + +void KisGrayColorSpace::compositeErase(TQ_UINT8 *dst, + TQ_INT32 dstRowSize, + const TQ_UINT8 *src, + TQ_INT32 srcRowSize, + const TQ_UINT8 *srcAlphaMask, + TQ_INT32 tqmaskRowStride, + TQ_INT32 rows, + TQ_INT32 cols, + TQ_UINT8 /*opacity*/) +{ + TQ_INT32 i; + TQ_UINT8 srcAlpha; + + while (rows-- > 0) + { + const TQ_UINT8 *s = src; + TQ_UINT8 *d = dst; + const TQ_UINT8 *tqmask = srcAlphaMask; + + for (i = cols; i > 0; i--, s+=MAX_CHANNEL_GRAYSCALEA, d+=MAX_CHANNEL_GRAYSCALEA) + { + srcAlpha = s[PIXEL_GRAY_ALPHA]; + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_BLEND(srcAlpha, OPACITY_OPAQUE, *tqmask); + tqmask++; + } + d[PIXEL_GRAY_ALPHA] = UINT8_MULT(srcAlpha, d[PIXEL_GRAY_ALPHA]); + } + + dst += dstRowSize; + if(srcAlphaMask) + srcAlphaMask += tqmaskRowStride; + src += srcRowSize; + } +} + +void KisGrayColorSpace::compositeAlphaDarken(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, + const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, + const TQ_UINT8 *tqmaskRowStart, TQ_INT32 tqmaskRowStride, + TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity) +{ + while (rows > 0) { + + const TQ_UINT8 *src = srcRowStart; + TQ_UINT8 *dst = dstRowStart; + const TQ_UINT8 *tqmask = tqmaskRowStart; + TQ_INT32 columns = numColumns; + + while (columns > 0) { + + TQ_UINT8 srcAlpha = src[PIXEL_GRAY_ALPHA]; + TQ_UINT8 dstAlpha = dst[PIXEL_GRAY_ALPHA]; + + // apply the alphatqmask + if(tqmask != 0) + { + if(*tqmask != OPACITY_OPAQUE) + srcAlpha = UINT8_MULT(srcAlpha, *tqmask); + tqmask++; + } + + if (opacity != OPACITY_OPAQUE) { + srcAlpha = UINT8_MULT(srcAlpha, opacity); + } + + if (srcAlpha != OPACITY_TRANSPARENT && srcAlpha >= dstAlpha) { + dst[PIXEL_GRAY_ALPHA] = srcAlpha; + memcpy(dst, src, MAX_CHANNEL_GRAYSCALE * sizeof(TQ_UINT8)); + } + + columns--; + src += MAX_CHANNEL_GRAYSCALEA; + dst += MAX_CHANNEL_GRAYSCALEA; + } + + rows--; + srcRowStart += srcRowStride; + dstRowStart += dstRowStride; + if(tqmaskRowStart) + tqmaskRowStart += tqmaskRowStride; + } +} diff --git a/chalk/colorspaces/gray_u8/kis_gray_colorspace.h b/chalk/colorspaces/gray_u8/kis_gray_colorspace.h new file mode 100644 index 00000000..8a3bc34b --- /dev/null +++ b/chalk/colorspaces/gray_u8/kis_gray_colorspace.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2004 Cyrille Berger <[email protected]> + * + * 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_GRAYSCALE_H_ +#define KIS_STRATEGY_COLORSPACE_GRAYSCALE_H_ +#include <tqcolor.h> + +#include <klocale.h> + +#include <koffice_export.h> + +#include "kis_global.h" +#include "kis_abstract_colorspace.h" +#include "kis_u8_base_colorspace.h" + +class KRITACORE_EXPORT KisGrayColorSpace : public KisU8BaseColorSpace { +public: + KisGrayColorSpace(KisColorSpaceFactoryRegistry * tqparent, KisProfile *p); + virtual ~KisGrayColorSpace(); + + virtual bool willDegrade(ColorSpaceIndependence /*independence*/) + { + return false; + }; + +public: + + void setPixel(TQ_UINT8 *pixel, TQ_UINT8 gray, TQ_UINT8 alpha) const; + void getPixel(const TQ_UINT8 *pixel, TQ_UINT8 *gray, TQ_UINT8 *alpha) const; + + virtual void getAlpha(const TQ_UINT8 *pixel, TQ_UINT8 *alpha) const; + virtual void setAlpha(TQ_UINT8 * pixels, TQ_UINT8 alpha, TQ_INT32 nPixels) const; + + virtual void mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const; + virtual void convolveColors(TQ_UINT8** colors, TQ_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, TQ_UINT8 *dst, TQ_INT32 factor, TQ_INT32 offset, TQ_INT32 nColors) const; + virtual void invertColor(TQ_UINT8 * src, TQ_INT32 nPixels); + virtual void darken(const TQ_UINT8 * src, TQ_UINT8 * dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const; + virtual TQ_UINT8 intensity8(const TQ_UINT8 * src) const; + + virtual TQValueVector<KisChannelInfo *> channels() const; + virtual TQ_UINT32 nChannels() const; + virtual TQ_UINT32 nColorChannels() const; + virtual TQ_UINT32 pixelSize() const; + + virtual void bitBlt(TQ_UINT8 *dst, + TQ_INT32 dststride, + const TQ_UINT8 *src, + TQ_INT32 srcRowStride, + const TQ_UINT8 *srcAlphaMask, + TQ_INT32 tqmaskRowStride, + TQ_UINT8 opacity, + TQ_INT32 rows, + TQ_INT32 cols, + const KisCompositeOp& op); + + KisCompositeOpList userVisiblecompositeOps() const; + +protected: + void compositeOver(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeMultiply(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeDivide(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeScreen(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeOverlay(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeDodge(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeBurn(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeDarken(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeLighten(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeErase(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + void compositeAlphaDarken(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *tqmask, TQ_INT32 tqmaskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity); + + +private: + friend class KisGrayColorSpaceTester; + + static const TQ_UINT8 PIXEL_GRAY = 0; + static const TQ_UINT8 PIXEL_GRAY_ALPHA = 1; +}; + +class KisGrayColorSpaceFactory : public KisColorSpaceFactory +{ +public: + /** + * Chalk definition for use in .kra files and internally: unchanging name + + * i18n'able description. + */ + virtual KisID id() const { return KisID("GRAYA", i18n("Grayscale (8-bit integer/channel)")); }; + + /** + * lcms colorspace type definition. + */ + virtual TQ_UINT32 colorSpaceType() { return TYPE_GRAYA_8; }; + + virtual icColorSpaceSignature colorSpaceSignature() { return icSigGrayData; }; + + virtual KisColorSpace *createColorSpace(KisColorSpaceFactoryRegistry * tqparent, KisProfile *p) { return new KisGrayColorSpace(tqparent, p); }; + + virtual TQString defaultProfile() { return "gray built-in - (lcms internal)"; }; +}; + +#endif // KIS_STRATEGY_COLORSPACE_GRAYSCALE_H_ diff --git a/chalk/colorspaces/gray_u8/templates/.directory b/chalk/colorspaces/gray_u8/templates/.directory new file mode 100644 index 00000000..e408f23f --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/.directory @@ -0,0 +1,48 @@ +[Desktop Entry] +Name=Grayscale +Name[bg]=Гама на сивото +Name[br]=SkeulLouet +Name[ca]=Escala de grisos +Name[cy]=Graddlwyd +Name[da]=Gråskala +Name[de]=Graustufen +Name[el]=Διαβαθμίσεις του γκρι +Name[eo]=Grizoskalo +Name[es]=Escala de grises +Name[et]=Halltoonid +Name[fa]=مقیاس خاکستری +Name[fi]=Harmaasävyinen +Name[fr]=Niveaux de gris +Name[fy]=Griiswearden +Name[ga]=Liathscála +Name[gl]=Escala de Gris +Name[he]=גווני אפור +Name[hi]=श्वेत-श्याम +Name[hu]=Szürkeárnyalatok +Name[is]=Gráskali +Name[it]=Scala di grigio +Name[ja]=グレースケール +Name[km]=មាត្រដ្ឋានប្រផេះ +Name[lv]=Pelēktoņu +Name[nb]=Gråtoner +Name[nds]=Griestöön +Name[ne]=ग्रेस्केल +Name[nl]=Grijswaarden +Name[pl]=Skala szarości +Name[pt]=Tons de Cinzento +Name[pt_BR]=Tons de Cinza +Name[ru]=Градации серого +Name[se]=Ránesivnnit +Name[sk]=Čiernobiely +Name[sl]=Sivinska +Name[sr]=Сиве нијансе +Name[sr@Latn]=Sive nijanse +Name[sv]=Gråskala +Name[ta]=பழுப்புநிற வண்ணம் +Name[tr]=Griton +Name[uk]=Відтінки сірого +Name[uz]=Oq-qora +Name[uz@cyrillic]=Оқ-қора +Name[zh_CN]=灰度 +Name[zh_TW]=灰階 +X-KDE-DefaultTab=true diff --git a/chalk/colorspaces/gray_u8/templates/Makefile.am b/chalk/colorspaces/gray_u8/templates/Makefile.am new file mode 100644 index 00000000..ab5be17b --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/Makefile.am @@ -0,0 +1,8 @@ +templates_DATA = .directory white_640x480.desktop +templatesdir = $(kde_datadir)/chalk/templates/gray + +templatesrc_DATA =white_640x480.kra +templatesrcdir = $(kde_datadir)/chalk/templates/gray/.source + +templatesicon_ICON = AUTO +templatesicondir = $(kde_datadir)/chalk/icons diff --git a/chalk/colorspaces/gray_u8/templates/cr48-action-template_gray_empty.png b/chalk/colorspaces/gray_u8/templates/cr48-action-template_gray_empty.png Binary files differnew file mode 100644 index 00000000..73e064b6 --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/cr48-action-template_gray_empty.png diff --git a/chalk/colorspaces/gray_u8/templates/crsc-action-template_gray_empty.svgz b/chalk/colorspaces/gray_u8/templates/crsc-action-template_gray_empty.svgz Binary files differnew file mode 100644 index 00000000..93af227f --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/crsc-action-template_gray_empty.svgz diff --git a/chalk/colorspaces/gray_u8/templates/white_640x480.desktop b/chalk/colorspaces/gray_u8/templates/white_640x480.desktop new file mode 100644 index 00000000..1da17a33 --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/white_640x480.desktop @@ -0,0 +1,99 @@ +[Desktop Entry] +Type=Link +URL=.source/white_640x480.kra +Icon=template_gray_empty +Name=White Background, 640 x 480 +Name[bg]=Бял фон, 640x480 +Name[ca]=Fons blanc, 640 x 480 +Name[cy]=Cefndir Gwyn, 640 x 480 +Name[da]=Hvid baggrund, 640 x 480 +Name[de]=Weißer Hintergrund, 640 x 480 +Name[el]=Λευκό φόντο, 640 x 480 +Name[eo]=Blanka fono, 640 x 480 +Name[es]=Fondo blanco, 640 x 480 +Name[et]=Valge taust, 640 x 480 +Name[eu]=Atzeko plano zuria, 640 x 480 +Name[fa]=زمینۀ سفید، ۴۸۰ × ۶۴۰ +Name[fi]=Valkoinen tausta, 640 x 480 +Name[fr]=Fond blanc 640 x 480 +Name[fy]=Wite eftergrûn, 640 x 480 +Name[ga]=Cúlra Bán, 640×480 +Name[gl]=Fondo Branco, 640 x 480 +Name[he]=רקע לבן, 640 x 480 +Name[hi]=सफेद पृष्ठभूमि, 640 x 480 +Name[hu]=Fehér háttér, 640 x 480 +Name[is]=Hvítur bakgrunnur, 640 x 480 +Name[it]=Sfondo bianco, 640 × 480 +Name[ja]=白い背景 640 x 480 +Name[km]=ផ្ទៃខាងក្រោយពណ៌ស, 640 x 480 +Name[lt]=Baltas fonas, 640 x 480 +Name[lv]=Balts fons, 640x480 +Name[ms]=Latar Belakang Putih, 640 x 480 +Name[nb]=Hvit bakgrunn, 640 x 480 +Name[nds]=Witt Achtergrund, 640 x 480 +Name[ne]=सेतो पृष्ठभूमि, ६४० x ४८० +Name[nl]=Witte achtergrond, 640 x 480 +Name[nn]=Kvit bakgrunn, 640 × 480 +Name[pl]=Białe tło, 640 x 480 +Name[pt]=Fundo Branco, 640 x 480 +Name[pt_BR]=Fundo em branco, 640 x 480 +Name[ru]=Рисунок 640x480, белый фон +Name[se]=Vilges duogáš, 640 × 480 +Name[sk]=Biele pozadie, 640 x 480 +Name[sl]=Belo ozadje, 640 x 480 +Name[sr]=Бела позадина, 640 x 480 +Name[sr@Latn]=Bela pozadina, 640 x 480 +Name[sv]=Vit bakgrund, 640 x 480 +Name[ta]=வெள்ளை பின்னணி, 640 x 480 +Name[tr]=Beyaz Arkaplan, 640 x 480 +Name[uk]=Біле тло, 640 x 480 +Name[uz]=Oq orqa fon 640 x 480 +Name[uz@cyrillic]=Оқ орқа фон 640 x 480 +Name[zh_CN]=白色背景,640 x 480 +Name[zh_TW]=白色背景, 640 x 480 +Comment=Creates an image of 640 x 480 pixels with a white background. +Comment[bg]=Създаване на изображение с размери 640x480 пиксела и бял фон. +Comment[ca]=Crea una imatge de 640 x 480 píxels amb el fons blanc. +Comment[cy]=Creu delwedd o 640 x 480 o bicseli efo cefndir gwyn. +Comment[da]=Laver et billede på 640 x 480 billedpunkter med en hvid baggrund. +Comment[de]=Erstellt ein Bild mit 640 x 480 Pixeln mit einem weißen Hintergrund. +Comment[el]=Δημιουργεί μία εικόνα μεγέθους 640 x 480 εικονοστοιχείων με λευκό φόντο. +Comment[es]=Crea una imagen de 640 x 480 píxeles con un fondo blanco. +Comment[et]=Loob valge taustaga pildi mõõtmetega 640 x 800 pikslit. +Comment[eu]=640 x 480 pixeleko atzeko planoa zuria duen irudi bat sortzen du. +Comment[fa]=تصویری ۴۸۰ × ۶۴۰ تصویردانهای با یک زمینۀ سفید ایجاد میکند. +Comment[fi]=Luo 640 x 480 pikselin kuvan valkoisella taustalla. +Comment[fr]=Crée une image de 640 x 480 pixels avec un fond blanc. +Comment[fy]=Makket in ôfbylding oan fan 640 x 480 byldpunten, mei in wite eftergrûn +Comment[gl]=Cria unha imaxe de 640 x 480 pixels cun fondo branco. +Comment[he]=יצירת תמונת בגודל 640 x 480 פיקסלים עם רקע לבן +Comment[hi]=640 x 480 पिक्सेल का, सफेद पृष्ठभूमि युक्त छवि बनाता है +Comment[hu]=Létrehoz egy 640 x 480 képpontos képet fehér háttérrel. +Comment[is]=Býr til hvíta mynd í 640 x 480 punkta upplausn með hvítum bakgrunni. +Comment[it]=Crea un'immagine di 640 × 480 pixel con uno sfondo bianco. +Comment[ja]=640 x 480 ピクセルの白い背景の画像を作成 +Comment[km]=បង្កើតរូបភាពទំហំ 640 x 480 ភីកសែល ដែលមានផ្ទៃខាងក្រោយពណ៌ស ។ +Comment[ms]=Cipta imej 640 x 480 piksel dengan latar belakang putih. +Comment[nb]=Lager et bilde på 640 x 480 piksler med hvit bakgrunn. +Comment[nds]=Stellt en Bild mit 640 x 480 Pixels mit witten Achtergrund op. +Comment[ne]=सेतो पृष्ठभूमि सहित ६४० x ४८० पिक्सेलको छवि सिर्जना गर्दछ । +Comment[nl]=Maakt een afbeelding aan van 640 x 480 pixels, met een witte achtergrond. +Comment[nn]=Lagar eit bilete på 640 × 480 pikslar med ein kvit bakgrunn. +Comment[pl]=Tworzy obrazek z białym tłem o rozmiarach 640 x 480 pikseli. +Comment[pt]=Cria uma imagem de 640 x 480 pontos com um fundo branco. +Comment[pt_BR]=Cria uma imagem de 640 x 480 pixéis com um fundo branco. +Comment[ru]=Рисунок 640x480, белый фон +Comment[se]=Ráhkada vilges govva mas leat 640 × 480 govvačuogga. +Comment[sk]=Vytvorí obrázok s rozmermi 640 x 480 pixelov a bielym pozadím. +Comment[sl]=Ustvari sliko velikosti 640 x 480 pik z belim ozadjem. +Comment[sr]=Прави слику од 640 x 480 пиксела са белом позадином. +Comment[sr@Latn]=Pravi sliku od 640 x 480 piksela sa belom pozadinom. +Comment[sv]=Skapar en bild med 640 x 480 bildpunkter och en vit bakgrund. +Comment[ta]=640 x 480 படத்துணுக்குகளில் வெள்ளை பின்னணியுடன் ஒரு பிம்பத்தை உருவாக்குகிறது. +Comment[tr]=640 x 480 piksel ebadında beyaz arkaplana sahip bir görüntü oluşturur +Comment[uk]=Створює зображення 640 x 480 пікселів з білим тлом. +Comment[uz]=Oʻlchami 640 x 480 nuqta va foni oq boʻlgan rasmni yaratish. +Comment[uz@cyrillic]=Ўлчами 640 x 480 нуқта ва фони оқ бўлган расмни яратиш. +Comment[zh_CN]=创建白色背景的 640 x 480 像素的图像。 +Comment[zh_TW]=建立一個 640 x 480 像素,白色背景的圖片。 +X-Chalk-Version=2 diff --git a/chalk/colorspaces/gray_u8/templates/white_640x480.kra b/chalk/colorspaces/gray_u8/templates/white_640x480.kra Binary files differnew file mode 100644 index 00000000..534368ef --- /dev/null +++ b/chalk/colorspaces/gray_u8/templates/white_640x480.kra diff --git a/chalk/colorspaces/gray_u8/tests/Makefile.am b/chalk/colorspaces/gray_u8/tests/Makefile.am new file mode 100644 index 00000000..35e83689 --- /dev/null +++ b/chalk/colorspaces/gray_u8/tests/Makefile.am @@ -0,0 +1,17 @@ +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../chalkcolor/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_grayscale_tester.la + +kunittest_kis_strategy_colorspace_grayscale_tester_la_SOURCES = kis_strategy_colorspace_grayscale_tester.cpp +kunittest_kis_strategy_colorspace_grayscale_tester_la_LIBADD = -lkunittest ../libchalkgrayscale.la +kunittest_kis_strategy_colorspace_grayscale_tester_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN) $(all_libraries) + +check-local: kunittest_kis_strategy_colorspace_grayscale_tester.la + kunittestmodrunner + diff --git a/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.cpp b/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.cpp new file mode 100644 index 00000000..0374c072 --- /dev/null +++ b/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2005 Adrian Page <[email protected]> + * + * 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_grayscale_tester.h" +#include "kis_gray_colorspace.h" + +using namespace KUnitTest; + +KUNITTEST_MODULE( kunittest_kis_strategy_colorspace_grayscale_tester, "Greyscale ColorSpace Tester" ); +KUNITTEST_MODULE_REGISTER_TESTER( KisGrayColorSpaceTester ); + +void KisGrayColorSpaceTester::allTests() +{ + // We need this so that the colour profile loading can operate without crashing. + KisFactory *factory = new KisFactory(); + + testBasics(); + testMixColors(); + + delete factory; +} + +#define MAX_CHANNEL_GRAYSCALEA 2 + +#define GRAY_CHANNEL 0 +#define ALPHA_CHANNEL 1 + +void KisGrayColorSpaceTester::testBasics() +{ + KisProfile *profile = new KisProfile(cmsCreate_sRGBProfile()); + KisGrayColorSpace *cs = new KisGrayColorSpace(profile); + + + TQ_UINT8 pixel[MAX_CHANNEL_GRAYSCALEA]; + + pixel[KisGrayColorSpace::PIXEL_GRAY] = 255; + pixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 128; + + TQString valueText = cs->channelValueText(pixel, GRAY_CHANNEL); + CHECK(valueText, TQString("255")); + + valueText = cs->channelValueText(pixel, ALPHA_CHANNEL); + CHECK(valueText, TQString("128")); + + valueText = cs->normalisedChannelValueText(pixel, GRAY_CHANNEL); + CHECK(valueText, TQString().setNum(1.0)); + + valueText = cs->normalisedChannelValueText(pixel, ALPHA_CHANNEL); + CHECK(valueText, TQString().setNum(128.0 / 255.0)); + + cs->setPixel(pixel, 128, 192l); + CHECK((uint)pixel[KisGrayColorSpace::PIXEL_GRAY], 128u); + CHECK((uint)pixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 192u); + + TQ_UINT8 gray; + TQ_UINT8 alpha; + + cs->getPixel(pixel, &gray, &alpha); + CHECK((uint)gray, 128u); + CHECK((uint)alpha, 192u); + + delete cs; +} + +void KisGrayColorSpaceTester::testMixColors() +{ + KisProfile *profile = new KisProfile(cmsCreate_sRGBProfile()); + KisAbstractColorSpace * cs = new KisGrayColorSpace(profile); + + TQ_UINT8 pixel1[MAX_CHANNEL_GRAYSCALEA]; + TQ_UINT8 pixel2[MAX_CHANNEL_GRAYSCALEA]; + TQ_UINT8 outputPixel[MAX_CHANNEL_GRAYSCALEA]; + + pixel1[KisGrayColorSpace::PIXEL_GRAY] = 255; + pixel1[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 255; + + pixel2[KisGrayColorSpace::PIXEL_GRAY] = 0; + pixel2[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 0; + + const TQ_UINT8 *pixelPtrs[2]; + TQ_UINT8 weights[2]; + + pixelPtrs[0] = pixel1; + pixelPtrs[1] = pixel2; + + weights[0] = 255; + weights[1] = 0; + + cs->mixColors(pixelPtrs, weights, 2, outputPixel); + + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY], 255); + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 255); + + weights[0] = 0; + weights[1] = 255; + + cs->mixColors(pixelPtrs, weights, 2, outputPixel); + + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY], 0); + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 0); + + weights[0] = 128; + weights[1] = 127; + + cs->mixColors(pixelPtrs, weights, 2, outputPixel); + + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY], 255); + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 128); + + pixel1[KisGrayColorSpace::PIXEL_GRAY] = 200; + pixel1[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 255; + + pixel2[KisGrayColorSpace::PIXEL_GRAY] = 100; + pixel2[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 255; + + cs->mixColors(pixelPtrs, weights, 2, outputPixel); + + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY], 150); + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 255); + + pixel1[KisGrayColorSpace::PIXEL_GRAY] = 0; + pixel1[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 0; + + pixel2[KisGrayColorSpace::PIXEL_GRAY] = 255; + pixel2[KisGrayColorSpace::PIXEL_GRAY_ALPHA] = 254; + + weights[0] = 89; + weights[1] = 166; + + cs->mixColors(pixelPtrs, weights, 2, outputPixel); + + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY], 255); + CHECK((int)outputPixel[KisGrayColorSpace::PIXEL_GRAY_ALPHA], 165); +} + + diff --git a/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.h b/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.h new file mode 100644 index 00000000..9b5f8d5e --- /dev/null +++ b/chalk/colorspaces/gray_u8/tests/kis_strategy_colorspace_grayscale_tester.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Adrian Page <[email protected]> + * + * 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_GRAYSCALE_TESTER_H +#define KIS_STRATEGY_COLORSPACE_GRAYSCALE_TESTER_H + +#include <kunittest/tester.h> + +class KisGrayColorSpaceTester : public KUnitTest::Tester +{ +public: + void allTests(); + void testMixColors(); + void testBasics(); +}; + +#endif + |