From 32eb6b996c73708d5dc30c75cf7f4fe4a8061028 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 15 Dec 2015 01:06:38 +0100 Subject: [PATCH] Adding softproofing. Now the output profile and the new rendering intent profile for the output profile will only be shown when the new softproof toggle button (bottom of the preview in the Editor panel) will be on. --- .../images/Dark/actions/intent-absolute.png | Bin 0 -> 464 bytes .../images/Dark/actions/intent-perceptual.png | Bin 0 -> 666 bytes .../images/Dark/actions/intent-relative.png | Bin 0 -> 944 bytes .../images/Dark/actions/intent-saturation.png | Bin 0 -> 809 bytes rtdata/images/Dark/actions/softProof.png | Bin 0 -> 827 bytes .../images/Light/actions/intent-absolute.png | Bin 0 -> 445 bytes .../Light/actions/intent-perceptual.png | Bin 0 -> 638 bytes .../images/Light/actions/intent-relative.png | Bin 0 -> 882 bytes .../Light/actions/intent-saturation.png | Bin 0 -> 779 bytes rtdata/images/Light/actions/softProof.png | Bin 0 -> 868 bytes rtdata/languages/default | 2 + rtengine/dcrop.cc | 8 +- rtengine/dcrop.h | 5 + rtengine/iccstore.h | 6 + rtengine/improccoordinator.cc | 45 +- rtengine/improccoordinator.h | 11 + rtengine/improcfun.cc | 44 +- rtengine/improcfun.h | 9 +- rtengine/iplab2rgb.cc | 16 +- rtengine/procevents.h | 3 + rtengine/procparams.cc | 34 +- rtengine/procparams.h | 12 +- rtengine/refreshmap.cc | 24 +- rtengine/refreshmap.h | 56 +- rtengine/rtengine.h | 8 +- rtengine/settings.h | 4 +- rtengine/simpleprocess.cc | 4 +- rtgui/editorpanel.cc | 171 +- rtgui/editorpanel.h | 2 +- rtgui/filecatalog.cc | 1 + rtgui/history.cc | 5 +- rtgui/icmpanel.cc | 29 +- rtgui/icmpanel.h | 1 + rtgui/options.cc | 10 +- rtgui/options.h | 1 + rtgui/paramsedited.cc | 5 + rtgui/paramsedited.h | 1 + rtgui/preferences.cc | 2 +- .../scalable/intent-absolute.file | 1 + .../source_icons/scalable/intent-absolute.svg | 1378 ++++++++++++++++ .../scalable/intent-perceptual.file | 1 + .../scalable/intent-perceptual.svg | 1366 ++++++++++++++++ .../scalable/intent-relative.file | 1 + .../source_icons/scalable/intent-relative.svg | 1374 ++++++++++++++++ .../scalable/intent-saturation.file | 1 + .../scalable/intent-saturation.svg | 1366 ++++++++++++++++ tools/source_icons/scalable/softProof.file | 1 + tools/source_icons/scalable/softProof.svg | 1389 +++++++++++++++++ 48 files changed, 7255 insertions(+), 142 deletions(-) create mode 100644 rtdata/images/Dark/actions/intent-absolute.png create mode 100644 rtdata/images/Dark/actions/intent-perceptual.png create mode 100644 rtdata/images/Dark/actions/intent-relative.png create mode 100644 rtdata/images/Dark/actions/intent-saturation.png create mode 100644 rtdata/images/Dark/actions/softProof.png create mode 100644 rtdata/images/Light/actions/intent-absolute.png create mode 100644 rtdata/images/Light/actions/intent-perceptual.png create mode 100644 rtdata/images/Light/actions/intent-relative.png create mode 100644 rtdata/images/Light/actions/intent-saturation.png create mode 100644 rtdata/images/Light/actions/softProof.png create mode 100644 tools/source_icons/scalable/intent-absolute.file create mode 100644 tools/source_icons/scalable/intent-absolute.svg create mode 100644 tools/source_icons/scalable/intent-perceptual.file create mode 100644 tools/source_icons/scalable/intent-perceptual.svg create mode 100644 tools/source_icons/scalable/intent-relative.file create mode 100644 tools/source_icons/scalable/intent-relative.svg create mode 100644 tools/source_icons/scalable/intent-saturation.file create mode 100644 tools/source_icons/scalable/intent-saturation.svg create mode 100644 tools/source_icons/scalable/softProof.file create mode 100644 tools/source_icons/scalable/softProof.svg diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7e1a85d0cf0b4a131e3dc02ef8e74161a5f367 GIT binary patch literal 464 zcmV;>0WbcEP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdu*o9?cT=WR@DbA6 zO0c!hJ7}41leM!+At|&`v9i*1F|r7|_gbiBU@nY!>cjWJW#-Nh0AyL#VrCCTX0zGT za5&_Ut^)w)+<=)6G?GrIa{}N!SW;EhB@tyBNu$vyLc0zC>h=1=VzF=P000&U1^@s6HNQ8u00004b3#c}2nYxW zdPNB7i*4H_JLPvshJcg%IvI z=MvzN_Z|@$1EW08->Iq<<>q;Q02MXa+1aV5X?h!Ih)4ri0(3^oUZ>O9s6hEtg7ncvd&fYJMj5bGnS1NRb4Z)1v8s9R;rt^-|sh6b=}NvQguL{ zhI1M97rnHi<3bOdb2Ha(9LHx~zf<8~T;xaMANVyY-gCezlK=n!07*qoM6N<$g0=S` AF8}}l literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png new file mode 100644 index 0000000000000000000000000000000000000000..c1fb040a9ddabae8f9ebdd03367c2bacbba0978c GIT binary patch literal 944 zcmV;h15f;kP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zd z86-(Excq7v6hy(x@ z0Ki(CkUSQVeUd&S$&-IOIX^$YS1cB@=z@p zD*#g477;HZCrOfYYPDLgUayeLylW#=MplTvboPF#Md8s!&z#?(V*oBuQY5 zSpl%5s)h0P8GsXG%qXM4$6*+LNdRax8uyGbw=?oMRn3pTp8`0t*0wJ$F51;fYYo3#z)@Y&L5EUe5|HB9F@D@)r~70)YMf{Tsbr z?~aJ97-NC}4m9ueoxAOV?JEPGkl@V+0p8(Dr02B&^&$6U`eturd^A(Z5fUC=R z7eFdqBtddS@@EnG&N9o+Ty!fdc?z%>5)uZloGGC&S_Jw`m`!H2e+50fabx S=)Ix<0000P000&U1^@s6HNQ8u00004b3#c}2nYxW zdk)ELp(-tYN- z?m6Fkf&Wkf0L5Z)gyfEYZZ0x6Ffec}0Dzf&^4@3vHAGcE0rg4#wu;4KPF35RoyQm} z`Fy?<)@tg#?Jh>Vg<%n|^+_s;-42z8S_ zl8H~zIoA$gkff2k9b>$ss=cauh2&BQ;X<`qT}tYWF;*Irh{zrhNesSzJ`3R1%*@Q^ zo}QkAB=?bgCnAr{>{tlN3o)}-0Dk`XwzjrQ3kwTANtny!I5ad=o}Hb|c6WE5Cb^sB z{Sd-SRXt*6Z@u>)l6py&fEIuJ`1tr1@BKLu*#=r~{Yb4=`&}lV&FoA%oleyQ z|B}sS&kqg`{t?iCkQ^uZFiGH?V+i5i^78TqGrM4BWs+xmdwajN0sz*Q$yES8l}erJ z>+73u6#%sG8K0*|5aVxLlBlgKm=J>Z;E^NU?Mm+bW6O5 zhZZ~tiXQgv$3-#XO}vRlK@fF8Z{iA*kC)g)Q1IZAfF4A=8c5724w7`w>sKB!BjY$T z$$)<-cwJQex<2TBKtmG~6MxOk&HahrBxxRe-#?w_xdU(!0466VcYB_9n3*TSF#Nw? zFav-wX1}WL1h6Yj(-8m=kqZEhJLeu6W5%bZrndG2rZi2ZD2j1a-PZ6eW?6Q=R4Tmy z;57qP^^50uXTvajzNw1yJTE!tZm8-EfN52|31C|*6aa{5&^dR@7;|h>;5d%IMNu?Q zM2pV3#VCsAMTEP=djKvOW6o>{?&Kt*VuQTXv$M13Rh9Yz2SM;@ql%n!Cyg|5n&Nw zW~R3IJxfbV_tP{T>yY-hwf0`6Qu*VTp|`+ZTWbsFoQen&k*aDF zincuhfW`U;c5ifa^lMjexm^AXRf%R)6WZ7nqr!*6a0uYPH%95urTK z3nF@16vcxmic%uduDQLy<#O3F^A+dZ*LuDFukZT@!!SG%$MLgP==AjTsrF0a#|Dfs z2{Y@;%F2@t?+5_o-3k~Q8oKP9+penfs(L$)<8Q6tBSdthR|nmss#~x=R>#aAnE71S zzf(Ul##{w3NJMkhYV}c)Bt_5V^`RF70|U=SMn-B)$9E!tHa;dGDfa*X002ovPDHLk FV1jU2Y!3hc literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..1396e378553270124944c886d2536016f879e622 GIT binary patch literal 445 zcmV;u0Yd(XP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdZHp_>f})Ds;LOx90%L6aId8JZ-Jlhg9G^!15gyjz*@UQL`0+p+K{dV z==FNzwrvk%B+j`r5qS@msOq(<-o{A!{r;zj1a%ESp66+nWj014A|HSTOUkmmRMn_+ zB}o!@F5nJ$iji1rzhe4Zj{z8sM(3(pb`CeDs_Xj7t{xVu8ugw8N)}x+H_HHq!{Hbx zw!nXx&1REi3*i5W0dUTpsOq3|xG}FHa$^C!_xnkb9CR)5-e+AiH)g$EN2P000&U1^@s6HNQ8u00004b3#c}2nYxW zd9p#k(uphS(a}t5{BU&0N3jX&bccjACgq( z+=tn0_GUVrp0pNOhkn0*&CH&XybIujjIxQXI$k%xnih2f$YVW!+hl$7z}#cmSZP&zcHvW>8f` zQIwM$nb~MQpMNTf;$x@Nd17X_8#5630{|WXR8@7*lnH=~BGNarTLA8>>LXQ!@B6u# zjhu7uM1&2Q`~q6mq}%OYQq_T~4oMD4Mk1msG8rdHve!zaPSo?f8zgJvsA`cU$qx?z zq9}S!GTK&5r2bn;egp8zTaroSkp0Am1q9hnOyw;3MGDIXNd017|$jrt?Q7o2beB5+SL=pg>*P5|utoXjaL$V_x ztHw%uGX_C0bk6MpxQVs{avjcO)SvgGP000&U1^@s6HNQ8u00004b3#c}2nYxW zdyD28hkRH zPJb2vaL#?Fs@K{aNyY#!HOChsvIihHv)p_Cbd4s@)FmQbL|XZhG?JyN?v-Wv2mpt} z;X5QJ&bco|l8?RjKdplcyD! zT$bgpYvBTb!C>$)fNc?(nArrtyZ;sQ#*6Rw`?pnftId&QL~=m#z2@o_fPIpA6h(Pa z6pwL+F=*$z%aII8*Z>@n{5^`Iy`m_l0PI{0{eJ&*k|83`y!Ut4#^s#rh{!cF%S0pt z;2JRm?G0Scxf=l95BOeE)iKE-fVWf?0G^WEF|#~Lk|R|O;aUO>E>*pC(SkIynTYI? z%sZVP000&U1^@s6HNQ8u00004b3#c}2nYxW zdux+o%-Nw%r#M{DgyOztw!r175TodR$JKsU(+k~7Y^LvebNtGQh6eM81) zGMN)$7>)oqO>)&*`z#E@vN2{%RU^HuPm%?&4N0fd=K#b##jY?6&x?qXd>I76D-k&h zUB>GhRgAB@&4j*=)Ab+uM7Uxm;dLrBZF4=iMWD#u)P!z&BML5s`v1=6h7Gs+NETjqmU8 zKOO|ZIDnLh%&2NnMD75X_kDkS=jFw20ssaE208&Gq6EJ0cayvgpoQd95!nDRL9$e> zR>vxpN^P$uUA@rgZk_2tFHpzeu?bdo$4qX_^^?-y`j@f(*TH1x}--+TZ7002ov JPDHLkV1jwrP1yhd literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/softProof.png b/rtdata/images/Light/actions/softProof.png new file mode 100644 index 0000000000000000000000000000000000000000..2c12e216fe3e86915a5928a7a413c37a6219fc23 GIT binary patch literal 868 zcmV-q1DpJbP)F_~hZyqC1|D|6?a z(?w@OJI;&~@C%Q7Ih^x(-*fNfUSOcb#l`2AmX@Bu|0FY(*W)-oGe1B7bCzYTS;1VXR1AQ( z0E8kEG4tEY%ggfsUKl2+>RD#KnIy?8Gdu2dIwuN+LLGpJNR64lZnxVfnEB0-+yW7; z$8nscY5Mzrf?KVYPt)|DVzKzFs@|{FYPX8T;!^-FjO!3UC641lnx?m>fq86@IiFUf zsu!Je9|E9bfdSl|1|I0$BuOq!G&e3-tyVK4$^pO_L)Kch)>04zk2zG;3(mPu2M1s# z$2k#Y%#1J$If^2Vq9_Q%kgc_&?XNc)jnAEP(JWx7>R$k0tqr0m3I^ce$RoLDnfc3= zm6emTfd3eP$y&=p=hj*_#_;H}h{%hbPUp(%>guVfU;uv(Cxt>G2*WTK0*BuiGfS;j z>#}q1$$u^SQ7g>90LZ=fYK&nK(LB$InTeS}^f;G@`l|XpfXlU7?cPLiwOYNKB*{w39budY)dXk8YstPmLOQq5W6K|*EC`pn}RP_{q uAJ^8_u5WB?OuZdvmUHgaa=HA(qp=6oX)*PXM7#a~0000Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l MAIN_TOOLTIP_THRESHOLD;Threshold MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +MONITOR_PROFILE_SYSTEM;System default NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -1512,6 +1513,7 @@ TP_ICM_INPUTPROFILE;Input Profile TP_ICM_LABEL;Color Management TP_ICM_NOICM;No ICM: sRGB Output TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a97ae7f39..cd68aa0a6 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -33,7 +33,7 @@ extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), - updating(false), newUpdatePending(false), skip(10), + softProofing(false), updating(false), newUpdatePending(false), skip(10), cropx(0), cropy(0), cropw(-1), croph(-1), trafx(0), trafy(0), trafw(-1), trafh(-1), rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), @@ -987,7 +987,7 @@ void Crop::update (int todo) EditBuffer::setReady(); // switch back to rgb - parent->ipf.lab2monitorRgb (labnCrop, cropImg); + parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing); //parent->ipf.lab2monitorRgb (laboCrop, cropImg); @@ -1030,13 +1030,13 @@ void Crop::update (int todo) Image8 *cropImgtrue; if(settings->HistogramWorking) { - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false); } int finalW = rqcropw; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 57f388a51..ea9b1bc00 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -54,6 +54,7 @@ protected: // ----------------------------------------------------------------- float** cbuffer; + bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile bool updating; /// Flag telling if an updater thread is currently processing bool newUpdatePending; /// Flag telling the updater thread that a new update is pending int skip; @@ -103,6 +104,10 @@ public: /** @brief Asynchronously reprocess the detailed crop */ void fullUpdate (); // called via thread + void setSoftProofing(bool doSoftProof) { + softProofing = doSoftProof; + } + void setListener (DetailedCropListener* il); void destroy (); int get_skip () diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index ed9fbb424..6b41987f7 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -91,6 +91,7 @@ public: // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); cmsHPROFILE getDefaultMonitorProfile () const; + Glib::ustring getDefaultMonitorProfileStr () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -134,6 +135,11 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const return getProfile (defaultMonitorProfile); } +inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const +{ + return defaultMonitorProfile; +} + inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const { return getInputIntents (getProfile (name)); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8389ec34e..62de26076 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,9 +31,9 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), - highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), - bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), + softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), shtonecurve(65536), @@ -781,9 +781,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + // Update the output color transform if necessary + if (isColorProfileDirty || (todo & M_MONITOR)) { + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing); + isColorProfileDirty = false; + } + // process crop, if needed for (size_t i = 0; i < crops.size(); i++) if (crops[i]->hasListener () && cropCall != crops[i] ) { + crops[i]->setSoftProofing(softProofing); crops[i]->update (todo); // may call ourselves } @@ -794,23 +801,23 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Conversion to RGB...", 100 * readyphase / numofphases); - if (todo != CROP && todo != MINUPDATE) { + if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); try { - ipf.lab2monitorRgb (nprevl, previmg); + ipf.lab2monitorRgb (nprevl, previmg, softProofing); delete workimg; Glib::ustring outProfile = params.icm.output; if(settings->HistogramWorking) { Glib::ustring workProfile = params.icm.working; - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, true); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, RI_RELATIVE, true); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { - if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { + if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, false); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false); } } catch(char * str) { progress ("Error converting file...", 0); @@ -1126,6 +1133,28 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } +void ImProcCoordinator::setSoftProofing (bool softProof) +{ + softProofing = softProof; +} + +void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent) +{ + if (profile != monitorProfile) { + monitorProfile = profile; + isColorProfileDirty = true; + } + if (intent != monitorIntent) { + monitorIntent = intent; + isColorProfileDirty = true; + } +} + +void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent) +{ + profile = monitorProfile; + intent = monitorIntent; +} void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ef981fe6a..901804eba 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -72,11 +72,18 @@ protected: ImProcFunctions ipf; + Glib::ustring monitorProfile; + + eRenderingIntent monitorIntent; + int scale; bool highDetailPreprocessComputed; bool highDetailRawComputed; bool allocated; + bool isColorProfileDirty; + bool softProofing; + void freeAll (); // Precomputed values used by DetailedCrop ---------------------------------------------- @@ -249,6 +256,10 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent); + void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent); + void setSoftProofing (bool softProof); + bool updateTryLock () { return updaterThreadStart.trylock(); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c9fa3c6c8..e99daa79a 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -186,12 +186,11 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) } } */ -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) + + +void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing) { - // set up monitor transform - Glib::ustring wprofile = params->icm.working; - if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); } @@ -210,36 +209,30 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB -#if defined(WIN32) - - cmsHPROFILE monitor = settings->autoMonitorProfile - ? iccStore->getDefaultMonitorProfile () - : iccStore->getProfile (params->icm.monitorProfile); - -#else - - cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile); - -#endif + cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); + printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent); if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, + printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; - if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) { - outputProfile = params->icm.output; + if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) { + outputProfile = icm.output; cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + //TODO: Create a dedicated softproof transformation (line below to be finished) + //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - } + printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent); + lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } @@ -247,6 +240,13 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par } #endif +} + +void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +{ + + Glib::ustring wprofile = params->icm.working; + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments int T = 1; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cfabbba64..c34219c0d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,6 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -265,7 +266,7 @@ public: void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); - void lab2monitorRgb (LabImage* lab, Image8* image); + void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false); void resize (Image16* src, Image16* dst, float dScale); void Lanczos (const LabImage* src, LabImage* dst, float scale); void Lanczos (const Image16* src, Image16* dst, float scale); @@ -379,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cc01b783f..a727423ef 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; const int numprof = 7; -void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing) { //gamutmap(lab); @@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) buffer[iy++] = rb[j] / 327.68f; } - if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { AlignedBuffer buf(3 * W); cmsDoTransform (lab2outputTransform, buffer, buf.data, W); cmsDoTransform (output2monitorTransform, buf.data, data + ix, W); @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -167,7 +167,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, lcmsMutex->lock (); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); - cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety cmsCloseProfile(hLab); lcmsMutex->unlock (); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw) { //gamutmap(lab); @@ -322,7 +322,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); @@ -593,7 +593,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4dbbad07c..4609c674a 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -454,6 +454,9 @@ enum ProcEvent { EvLbaselog = 424, // EvLgrbl = 425, EvRetinexlhcurve = 425, + EvOIntent = 426, + EvSoftProof = 427, + EvMonitorTransform = 428, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 44c02a531..2c93bfd47 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,8 +894,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; - monitorProfile = Glib::ustring (); - monitorIntent = 1; + outputIntent = RI_PERCEPTUAL; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2550,6 +2549,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Color Management", "OutputProfile", icm.output); } + if (!pedited || pedited->icm.outputIntent) { + Glib::ustring intent; + if (icm.outputIntent == RI_PERCEPTUAL) { + intent = "Perceptual"; + } else if (icm.outputIntent == RI_RELATIVE) { + intent = "Relative"; + } else if (icm.outputIntent == RI_SATURATION) { + intent = "Saturation"; + } else if (icm.outputIntent == RI_ABSOLUTE) { + intent = "Absolute"; + } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); + } + if (!pedited || pedited->icm.gamma) { keyFile.set_string ("Color Management", "Gammafree", icm.gamma); } @@ -5674,6 +5687,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Color Management", "OutputProfileIntent")) { + Glib::ustring intent = keyFile.get_string ("Color Management", "OutputProfileIntent"); + if (intent == "Perceptual") { + icm.outputIntent = RI_PERCEPTUAL; + } else if (intent == "Relative") { + icm.outputIntent = RI_RELATIVE; + } else if (intent == "Saturation") { + icm.outputIntent = RI_SATURATION; + } else if (intent == "Absolute") { + icm.outputIntent = RI_ABSOLUTE; + } + + if (pedited) { + pedited->icm.outputIntent = true; + } + } + if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 77c1004e8..cbbbed7a5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "LUT.h" #include "coord.h" @@ -41,6 +42,14 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; +typedef enum RenderingIntent { + RI_PERCEPTUAL = INTENT_PERCEPTUAL, + RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, + RI_SATURATION = INTENT_SATURATION, + RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, + RI__COUNT +} eRenderingIntent; + namespace procparams { @@ -941,8 +950,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; - Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override. - int monitorIntent; // Not store persistently as it is just an optional settings override. + eRenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3505da24f..37d0f52b4 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DARKFRAME, // EvLCPUseVign, TRANSFORM, // EvLCPUseCA, M_VOID, // EvFixedExp - WHITEBALANCE, // EvWBMethod, - WHITEBALANCE, // EvWBTemp, - WHITEBALANCE, // EvWBGreen, + ALLNORAW, // EvWBMethod, + ALLNORAW, // EvWBTemp, + ALLNORAW, // EvWBGreen, RGBCURVE, // EvToneCurveMode1, RGBCURVE, // EvToneCurve2, RGBCURVE, // EvToneCurveMode2, @@ -75,7 +75,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvCDNEnabled:obsolete, ALL, // EvBlendCMSMatrix, RGBCURVE, // EvDCPToneCurve, - INPUTPROFILE, // EvDCPIlluminant, + ALLNORAW, // EvDCPIlluminant, RETINEX, // EvSHEnabled, RGBCURVE, // EvSHHighlights, RGBCURVE, // EvSHShadows, @@ -97,7 +97,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvHRMethod, ALLNORAW, // EvWProfile, OUTPUTPROFILE, // EvOProfile, - INPUTPROFILE, // EvIProfile, + ALLNORAW, // EvIProfile, TRANSFORM, // EvVignettingAmount, RGBCURVE, // EvChMixer, RESIZE, // EvResizeScale, @@ -234,8 +234,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATbadpix LUMINANCECURVE, // EvCATAutoadap DEFRINGE, // EvPFCurve - WHITEBALANCE, // EvWBequal - WHITEBALANCE, // EvWBequalbo + ALLNORAW, // EvWBequal + ALLNORAW, // EvWBequalbo TRANSFORM, // EvGradientDegree TRANSFORM, // EvGradientEnabled TRANSFORM, // EvPCVignetteStrength @@ -421,7 +421,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DIRPYREQUALIZER, // EvWavNeutral RGBCURVE, // EvDCPApplyLookTable, RGBCURVE, // EvDCPApplyBaselineExposureOffset, - INPUTPROFILE, // EvDCPApplyHueSatMap + ALLNORAW, // EvDCPApplyHueSatMap DIRPYREQUALIZER, // EvWavenacont DIRPYREQUALIZER, // EvWavenachrom DIRPYREQUALIZER, // EvWavenaedge @@ -452,7 +452,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DEMOSAIC, // EvLslope RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog -// DEMOSAIC, // EvLgrbl - DEMOSAIC // EvRetinexlhcurve +// DEMOSAIC, // EvLgrbl + DEMOSAIC, // EvRetinexlhcurve + ALLNORAW, // EvOIntent + ALLNORAW, // EvSoftProof + MONITORTRANSFORM // EvMonitorTransform + }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index e24d0c422..23e179f9f 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -20,15 +20,16 @@ #define __REFRESHMAP__ // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<15) +#define M_VOID (1<<16) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<14) +#define M_MINUPDATE (1<<15) // Force high quality -#define M_HIGHQUAL (1<<13) +#define M_HIGHQUAL (1<<14) // Elementary functions that can be done to // the preview image when an event occurs +#define M_MONITOR (1<<13) #define M_RETINEX (1<<12) #define M_CROP (1<<11) #define M_PREPROC (1<<10) @@ -45,31 +46,30 @@ // Bitfield of functions to do to the preview image when an event occurs // Use those or create new ones for your new events -#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE) -#define SHARPENING M_LUMINANCE -#define IMPULSEDENOISE M_LUMINANCE -#define DEFRINGE M_LUMINANCE -#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) -#define CROP M_CROP -#define RESIZE M_VOID -#define EXIF M_VOID -#define IPTC M_VOID -#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) -#define OUTPUTPROFILE (M_INIT|M_COLOR|M_LUMINANCE) -#define INPUTPROFILE WHITEBALANCE -#define GAMMA (M_COLOR|M_LUMINANCE) -#define MINUPDATE M_MINUPDATE -#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RETINEX (M_RETINEX|ALLNORAW) +#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SHARPENING (M_LUMINANCE|M_COLOR) +#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) +#define DEFRINGE (M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) +#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) +#define GAMMA (M_LUMINANCE|M_COLOR) +#define CROP M_CROP +#define RESIZE M_VOID +#define EXIF M_VOID +#define IPTC M_VOID +#define MINUPDATE M_MINUPDATE +#define RETINEX (M_RETINEX|ALLNORAW) +#define MONITORTRANSFORM M_MONITOR +#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM) extern int refreshmap[]; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 195911a3a..d10acb561 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -35,7 +35,7 @@ #include "LUT.h" /** * @file - * This file contains the main functionality of the raw therapee engine. + * This file contains the main functionality of the RawTherapee engine. * */ @@ -413,9 +413,13 @@ public: virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; virtual void setAutoChromaListener (AutoChromaListener* l) = 0; - virtual void setRetinexListener (RetinexListener* l) = 0; + virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; + virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0; + virtual void setSoftProofing (bool softProof) = 0; + virtual ~StagedImageProcessor () {} /** Returns a staged, cached image processing manager supporting partial updates diff --git a/rtengine/settings.h b/rtengine/settings.h index bd37faaf2..98c85ba6f 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -19,6 +19,8 @@ #ifndef _RTSETTINGS_ #define _RTSETTINGS_ +#include "procparams.h" + namespace rtengine { @@ -37,7 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile name used for the monitor - int monitorIntent; ///< Colorimetric intent used with the above profile + eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5ea834b2d..1edfa590c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1151,7 +1151,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cmsFloat64Number Parameters[7]; double ga0, ga1, ga2, ga3, ga4, ga5, ga6; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); + readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); customGamma = true; //or selected Free gamma @@ -1343,7 +1343,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bwonly = false; } - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly); if (settings->verbose) { printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c6d2804c1..a762fc95b 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -35,88 +35,171 @@ using namespace rtengine::procparams; class MonitorProfileSelector { private: - Gtk::ComboBoxText profileBox; - Gtk::ComboBoxText intentBox; + Gtk::ToggleButton* softProof; + MyComboBoxText* profileBox; + //PopUpButton* intentBox; + MyComboBoxText* intentBox; + sigc::connection profileConn, intentConn; - rtengine::StagedImageProcessor* const& processor; + rtengine::StagedImageProcessor* processor; private: - MonitorProfileSelector(const MonitorProfileSelector&); - MonitorProfileSelector& operator=(const MonitorProfileSelector&); + void prepareSoftProofButton () + { + Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png")); + softProofImg->set_padding(0, 0); + softProof = Gtk::manage(new Gtk::ToggleButton()); + softProof->add(*softProofImg); + softProof->set_relief(Gtk::RELIEF_NONE); + softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); + } void prepareProfileBox () { - profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); - profileBox.set_active (0); + profileBox = Gtk::manage(new MyComboBoxText()); + profileBox->set_size_request(100,-1); - const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); - for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) - profileBox.append_text (*iterator); + profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); + #if defined(WIN32) + profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")"); + profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); + #else + profileBox->set_active (0); + #endif + + const std::vector profiles = rtengine::iccStore->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { + profileBox->append_text (*iterator); + } + profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } void prepareIntentBox () { - intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE")); - intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox.set_active (0); + intentBox = Gtk::manage(new MyComboBoxText()); + intentBox->set_size_request(-1,-1); + //intentBox = Gtk::manage(new PopUpButton()); + + intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + //intentBox->setSelected(0); + intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + } + + void softProofToggled () + { + if (processor) { + processor->setSoftProofing( softProof->get_active() ); + processor->endUpdateParams ( rtengine::EvMonitorTransform ); + } + } + + void updateIntent (int i) + { + updateParameters(); } void updateParameters () { - const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring(); + Glib::ustring profile; +#ifdef WIN32 + if (profileBox->get_active_row_number () == 1) { + profile = rtengine::iccStore->getDefaultMonitorProfileStr (); + if (profile.empty()) { + profile = options.rtSettings.monitorProfile; + } + if (profile.empty()) { + profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows + } + } else if (profileBox->get_active_row_number () > 1) { + profile = profileBox->get_active_text (); + } +#else + profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); +#endif - std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile); + std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; if (supportsPerceptual && supportsRelativeColorimetric) { - intentBox.set_sensitive (true); + intentBox->set_sensitive (true); } else { - intentBox.set_sensitive (false); - intentBox.set_active (supportsPerceptual ? 1 : 0); + bool wasBlocked = intentConn.block(true); + intentBox->set_active(supportsPerceptual ? 0 : 1); + //intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->set_sensitive (false); + intentConn.block(wasBlocked); } - const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL; - if (!processor) + if (!processor) { return; + } - rtengine::ProcParams* parameters = processor->beginUpdateParams (); + // either store them in the options file for the default value when opening the next EditorPanel + //options.rtSettings.monitorProfile = profile; + //options.rtSettings.monitorIntent = intent; - parameters->icm.monitorProfile = profile; - parameters->icm.monitorIntent = intent; - - processor->endUpdateParams (rtengine::EvOProfile); + // ...or store them locally + printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent); + processor->setMonitorProfile(profile, intent); + printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform); + processor->endUpdateParams (rtengine::EvMonitorTransform); } public: - MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : - profileBox (), - intentBox (), - processor (ipc) + MonitorProfileSelector () : + processor (NULL) { + prepareSoftProofButton (); prepareProfileBox (); prepareIntentBox (); reset (); - - profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); - intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } - void pack_end (Gtk::Box* box) + // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way + void pack_end_in (Gtk::Box* box) { - box->pack_end (intentBox, Gtk::PACK_SHRINK, 0); - box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); + box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0); } void reset () { - setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); - intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + bool wasBlocked; +#ifdef WIN32 + wasBlocked = profileConn.block(true); + if (options.rtSettings.autoMonitorProfile) { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1); + } else { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + } + profileConn.block(wasBlocked); +#else + wasBlocked = profileConn.block(true); + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + profileConn.block(wasBlocked); +#endif + wasBlocked = intentConn.block(true); + intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentConn.block(wasBlocked); - updateParameters (); + // useless, set_active will trigger the signal_changed event + //updateParameters (); + } + + void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { + processor = imageProc; } }; @@ -269,6 +352,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Save buttons Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + iops->set_spacing(2); //Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)); Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png")); @@ -346,14 +430,16 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navSync->set_relief(Gtk::RELIEF_NONE); navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); - iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); } - monitorProfile.reset(new MonitorProfileSelector (ipc)); - monitorProfile->pack_end (iops); + // Monitor profile buttons + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + monitorProfile = new MonitorProfileSelector (); + monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); @@ -491,6 +577,7 @@ EditorPanel::~EditorPanel () delete ppframe; delete leftbox; delete vboxright; + delete monitorProfile; //delete saveAsDialog; if(catalogPane) { @@ -612,6 +699,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) this->isrc = isrc; ipc = rtengine::StagedImageProcessor::create (isrc); + monitorProfile->setImageProcessor(ipc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); ipc->setPreviewScale (10); // Important @@ -662,6 +750,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); + //HOMBRE: not sure if we want to reset on opening a new image monitorProfile->reset (); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index ffb8a93a4..0575b7f92 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; - std::auto_ptr monitorProfile; + MonitorProfileSelector* monitorProfile; ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d40b7d720..0112f9ebf 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1139,6 +1139,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.icm.input = options.fastexport_icm_input ; params.icm.working = options.fastexport_icm_working ; params.icm.output = options.fastexport_icm_output ; + params.icm.outputIntent = options.fastexport_icm_outputIntent ; params.icm.gamma = options.fastexport_icm_gamma ; params.resize.enabled = options.fastexport_resize_enabled ; params.resize.scale = options.fastexport_resize_scale ; diff --git a/rtgui/history.cc b/rtgui/history.cc index 57f7549db..689ea6394 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -24,7 +24,6 @@ using namespace rtengine; using namespace rtengine::procparams; Glib::ustring eventDescrArray[NUMOFEVENTS]; -extern Glib::ustring argv0; History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1) { @@ -204,8 +203,8 @@ void History::bookmarkSelectionChanged () void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { - // to prevent recursion, we filter out the events triggered by the history - if (ev == EvHistoryBrowsed) { + // to prevent recursion, we filter out the events triggered by the history and events that should not be registered + if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) { return; } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 51ee408a2..55e8e1a6e 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -193,6 +193,18 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); + // Rendering intent + + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT"))); + oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + ointent = Gtk::manage (new MyComboBoxText ()); + oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); + ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + ointent->set_active(0); + // Output gamma Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ()); @@ -282,6 +294,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -507,6 +520,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) if (onames->get_active_row_number() == -1) { onames->set_active_text (M("TP_ICM_NOICM")); } + ointent->set_active(pp->icm.outputIntent); ckbToneCurve->set_active (pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; @@ -545,6 +559,10 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) onames->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->icm.outputIntent) { + ointent->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->icm.dcpIlluminant) { dcpIll->set_active_text(M("GENERAL_UNCHANGED")); } @@ -605,6 +623,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.output = onames->get_active_text(); } + int ointentVal = ointent->get_active_row_number(); + if (ointentVal >= 0 && ointentVal < RI__COUNT) { + pp->icm.outputIntent = static_cast(ointentVal); + } else { + pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; + } + pp->icm.freegamma = freegamma->get_active(); DCPProfile* dcp = NULL; @@ -641,6 +666,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pedited->icm.input = !iunchanged->get_active (); pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent (); @@ -876,7 +902,7 @@ void ICMPanel::opChanged () { if (listener) { - listener->panelChanged (EvOProfile, onames->get_active_text()); + listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text()); } } @@ -979,6 +1005,7 @@ void ICMPanel::setBatchMode (bool batchMode) iVBox->reorder_child (*iunchanged, 5); removeIfThere (this, saveRef); onames->append_text (M("GENERAL_UNCHANGED")); + ointent->append_text (M("GENERAL_UNCHANGED")); wnames->append_text (M("GENERAL_UNCHANGED")); wgamma->append_text (M("GENERAL_UNCHANGED")); dcpIll->append_text (M("GENERAL_UNCHANGED")); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 93828f5fd..e10f42b20 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -78,6 +78,7 @@ private: MyComboBoxText* wgamma; MyComboBoxText* onames; + MyComboBoxText* ointent; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; diff --git a/rtgui/options.cc b/rtgui/options.cc index ce85acc09..1ffc74e2b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; + fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -636,7 +637,7 @@ void Options::setDefaults () rtSettings.leveldnautsimpl = 0; rtSettings.monitorProfile = Glib::ustring(); - rtSettings.monitorIntent = 1; + rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -1712,6 +1713,10 @@ int Options::readFromFile (Glib::ustring fname) fastexport_icm_output = keyFile.get_string ("Fast Export", "fastexport_icm_output" ); } + if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) { + fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); + } + if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) { fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" ); } @@ -2075,6 +2080,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); diff --git a/rtgui/options.h b/rtgui/options.h index 614042fa2..969b66642 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,6 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; + rtengine::eRenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ac2fe6523..28d4c13b8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -816,6 +816,7 @@ void ParamsEdited::initFrom (const std::vector icm.dcpIlluminant = icm.dcpIlluminant && p.icm.dcpIlluminant == other.icm.dcpIlluminant; icm.working = icm.working && p.icm.working == other.icm.working; icm.output = icm.output && p.icm.output == other.icm.output; + icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent; icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma; icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma; icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; @@ -2119,6 +2120,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.icm.output = mods.icm.output; } + if (icm.outputIntent) { + toEdit.icm.outputIntent = mods.icm.outputIntent; + } + //if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos; //if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos; if (icm.gampos) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3fa753013..1993c7aaa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -530,6 +530,7 @@ public: bool dcpIlluminant; bool working; bool output; + bool outputIntent; bool gamma; bool gampos; bool slpos; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4aa1d2427..56fb63c3e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1434,7 +1434,7 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); - moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif diff --git a/tools/source_icons/scalable/intent-absolute.file b/tools/source_icons/scalable/intent-absolute.file new file mode 100644 index 000000000..57278bff2 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.file @@ -0,0 +1 @@ +intent-absolute.png,w25,actions diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg new file mode 100644 index 000000000..497ce9c66 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -0,0 +1,1378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.file b/tools/source_icons/scalable/intent-perceptual.file new file mode 100644 index 000000000..3e7520042 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.file @@ -0,0 +1 @@ +intent-perceptual.png,w25,actions diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg new file mode 100644 index 000000000..ab34b86b7 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-relative.file b/tools/source_icons/scalable/intent-relative.file new file mode 100644 index 000000000..5191a25c3 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.file @@ -0,0 +1 @@ +intent-relative.png,w25,actions diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg new file mode 100644 index 000000000..31a2fb342 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.svg @@ -0,0 +1,1374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-saturation.file b/tools/source_icons/scalable/intent-saturation.file new file mode 100644 index 000000000..9f33b978e --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.file @@ -0,0 +1 @@ +intent-saturation.png,w25,actions diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg new file mode 100644 index 000000000..638df39f2 --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/softProof.file b/tools/source_icons/scalable/softProof.file new file mode 100644 index 000000000..e275113ec --- /dev/null +++ b/tools/source_icons/scalable/softProof.file @@ -0,0 +1 @@ +softProof.png,w22,actions diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg new file mode 100644 index 000000000..7d142fc4c --- /dev/null +++ b/tools/source_icons/scalable/softProof.svg @@ -0,0 +1,1389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + +