diff options
Diffstat (limited to 'chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp')
-rw-r--r-- | chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp b/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp new file mode 100644 index 000000000..c43e56900 --- /dev/null +++ b/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp @@ -0,0 +1,206 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 "fastcolortransfer.h" + +#include <kgenericfactory.h> +#include <kurlrequester.h> + +#include <kis_colorspace_factory_registry.h> +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_iterators_pixel.h> +#include <kis_meta_registry.h> +#include <kis_paint_device.h> + +#include "kis_wdg_fastcolortransfer.h" +#include "wdgfastcolortransfer.h" + +typedef KGenericFactory<FastColorTransferPlugin> ChalkFastColorTransferFactory; +K_EXPORT_COMPONENT_FACTORY( chalkfastcolortransfer, ChalkFastColorTransferFactory( "chalk" ) ) + + +FastColorTransferPlugin::FastColorTransferPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkFastColorTransferFactory::instance()); + + kdDebug(41006) << "Color Transfer Filter plugin. Class: " + << className() + << ", Parent: " + << parent -> className() + << "\n"; + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast<KisFilterRegistry *>(parent); + manager->add(new KisFilterFastColorTransfer()); + } +} + +FastColorTransferPlugin::~FastColorTransferPlugin() +{ +} + +KisFilterFastColorTransfer::KisFilterFastColorTransfer() : KisFilter(id(), "colors", i18n("&Color Transfer...")) +{ +} + + +KisFilterConfigWidget * KisFilterFastColorTransfer::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) +{ + return new KisWdgFastColorTransfer(this, parent, "configuration of color to alpha"); +} + +KisFilterConfiguration* KisFilterFastColorTransfer::configuration(TQWidget* w) +{ + KisWdgFastColorTransfer * wCTA = dynamic_cast<KisWdgFastColorTransfer*>(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wCTA) + { + config->setProperty("filename", wCTA->widget()->fileNameURLRequester->url() ); + } + return config; +} + +void KisFilterFastColorTransfer::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + kdDebug() << "Start transfering color" << endl; + TQVariant value; + TQString fileName; + if (config && config->getProperty("filename", value)) + { + fileName = value.toString(); + } else { + kdDebug() << "No file name for the reference image was specified." << endl; + return; + } + + KisPaintDeviceSP ref; + + KisDoc d; + d.import(fileName); + KisImageSP importedImage = d.currentImage(); + + if(importedImage) + { + ref = importedImage->projection(); + } + if(!ref) + { + kdDebug() << "No reference image was specified." << endl; + return; + } + + // Convert ref and src to LAB + KisColorSpace* labCS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("LABA"),""); + if(!labCS) + { + kdDebug() << "The LAB colorspace is not available." << endl; + return; + } + + setProgressTotalSteps(5); + + KisColorSpace* oldCS = src->colorSpace(); + KisPaintDeviceSP srcLAB = new KisPaintDevice(*src.data()); + srcLAB->convertTo(labCS); + ref->convertTo(labCS); + + setProgress( 1 ); + + // Compute the means and sigmas of src + double meanL_src = 0., meanA_src = 0., meanB_src = 0.; + double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.; + KisRectIteratorPixel srcLABIt = srcLAB->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false ); + while(!srcLABIt.isDone()) + { + const TQ_UINT16* data = reinterpret_cast<const TQ_UINT16*>(srcLABIt.oldRawData()); + TQ_UINT32 L = data[0]; + TQ_UINT32 A = data[1]; + TQ_UINT32 B = data[2]; + meanL_src += L; + meanA_src += A; + meanB_src += B; + sigmaL_src += L*L; + sigmaA_src += A*A; + sigmaB_src += B*B; + ++srcLABIt; + } + + setProgress( 3 ); + + double size = 1. / ( rect.width() * rect.height() ); + meanL_src *= size; + meanA_src *= size; + meanB_src *= size; + sigmaL_src *= size; + sigmaA_src *= size; + sigmaB_src *= size; + kdDebug() << size << " " << meanL_src << " " << meanA_src << " " << meanB_src << " " << sigmaL_src << " " << sigmaA_src << " " << sigmaB_src << endl; + // Compute the means and sigmas of src + double meanL_ref = 0., meanA_ref = 0., meanB_ref = 0.; + double sigmaL_ref = 0., sigmaA_ref = 0., sigmaB_ref = 0.; + KisRectIteratorPixel refIt = ref->createRectIterator(0, 0, importedImage->width(), importedImage->height(), false ); + while(!refIt.isDone()) + { + const TQ_UINT16* data = reinterpret_cast<const TQ_UINT16*>(refIt.oldRawData()); + TQ_UINT32 L = data[0]; + TQ_UINT32 A = data[1]; + TQ_UINT32 B = data[2]; + meanL_ref += L; + meanA_ref += A; + meanB_ref += B; + sigmaL_ref += L*L; + sigmaA_ref += A*A; + sigmaB_ref += B*B; + ++refIt; + } + + setProgress( 4 ); + + size = 1. / ( importedImage->width() * importedImage->height() ); + meanL_ref *= size; + meanA_ref *= size; + meanB_ref *= size; + sigmaL_ref *= size; + sigmaA_ref *= size; + sigmaB_ref *= size; + kdDebug() << size << " " << meanL_ref << " " << meanA_ref << " " << meanB_ref << " " << sigmaL_ref << " " << sigmaA_ref << " " << sigmaB_ref << endl; + + // Transfer colors + dst->convertTo(labCS); + { + double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src)); + double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src)); + double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src)); + kdDebug() << coefL << " " << coefA << " " << coefB << endl; + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + while(!dstIt.isDone()) + { + TQ_UINT16* data = reinterpret_cast<TQ_UINT16*>(dstIt.rawData()); + data[0] = (TQ_UINT16)CLAMP( ( (double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.); + data[1] = (TQ_UINT16)CLAMP( ( (double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.); + data[2] = (TQ_UINT16)CLAMP( ( (double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.); + ++dstIt; + } + } + dst->convertTo(oldCS); + setProgressDone(); // Must be called even if you don't really support progression +} |