/* Copyright (c) 2008-2022 Jan W. Krieger () This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation, either version 2.1 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 Lesser General Public License (LGPL) for more details. You should have received a copy of the GNU Lesser General Public License (LGPL) along with this program. If not, see . */ #include "jkqtcommon/jkqtpbasicimagetools.h" #include #include #include #include #include #ifdef QT_XML_LIB # include #endif #if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0)) #include #include #else #include #endif const int JKQTPImageTools::PALETTE_ICON_WIDTH = 64; const int JKQTPImageTools::PALETTE_IMAGEICON_HEIGHT = 64; const int JKQTPImageTools::LUTSIZE = 256; const int JKQTPImageTools::NDEFAULTSTEPS = 5; QMap JKQTPImageTools::global_jkqtpimagetools_lutstore = JKQTPImageTools::getDefaultLUTs(); int JKQTPImageTools::global_next_userpalette = JKQTPMathImageFIRST_REGISTERED_USER_PALETTE; std::mutex JKQTPImageTools::lutMutex; QMap JKQTPImageTools::getDefaultLUTs() { QMap lutstore; { const auto palette=JKQTPMathImageDefault_STEP; const QString palN="jkqtplotterdefault_step"; const QString palNT=QObject::tr("steps: JKQTPlotter Default"); lutstore[palette]=JKQTPImageTools::LUTData(palN, palNT); JKQTPPaletteList lst; lst<(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(static_cast(255.0*v), 0, 0); } } } { const auto palette=JKQTPMathImageGREEN; const QString palN="green"; const QString palNT=QObject::tr("green"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(0, static_cast(255.0*v), 0); } } } { const auto palette=JKQTPMathImageBLUE; const QString palN="blue"; const QString palNT=QObject::tr("blue"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(0, 0, static_cast(255.0*v)); } } } { const auto palette=JKQTPMathImageGRAY; const QString palN="gray"; const QString palNT=QObject::tr("gray"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(static_cast(255.0*v), static_cast(255.0*v), static_cast(255.0*v)); } } } { const auto palette=JKQTPMathImageALPHA; const QString palN="alpha"; const QString palNT=QObject::tr("alpha"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgba(255,255,255, static_cast(255.0*v)); } } } { const auto palette=JKQTPMathImageINVERTED_ALPHA; const QString palN="invAlpha"; const QString palNT=QObject::tr("inv. alpha"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgba(255,255,255, static_cast(255.0*v)); } } } { const auto palette=JKQTPMathImageINVERTEDRED; const QString palN="invred"; const QString palNT=QObject::tr("inv. red"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(static_cast(255.0*(1.0-v)), 0, 0); } } } { const auto palette=JKQTPMathImageINVERTEDGREEN; const QString palN="invgreen"; const QString palNT=QObject::tr("inv. green"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(0, static_cast(255.0*(1.0-v)), 0); } } } { const auto palette=JKQTPMathImageINVERTEDBLUE; const QString palN="invblue"; const QString palNT=QObject::tr("inv. blue"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=qRgb(0, 0, static_cast(255.0*(1.0-v))); } } } { const auto palette=JKQTPMathImageINVERTEDGRAY; const QString palN="invgray"; const QString palNT=QObject::tr("inv. gray"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=1.0-(l/static_cast(JKQTPImageTools::LUTSIZE)); plut[l]=qRgb(static_cast(255.0*v), static_cast(255.0*v), static_cast(255.0*v)); } } } { const auto palette=JKQTPMathImageMATLAB; const QString palN="Matlab"; const QString palNT=QObject::tr("Matlab"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = 382.5 - 1020.0 * std::abs(v - 0.75); if (r > 255.0) r = 255.0; else if (r < 0.0) r = 0.0; double g = 382.5 - 1020.0 * std::abs(v - 0.5); if (g > 255.0) g = 255.0; else if (g < 0.0) g = 0.0; double b = 382.5 - 1020.0 * std::abs(v - 0.25); if (b > 255.0) b = 255.0; else if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageINVERTED_MATLAB; const QString palN="invMatlab"; const QString palNT=QObject::tr("inv. Matlab"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = 382.5 - 1020.0 * std::abs(v - 0.75); if (r > 255.0) r = 255.0; else if (r < 0.0) r = 0.0; double g = 382.5 - 1020.0 * std::abs(v - 0.5); if (g > 255.0) g = 255.0; else if (g < 0.0) g = 0.0; double b = 382.5 - 1020.0 * std::abs(v - 0.25); if (b > 255.0) b = 255.0; else if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageRYGB; const QString palN="RYGB"; const QString palNT=QObject::tr("RYGB"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = 796.875*v - 199.21875; if (r > 255.0) r = 255.0; else if (r < 0.0) r = 0.0; const double g = 255.0 * std::sin(JKQTPSTATISTICS_PI*v); double b = 255.0 - 765.0 * v; if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageINVERTED_RYGB; const QString palN="invRYGB"; const QString palNT=QObject::tr("inv. RYGB"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = 796.875*v - 199.21875; if (r > 255.0) r = 255.0; else if (r < 0.0) r = 0.0; const double g = 255.0 * std::sin(JKQTPSTATISTICS_PI*v); double b = 255.0 - 765.0 * v; if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageHSV; const QString palN="HSV"; const QString palNT=QObject::tr("HSV"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); const int h = static_cast(floor(6*v)); const double f = 6*v-double(h); switch (h) { case 0: plut[l]=qRgb(255, static_cast(255.0*f), 0); break; case 1: plut[l]=qRgb(static_cast(255.0*(1-f)), 255, 0); break; case 2: plut[l]=qRgb(0, 255, static_cast(255.0*f)); break; case 3: plut[l]=qRgb(0, static_cast(255.0*(1-f)), 255); break; case 4: plut[l]=qRgb(static_cast(255.0*f), 0, 255); break; case 5: plut[l]=qRgb(255, 0, static_cast(255.0*(1-f))); break; case 6: plut[l]=qRgb(255, static_cast(255.0*f), 0); break; } } } } { const auto palette=JKQTPMathImageINVERTED_HSV; const QString palN="invHSV"; const QString palNT=QObject::tr("inv. HSV"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); const int h = static_cast(floor(6.0-6.0*v)); const double f = 6.0-6.0*v-double(h); switch (h) { case 0: plut[l]=qRgb(255, static_cast(255.0*f), 0); break; case 1: plut[l]=qRgb(static_cast(255.0*(1-f)), 255, 0); break; case 2: plut[l]=qRgb(0, 255, static_cast(255.0*f)); break; case 3: plut[l]=qRgb(0, static_cast(255.0*(1-f)), 255); break; case 4: plut[l]=qRgb(static_cast(255.0*f), 0, 255); break; case 5: plut[l]=qRgb(255, 0, static_cast(255.0*(1-f))); break; case 6: plut[l]=qRgb(255, static_cast(255.0*f), 0); break; } } } } { const auto palette=JKQTPMathImageRAINBOW; const QString palN="rainbow"; const QString palNT=QObject::tr("rainbow"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = 255.0*std::abs(2.0*v-0.5); if (r > 255.0) r = 255.0; const double g = 255.0*sin(JKQTPSTATISTICS_PI*v); const double b = 255.0*cos(0.5*JKQTPSTATISTICS_PI*v); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageINVERTED_RAINBOW; const QString palN="invrainbow"; const QString palNT=QObject::tr("inv. rainbow"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = 255.0*std::abs(2.0*v-0.5); if (r > 255.0) r = 255.0; const double g = 255.0*sin(JKQTPSTATISTICS_PI*v); const double b = 255.0*cos(0.5*JKQTPSTATISTICS_PI*v); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageHOT; const QString palN="AFMhot"; const QString palNT=QObject::tr("AFM hot"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = 765.0*v; if (r > 255.0) r = 255.0; double g = 765.0*v-255.0; if (g > 255.0) g = 255.0; else if (g < 0.0) g = 0.0; double b = 765.0*v-510.0; if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageINVERTED_HOT; const QString palN="invAFMhot"; const QString palNT=QObject::tr("inv. AFM hot"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = 765.0*v; if (r > 255.0) r = 255.0; double g = 765.0*v-255.0; if (g > 255.0) g = 255.0; else if (g < 0.0) g = 0.0; double b = 765.0*v-510.0; if (b < 0.0) b = 0.0; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageOCEAN; const QString palN="ocean"; const QString palNT=QObject::tr("ocean"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = 765.0*v-510.0; if (r < 0.0) r = 0.0; const double g = std::abs(382.5*v-127.5); const double b = 255.0*v; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageINVERTED_OCEAN; const QString palN="invocean"; const QString palNT=QObject::tr("inv. ocean"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = 765.0*v-510.0; if (r < 0.0) r = 0.0; const double g = std::abs(382.5*v-127.5); const double b = 255.0*v; plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageBLUEMAGENTAYELLOW; const QString palN="BlMaYe"; const QString palNT=QObject::tr("blue-magenta-yellow"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = (v/0.32-0.78125); if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = 2.0*v-0.84; if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = 4.0*v; if (b>1 || b<0) b = -2.0*v+1.84; if (b>1 || b<0) b = v/0.08-11.5; if (b>1 || b<0) b=1; if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageINVERTED_BLUEMAGENTAYELLOW; const QString palN="YeMaBl"; const QString palNT=QObject::tr("yellow-magenta-blue"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = (v/0.32-0.78125); if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = 2.0*v-0.84; if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = 4.0*v; if (b>1 || b<0) b = -2.0*v+1.84; if (b>1 || b<0) b = v/0.08-11.5; if (b>1 || b<0) b=1; if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageBLUEYELLOW; const QString palN="BlYe"; const QString palNT=QObject::tr("blue-yellow"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = sqrt(sqrt(v)); if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = sin(JKQTPSTATISTICS_PI/2.0*v); if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = cos(JKQTPSTATISTICS_PI/2.0*v); if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageINVERTED_BLUEYELLOW; const QString palN="YeBl"; const QString palNT=QObject::tr("yellow-blue"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = sqrt(sqrt(v)); if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = sin(JKQTPSTATISTICS_PI/2.0*v); if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = cos(JKQTPSTATISTICS_PI/2.0*v); if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageCYAN; const QString palN="cyan"; const QString palNT=QObject::tr("cyan"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = v*0.5; if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = v; if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = v; if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageINVERTED_CYAN; const QString palN="invcyan"; const QString palNT=QObject::tr("inv. cyan"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = v*0.5; if (r < 0.0) r = 0.0; if (r > 1.0) r = 1.0; double g = v; if (g < 0.0) g = 0.0; if (g > 1.0) g = 1.0; double b = v; if (b < 0.0) b = 0.0; if (b > 1.0) b = 1.0; plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b)); } } } { const auto palette=JKQTPMathImageTRAFFICLIGHT; const QString palN="trafficlight"; const QString palNT=QObject::tr("trafficlight"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=l/static_cast(JKQTPImageTools::LUTSIZE); double r = (v < 0.5) ? 128.0*sin(JKQTPSTATISTICS_PI*(2.0*v-0.5))+128.0 : 255.0; if (r > 255.0) r = 255.0; double g = (v < 0.5) ? 512.0*v+128.0 : 512.0-512.0*v; if (g > 255.0) g = 255.0; plut[l]=qRgb(static_cast(r), static_cast(g), 0); } } } { const auto palette=JKQTPMathImageINVERTED_TRAFFICLIGHT; const QString palN="invtrafficlight"; const QString palNT=QObject::tr("inv. trafficlight"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); double r = (v < 0.5) ? 128.0*sin(JKQTPSTATISTICS_PI*(2.0*v-0.5))+128.0 : 255.0; if (r > 255.0) r = 255.0; double g = (v < 0.5) ? 512.0*v+128.0 : 512.0-512.0*v; if (g > 255.0) g = 255.0; plut[l]=qRgb(static_cast(r), static_cast(g), 0); } } } { const auto palette=JKQTPMathImageBLUEWHITERED; const QString palN="bluewhitered"; const QString palNT=QObject::tr("blue-white-red"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); JKQTPPaletteList lst; lst<(8.0, 0xFFB2182B); lst<(7.0, 0xFFD6604D); lst<(6.0, 0xFFF4A582); lst<(5.0, 0xFFFDDBC7); lst<(4.0, 0xFFD1E5F0); lst<(3.0, 0xFF92C5DE); lst<(2.0, 0xFF4393C3); lst<(1.0, 0xFF2166AC); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst, JKQTPImageTools::LUTSIZE+1); } { const auto palette=JKQTPMathImageREDWHITEBLUE; const QString palN="redwhiteblue"; const QString palNT=QObject::tr("red-white-blue"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); JKQTPPaletteList lst; lst<(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); const double r = 255.0*qBound(0.0,sqrt(v),1.0); const double g = 255.0*qBound(0.0,v*v*v,1.0); const double b = 255.0*qBound(0.0,sin(2.0*JKQTPSTATISTICS_PI*v),1.0); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageGREENREDVIOLET; const QString palN="GnRdVi"; const QString palNT=QObject::tr("green-red-violet"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); const double r = 255.0*qBound(0.0,v,1.0); const double g = 255.0*qBound(0.0,fabs(v-0.5),1.0); const double b = 255.0*qBound(0.0,v*v*v*v,1.0); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageBLACKBLUEWHITEYELLOWWHITE; const QString palN="BWprint"; const QString palNT=QObject::tr("black-blue-white-yellow-white"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); const double r = 255.0*qBound(0.0,v/0.32-0.78125,1.0); const double g = 255.0*qBound(0.0,v/0.32-0.78125,1.0); const double b = 255.0*qBound(0.0,(v<0.25)?4*v:(v<0.42)?1.0:(v<0.92)?-2.0*v+1.84:v/0.08-11.5,1.0); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageWHITEYELLOWWHITEBLUEBLACK; const QString palN="invBWprint"; const QString palNT=QObject::tr("white-yellow-white-blue-black"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); const double r = 255.0*qBound(0.0,v/0.32-0.78125,1.0); const double g = 255.0*qBound(0.0,v/0.32-0.78125,1.0); const double b = 255.0*qBound(0.0,(v<0.25)?4*v:(v<0.42)?1.0:(v<0.92)?-2.0*v+1.84:v/0.08-11.5,1.0); plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b)); } } } { const auto palette=JKQTPMathImageBR_GR; const QString palN="BrBG"; const QString palNT=QObject::tr("BrBG"); lutstore[palette]=JKQTPImageTools::LUTData(palN, palNT); JKQTPPaletteList lst; lst<(0.0, qRgb(0x8C, 0x51, 0x0A)); lst<(1.0, qRgb(0xBF, 0x81, 0x2D)); lst<(2.0, qRgb(0xDF, 0xC2, 0x7D)); lst<(JKQTPImageTools::LUTSIZE+1, 0), "magenta", QObject::tr("magenta")); lutstore[palettei]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), "invmagenta", QObject::tr("inv. magenta")); QRgb* plut=lutstore[palette].lut.data(); QRgb* pluti=lutstore[palettei].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,1,0,v).rgba(); pluti[l]=QColor::fromCmykF(0,1,0,1.0-v).rgba(); } } } { const auto palette=JKQTPMathImageYELLOW; const auto palettei=JKQTPMathImageINVERTED_YELLOW; lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), "yellow", QObject::tr("yellow")); lutstore[palettei]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), "invyellow", QObject::tr("inv. yellow")); QRgb* plut=lutstore[palette].lut.data(); QRgb* pluti=lutstore[palettei].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,0,1,v).rgba(); pluti[l]=QColor::fromCmykF(0,0,1,1.0-v).rgba(); } } } { const auto palette=JKQTPMathImageCYAN; const auto palettei=JKQTPMathImageINVERTED_CYAN; lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), "cyan", QObject::tr("cyan")); lutstore[palettei]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), "invcyan", QObject::tr("inv. cyan")); QRgb* plut=lutstore[palette].lut.data(); QRgb* pluti=lutstore[palettei].lut.data(); if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(1,0,0,v).rgba(); pluti[l]=QColor::fromCmykF(1,0,0,1.0-v).rgba(); } } } { const auto palette=JKQTPMathImageINVERTED_MAGENTAWHITE; const QString palN="whitemagenta"; const QString palNT=QObject::tr("white-magenta"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,v,0,0).rgba(); } } } { const auto palette=JKQTPMathImageMAGENTAWHITE; const QString palN="magentawhite"; const QString palNT=QObject::tr("magenta-white"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,v,0,0).rgba(); } } } { const auto palette=JKQTPMathImageINVERTED_YELLOWWHITE; const QString palN="whiteyellow"; const QString palNT=QObject::tr("white-yellow"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,0,v,0).rgba(); } } } { const auto palette=JKQTPMathImageYELLOWWHITE; const QString palN="yellowwhite"; const QString palNT=QObject::tr("yellow-white"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(0,0,v,0).rgba(); } } } { const auto palette=JKQTPMathImageINVERTED_CYANWHITE; const QString palN="whitecyan"; const QString palNT=QObject::tr("white-cyan"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(v,0,0,0).rgba(); } } } { const auto palette=JKQTPMathImageCYANWHITE; const QString palN="cyanwhite"; const QString palNT=QObject::tr("cyan-white"); lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT); QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n"; if (plut!=nullptr) { for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) { const double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE); plut[l]=QColor::fromCmykF(v,0,0,0).rgba(); } } } { const auto palette=JKQTPMathImageBlueGreenRed; const QString palN="bluegreenred"; const QString palNT=QObject::tr("blue-green-red"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("blue").rgb()); lst<(2.0, QColor("green").rgb()); lst<(3.0, QColor("red").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageRedGreenBlue; const QString palN="redgreenblue"; const QString palNT=QObject::tr("red-green-blue"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("red").rgb()); lst<(2.0, QColor("green").rgb()); lst<(3.0, QColor("blue").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageMagentaYellow; const QString palN="magentayellow"; const QString palNT=QObject::tr("magenta-yellow"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("magenta").rgb()); lst<(2.0, QColor("yellow").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageYellowMagenta; const QString palN="yellowmagenta"; const QString palNT=QObject::tr("yellow-magenta"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("yellow").rgb()); lst<(2.0, QColor("magenta").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageRedBlue; const QString palN="redblue"; const QString palNT=QObject::tr("red-blue"); lutstore[palette]=JKQTPImageTools::LUTData(palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("red").rgb()); lst<(2.0, QColor("blue").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageBlueRed; const QString palN="bluered"; const QString palNT=QObject::tr("blue-red"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(1.0, QColor("blue").rgb()); lst<(2.0, QColor("red").rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); } { const auto palette=JKQTPMathImageSeismic; const QString palN="seismic"; const QString palNT=QObject::tr("seismic"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(0, QColor::fromRgbF(0.0f, 0.0f, 0.3f).rgb()); lst<(1, QColor::fromRgbF(0.0f, 0.0f, 1.0f).rgb()); lst<(2, QColor::fromRgbF(1.0f, 1.0f, 1.0f).rgb()); lst<(3, QColor::fromRgbF(1.0f, 0.0f, 0.0f).rgb()); lst<(4, QColor::fromRgbF(0.5f, 0.0f, 0.0f).rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); { const auto palettei=JKQTPMathImageSeismic_STEP; lutstore[palettei]=JKQTPImageTools::LUTData("seismic_step", QObject::tr("steps: seismic")); lutstore[palettei].lut=JKQTPBuildColorPaletteLUTColorsOnlySteps(lst); } } { const auto palette=JKQTPMathImageTerrain; const QString palN="terrain"; const QString palNT=QObject::tr("terrain"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); JKQTPPaletteList lst; lst<(0.00, QColor::fromRgbF(0.2f, 0.2f, 0.6f).rgb()); lst<(0.15, QColor::fromRgbF(0.0f, 0.6f, 1.0f).rgb()); lst<(0.25, QColor::fromRgbF(0.0f, 0.8f, 0.4f).rgb()); lst<(0.50, QColor::fromRgbF(1.0f, 1.0f, 0.6f).rgb()); lst<(0.75, QColor::fromRgbF(0.5f, 0.36f, 0.33f).rgb()); lst<(1.00, QColor::fromRgbF(1.0f, 1.0f, 1.0f).rgb()); lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst); { const auto palettei=JKQTPMathImageTerrain_STEP; lutstore[palettei]=JKQTPImageTools::LUTData("terrain_step", QObject::tr("steps: terrain")); lutstore[palettei].lut=JKQTPBuildColorPaletteLUTColorsOnlySteps(lst); } } { const auto palette=JKQTPMathImageBone; const QString palN="bone"; const QString palNT=QObject::tr("bone"); lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT); QList lstR,lstG,lstB; lstR< lstR,lstG,lstB; lstR< lstR,lstG,lstB; lstR< lstR,lstG,lstB; lstR< &s1, const QPair &s2) { return s1.first itemsR, QList itemsG, QList itemsB, int lut_size) { std::sort(itemsR.begin(), itemsR.end(), JKQTPBuildColorPaletteLUTLinSegLessThan); std::sort(itemsG.begin(), itemsG.end(), JKQTPBuildColorPaletteLUTLinSegLessThan); std::sort(itemsB.begin(), itemsB.end(), JKQTPBuildColorPaletteLUTLinSegLessThan); return JKQTPBuildColorPaletteLUTLinSegmentsSorted(itemsR, itemsG, itemsB, lut_size); } JKQTPImageTools::LUTType JKQTPBuildColorPaletteLUTLinSegmentsSorted(const QList &itemsR, const QList &itemsG, const QList &itemsB, int lut_size) { JKQTPImageTools::LUTType lut(lut_size, qRgb(255,255,255)); if (itemsR.size()<=0 && itemsG.size()<=0 && itemsB.size()<=0) return lut; auto buildChannel=[](JKQTPImageTools::LUTType& lut, const QList &items, int channel) { if (items.size()==1) { for (int i=0; i(lut.size()-2); double v=dmin; int j1=0; for (int i=0; i(static_cast(items[j2].colval_endprevious-items[j1].colval_startnext)*local_relV); JKQTPSetColorChannel(lut[i], channel, jkqtp_bounded(0, newCol, 255)); //qDebug()<<"i="< lut[i]=0x"<=items[j1].position && v>=items[j2].position && j1(0, items.last().colval_endprevious, 255)); } }; buildChannel(lut, itemsR, 0); buildChannel(lut, itemsG, 1); buildChannel(lut, itemsB, 2); return lut; } JKQTPImageTools::LUTType JKQTPBuildColorPaletteLUTLinInterpolateSorted(const JKQTPPaletteList &items, int lut_size) { JKQTPImageTools::LUTType lut(lut_size, 0); if (items.size()<=1) return lut; double dmin=items.first().first; double dmax=items.last().first; double delta=(dmax-dmin)/static_cast(lut_size-2); double v=dmin; int j1=0; for (int i=0; i(r), static_cast(g), static_cast(b)); v+=delta; // advance over items, if v crosses items[j2].first while (v>=items[j1].first && v>=items[j2].first && j1=items[j+1].first) j++; } if (i<=lut_size) lut[i]=qRgb(static_cast(r), static_cast(g), static_cast(b)); i++; } return lut; } JKQTPImageTools::LUTType JKQTPBuildColorPaletteLUTLinInterpolate(const QMap &items, int lut_size) { JKQTPPaletteList itemsi; for (auto it=items.begin(); it!=items.end(); ++it) { itemsi.append(QPair(it.key(), it.value())); } return JKQTPBuildColorPaletteLUTLinInterpolateSorted(itemsi, lut_size); } JKQTPImageTools::LUTType JKQTPBuildColorPaletteLUT(const QMap &items, int lut_size) { JKQTPPaletteList itemsi; for (auto it=items.begin(); it!=items.end(); ++it) { itemsi.append(QPair(it.key(), it.value())); } return JKQTPBuildColorPaletteLUTSorted(itemsi, lut_size); } double JKQTPImagePlot_QStringToDouble(QString value) { QString v=value; if (value.contains(',')) { v=value.replace(',', '.'); } QLocale loc=QLocale::c(); loc.setNumberOptions(QLocale::OmitGroupSeparator); return loc.toDouble(v) ; } JKQTPImageTools::LUTType JKQTPBuildColorPaletteLUTBySubsampling(const JKQTPImageTools::LUTType &lut, int lut_size) { JKQTPImageTools::LUTType out; out.reserve(lut_size); for (int i=0; i(0, i*(lut.size()-1)/lut_size, lut.size()-1); out.append(lut[step]); } return out; } template bool JKQTPImagePlot_QPairCompareFirst(const QPair &s1, const QPair &s2) { return s1.first < s2.first; } QStringList JKQTPImageTools::getPredefinedPalettes() { std::lock_guard lock(JKQTPImageTools::lutMutex); static QStringList sl; if (sl.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) { sl.clear(); for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) { if (it.key()>=0 && it.key()<=JKQTPMathImageLAST_POSSIBLE_REGISTERED_USER_PALETTE) { if (it.value().nameT.size()!=0) sl< lock(JKQTPImageTools::lutMutex); static QStringList sl; if (sl.size()!=JKQTPImageTools::global_jkqtpimagetools_lutstore.size()) { sl.clear(); for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) { if (it.key()>=0) { if (it.value().name.size()!=0) sl< lock(JKQTPImageTools::lutMutex); auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.find(p); if (it==JKQTPImageTools::global_jkqtpimagetools_lutstore.end()) return QString::number(static_cast(p)); else { if (it.value().name.size()>0) return it.value().name; else return QString::number(static_cast(p)); } } JKQTPMathImageColorPalette JKQTPImageTools::String2JKQTPMathImageColorPalette(const QString &p) { std::lock_guard lock(JKQTPImageTools::lutMutex); for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) { if (QString::compare(p, it.value().name, Qt::CaseInsensitive)==0) { return static_cast(it.key()); } } for (auto it=JKQTPImageTools::global_jkqtpimagetools_lutstore.begin(); it!=JKQTPImageTools::global_jkqtpimagetools_lutstore.end(); ++it) { if (QString::compare(p, it.value().nameT, Qt::CaseInsensitive)==0) { return static_cast(it.key()); } } bool ok=false; JKQTPMathImageColorPalette res = static_cast(p.toInt(&ok)); if (!ok) return JKQTPMathImageMATLAB; else return res; } const JKQTPImageTools::LUTType& JKQTPImageTools::getLUTforPalette(QMap& lutstore, JKQTPMathImageColorPalette palette) { static JKQTPImageTools::LUTType empty(JKQTPImageTools::LUTSIZE, 0); auto it=lutstore.find(static_cast(palette)); if (it==lutstore.end()) { return empty; } else { return it.value().lut; } } QImage JKQTPImageTools::GetPaletteImage(int i, int width) { return JKQTPImageTools::GetPaletteImage(i, width, 1); } QImage JKQTPImageTools::GetPaletteImage(int i, int width, int height) { QImage img; QVector pic(width*height,0); for (int j=0; j(pic.data(), width, height, img, static_cast(i), Qt::black, Qt::black); return img; } QImage JKQTPImageTools::GetPaletteImage(JKQTPMathImageColorPalette palette, int width) { return JKQTPImageTools::GetPaletteImage(static_cast(palette), width); } QImage JKQTPImageTools::GetPaletteImage(JKQTPMathImageColorPalette palette, int width, int height) { return JKQTPImageTools::GetPaletteImage(static_cast(palette), width, height); } QImage JKQTPImageTools::GetPaletteImage(const JKQTPImageTools::LUTType& lut, int width) { QImage img; QVector pic(width); for (int j=0; j(pic.data(), pic.size(), 1, img, lut, Qt::black, Qt::black); return img; } QIcon JKQTPImageTools::GetPaletteIcon(int i) { const QImage img=JKQTPImageTools::GetPaletteImage(i, JKQTPImageTools::PALETTE_ICON_WIDTH); QPixmap pix(JKQTPImageTools::PALETTE_ICON_WIDTH,8); const QRect r(0,0,JKQTPImageTools::PALETTE_ICON_WIDTH-1,7); QPainter p(&pix); p.drawImage(r, img); p.setPen(QPen(QColor("black"))); p.drawRect(r); p.end(); return QIcon(pix); } QIcon JKQTPImageTools::GetPaletteIcon(JKQTPMathImageColorPalette palette) { return JKQTPImageTools::GetPaletteIcon(static_cast(palette)); } int JKQTPImageTools::registerPalette(const QString &name, const JKQTPImageTools::LUTType &paletteLut, const QString &nameT) { std::lock_guard lock(JKQTPImageTools::lutMutex); int id=JKQTPImageTools::global_next_userpalette++; JKQTPImageTools::global_jkqtpimagetools_lutstore[id].name=name; JKQTPImageTools::global_jkqtpimagetools_lutstore[id].nameT=((nameT.size()>0)?nameT:name); JKQTPImageTools::global_jkqtpimagetools_lutstore[id].lut=paletteLut; return id; } QVector JKQTPImageTools::registerPalettesFromFile(const QString &filename, bool interpolatePalette) { QVector ids; QString ext=QFileInfo(filename).suffix().toLower(); if (ext=="rgb" || ext=="pal" || ext=="csv") { QFile file(filename); if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { QString txt=file.readAll(); QStringList slt=txt.split('\n'); bool has4=false; bool rgb255=false; JKQTPPaletteList pal; #if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0)) QRegularExpression rx3("\\s*([0-9eE.+-]+)\\s*([,\\t ])\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*", QRegularExpression::CaseInsensitiveOption|QRegularExpression::InvertedGreedinessOption); QRegularExpression rx4("\\s*([0-9eE.+-]+)\\s*([,\\t ])\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*", QRegularExpression::CaseInsensitiveOption|QRegularExpression::InvertedGreedinessOption); #else QRegExp rx3("\\s*([0-9eE.+-]+)\\s*([,\\t ])\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*", Qt::CaseInsensitive); rx3.setMinimal(false); QRegExp rx4("\\s*([0-9eE.+-]+)\\s*([,\\t ])\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*\\2\\s*([0-9eE.+-]+)\\s*", Qt::CaseInsensitive); rx4.setMinimal(false); #endif // determine format for (int i=slt.size()-1; i>=0; i--) { slt[i]=slt[i].trimmed(); #if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0)) const auto m4=rx4.match(slt[i]); const auto m3=rx3.match(slt[i]); if (m4.hasMatch()) { const double r=JKQTPImagePlot_QStringToDouble(m4.captured(3)); const double g=JKQTPImagePlot_QStringToDouble(m4.captured(4)); const double b=JKQTPImagePlot_QStringToDouble(m4.captured(5)); #else if (rx4.indexIn(slt[i])>=0) { const double r=JKQTPImagePlot_QStringToDouble(rx4.cap(3)); const double g=JKQTPImagePlot_QStringToDouble(rx4.cap(4)); const double b=JKQTPImagePlot_QStringToDouble(rx4.cap(5)); #endif has4=true; if (r>1.0 || g>1.0 || b>1.0) { rgb255=true; } #if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0)) } else if (m3.hasMatch()) { const double r=JKQTPImagePlot_QStringToDouble(m3.captured(1)); const double g=JKQTPImagePlot_QStringToDouble(m3.captured(3)); const double b=JKQTPImagePlot_QStringToDouble(m3.captured(4)); #else } else if (rx3.indexIn(slt[i])>=0) { double r=JKQTPImagePlot_QStringToDouble(rx3.cap(1)); double g=JKQTPImagePlot_QStringToDouble(rx3.cap(3)); double b=JKQTPImagePlot_QStringToDouble(rx3.cap(4)); #endif has4=false; if (r>1.0 || g>1.0 || b>1.0) { rgb255=true; } } else { slt.removeAt(i); } } // read data bool ok=true; for (int i=0; i=QT_VERSION_CHECK(6, 0, 0)) const auto m4=rx4.match(slt[i]); const auto m3=rx3.match(slt[i]); if (has4 && m4.hasMatch()) { x=JKQTPImagePlot_QStringToDouble(m4.captured(1)); r=JKQTPImagePlot_QStringToDouble(m4.captured(3)); g=JKQTPImagePlot_QStringToDouble(m4.captured(4)); b=JKQTPImagePlot_QStringToDouble(m4.captured(5)); } else if (!has4 && m3.hasMatch()) { x=i; r=JKQTPImagePlot_QStringToDouble(m3.captured(1)); g=JKQTPImagePlot_QStringToDouble(m3.captured(3)); b=JKQTPImagePlot_QStringToDouble(m3.captured(4)); #else if (has4 && rx4.indexIn(slt[i])>=0) { x=JKQTPImagePlot_QStringToDouble(rx4.cap(1)); r=JKQTPImagePlot_QStringToDouble(rx4.cap(3)); g=JKQTPImagePlot_QStringToDouble(rx4.cap(4)); b=JKQTPImagePlot_QStringToDouble(rx4.cap(5)); } else if (!has4 && rx3.indexIn(slt[i])>=0) { x=i; r=JKQTPImagePlot_QStringToDouble(rx3.cap(1)); g=JKQTPImagePlot_QStringToDouble(rx3.cap(3)); b=JKQTPImagePlot_QStringToDouble(rx3.cap(4)); //qDebug()<(x, qRgb(qBound(0,static_cast(round(255*r)), 255), qBound(0,static_cast(round(255*g)), 255), qBound(0,static_cast(round(255*b)), 255))); } else { pal<(x, qRgb(qBound(0,static_cast(round(r)), 255), qBound(0,static_cast(round(g)), 255), qBound(0,static_cast(round(b)), 255))); } } } if (ok && pal.size()>1) { if (interpolatePalette) ids<(round(255*r)), 255), qBound(0,static_cast(round(255*g)), 255), qBound(0,static_cast(round(255*b)), 255))); e = e.nextSiblingElement("Point"); } if (pal.size()>1) { if (interpolatePalette) ids<(0, y1*255.0, 255), jkqtp_boundedRoundTo(0, y2*255.0, 255)); } JKQTPColorPaletteSingleColorLinSegment::JKQTPColorPaletteSingleColorLinSegment(): position(0), colval_endprevious(0), colval_startnext(0) { } JKQTPMathImageModifierMode StringToModifierMode(const QString &mode) { QString m=mode.toLower(); if (m=="value" ) return JKQTPMathImageModifierMode::ModifyValue; if (m=="saturation" ) return JKQTPMathImageModifierMode::ModifySaturation; if (m=="alpha" ) return JKQTPMathImageModifierMode::ModifyAlpha; if (m=="luminance" ) return JKQTPMathImageModifierMode::ModifyLuminance; if (m=="hue" ) return JKQTPMathImageModifierMode::ModifyHue; return JKQTPMathImageModifierMode::ModifyNone; } QString ModifierModeToString(const JKQTPMathImageModifierMode &mode) { if (mode==JKQTPMathImageModifierMode::ModifyValue) return "value"; if (mode==JKQTPMathImageModifierMode::ModifySaturation) return "saturation"; if (mode==JKQTPMathImageModifierMode::ModifyAlpha) return "alpha"; if (mode==JKQTPMathImageModifierMode::ModifyLuminance) return "luminance"; if (mode==JKQTPMathImageModifierMode::ModifyHue) return "hue"; return "none"; } void JKQTPModifyImage(QImage &img, JKQTPMathImageModifierMode modifierMode, const void *dataModifier, JKQTPMathImageDataType datatypeModifier, int Nx, int Ny, double internalModifierMin, double internalModifierMax) { if (!dataModifier) return; //getModifierMinMax(internalModifierMin, internalModifierMax); if (modifierMode!=JKQTPMathImageModifierMode::ModifyNone) { JKQTPRGBMathImageRGBMode rgbModMode=JKQTPRGBMathImageModeRGBMode; int modChannel=3; if (modifierMode==JKQTPMathImageModifierMode::ModifyValue) { modChannel=2; rgbModMode=JKQTPRGBMathImageModeHSVMode; } else if (modifierMode==JKQTPMathImageModifierMode::ModifySaturation) { modChannel=1; rgbModMode=JKQTPRGBMathImageModeHSVMode; } else if (modifierMode==JKQTPMathImageModifierMode::ModifyAlpha) { modChannel=3; rgbModMode=JKQTPRGBMathImageModeRGBMode; } else if (modifierMode==JKQTPMathImageModifierMode::ModifyLuminance) { modChannel=2; rgbModMode=JKQTPRGBMathImageModeHSLMode; } else if (modifierMode==JKQTPMathImageModifierMode::ModifyHue) { modChannel=0; rgbModMode=JKQTPRGBMathImageModeHSLMode; } //qDebug()<<"mod: "<(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::FloatArray: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::UInt8Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::UInt16Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::UInt32Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::UInt64Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::Int8Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::Int16Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::Int32Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; case JKQTPMathImageDataType::Int64Array: JKQTPImagePlot_array2RGBimage(static_cast(dataModifier), Nx, Ny, img, modChannel, internalModifierMin, internalModifierMax, rgbModMode); break; } } } JKQTPImageTools::LUTType JKQTPModifyLUT(JKQTPImageTools::LUTType lut, std::function f) { int i=0; for (auto& c: lut) { c=f(i, c); i++; } return lut; } JKQTPImageTools::LUTType JKQTPModifyLUT(JKQTPImageTools::LUTType lut, std::function f) { for (auto& c: lut) { c=f(c); } return lut; } JKQTPImageTools::LUTType JKQTPCreateGreensCubeHelixLUT(float start, float rotation, float gamma, int lutsize, float lambda_min, float lambda_max, float saturation_min, float saturation_max) { JKQTPImageTools::LUTType res; for (int i=0; i(i)/static_cast(lutsize-1)*(lambda_max-lambda_min); const float sat=saturation_min+static_cast(i)/static_cast(lutsize-1)*(saturation_max-saturation_min); const float lambda_gamma=pow(lambda, gamma); const float phi=2.0*JKQTPSTATISTICS_PI*(start/3.0+rotation*lambda); const float cosphi=cos(phi); const float sinphi=sin(phi); const float amplitude=sat*lambda_gamma*(1-lambda_gamma)/2.0; const float R=lambda_gamma + amplitude*(-0.14861*cosphi+1.78277*sinphi); const float G=lambda_gamma + amplitude*(-0.29227*cosphi-0.90649*sinphi); const float B=lambda_gamma + amplitude*(1.972940*cosphi+0.0*sinphi); res<(0.0,R,1.0), jkqtp_bounded(0.0,G,1.0), jkqtp_bounded(0.0,B,1.0)).rgb(); } return res; }