Merge from DEFAULT f1e80d00c3099a65283f143268318e504ce6ea85

see comments in issue 1052, comment 439
This commit is contained in:
michael 2012-07-25 21:24:57 -04:00
commit 00097e8dd2
89 changed files with 6454 additions and 4740 deletions

View File

@ -72,6 +72,7 @@ DEPENDENCIES
BZIP2 bzip2>-1.0.4 http://www.bzip.org/
EXIV2 exiv2>=0.19 http://www.exiv2.org/
EXPAT expat>=2.1.0 http://expat.sourceforge.net/
FFTW fftw>=3.2.2 http://fftw.org/
GLIB2 glib-2.0>=2.16 http://www.gtk.org/
GLIBMM glibmm-2.4>=2.16 http://www.gtkmm.org
GTK+ gtk+-2.0>=2.12 http://www.gtk.org/
@ -282,6 +283,9 @@ WINDOWS
- Download: http://expat.sourceforge.net/
- Install
FFTW:
- Instructions: http://www.fftw.org/install/windows.html
IMPORTANT:
Make sure that the lcms.pc and libiptcdata.pc files located in the
@ -359,19 +363,27 @@ LINUX
See the list of dependencies at the beginning of this document.
In Ubuntu/Debian the requirements can be installed by running:
sudo apt-get install build-essential cmake libbz2-dev libexiv2-dev \
libexpat1-dev libglib2.0-dev libglibmm-2.4-dev libgtk2.0-dev \
libgtkmm-2.4-dev libiptcdata-dev libjpeg8-dev liblcms2-dev libpng-dev \
libsigc++-2.0-dev libtiff-dev mercurial zlib1g-dev
sudo apt-get install build-essential cmake libfftw3-dev libbz2-dev \
libexiv2-dev libexpat1-dev libglib2.0-dev libglibmm-2.4-dev \
libgtk2.0-dev libgtkmm-2.4-dev libiptcdata-dev libjpeg8-dev \
liblcms2-dev libpng-dev libsigc++-2.0-dev libtiff-dev mercurial \
zlib1g-dev
In Fedora, run:
sudo yum install gcc-c++ cmake bzip2-devel exiv2-devel expat-devel \
fftw-devel glib2-devel glibmm24-devel gtk+-devel gtkmm24-devel \
libjpeg-turbo-devel lcms2-devel libiptcdata-devel libpng-devel \
libsigc++20-devel libtiff-devel zlib-devel
In Gentoo, run:
sudo emerge -uva app-arch/bzip2 media-gfx/exiv2 dev-libs/expat \
dev-libs/glib dev-cpp/glibmm x11-libs/gtk+ dev-cpp/gtkmm \
media-libs/libjpeg-turbo media-libs/lcms media-libs/libiptcdata \
media-libs/libpng dev-libs/libsigc++ media-libs/tiff sys-libs/zlib
media-libs/libpng dev-libs/libsigc++ media-libs/tiff sci-libs/fftw \
sys-libs/zlib
In Arch, run:
sudo pacman -S bzip2 exiv2 expat glib2 glibmm gtk gtkmm lcms2 \
sudo pacman -S bzip2 exiv2 expat fftw glib2 glibmm gtk gtkmm lcms2 \
libiptcdata libjpeg-turbo libpng libsigc++ libtiff zlib
COMPILE:
@ -456,7 +468,8 @@ OS X
- Edit the beginning of CMakeLists.txt to enable the same architectures
as you added to variants.conf
- To install all the tools and dependencies, run:
sudo port install cairomm pango-devel gtk2 cmake glibmm gtkmm lcms libiptcdata
sudo port install cairomm cmake fftw-3 glibmm gtk2 gtkmm lcms \
libiptcdata pango-devel
- If you don't already have Mercurial installed, run:
sudo port install mercurial
- If you want to try OpenMP builds, run:

Binary file not shown.

Binary file not shown.

View File

@ -13,5 +13,5 @@ Comment[pl]=Zaawansowany program do wywoływania zdjęć
Icon=rawtherapee
Exec=rawtherapee %f
Terminal=false
MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-tif;inode/directory;
MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-tif;
Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK;

View File

@ -796,11 +796,11 @@ SAVEDLG_PUTTOQUEUETAIL;An das Ende der Warteschlange für Verarbeitung legen
SAVEDLG_PUTTOQUEUE;In Warteschlange für Verarbeitung legen
SAVEDLG_SAVEIMMEDIATELY;Sofort speichern
SAVEDLG_SAVESPP;Prozessparameter mit dem Bild speichern
SAVEDLG_SUBSAMP;Subsampling
SAVEDLG_SUBSAMP_1;Beste Kompression
SAVEDLG_SUBSAMP_2;Ausbalanciert
SAVEDLG_SUBSAMP;Subsampling
SAVEDLG_SUBSAMP_1;Beste Kompression
SAVEDLG_SUBSAMP_2;Ausbalanciert
SAVEDLG_SUBSAMP_3;Beste Qualität
SAVEDLG_SUBSAMP_TOOLTIP;Kompression: 4:1:1\nAusbalanciert: 4:2:2\nQualität: 4:4:4
SAVEDLG_SUBSAMP_TOOLTIP;Beste Kompression: 4:1:1\nAusbalanciert: 4:2:2\nBeste Qualität: 4:4:4
SAVEDLG_TIFFFILTER;TIFF-Datei
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
TOOLBAR_TOOLTIP_CROP;Ausschnitt wählen <b>C</b>\n\nZum Verschieben des Ausschnitts muss die Umschalttaste gedrückt gehalten werden

View File

@ -202,6 +202,7 @@ GENERAL_PORTRAIT;Portrait
GENERAL_SAVE;Enregistrer
GENERAL_UNCHANGED;(Inchangé)
GENERAL_YES;Oui
GENERAL_WARNING;Attention
HISTOGRAM_BUTTON_BAR;RVB
HISTOGRAM_BUTTON_B;B
HISTOGRAM_BUTTON_G;V
@ -256,7 +257,7 @@ HISTORY_MSG_33;Déconvolution - Itérations
HISTORY_MSG_34;Éviter l'écrêtage couleur
HISTORY_MSG_35;Limiteur de saturation
HISTORY_MSG_36;Limite de saturation
HISTORY_MSG_37;Rehaussement couleur
HISTORY_MSG_37;Exposition auto
HISTORY_MSG_38;Méthode de balance des blancs
HISTORY_MSG_39;Température de couleur
HISTORY_MSG_40;Teinte de balance des blancs
@ -314,7 +315,7 @@ HISTORY_MSG_91;Réd. de bruit Chrominance
HISTORY_MSG_92;Réd. de bruit Gamma
HISTORY_MSG_93;Param. de contraste
HISTORY_MSG_94;Contraste par niveau de détail
HISTORY_MSG_95;Saturation
HISTORY_MSG_95;Chromaticité
HISTORY_MSG_96;Courbe 'a'
HISTORY_MSG_97;Courbe 'b'
HISTORY_MSG_98;Algorithme de dématriçage
@ -330,9 +331,9 @@ HISTORY_MSG_107;A.C. - Seuil
HISTORY_MSG_108;Seuil de compr. des hautes lumières
HISTORY_MSG_109;Redim. - boîte englobante
HISTORY_MSG_110;Redim. s'applique à
HISTORY_MSG_111;Éviter l'écrêtage couleur
HISTORY_MSG_112;Limiteur de saturation
HISTORY_MSG_113;Limite de saturation
HISTORY_MSG_111;Éviter les dérives de teinte
HISTORY_MSG_112;--inutilisé--
HISTORY_MSG_113;Protection des tons rouges et chair
HISTORY_MSG_114;Nbr d'itération DCB
HISTORY_MSG_115;Nbr d'itération des fausses couleurs
HISTORY_MSG_116;DCB amélioré
@ -386,6 +387,10 @@ HISTORY_MSG_163;Courbes RVB - R
HISTORY_MSG_164;Courbes RVB - V
HISTORY_MSG_165;Courbes RVB - B
HISTORY_MSG_166;Niveaux neutre
HISTORY_MSG_167;Mode N&amp;B colorisable
HISTORY_MSG_168;Courbe 'Cc'
HISTORY_MSG_169;Courbe 'Ct'
HISTORY_MSG_170;Vibrance - courbe
HISTORY_NEWSNAPSHOTAS;Sous...
HISTORY_NEWSNAPSHOT;Ajouter
HISTORY_NEWSSDIALOGLABEL;Label de la capture:
@ -801,8 +806,15 @@ SAVEDLG_PUTTOQUEUETAIL;Placer au fin de la file de traitement
SAVEDLG_PUTTOQUEUE;Placer dans la file de traitement
SAVEDLG_SAVEIMMEDIATELY;Enregistrer immédiatement
SAVEDLG_SAVESPP;Enregistrer les paramètres de développement avec l'image
SAVEDLG_SUBSAMP;Sous-échantillonnage
SAVEDLG_SUBSAMP_1;Meilleure compression
SAVEDLG_SUBSAMP_2;Équilibré
SAVEDLG_SUBSAMP_3;Meilleure qualité
SAVEDLG_SUBSAMP_TOOLTIP;Compression: 4:1:1\nÉquilibré: 4:2:2\nQualité: 4:4:4
SAVEDLG_TIFFFILTER;Fichiers TIFF
SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé
SAVEDLG_WARNFILENAME;Le fichier sera nommé
SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitiliser la position de ces 3 curseurs
THRESHOLDSELECTOR_B;Bas
THRESHOLDSELECTOR_BL;Bas-gauche
THRESHOLDSELECTOR_BR;Bas-droite
@ -958,14 +970,32 @@ TP_ICM_SAVEREFERENCE;Utiliser l'image comme profil de référence
TP_ICM_WORKINGPROFILE;Profil de Travail
TP_IMPULSEDENOISE_LABEL;Réduction du bruit d'impulsion
TP_IMPULSEDENOISE_THRESH;Seuil
TP_LABCURVE_AVOIDCOLORCLIP;Éviter l'écrêtage couleur
TP_LABCURVE_AVOIDCOLORSHIFT;Éviter les dérives de teinte
TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Ramènes les données dans le gamut de l'espace couleur de travail\npuis applique la correction de Munsell
TP_LABCURVE_BRIGHTNESS;Luminosité
TP_LABCURVE_BWTONING;Mode N&B colorisable
TP_LABCURVE_BWTONING_TIP;Avec le mode <b>N&amp;B colorisable</b> activé, la Chromaticité, la courbe Cc et Ct sont sans effet.\nLa colorisation peut être effctué en utilisant les courbes <b>a</b> et <b>b</b>.
TP_LABCURVE_CONTRAST;Contraste
TP_LABCURVE_CURVEEDITOR;Courbe de luminance
TP_LABCURVE_ENABLESATLIMITER;Activer le limiteur de saturation
TP_LABCURVE_CURVEEDITOR_A_RANGE1;Vert saturé
TP_LABCURVE_CURVEEDITOR_A_RANGE2;Vert pastel
TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rouge pastel
TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rouge saturé
TP_LABCURVE_CURVEEDITOR_B_RANGE1;Bleu saturé
TP_LABCURVE_CURVEEDITOR_B_RANGE2;Bleu pastel
TP_LABCURVE_CURVEEDITOR_B_RANGE3;Jaune pastel
TP_LABCURVE_CURVEEDITOR_B_RANGE4;Jaune saturé
TP_LABCURVE_CURVEEDITOR_CC;CC
TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutre
TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Terne
TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel
TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturé
TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticité en fonction de la Chromaticité
TP_LABCURVE_CURVEEDITOR_CH;CT
TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticité en fonction de la Teinte
TP_LABCURVE_LABEL;Courbes Lab
TP_LABCURVE_SATLIMIT;Limite de saturation
TP_LABCURVE_SATURATION;Saturation
TP_LABCURVE_RSTPROTECTION;Protection des tons rouges et chair
TP_LABCURVE_CHROMATICITY;Chromaticité
TP_LENSGEOM_AUTOCROP;Recadrage auto
TP_LENSGEOM_FILL;Remplir
TP_LENSGEOM_LABEL;Objectif / Géométrie
@ -1060,6 +1090,13 @@ TP_SHARPENMICRO_LABEL;Microcontraste
TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformité
TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte
TP_VIBRANCE_CURVEEDITOR_SKINTONES;TT
TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tons chair
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rouge/Pourpre
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rouge
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rouge/Jaune
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Jaune
TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Teinte en fonction de la teinte
TP_VIBRANCE_LABEL;Vibrance
TP_VIBRANCE_PASTELS;Tons pastels
TP_VIBRANCE_PASTSATTOG;Lier Pastels et Saturés

View File

@ -78,6 +78,8 @@ EXPORT_MAXWIDTH;最大幅:
EXPORT_PUTTOQUEUEFAST; 高速書き出しのキューに追加
EXPORT_RAW_DMETHOD;デモザイクの方式
EXPORT_RESIZEMETHOD;リサイズの方式
EXTPROGTARGET_1;RAW
EXTPROGTARGET_2;キュー処理
FILEBROWSER_ADDDELTEMPLATE;テンプレートの追加/削除...
FILEBROWSER_APPLYPROFILE;プロファイルの適用
FILEBROWSER_APPLYPROFILE_PARTIAL;プロファイルの適用 (部分)
@ -94,8 +96,8 @@ FILEBROWSER_COPYPROFILE;プロファイルをコピー
FILEBROWSER_CURRENT_NAME;カーブ名:
FILEBROWSER_DARKFRAME;ダークフレーム
FILEBROWSER_DELETEDLGLABEL;ファイル削除確認
FILEBROWSER_DELETEDLGMSGINCLPROC;バッチ処理に含まれる選択済みの1個のファイル %1 を削除してもいいですか?
FILEBROWSER_DELETEDLGMSG;%1 を削除してもいいですか?
FILEBROWSER_DELETEDLGMSGINCLPROC;バッチ処理に<b>組み込まれている</b>選択済みのファイル <b>%1</b> を削除してもいいですか?
FILEBROWSER_DELETEDLGMSG;選択済みのファイル <b>%1</b> を削除してもいいですか?
FILEBROWSER_EMPTYTRASHHINT;ゴミ箱を完全に空にする
FILEBROWSER_EMPTYTRASH;ゴミ箱を空にする
FILEBROWSER_EXEC_CPB;カスタム・プロファイルビルダーを実行
@ -104,10 +106,12 @@ FILEBROWSER_EXIFFILTERAPPLY;適用
FILEBROWSER_EXIFFILTERLABEL;Exifフィルタ
FILEBROWSER_EXIFFILTERSETTINGSHINT;Exifフィルタの設定を変える
FILEBROWSER_EXIFFILTERSETTINGS;セットアップ
FILEBROWSER_EXTPROGMENU;..で開く
FILEBROWSER_FLATFIELD;フラットフィールド
FILEBROWSER_MOVETODARKFDIR;ダークフレーム・ディレクトリに移動
FILEBROWSER_MOVETOFLATFIELDDIR;フラットフィールド・ディレクトリに移動
FILEBROWSER_NEW_NAME;新規名称:
FILEBROWSER_OPENDEFAULTVIEWER;Windowsのデフォルト・ビューアキュー処理
FILEBROWSER_PARTIALPASTEPROFILE;部分的に貼り付け
FILEBROWSER_PASTEPROFILE;プロファイルの貼り付け
FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル
@ -198,6 +202,7 @@ GENERAL_OK;OK
GENERAL_PORTRAIT;縦
GENERAL_SAVE;保存
GENERAL_UNCHANGED;(変更なし)
GENERAL_WARNING;警告
GENERAL_YES;Yes
HISTOGRAM_BUTTON_BAR;RGB
HISTOGRAM_BUTTON_B;B
@ -383,6 +388,7 @@ HISTORY_MSG_163;RGB カーブ - R
HISTORY_MSG_164;RGB カーブ - G
HISTORY_MSG_165;RGB カーブ - B
HISTORY_MSG_166;ニュートラル・レベル
HISTORY_MSG_167;白黒トーン
HISTORY_NEWSNAPSHOTAS;ラベル
HISTORY_NEWSNAPSHOT;追加
HISTORY_NEWSSDIALOGLABEL;スナップのラベル:
@ -477,6 +483,7 @@ MAIN_MSG_EMPTYFILENAME;未定義のファイル名
MAIN_MSG_ERRORDURINGIMAGESAVING;画像の保存中にエラー
MAIN_MSG_EXITJOBSINQUEUEINFO;未処理画像の順番は終了時に失われます
MAIN_MSG_EXITJOBSINQUEUEQUEST;キュー待ちの画像がありますが、終了しますか?
MAIN_MSG_IMAGEUNPROCESSED;このコマンドは、先に選択されたすべての画像をキュー処理する必要があります。
MAIN_MSG_JOBSINQUEUE; キューの作業中・・・
MAIN_MSG_NAVIGATOR;ナビゲータ
MAIN_MSG_PLACES;場所
@ -502,6 +509,9 @@ MAIN_TAB_TAGGING;タグ付け
MAIN_TAB_TRANSFORM;変形
MAIN_TAB_TRANSFORM_TOOLTIP;ショートカット: <b>Alt-t</b>
MAIN_TOGGLE_BEFORE_AFTER;補正 前|後
MAIN_TOOLTIP_BACKCOLOR0;プレビューの背景色を指定します: <b>テーマに基づく</b>\nショートカット: <b>8</b>
MAIN_TOOLTIP_BACKCOLOR1;プレビューの背景色を指定します: <b>黒</b>\nショートカットt: <b>9</b>
MAIN_TOOLTIP_BACKCOLOR2;プレビューの背景色を指定します: <b>白</b>\nショートカット: <b>0</b>
MAIN_TOOLTIP_BEFOREAFTERLOCK;<b>固定</b> / <b>固定解除</b> - <b>補正前</b> の表示設定\n\n<b>固定</b>: <b>補正前</b>をそのまま表示し変更されません。\n複数のツールの累積効果を評価するのに役立ちます。\nさらに、比較は履歴上のどこからでも行うことができます。\n\n<b>固定解除</b>: 現在使用のツールの効果が <b>補正後</b> に表示され、その1段階前が <b>補正前</b> に表示されます。
MAIN_TOOLTIP_HIDEFP;ボタンパネル 表示/非表示(ディレクトリとファイルブラウザ)\nショートカット: <b>F</b>
MAIN_TOOLTIP_HIDEHP;左パネル 表示/非表示 (履歴含む)\nショートカット: <b>l</b>
@ -539,7 +549,10 @@ NAVIGATOR_S_NA;S = n/a
NAVIGATOR_S_VALUE;S = %1
NAVIGATOR_V_NA;V = n/a
NAVIGATOR_V_VALUE;V = %1
NAVIGATOR_XY_FULL;幅 = %1, 高さ = %2
NAVIGATOR_XY_NA;x = n/a, y = n/a
OPTIONS_DEFIMG_MISSING;<b>RAWではない画像</b>のデフォルプロファイルが見つからないか、設定されていません。\n\nプロファイル・ディレクトリを確認してください、存在しないか破損しているかもしれません。\n\nデフォルト設定値が使用されます。
OPTIONS_DEFRAW_MISSING;<b>RAW画像</b>のデフォル・プロファイルが見つからないか、設定されていません。\n\nプロファイル・ディレクトリを確認してください、存在しないか破損しているかもしれません。\n\nデフォルト設定値が使用されます。
PARTIALPASTE_BASICGROUP;基本設定
PARTIALPASTE_CACORRECTION;色収差補正
PARTIALPASTE_CHANNELMIXER;チャンネル・ミキサー
@ -692,6 +705,7 @@ PREFERENCES_INTERNALTHUMBIFUNTOUCHED;未編集の場合 内部のRAWサムネイ
PREFERENCES_LANGAUTODETECT;OSの言語設定を使用
PREFERENCES_LINEDENOISE;ラインノイズ フィルタ
PREFERENCES_LIVETHUMBNAILS;ライブ・サムネイル (遅い)
PREFERENCES_MENUGROUPEXTPROGS;グループ "..で開く"
PREFERENCES_MENUGROUPFILEOPERATIONS;ファイル・グループの操作
PREFERENCES_MENUGROUPLABEL;グループ・ラベル
PREFERENCES_MENUGROUPPROFILEOPERATIONS;プロファイル・グループの操作
@ -814,6 +828,14 @@ SAVEDLG_SAVEIMMEDIATELY;すぐに保存
SAVEDLG_SAVESPP;設定値も保存する
SAVEDLG_TIFFFILTER;TIFF ファイル
SAVEDLG_TIFFUNCOMPRESSED;非圧縮 TIFF
SAVEDLG_WARNFILENAME;ファイルに名前が付けられます
THRESHOLDSELECTOR_BL;下-左
THRESHOLDSELECTOR_BR;下-右
THRESHOLDSELECTOR_B;下
THRESHOLDSELECTOR_HINT;個々のコントロールポイントを移動するには、<b>Shiftキー</b>を押し続けます。
THRESHOLDSELECTOR_TL;上-左
THRESHOLDSELECTOR_TR;上-右
THRESHOLDSELECTOR_T;上
TOOLBAR_TOOLTIP_CROP;切り抜き範囲選択\nショートカット: <b>c</b>
TOOLBAR_TOOLTIP_HAND;手の平ツール\nショートカット: <b>h</b>
TOOLBAR_TOOLTIP_STRAIGHTEN;<b>直線選択</b> / <b>角度補正</b>\nショートカット: <b>s</b>\nプレビュー画像上にガイド線を描画し、垂直または水平方向を指示します。回転角度は、ガイド線の隣に表示されます。回転の中心は、プレビュー画像の中心です。
@ -850,6 +872,7 @@ TP_COLORSHIFT_LABEL;カラー シフト
TP_CROP_FIXRATIO;縦横比 固定:
TP_CROP_GTDIAGONALS;対角線
TP_CROP_GTEPASSPORT;バイオメトリック・パスポート
TP_CROP_GTFRAME;フレーム
TP_CROP_GTGRID;グリッド
TP_CROP_GTHARMMEANS1;調和平均 1
TP_CROP_GTHARMMEANS2;調和平均 2
@ -957,12 +980,19 @@ TP_ICM_LABEL;カラー・マネジメント
TP_ICM_NOICM;No ICM: sRGB 出力
TP_ICM_OUTPUTDLGLABEL;出力 ICC プロファイルを選択...
TP_ICM_OUTPUTPROFILE;出力プロファイル
TP_ICM_PREFERREDPROFILE;DCPプロファイル優先
TP_ICM_PREFERREDPROFILE_1;昼光
TP_ICM_PREFERREDPROFILE_2;タングステン
TP_ICM_PREFERREDPROFILE_3;蛍光灯
TP_ICM_PREFERREDPROFILE_4;フラッシュ
TP_ICM_SAVEREFERENCE;プロファイリングの参照する画像を保存
TP_ICM_WORKINGPROFILE;作業プロファイル
TP_IMPULSEDENOISE_LABEL;インパルス ノイズ低減
TP_IMPULSEDENOISE_THRESH;インパルス NR しきい値
TP_LABCURVE_AVOIDCOLORCLIP;カラークリッピング回避
TP_LABCURVE_BRIGHTNESS;明るさ
TP_LABCURVE_BWTONING;白黒トーン
TP_LABCURVE_BWTONING_TIP;<b>白黒トーン</b> オプションを有効にすると、Lab調整の彩度は無効になります。\n色調は <b>a</b> と <b>b</b> カーブで調整することができます。
TP_LABCURVE_CONTRAST;コントラスト
TP_LABCURVE_CURVEEDITOR;Lab 明度カーブ
TP_LABCURVE_ENABLESATLIMITER;彩度制限・有効
@ -972,6 +1002,11 @@ TP_LABCURVE_SATURATION;彩度
TP_LENSGEOM_AUTOCROP;自動的に切り抜き選択
TP_LENSGEOM_FILL;オートフィル
TP_LENSGEOM_LABEL;レンズ / ジオメトリ
TP_LENSPROFILE_FILEDLGFILTERLCP;レンズ補正 ファイル
TP_LENSPROFILE_LABEL;レンズ補正 プロファイル
TP_LENSPROFILE_USECA;色収差補正を使用
TP_LENSPROFILE_USEDIST;歪曲収差補正を使用
TP_LENSPROFILE_USEVIGN;周辺光量補正を使用
TP_LUMADENOISE_EDGETOLERANCE;エッジの許容度
TP_LUMADENOISE_LABEL;輝度 ノイズ低減
TP_LUMADENOISE_RADIUS;半径
@ -1074,6 +1109,9 @@ TP_VIBRANCE_PASTELS;パステルトーン
TP_VIBRANCE_PASTSATTOG;パステルと純色トーンをリンク
TP_VIBRANCE_PROTECTSKINS;肌トーンを保護
TP_VIBRANCE_PSTHRESHOLD;パステル/純色トーン しきい値
TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;純色トーン しきい値
TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;縦軸は下がパステルトーン,上が純色を表し。\n\n横軸は彩度の範囲を表しています。
TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;パステル/純色トーン 移行の荷重
TP_VIBRANCE_SATURATED;純色トーン
TP_VIGNETTING_AMOUNT;適用量
TP_VIGNETTING_CENTER;中心
@ -1144,26 +1182,4 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: <b>-</b>
#04 update: 2011-12-03 (for 4.0.6)
#05 update: 2012-02-11 (for 4.0.7)
#06 update: 2012-04-04 (for 4.0.8)
!!!!!!!!!!!!!!!!!!!!!!!!!
! Untranslated keys follow; remove the ! prefix after an entry is translated.
!!!!!!!!!!!!!!!!!!!!!!!!!
!EXTPROGTARGET_1;raw
!EXTPROGTARGET_2;queue-processed
!FILEBROWSER_EXTPROGMENU;Open with
!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed)
!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue processed first.
!OPTIONS_DEFIMG_MISSING;The default profile for <b>non-raw photos</b> could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used.
!OPTIONS_DEFRAW_MISSING;The default profile for <b>raw photos</b> could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used.
!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with"
!TP_ICM_PREFERREDPROFILE;Preferred DCP profile
!TP_ICM_PREFERREDPROFILE_1;Daylight
!TP_ICM_PREFERREDPROFILE_2;Tungsten
!TP_ICM_PREFERREDPROFILE_3;Fluorescent
!TP_ICM_PREFERREDPROFILE_4;Flash
!TP_LENSPROFILE_FILEDLGFILTERLCP;Lens correction files
!TP_LENSPROFILE_LABEL;Lens Correction Profile
!TP_LENSPROFILE_USECA;Use CA correction
!TP_LENSPROFILE_USEDIST;Use distortion correction
!TP_LENSPROFILE_USEVIGN;Use vignette correction
#07 update: 2012-07-12 (for 4.0.9)

File diff suppressed because it is too large Load Diff

View File

@ -258,7 +258,7 @@ HISTORY_MSG_33;Deconvolution Iterations
HISTORY_MSG_34;LCP use disortion
HISTORY_MSG_35;LCP use vignette
HISTORY_MSG_36;LCP use CA
HISTORY_MSG_37;Color Boost
HISTORY_MSG_37;Auto Exposure
HISTORY_MSG_38;White Balance Method
HISTORY_MSG_39;Color Temperature
HISTORY_MSG_40;White Balance Tint
@ -316,7 +316,7 @@ HISTORY_MSG_91;NR - Chrominance
HISTORY_MSG_92;NR - Gamma
HISTORY_MSG_93;Contrast by Detail Levels Value
HISTORY_MSG_94;Contrast by Detail Levels
HISTORY_MSG_95;Saturation
HISTORY_MSG_95;Chromaticity
HISTORY_MSG_96;'a' Curve
HISTORY_MSG_97;'b' Curve
HISTORY_MSG_98;Demosaicing Method
@ -332,9 +332,9 @@ HISTORY_MSG_107;Defringing Threshold
HISTORY_MSG_108;Highlight Compr. Threshold
HISTORY_MSG_109;Resize Bounding Box
HISTORY_MSG_110;Resizing applies o
HISTORY_MSG_111;Avoid Color Clipping
HISTORY_MSG_112;Saturation Limiter
HISTORY_MSG_113;Saturation Limit
HISTORY_MSG_111;Avoid Color Shift
HISTORY_MSG_112;--unused--
HISTORY_MSG_113;Red and Skin Tones Protection
HISTORY_MSG_114;DCB Iterations
HISTORY_MSG_115;False Color Iterations
HISTORY_MSG_116;Enhanced DCB
@ -388,8 +388,11 @@ HISTORY_MSG_163;RGB Curves - R
HISTORY_MSG_164;RGB Curves - G
HISTORY_MSG_165;RGB Curves - B
HISTORY_MSG_166;Neutral Levels
HISTORY_MSG_167;BW Toning
HISTORY_MSG_168;NR - Luminance Detail
HISTORY_MSG_167;B&amp;W Toning
HISTORY_MSG_168;'Cc' curve
HISTORY_MSG_169;'Ch' curve
HISTORY_MSG_170;Vibrance - Curve
HISTORY_MSG_171;NR - Luminance Detail
HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSSDIALOGLABEL;Label of the snapshot:
@ -813,6 +816,7 @@ SAVEDLG_SUBSAMP_TOOLTIP;Compression: 4:1:1\nBalanced: 4:2:2\nQuality: 4:4:4
SAVEDLG_TIFFFILTER;TIFF files
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
SAVEDLG_WARNFILENAME;File will be named
SHCSELECTOR_TOOLTIP;Click right mouse button to reset\nthe position of those 3 sliders
THRESHOLDSELECTOR_B;Bottom
THRESHOLDSELECTOR_BL;Bottom-left
THRESHOLDSELECTOR_BR;Bottom-right
@ -974,16 +978,32 @@ TP_ICM_SAVEREFERENCE;Save reference image for profiling
TP_ICM_WORKINGPROFILE;Working Profile
TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction
TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold
TP_LABCURVE_AVOIDCOLORCLIP;Avoid color clipping
TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift
TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction
TP_LABCURVE_BRIGHTNESS;Brightness
TP_LABCURVE_BWTONING;BW Toning
TP_LABCURVE_BWTONING_TIP;With <b>BT Toning</b> option enabled the Lab Saturation is not in effect.\nToning can be achieved using the <b>a</b> and <b>b</b> curves
TP_LABCURVE_BWTONING;B&W Toning
TP_LABCURVE_BWTONING_TIP;With <b>B&amp;W Toning</b> option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the <b>a</b> and <b>b</b> curves
TP_LABCURVE_CONTRAST;Contrast
TP_LABCURVE_CURVEEDITOR;Luminance Curve
TP_LABCURVE_ENABLESATLIMITER;Enable saturation limiter
TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green saturated
TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green pastel
TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red pastel
TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red saturated
TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue saturated
TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue pastel
TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow pastel
TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow saturated
TP_LABCURVE_CURVEEDITOR_CC;CC
TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral
TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull
TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel
TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated
TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to the Chromaticity
TP_LABCURVE_CURVEEDITOR_CH;CH
TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue
TP_LABCURVE_LABEL;Lab Adjustments
TP_LABCURVE_SATLIMIT;Saturation limit
TP_LABCURVE_SATURATION;Saturation
TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection
TP_LABCURVE_CHROMATICITY;Chromaticity
TP_LENSGEOM_AUTOCROP; Auto Crop
TP_LENSGEOM_FILL;Auto Fill
TP_LENSGEOM_LABEL;Lens / Geometry
@ -1081,6 +1101,13 @@ TP_SHARPENMICRO_LABEL;Microcontrast
TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformity
TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift
TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH
TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin tones
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow
TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow
TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to the Hue
TP_VIBRANCE_LABEL;Vibrance
TP_VIBRANCE_PASTELS;Pastel tones
TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones
@ -1152,5 +1179,4 @@ ZOOMPANEL_ZOOMFITSCREEN;Fit to screen <b>F</b>
ZOOMPANEL_ZOOMIN;Zoom In <b>+</b>
ZOOMPANEL_ZOOMOUT;Zoom Out <b>-</b>
#00 default translation file
#01 Developers should add translations to this file and then run 'generateTranslationDiffs' script to update other locales.
#02 WARNING: This script works on Linux only
#01 Developers should add translations to this file and then run the 'generateTranslationDiffs' script to update other locales. This is a Bash script, tested in >=Bash-4.2.

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=-100
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=true
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=-100
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=true
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=-25
Saturation=-100
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=true
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=2;0.25;0.5;0.75;50;12;-12;-50;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=-35
Saturation=-100
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=true
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=3;0;0;0.18623481781376497;0.028340080971659902;0.50607287449392713;0.50607287449392713;0.77732793522267185;0.97975708502024295;1;1;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=5
Saturation=-10
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=-10
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=0
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=0
Saturation=0
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=0
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=-10;-10;120;
[Luminance Curve]
Brightness=0
Contrast=10
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=false
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -1,7 +1,7 @@
[Version]
AppVersion=4.0.9
Version=302
Version=303
[General]
Rank=0
@ -29,13 +29,15 @@ Blue=0;0;100;
[Luminance Curve]
Brightness=0
Contrast=10
Saturation=5
AvoidColorClipping=false
SaturationLimiter=false
SaturationLimit=50
Chromaticity=5
BWtoning=false
AvoidColorShift=true
RedAndSkinTonesProtection=0
LCurve=0;
aCurve=0;
bCurve=0;
ccCurve=0;
chCurve=0;
[Sharpening]
Enabled=false
@ -57,10 +59,11 @@ DeconvIterations=30
Enabled=true
Pastels=50
Saturated=50
PSThreshold=1;75;
PSThreshold=0;75;
ProtectSkins=false
AvoidColorShift=true
PastSatTog=true
SkinTonesCurve=0;
[SharpenEdge]
Enabled=false

View File

@ -66,6 +66,9 @@
#define LUTu LUT<unsigned int>
#include <cstring>
#ifndef NDEBUG
#include <fstream>
#endif
template<typename T>
class LUT {
@ -165,6 +168,22 @@ public:
T p2 = data[idx + 1]-p1;
return (p1 + p2*diff);
}
#ifndef NDEBUG
// Debug facility ; dump the content of the LUT in a file. No control of the filename is done
void dump(Glib::ustring fname) {
if (size) {
Glib::ustring fname_ = fname + ".xyz"; // TopSolid'Design "plot" file format
std::ofstream f (fname_.c_str());
f << "$" << std::endl;;
for (unsigned int iter=0; iter<size; iter++) {
f << iter << ", " << data[iter] << ", 0." << std::endl;;
}
f << "$" << std::endl;;
f.close ();
}
}
#endif
operator bool (void)
{

File diff suppressed because it is too large Load Diff

View File

@ -22,26 +22,82 @@
#include <math.h>
#include "LUT.h"
#include "labimage.h"
#include "iccstore.h"
namespace rtengine {
#ifdef _DEBUG
class MunsellDebugInfo {
public:
float maxdhuelum[4];
float maxdhue[4];
unsigned int depass;
unsigned int depassLum;
MunsellDebugInfo();
void reinitValues();
};
#endif
class Color {
private:
// Jacques' 195 LUTf for Munsell Lch correction
static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60;
static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60;
static LUTf _5B40,_5B50,_5B60, _5B70,_5B80;
static LUTf _7B40,_7B50,_7B60, _7B70,_7B80;
static LUTf _9B40,_9B50,_9B60, _9B70,_9B80;
static LUTf _10B40,_10B50,_10B60, _10B70,_10B80;
static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80;
static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60;
static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80;
static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80;
static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80;
static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80;
static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80;
static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80;
static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90;
static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90;
static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80;
static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90;
static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80;
static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70;
static LUTf _10R30, _10R40,_10R50,_10R60,_10R70;
static LUTf _9R30, _9R40,_9R50,_9R60,_9R70;
static LUTf _7R30, _7R40,_7R50,_7R60,_7R70;
static LUTf _5R10, _5R20,_5R30;
static LUTf _25R10, _25R20,_25R30;
static LUTf _10RP10, _10RP20,_10RP30;
static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80;
static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80;
static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80;
static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80;
static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80;
static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80;
static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80;
// Separated from init() to keep the code clear
static void initMunsell ();
public:
const static double sRGBGamma; // standard average gamma
const static double sRGBGammaCurve; // 2.4 in the curve
const static double eps_max, kappa;
const static float D50x, D50z;
const static double u0, v0;
const static double sRGBGammaCurve; // 2.4 in the curve
const static double eps_max, kappa;
const static float D50x, D50z;
const static double u0, v0;
static LUTf cachef;
static LUTf cachef;
static LUTf gamma2curve;
// look-up tables for the standard srgb gamma and its inverse (filled by init())
static LUTf igammatab_srgb;
static LUTf gammatab_srgb;
// look-up tables for the simple exponential gamma
static LUTf gammatab;
// look-up tables for the standard srgb gamma and its inverse (filled by init())
static LUTf igammatab_srgb;
static LUTf gammatab_srgb;
// look-up tables for the simple exponential gamma
static LUTf gammatab;
static void init ();
@ -50,10 +106,10 @@ public:
static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v);
static void hsv2rgb (float h, float s, float v, float &r, float &g, float &b);
static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b);
static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b);
static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b);
static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b);
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]);
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]);
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]);
static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
static void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b);
static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v);
@ -87,6 +143,20 @@ public:
//static inline float gamma (double x) { return gammatab[x]; }
//static inline float igamma_srgb (double x) { return igammatab_srgb[x]; }
//Jacques's Munsell correction
#ifdef _DEBUG
static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo);
static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb);
#else
static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum);
static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef);
#endif
static void LabGamutMunsell (LabImage *lab, float *Lold, float *Cold, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const Glib::ustring &working, bool multiThread );
static void SkinSat (float lum, float hue, float chrom, float &satreduc, int chromx);//jacques Skin color
static void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL);//jacques: Munsell correction
// end Munsell
//void gamutmap(LabImage* );
static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]);

View File

@ -554,11 +554,13 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
xD=x; yD=y;
/*
if (settings->verbose) {
double u=4*xD/(-2*xD+12*yD+3);
double v=6*yD/(-2*xD+12*yD+3);
printf("xD=%f yD=%f u=%f v=%f\n",xD,yD,u,v);
}
*/
double X = xD/yD;
double Y = 1.0;

View File

@ -154,9 +154,9 @@ namespace rtengine {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::complexsgnCurve (double saturation, bool satlimit, double satlimthresh,
const std::vector<double>& acurvePoints, const std::vector<double>& bcurvePoints,
LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip) {
void CurveFactory::complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, double saturation, double rstprotection,
const std::vector<double>& acurvePoints, const std::vector<double>& bcurvePoints,const std::vector<double>& cccurvePoints,
/*const std::vector<double>& cbgcurvePoints,*/ LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve,/* LUTf & satbgCurve,*/ int skip) {
//colormult = chroma_scale for Lab manipulations
@ -164,7 +164,7 @@ namespace rtengine {
bool needed;
DiagonalCurve* dCurve = NULL;
/*
// check if contrast curve is needed
needed = (saturation<-0.0001 || saturation>0.0001);
@ -194,13 +194,15 @@ namespace rtengine {
satcurvePoints.push_back(0.5+0.5*scale); //shoulder point
satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point
/*} else {
satcurvePoints.push_back(0.25+saturation/500.0); //toe point
satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point
/ Commented out...
} else {
satcurvePoints.push_back(0.25+saturation/500.0); //toe point
satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point
satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point
satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point
}*/
satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point
satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point
}
/
satcurvePoints.push_back(1); // white point
satcurvePoints.push_back(1); // value at white point
@ -222,17 +224,21 @@ namespace rtengine {
else {
fillCurveArray(NULL, satCurve, skip, needed);
}
*/
//-----------------------------------------------------
needed = false;
// create a curve if needed
if (!acurvePoints.empty() && acurvePoints[0]!=0) {
dCurve = new DiagonalCurve (acurvePoints, CURVES_MIN_POLY_POINTS/skip);
if (dCurve && !dCurve->isIdentity())
if (dCurve && !dCurve->isIdentity()) {
needed = true;
autili=true;
}
}
fillCurveArray(dCurve, aoutCurve, skip, needed);
//if(autili) aoutCurve.dump("acurve");
if (dCurve) {
delete dCurve;
dCurve = NULL;
@ -243,14 +249,43 @@ namespace rtengine {
needed = false;
if (!bcurvePoints.empty() && bcurvePoints[0]!=0) {
dCurve = new DiagonalCurve (bcurvePoints, CURVES_MIN_POLY_POINTS/skip);
if (dCurve && !dCurve->isIdentity())
if (dCurve && !dCurve->isIdentity()) {
needed = true;
butili=true;
}
}
fillCurveArray(dCurve, boutCurve, skip, needed);
if (dCurve) {
delete dCurve;
dCurve = NULL;
}
//-----------------------------------------------
needed = false;
if (!cccurvePoints.empty() && cccurvePoints[0]!=0) {
dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS/skip);
if (dCurve && !dCurve->isIdentity())
{needed = true;ccutili=true;}
}
fillCurveArray(dCurve, satCurve, skip, needed);
if (dCurve) {
delete dCurve;
dCurve = NULL;
}
//----------------------------
/*needed = false;
if (!cbgcurvePoints.empty() && cbgcurvePoints[0]!=0) {
dCurve = new DiagonalCurve (cbgcurvePoints, CURVES_MIN_POLY_POINTS/skip);
if (dCurve && !dCurve->isIdentity())
{needed = true;cbgutili=true;}
}
fillCurveArray(dCurve, satbgCurve, skip, needed);
if (dCurve) {
delete dCurve;
dCurve = NULL;
}
*/
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -489,7 +524,7 @@ namespace rtengine {
void CurveFactory::complexLCurve (double br, double contr, const std::vector<double>& curvePoints,
LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve,
LUTu & outBeforeCCurveHistogram, int skip) {
LUTu & outBeforeCCurveHistogram, int skip, bool & utili) {
// curve without contrast
LUTf dcurve(65536,0);
@ -504,6 +539,7 @@ namespace rtengine {
// check if brightness curve is needed
if (br>0.00001 || br<-0.00001) {
utili=true;
std::vector<double> brightcurvePoints;
brightcurvePoints.push_back((double)((CurveType)DCT_NURBS));
@ -550,13 +586,13 @@ namespace rtengine {
dcurve[i] = (float)i / 32767.0;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// check if contrast curve is needed
if (contr>0.00001 || contr<-0.00001) {
utili=true;
// compute mean luminance of the image with the curve applied
int sum = 0;
@ -613,6 +649,8 @@ namespace rtengine {
}
if (tcurve) {
utili=true;//if active
// L values go up to 32767, last stop is for highlight overflow
for (int i=0; i<32768; i++) {
float val;
@ -694,5 +732,5 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}

View File

@ -161,7 +161,7 @@ class CurveFactory {
static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){
return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) );
}
static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
{
if (comp>0.0) {
@ -178,11 +178,12 @@ class CurveFactory {
static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr,
double gamma_, bool igamma_, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped,
LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1);
static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& acurvePoints,
const std::vector<double>& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1);
static void complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, double saturation, double rstprotection, const std::vector<double>& acurvePoints,
const std::vector<double>& bcurvePoints,const std::vector<double>& cccurvePoints,/*const std::vector<double>& cbgurvePoints,*/ LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, /*LUTf & satbgCurve,*/ int skip=1);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped,
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
static void RGBCurve (const std::vector<double>& curvePoints, LUTf & outCurve, int skip);
};
class Curve {

View File

@ -63,9 +63,6 @@ void Crop::update (int todo) {
ProcParams& params = parent->params;
parent->ipf.setScale (skip);
// give possibility to the listener to modify crop window (as the full image dimensions are already known at this point)
int wx, wy, ww, wh, ws;
bool overrideWindow = false;
@ -82,6 +79,9 @@ void Crop::update (int todo) {
if (needsinitupdate || (todo & M_HIGHQUAL))
todo = ALL;
// set improcfuncions' scale now that skip has been updated
parent->ipf.setScale (skip);
baseCrop = origCrop;
bool needstransform = parent->ipf.needsTransform();
@ -175,8 +175,13 @@ void Crop::update (int todo) {
parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay.
parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve);
parent->ipf.chrominanceCurve (labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve);
// parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve);
bool utili=false;
bool autili=false;
bool butili=false;
bool ccutili=false;
parent->ipf.chromiLuminanceCurve (labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve,/*parent->satbgcurve,*/ parent->lumacurve, utili, autili, butili, ccutili);
//parent->ipf.colorCurve (labnCrop, labnCrop);
parent->ipf.vibrance (labnCrop);

View File

@ -213,8 +213,8 @@ void DFManager::init( Glib::ustring pathname )
dfList.clear();
bpList.clear();
for (size_t i=0; i<names.size(); i++) {
size_t lastdot = names[i].find_last_of ('.');
for (size_t i=0; i<names.size(); i++) {
size_t lastdot = names[i].find_last_of ('.');
if (lastdot != Glib::ustring::npos && names[i].substr(lastdot) == ".badpixels" ){
int n = scanBadPixelsFile( names[i] );
if( n>0 && settings->verbose)
@ -256,7 +256,7 @@ dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ,bool pool )
return false;
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file);
if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) {
size_t lastdot = info->get_name().find_last_of ('.');
size_t lastdot = info->get_name().find_last_of ('.');
if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){
RawImage ri(filename);
int res = ri.loadRaw(false); // Read informations about shot
@ -397,9 +397,9 @@ int DFManager::scanBadPixelsFile( Glib::ustring filename )
{
FILE *file = fopen( filename.c_str(),"r" );
if( !file ) return false;
size_t lastdot = filename.find_last_of ('.');
size_t dirpos1 = filename.find_last_of ('/');
size_t dirpos2 = filename.find_last_of ('\\');
size_t lastdot = filename.find_last_of ('.');
size_t dirpos1 = filename.find_last_of ('/');
size_t dirpos2 = filename.find_last_of ('\\');
if( dirpos1 == Glib::ustring::npos && dirpos2== Glib::ustring::npos )
dirpos1 =0;
else if( dirpos1 != Glib::ustring::npos && dirpos2 != Glib::ustring::npos )

View File

@ -28,7 +28,7 @@ namespace rtengine {
extern const Settings* settings;
ImProcCoordinator::ImProcCoordinator ()
: workimg(NULL), awbComputed(false), ipf(&params, true), scale(10), highDetailComputed(false), allocated(false),
: workimg(NULL), awbComputed(false), ipf(&params, true), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
pW(-1), pH(-1), plistener(NULL),
imageListener(NULL), aeListener(NULL), hListener(NULL), resultValid(false),
changeSinceLast(0), updaterRunning(false), destroying(false) {
@ -41,6 +41,7 @@ ImProcCoordinator::ImProcCoordinator ()
chroma_acurve(65536,0);
chroma_bcurve(65536,0);
satcurve(65536,0);
// satbgcurve(65536,0);
vhist16(65536);
lhist16(65536); lhist16Cropped(65536);
@ -121,9 +122,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
}
progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);
if ( todo & M_PREPROC) {
// raw auto CA is bypassed if no high detail is needed, so we have to compute it when high detail is needed
if ( (todo & M_PREPROC) || (!highDetailPreprocessComputed && highDetailNeeded)) {
imgsrc->preprocess( rp, params.lensProf, params.coarse );
imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw );
if (highDetailNeeded)
highDetailPreprocessComputed = true;
else
highDetailPreprocessComputed = false;
}
/*
@ -138,7 +144,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
*/
// If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST
if ( (todo & M_RAW)
|| (!highDetailComputed && highDetailNeeded)
|| (!highDetailRawComputed && highDetailNeeded)
|| ( params.hlrecovery.enabled && params.hlrecovery.method!="Color" && imgsrc->IsrgbSourceModified())
|| (!params.hlrecovery.enabled && params.hlrecovery.method=="Color" && imgsrc->IsrgbSourceModified()))
{
@ -162,13 +168,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
imgsrc->demosaic( rp );
if (highDetailNeeded) {
highDetailComputed = true;
highDetailRawComputed = true;
if (params.hlrecovery.enabled && params.hlrecovery.method=="Color") {
todo |= M_INIT;
}
}
else
highDetailComputed = false;
highDetailRawComputed = false;
LUTu aehist; int aehistcompr;
@ -282,7 +288,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
// if it's just crop we just need the histogram, no image updates
if ( todo!=CROP ) {
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation,
rCurve, gCurve, bCurve);
rCurve, gCurve, bCurve, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
}
// compute L channel histogram
@ -300,16 +306,19 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
}
readyphase++;
bool utili=false;
bool autili=false;
bool butili=false;
bool ccutili=false;
if ((todo & M_LUMACURVE) || todo==CROP) {
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
lumacurve, histLCurve, scale==1 ? 1 : 16);
lumacurve, histLCurve, scale==1 ? 1 : 16, utili);
}
if (todo & M_LUMACURVE) {
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit,
params.labCurve.acurve, params.labCurve.bcurve, chroma_acurve, chroma_bcurve, satcurve, scale==1 ? 1 : 16);
CurveFactory::complexsgnCurve (autili, butili,ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve/*,params.labCurve.cbgcurve*/, chroma_acurve, chroma_bcurve, satcurve,/*satbgcurve,*/ scale==1 ? 1 : 16);
}
if (todo & (M_LUMINANCE+M_COLOR) ) {
@ -317,13 +326,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
ipf.EPDToneMap(nprevl,0,scale);
progress ("Applying Luminance Curve...",100*readyphase/numofphases);
//progress ("Applying Luminance Curve...",100*readyphase/numofphases);
ipf.luminanceCurve (nprevl, nprevl, lumacurve);
//ipf.luminanceCurve (nprevl, nprevl, lumacurve);
readyphase++;
//readyphase++;
progress ("Applying Color Boost...",100*readyphase/numofphases);
ipf.chrominanceCurve (nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*, params.labCurve.saturation*/);
ipf.chromiLuminanceCurve (nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*,satbgcurve*/, lumacurve, utili, autili, butili, ccutili);
//ipf.colorCurve (nprevl, nprevl);
ipf.vibrance(nprevl);
readyphase++;

View File

@ -60,7 +60,8 @@ class ImProcCoordinator : public StagedImageProcessor {
ImProcFunctions ipf;
int scale;
bool highDetailComputed;
bool highDetailPreprocessComputed;
bool highDetailRawComputed;
bool allocated;
void freeAll ();
@ -73,6 +74,7 @@ class ImProcCoordinator : public StagedImageProcessor {
LUTf chroma_acurve;
LUTf chroma_bcurve;
LUTf satcurve;
// LUTf satbgcurve;
LUTf rCurve;
LUTf gCurve;

View File

@ -56,7 +56,7 @@ namespace rtengine {
#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000)
#define CLIP2(a) ((a)<MAXVAL ? a : MAXVAL )
#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0)
extern const Settings* settings;
@ -188,9 +188,15 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
}
void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve) {
rgbProc (working, lab, hltonecurve, shtonecurve, tonecurve, shmap, sat, rCurve, gCurve, bCurve, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh);
}
// Process RGB image and convert to LAB space
void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve) {
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve,
double expcomp, int hlcompr, int hlcomprthresh) {
int h_th, s_th;
if (shmap) {
@ -249,9 +255,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone
if (sCurveEnabled) sCurve = new FlatCurve(params->hsvequalizer.scurve);
if (vCurveEnabled) vCurve = new FlatCurve(params->hsvequalizer.vcurve);
const float exp_scale = pow (2.0, params->toneCurve.expcomp);
const float comp = (max(0.0, params->toneCurve.expcomp) + 1.0)*params->toneCurve.hlcompr/100.0;
const float shoulder = ((65536.0/max(1.0f,exp_scale))*(params->toneCurve.hlcomprthresh/200.0))+0.1;
const float exp_scale = pow (2.0, expcomp);
const float comp = (max(0.0, expcomp) + 1.0)*hlcompr/100.0;
const float shoulder = ((65536.0/max(1.0f,exp_scale))*(hlcomprthresh/200.0))+0.1;
const float hlrange = 65536.0-shoulder;
@ -422,7 +428,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone
if (sCurveEnabled) delete sCurve;
if (vCurveEnabled) delete vCurve;
delete [] cossq;
}
}
void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & curve) {
@ -437,64 +443,306 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur
lnew->L[i][j] = curve[Lin];
}
}
void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve) {
void ImProcFunctions::chromiLuminanceCurve (LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve/*,LUTf & satbgcurve*/, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili) {
int W = lold->W;
int H = lold->H;
//init Flatcurve for C=f(H)
FlatCurve* chCurve = NULL;
bool chutili = false;
if (!params->labCurve.bwtoning) {
chCurve = new FlatCurve(params->labCurve.chcurve);
if (chCurve && !chCurve->isIdentity()) {
chutili=true;
}//do not use "Munsell" if Chcurve not used
}
#ifdef _DEBUG
MyTime t1e,t2e, t3e, t4e;
t1e.set();
// init variables to display Munsell corrections
MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo();
#endif
unsigned int N = W*H;
float *L = lold->L[0];
float *a= lold->a[0];
float *b= lold->b[0];
float* Lold = new float [lold->W*lold->H];//to save L before any used
float* Cold = new float [lold->W*lold->H];//to save C before any used
float adjustr=1.0f, adjustbg=1.0f;
// if(params->labCurve.avoidclip ){
for (unsigned int j=0; j!=N; j++){
Lold[j]=L[j]/327.68f;
Cold[j]=sqrt(SQR(a[j]/327.68f)+SQR(b[j]/327.68f));
// Hr=atan2(b[j],a[j]);
// if(Hr >-0.15f && Hr < 1.5f && Cold[j]>maxCr)
// maxCr=Cold[j]; // I do not take into account "acurve" and "bcurve" to adjust max
// else if (Cold[j]>maxCbg)
// maxCbg=Cold[j];
}
// parameter to adapt curve C=f(C) to gamut
if (params->icm.working=="ProPhoto") {adjustr = adjustbg = 1.2f;}// 1.2 instead 1.0 because it's very rare to have C>170..
else if (params->icm.working=="Adobe RGB") {adjustr = 1.8f; adjustbg = 1.4f;}
else if (params->icm.working=="sRGB") {adjustr = 2.0f; adjustbg = 1.7f;}
else if (params->icm.working=="WideGamut") {adjustr = adjustbg = 1.2f;}
else if (params->icm.working=="Beta RGB") {adjustr = adjustbg = 1.4f;}
else if (params->icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;}
else if (params->icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;}
// reference to the params structure has to be done outside of the parallelization to avoid CPU cache problem
bool highlight = params->hlrecovery.enabled; //Get the value if "highlight reconstruction" is activated
int chromaticity = params->labCurve.chromaticity;
bool bwToning = params->labCurve.bwtoning;
double rstprotection = 100.-params->labCurve.rstprotection; // Red and Skin Tones Protection
// avoid color shift is disabled when bwToning is activated
bool avoidColorShift = params->labCurve.avoidcolorshift && !bwToning;
int protectRed = settings->protectred;
double protectRedH = settings->protectredh;
bool gamutLch = settings->gamutLch;
// only if user activate Lab adjustements
if (avoidColorShift) {
if(autili || butili || ccutili || chutili || utili || chromaticity)
Color::LabGamutMunsell(lold, Lold, Cold, /*corMunsell*/true, /*lumaMuns*/false, params->hlrecovery.enabled, /*gamut*/true, params->icm.working, multiThread);
}
#ifdef _DEBUG
#pragma omp parallel default(shared) firstprivate(highlight, chromaticity, bwToning, rstprotection, avoidColorShift, protectRed, protectRedH, gamutLch, lold, lnew, MunsDebugInfo) if (multiThread)
#else
#pragma omp parallel default(shared) firstprivate(highlight, chromaticity, bwToning, rstprotection, avoidColorShift, protectRed, protectRedH, gamutLch, lold, lnew) if (multiThread)
#endif
{
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
double wip[3][3] = {
{wiprof[0][0],wiprof[0][1],wiprof[0][2]},
{wiprof[1][0],wiprof[1][1],wiprof[1][2]},
{wiprof[2][0],wiprof[2][1],wiprof[2][2]}
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working);
//if(utili) curve.dump("Lcurve");
double wp[3][3] = {
{wprof[0][0],wprof[0][1],wprof[0][2]},
{wprof[1][0],wprof[1][1],wprof[1][2]},
{wprof[2][0],wprof[2][1],wprof[2][2]}};
#pragma omp parallel for if (multiThread)
for (int i=0; i<H; i++)
for (int j=0; j<W; j++) {
float atmp = acurve[lold->a[i][j]+32768.0f]-32768.0f;
float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f;
//float maxlp=-100.0, minlp=200.0;
#pragma omp for schedule(dynamic, 10)
for (int i=0; i<H; i++)
for (int j=0; j<W; j++) {
float LL=lold->L[i][j]/327.68f;
float CC=sqrt(SQR(lold->a[i][j]/327.68f) + SQR(lold->b[i][j]/327.68f));
float HH=atan2(lold->b[i][j],lold->a[i][j]);
float Chprov=CC;
float Chprov1=CC;
float memChprov=Chprov;
float Lprov2=LL;
float Lin=lold->L[i][j];
lnew->L[i][j] = curve[Lin];
float Lprov1=(lnew->L[i][j])/327.68f;
float chromaChfactor=1.0f;
float atmp = acurve[lold->a[i][j]+32768.0f]-32768.0f;// curves Lab a
float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f;// curves Lab b
//float chromaCredfactor=1.0f;
//float chromaCbgfactor=1.0f;
// chromaCfactor=(satcurve[chroma*adjustr])/(chroma*adjustr);//apply C=f(C)
// chromaCbgfactor=(satbgcurve[chroma*adjustbg])/(chroma*adjustbg);
// calculate C=f(H)
if (chutili) {
double hr;
//hr=translate Hue Lab value (-Pi +Pi) in approximative hr (hsv values) (0 1) [red 1/6 yellow 1/6 green 1/6 cyan 1/6 blue 1/6 magenta 1/6 ]
// with multi linear correspondances (I expect there is no error !!)
if (HH<-2.7f) hr=0.020380804*double(HH)+0.970281708; //Lab green =>hr # 0.33 ==> 0.33 0.42
else if (HH<-2.1f) hr=0.266666667*double(HH)+1.14; //Lab cyan =>hr # 0.50 ==> 0.42 0.58
else if (HH<-0.9f) hr=0.141666 *double(HH)+0.8775; //Lab blue =>hr # 0.67 ==> 0.58 0.75
else if (HH<-0.1f) hr=0.2125 *double(HH)+0.94125; //Lab magenta (purple) =>hr # 0.83 ==> 0.75 0.92
else if (HH< 1.3f) hr=0.12142857 *double(HH)+0.932142857; //Lab red and skin =>hr # 0 ==> 0.92 1.09
else if (HH< 2.2f) hr=0.1666667 *double(HH)-0.1266667; //Lab yellow and green yellow =>hr # 0.16 ==> 0.09 0.24
else hr=0.0955828 *double(HH)+0.02971784; //Lab green =>hr # 0.33 ==> 0.24 0.33
//allways put h between 0 and 1
if (hr<0.0) hr += 1.0;
else if(hr>1.0) hr -= 1.0;
float chparam = float((chCurve->getVal(hr)-0.5f) * 2.0f);//get C=f(H)
chromaChfactor=1.0f+chparam;
}
atmp *= chromaChfactor;//apply C=f(H)
btmp *= chromaChfactor;
// if (params->labCurve.chromaticity) {// if user use sliders
if(chromaticity!=0 && !bwToning){
// approximation in Lab mode to protect skin tones and avoid too big gamut clip for red
float scale = 100.0f/100.1f;//reduction in normal zone
float scaleext=1.0f;//reduction in transition zone
float protect_red,protect_redh;
float deltaHH;//HH value transition
float dred=55.0f;//C red value limit
protect_red=float(protectRed);//default=60 chroma: one can put more or less if necessary...in 'option' 40...160
if(protect_red < 20.0f) protect_red=20.0; // avoid too low value
if(protect_red > 180.0f) protect_red=180.0; // avoid too high value
protect_redh=float(protectRedH);//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1.0
if(protect_redh<0.1f) protect_redh=0.1f;//avoid divide by 0 and negatives values
if(protect_redh>1.0f) protect_redh=1.0f;//avoid too big values
deltaHH=protect_redh;//transition hue
//simulate very approximative gamut f(L) : with pyramid transition
if (Lprov1<25.0f) dred = 40.0f;
else if(Lprov1<30.0f) dred = 3.0f*Lprov1 -35.0f;
else if(Lprov1<70.0f) dred = 55.0f;
else if(Lprov1<75.0f) dred = -3.0f*Lprov1 +265.0f;
else dred = 40.0f;
if(rstprotection<99.9999) {
if(chromaticity>0)
scale = rstprotection/100.1f;
if((HH< (1.3f+deltaHH) && HH >=1.3f))
scaleext=HH*(1.0f-scale)/deltaHH + 1.0f - (1.3f+deltaHH)*(1.0f-scale)/deltaHH; //transition for Hue (red - yellow)
else if((HH< 0.15f && HH >(0.15f-deltaHH)))
scaleext=HH*(scale-1.0f)/deltaHH + 1.0f - (0.15f-deltaHH)*(scale-1.0f)/deltaHH; //transition for hue (red purple)
}
//transition for red , near skin tones
float factorskin, factorsat, factor, factorskinext;
factorskin=1.0f+(chromaticity*scale)/100.0f;
factorskinext=1.0f+(chromaticity*scaleext)/100.0f;
factorsat=1.0f+(chromaticity)/100.0f;/*if(factorsat==1.0f) factorsat=1.1f;*/
factor = factorsat;
// Test if chroma is in the normal range first
if(HH>=0.15f && HH<1.3f) {
if (Chprov1<dred)
factor = factorskin;
else if(Chprov1<(dred+protect_red))
factor = (factorsat-factorskin)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskin)/protect_red;
}
// then test if chroma is in the extanded range
else if ( HH>(0.15f-deltaHH) || HH<(1.3f+deltaHH) ) {
if (Chprov1 < dred)
factor = factorskinext;// C=dred=55 => real max of skin tones
else if (Chprov1 < (dred+protect_red))// transition
factor = (factorsat-factorskinext)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskinext)/protect_red;
}
atmp *= factor;
btmp *= factor;
// end approximation
}
// I have placed C=f(C) after all C treatments to assure maximum amplitude of "C"
if (!bwToning) {
float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001f);
float chromaCfactor = (satcurve[chroma*adjustr])/(chroma*adjustr);//apply C=f(C)
atmp *= chromaCfactor;
btmp *= chromaCfactor;
}
// end chroma C=f(C)
Chprov1 = sqrt(SQR(atmp/327.68f)+SQR(btmp/327.68f));
/*
// modulation of a and b curves with saturation
if (params->labCurve.saturation!=0 && !params->labCurve.bwtoning) {
if (params->labCurve.chromaticity!=0 && !params->labCurve.bwtoning) {
float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001);
float satfactor = (satcurve[chroma+32768.0f]-32768.0f)/chroma;
atmp *= satfactor;
btmp *= satfactor;
}
*/
// labCurve.bwtoning option allows to decouple modulation of a & b curves by saturation
// with bwtoning enabled the net effect of a & b curves is visible
if (params->labCurve.bwtoning) {
if (bwToning) {
atmp -= lold->a[i][j];
btmp -= lold->b[i][j];
}
if (params->labCurve.avoidclip) {
//Luv limiter
float Y,u,v;
Color::Lab2Yuv(lnew->L[i][j],atmp,btmp,Y,u,v);
//Yuv2Lab includes gamut restriction map
Color::Yuv2Lab(Y,u,v,lnew->L[i][j],lnew->a[i][j],lnew->b[i][j], wp);
} else {
if (avoidColorShift) {
//gamutmap Lch ==> preserve Hue,but a little slower than gamutbdy for high values...and little faster for low values
if(gamutLch) {
float R,G,B;
#ifdef _DEBUG
bool neg=false;
bool more_rgb=false;
//gamut control : Lab values are in gamut
Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.4f, 0.95f, neg, more_rgb);
#else
//gamut control : Lab values are in gamut
Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.4f, 0.95f);
#endif
Lprov2 = Lprov1;
lnew->L[i][j]=Lprov1*327.68f;
lnew->a[i][j]=327.68f*Chprov1*cos(HH);
lnew->b[i][j]=327.68f*Chprov1*sin(HH);
}
else {
//use gamutbdy
//Luv limiter
float Y,u,v;
Color::Lab2Yuv(lnew->L[i][j],atmp,btmp,Y,u,v);
//Yuv2Lab includes gamut restriction map
Color::Yuv2Lab(Y,u,v,lnew->L[i][j],lnew->a[i][j],lnew->b[i][j], wp);
}
if (utili || autili || butili || ccutili || chutili || chromaticity) {
float correctionHue=0.0f; // Munsell's correction
float correctlum=0.0f;
Lprov1=lnew->L[i][j]/327.68f;
Chprov=sqrt(SQR(lnew->a[i][j]/327.68f)+ SQR(lnew->b[i][j]/327.68f));
#ifdef _DEBUG
Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo);
#else
Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum);
#endif
if(fabs(correctionHue) < 0.015f) HH+=correctlum; // correct only if correct Munsell chroma very little.
lnew->a[i][j]=327.68f*Chprov*cos(HH+correctionHue);// apply Munsell
lnew->b[i][j]=327.68f*Chprov*sin(HH+correctionHue);
}
}
else {
// if(Lprov1 > maxlp) maxlp=Lprov1;
// if(Lprov1 < minlp) minlp=Lprov1;
lnew->L[i][j]=Lprov1*327.68f;
//Luv limiter only
lnew->a[i][j] = atmp;
lnew->b[i][j] = btmp;
}
}
} // end of parallelization
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#ifdef _DEBUG
if (settings->verbose) {
t3e.set();
printf("Color::AllMunsellLch (correction performed in %d usec):\n", t3e.etime(t1e));
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum);
}
delete MunsDebugInfo;
#endif
delete [] Lold;
delete [] Cold;
if (chutili) delete chCurve;
}
//#include "cubic.cc"
@ -920,7 +1168,7 @@ fclose(f);*/
else
return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}

View File

@ -33,11 +33,11 @@
#include "cplx_wavelet_dec.h"
namespace rtengine {
using namespace procparams;
using namespace procparams;
class ImProcFunctions {
static LUTf gamma2curve;
cmsHTRANSFORM monitorTransform;
@ -68,46 +68,11 @@ class ImProcFunctions {
public:
static LUTf cachef;
// 195 LUTf for Munsell Lch correction
static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60;
static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60;
static LUTf _5B40,_5B50,_5B60, _5B70,_5B80;
static LUTf _7B40,_7B50,_7B60, _7B70,_7B80;
static LUTf _9B40,_9B50,_9B60, _9B70,_9B80;
static LUTf _10B40,_10B50,_10B60, _10B70,_10B80;
static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80;
static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60;
static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80;
static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80;
static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80;
static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80;
static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80;
static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80;
static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90;
static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90;
static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80;
static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90;
static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80;
static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70;
static LUTf _10R30, _10R40,_10R50,_10R60,_10R70;
static LUTf _9R30, _9R40,_9R50,_9R60,_9R70;
static LUTf _7R30, _7R40,_7R50,_7R60,_7R70;
static LUTf _5R10, _5R20,_5R30;
static LUTf _25R10, _25R20,_25R30;
static LUTf _10RP10, _10RP20,_10RP30;
static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80;
static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80;
static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80;
static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80;
static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80;
static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80;
static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80;
double lumimul[3];
static void initCache ();
static void cleanupCache ();
static void initMunsell ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {}
@ -119,12 +84,13 @@ class ImProcFunctions {
void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma);
void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve);
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve);
void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve,
double expcomp, int hlcompr, int hlcomprthresh);
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve);
void chromiLuminanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve/*,LUTf & satbgcurve*/, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili);
void vibrance (LabImage* lab);//Jacques' vibrance
void skinsat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color
void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone);//jacques: Munsell correction
void colorCurve (LabImage* lold, LabImage* lnew);
void sharpening (LabImage* lab, float** buffer);
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH,

View File

@ -42,8 +42,7 @@ int init (const Settings* s, Glib::ustring baseDir) {
profileStore.init ();
ProcParams::init ();
Color::init ();
ImProcFunctions::initMunsell();
Color::init();
ImProcFunctions::initCache ();
Thumbnail::initGamma ();
delete lcmsMutex;

View File

@ -295,6 +295,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
return image;
}
// 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) {

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@ enum ProcEvent {
EvLCPUseDist=33,
EvLCPUseVign=34,
EvLCPUseCA=35,
EvCBBoost=36, // obsolete
EvFixedExp=36,
EvWBMethod=37,
EvWBTemp=38,
EvWBGreen=39,
@ -132,9 +132,9 @@ enum ProcEvent {
EvHLComprThreshold=107,
EvResizeBoundingBox=108,
EvResizeAppliesTo=109,
EvLAvoidClip=110,
EvLSatLimiter=111,
EvLSatLimit=112,
EvLAvoidColorShift=110,
EvLSatLimiter=111, // obsolete
EvLRSTProtection=112,
EvDemosaicDCBIter=113,
EvDemosaicFalseColorIter=114,
EvDemosaicDCBEnhanced=115,
@ -189,8 +189,11 @@ enum ProcEvent {
EvRGBbCurve=164,
EvNeutralExp=165,
EvLBWtoning=166,
EvDPDNLdetail=167,
NUMOFEVENTS=168
EvLCCCurve=167,
EvLCHCurve=168,
EvVibranceSkinTonesCurve=169,
EvDPDNLdetail=170,
NUMOFEVENTS=171
};
}
#endif

View File

@ -139,19 +139,24 @@ void ProcParams::setDefaults () {
toneCurve.curve.clear ();
toneCurve.curve.push_back(DCT_Linear);
labCurve.brightness = 0;
labCurve.contrast = 0;
labCurve.saturation = 0;
labCurve.avoidclip = false;
labCurve.enable_saturationlimiter = false;
labCurve.saturationlimit = 50;
labCurve.bwtoning = false;
labCurve.brightness = 0;
labCurve.contrast = 0;
labCurve.chromaticity = 0;
labCurve.avoidcolorshift = true;
labCurve.rstprotection = 0;
labCurve.bwtoning = false;
labCurve.lcurve.clear ();
labCurve.lcurve.push_back(DCT_Linear);
labCurve.acurve.clear ();
labCurve.acurve.push_back(DCT_Linear);
labCurve.bcurve.clear ();
labCurve.bcurve.push_back(DCT_Linear);
labCurve.cccurve.clear ();
labCurve.cccurve.push_back(DCT_Linear);
labCurve.chcurve.clear ();
labCurve.chcurve.push_back(FCT_Linear);
//labCurve.cbgcurve.clear ();
//labCurve.cbgcurve.push_back(DCT_Linear);
rgbCurves.rcurve.clear ();
rgbCurves.rcurve.push_back(DCT_Linear);
@ -189,10 +194,12 @@ void ProcParams::setDefaults () {
vibrance.enabled = false;
vibrance.pastels = 0;
vibrance.saturated = 0;
vibrance.psthreshold.setValues(1, 75);
vibrance.psthreshold.setValues(0, 75);
vibrance.protectskins = false;
vibrance.avoidcolorshift = true;
vibrance.pastsattog = true;
vibrance.skintonescurve.clear ();
vibrance.skintonescurve.push_back(DCT_Linear);
//colorBoost.amount = 0;
//colorBoost.avoidclip = false;
@ -402,13 +409,12 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
}
// save luma curve
if (!pedited || pedited->labCurve.brightness) keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness);
if (!pedited || pedited->labCurve.contrast) keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast);
if (!pedited || pedited->labCurve.saturation) keyFile.set_integer ("Luminance Curve", "Saturation", labCurve.saturation);
if (!pedited || pedited->labCurve.avoidclip) keyFile.set_boolean ("Luminance Curve", "AvoidColorClipping", labCurve.avoidclip);
if (!pedited || pedited->labCurve.enable_saturationlimiter) keyFile.set_boolean ("Luminance Curve", "SaturationLimiter", labCurve.enable_saturationlimiter);
if (!pedited || pedited->labCurve.saturationlimit) keyFile.set_double ("Luminance Curve", "SaturationLimit", labCurve.saturationlimit);
if (!pedited || pedited->labCurve.avoidclip) keyFile.set_boolean ("Luminance Curve", "BWtoning", labCurve.bwtoning);
if (!pedited || pedited->labCurve.brightness) keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness);
if (!pedited || pedited->labCurve.contrast) keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast);
if (!pedited || pedited->labCurve.chromaticity) keyFile.set_integer ("Luminance Curve", "Chromaticity", labCurve.chromaticity);
if (!pedited || pedited->labCurve.avoidcolorshift) keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift);
if (!pedited || pedited->labCurve.rstprotection) keyFile.set_double ("Luminance Curve", "SaturationLimit", labCurve.rstprotection);
if (!pedited || pedited->labCurve.bwtoning) keyFile.set_boolean ("Luminance Curve", "BWtoning", labCurve.bwtoning);
if (!pedited || pedited->labCurve.lcurve) {
Glib::ArrayHandle<double> lcurve = labCurve.lcurve;
keyFile.set_double_list("Luminance Curve", "LCurve", lcurve);
@ -421,7 +427,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
Glib::ArrayHandle<double> bcurve = labCurve.bcurve;
keyFile.set_double_list("Luminance Curve", "bCurve", bcurve);
}
if (!pedited || pedited->labCurve.cccurve) {
Glib::ArrayHandle<double> cccurve = labCurve.cccurve;
keyFile.set_double_list("Luminance Curve", "ccCurve", cccurve);
}
if (!pedited || pedited->labCurve.chcurve) {
Glib::ArrayHandle<double> chcurve = labCurve.chcurve;
keyFile.set_double_list("Luminance Curve", "chCurve", chcurve);
}
/*
if (!pedited || pedited->labCurve.cbgcurve) {
Glib::ArrayHandle<double> cbgcurve = labCurve.cbgcurve;
keyFile.set_double_list("Luminance Curve", "cbgCurve", cbgcurve);
}
*/
// save sharpening
if (!pedited || pedited->sharpening.enabled) keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled);
if (!pedited || pedited->sharpening.method) keyFile.set_string ("Sharpening", "Method", sharpening.method);
@ -452,6 +471,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
if (!pedited || pedited->vibrance.protectskins) keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins);
if (!pedited || pedited->vibrance.avoidcolorshift) keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift);
if (!pedited || pedited->vibrance.pastsattog) keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog);
if (!pedited || pedited->vibrance.skintonescurve) {
Glib::ArrayHandle<double> skintonescurve = vibrance.skintonescurve;
keyFile.set_double_list("Vibrance", "SkinTonesCurve", skintonescurve);
}
//save edge sharpening
if (!pedited || pedited->sharpenEdge.enabled) keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled);
@ -781,16 +804,25 @@ if (keyFile.has_group ("Channel Mixer")) {
// load luma curve
if (keyFile.has_group ("Luminance Curve")) {
if (keyFile.has_key ("Luminance Curve", "Brightness")) { labCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); if (pedited) pedited->labCurve.brightness = true; }
if (keyFile.has_key ("Luminance Curve", "Contrast")) { labCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); if (pedited) pedited->labCurve.contrast = true; }
if (keyFile.has_key ("Luminance Curve", "Saturation")) { labCurve.saturation = keyFile.get_integer ("Luminance Curve", "Saturation"); if (pedited) pedited->labCurve.saturation = true; }
if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) { labCurve.avoidclip = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (pedited) pedited->labCurve.avoidclip = true; }
if (keyFile.has_key ("Luminance Curve", "SaturationLimiter")) { labCurve.enable_saturationlimiter = keyFile.get_boolean ("Luminance Curve", "SaturationLimiter"); if (pedited) pedited->labCurve.enable_saturationlimiter = true; }
if (keyFile.has_key ("Luminance Curve", "SaturationLimit")) { labCurve.saturationlimit = keyFile.get_double ("Luminance Curve", "SaturationLimit"); if (pedited) pedited->labCurve.saturationlimit = true; }
if (keyFile.has_key ("Luminance Curve", "BWtoning")) { labCurve.bwtoning = keyFile.get_boolean ("Luminance Curve", "BWtoning"); if (pedited) pedited->labCurve.bwtoning = true; }
if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (pedited) pedited->labCurve.lcurve = true; }
if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (pedited) pedited->labCurve.acurve = true; }
if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); if (pedited) pedited->labCurve.bcurve = true; }
if (keyFile.has_key ("Luminance Curve", "Brightness")) { labCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); if (pedited) pedited->labCurve.brightness = true; }
if (keyFile.has_key ("Luminance Curve", "Contrast")) { labCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); if (pedited) pedited->labCurve.contrast = true; }
if (keyFile.has_key ("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Chromaticity"); if (pedited) pedited->labCurve.chromaticity = true; }
if (PPVERSION < 303) {
// transform AvoidColorClipping into AvoidColorShift
if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (pedited) pedited->labCurve.avoidcolorshift = true; }
}
else {
if (keyFile.has_key ("Luminance Curve", "AvoidColorShift")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorShift"); if (pedited) pedited->labCurve.avoidcolorshift = true; }
if (keyFile.has_key ("Luminance Curve", "RedAndSkinTonesProtection")) { labCurve.rstprotection = keyFile.get_double ("Luminance Curve", "RedAndSkinTonesProtection"); if (pedited) pedited->labCurve.rstprotection = true; }
}
if (keyFile.has_key ("Luminance Curve", "BWtoning")) { labCurve.bwtoning = keyFile.get_boolean ("Luminance Curve", "BWtoning"); if (pedited) pedited->labCurve.bwtoning = true; }
if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (pedited) pedited->labCurve.lcurve = true; }
if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (pedited) pedited->labCurve.acurve = true; }
if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); if (pedited) pedited->labCurve.bcurve = true; }
if (keyFile.has_key ("Luminance Curve", "ccCurve")) { labCurve.cccurve = keyFile.get_double_list ("Luminance Curve", "ccCurve"); if (pedited) pedited->labCurve.cccurve = true; }
if (keyFile.has_key ("Luminance Curve", "chCurve")) { labCurve.chcurve = keyFile.get_double_list ("Luminance Curve", "chCurve"); if (pedited) pedited->labCurve.chcurve = true; }
}
// load sharpening
@ -856,6 +888,7 @@ if (keyFile.has_group ("Vibrance")) {
if (keyFile.has_key ("Vibrance", "ProtectSkins")) { vibrance.protectskins = keyFile.get_boolean ("Vibrance", "ProtectSkins"); if (pedited) pedited->vibrance.protectskins = true; }
if (keyFile.has_key ("Vibrance", "AvoidColorShift")) { vibrance.avoidcolorshift = keyFile.get_boolean ("Vibrance", "AvoidColorShift"); if (pedited) pedited->vibrance.avoidcolorshift = true; }
if (keyFile.has_key ("Vibrance", "PastSatTog")) { vibrance.pastsattog = keyFile.get_boolean ("Vibrance", "PastSatTog"); if (pedited) pedited->vibrance.pastsattog = true; }
if (keyFile.has_key ("Vibrance", "SkinTonesCurve")) { vibrance.skintonescurve = keyFile.get_double_list ("Vibrance", "SkinTonesCurve"); if (pedited) pedited->vibrance.skintonescurve = true; }
}
// load colorBoost
@ -1200,12 +1233,14 @@ bool ProcParams::operator== (const ProcParams& other) {
&& labCurve.lcurve == other.labCurve.lcurve
&& labCurve.acurve == other.labCurve.acurve
&& labCurve.bcurve == other.labCurve.bcurve
&& labCurve.cccurve == other.labCurve.cccurve
&& labCurve.chcurve == other.labCurve.chcurve
// && labCurve.cbgcurve == other.labCurve.cbgcurve
&& labCurve.brightness == other.labCurve.brightness
&& labCurve.contrast == other.labCurve.contrast
&& labCurve.saturation == other.labCurve.saturation
&& labCurve.avoidclip == other.labCurve.avoidclip
&& labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter
&& labCurve.saturationlimit == other.labCurve.saturationlimit
&& labCurve.chromaticity == other.labCurve.chromaticity
&& labCurve.avoidcolorshift == other.labCurve.avoidcolorshift
&& labCurve.rstprotection == other.labCurve.rstprotection
&& labCurve.bwtoning == other.labCurve.bwtoning
&& sharpenEdge.enabled == other.sharpenEdge.enabled
&& sharpenEdge.passes == other.sharpenEdge.passes
@ -1236,6 +1271,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& vibrance.protectskins == other.vibrance.protectskins
&& vibrance.avoidcolorshift == other.vibrance.avoidcolorshift
&& vibrance.pastsattog == other.vibrance.pastsattog
&& vibrance.skintonescurve == other.vibrance.skintonescurve
//&& colorBoost.amount == other.colorBoost.amount
//&& colorBoost.avoidclip == other.colorBoost.avoidclip
//&& colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter

View File

@ -202,12 +202,14 @@ class LCurveParams {
std::vector<double> lcurve;
std::vector<double> acurve;
std::vector<double> bcurve;
std::vector<double> cccurve;
std::vector<double> chcurve;
//std::vector<double> cbgcurve;
int brightness;
int contrast;
int saturation;
bool avoidclip;
bool enable_saturationlimiter;
double saturationlimit;
int chromaticity;
bool avoidcolorshift;
double rstprotection;
bool bwtoning;
};
@ -273,8 +275,9 @@ class VibranceParams {
bool protectskins;
bool avoidcolorshift;
bool pastsattog;
std::vector<double> skintonescurve;
VibranceParams() : psthreshold(1, 75, false) {};
VibranceParams() : psthreshold(0, 75, false) {};
};
/**

View File

@ -56,7 +56,7 @@ SHARPENING, // EvShrDIterations,
TRANSFORM, // EvLCPUseDist,
DARKFRAME, // EvLCPUseVign,
TRANSFORM, // EvLCPUseCA,
0, // EvCBBoost: obsolete
M_VOID, // EvFixedExp
WHITEBALANCE, // EvWBMethod,
WHITEBALANCE, // EvWBTemp,
WHITEBALANCE, // EvWBGreen,
@ -187,7 +187,9 @@ RGBCURVE, // EvRGBgCurve
RGBCURVE, // EvRGBbCurve
RGBCURVE, // EvNeutralExp
LUMINANCECURVE, // EvLBWtoning
LUMINANCECURVE, // EvLCCurve
LUMINANCECURVE, // EvLCHGurve
RGBCURVE, // EvCCCurve
ALLNORAW // EvDPDNLdetail
};

View File

@ -9,7 +9,7 @@ namespace rtengine {
static const int MAXVAL = 0xffff;
template <typename _Tp>
inline const _Tp SQR (const _Tp& x) {
inline const _Tp SQR (_Tp x) {
// return std::pow(x,2); Slower than:
return (x*x);
}

View File

@ -734,6 +734,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf curve2 (65536);
LUTf curve (65536);
LUTf satcurve (65536);
LUTf satbgcurve (65536);
LUTf rCurve (65536);
LUTf gCurve (65536);
LUTf bCurve (65536);
@ -742,7 +744,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
//CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh,
// params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast,
// gamma, true, params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy, 16);
CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, params.toneCurve.hlcomprthresh,
CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh,
params.toneCurve.shcompr, bright, contr, gamma, true,
params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy, 16);
@ -752,7 +754,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LabImage* labView = new LabImage (fw,fh);
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve );
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, expcomp, hlcompr, hlcomprthresh);
if (shmap)
delete shmap;
@ -765,13 +767,17 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
// luminance processing
ipf.EPDToneMap(labView,0,6);
bool utili=false;
bool autili=false;
bool butili=false;
bool ccutili=false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
hist16, hist16, curve, dummy, 16);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit,
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16);
ipf.luminanceCurve (labView, labView, curve);
ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve);
hist16, hist16, curve, dummy, 16, utili);
CurveFactory::complexsgnCurve (autili, butili, ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve/*,params.labCurve.cbgcurve*/, curve1, curve2, satcurve,/*satbgcurve,*/ 16);
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,/*satbgcurve,*/ curve, utili, autili, butili, ccutili);
ipf.vibrance(labView);
// color processing

View File

@ -44,6 +44,9 @@ namespace rtengine {
Glib::ustring srgb10; // default name of SRGB space profile
bool gamutICC; //
bool gamutLch;
int protectred;
double protectredh;
/** Creates a new instance of Settings.
* @return a pointer to the new Settings instance. */

View File

@ -161,19 +161,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve2 (65536,0);
LUTf curve (65536,0);
LUTf satcurve (65536,0);
//LUTf satbgcurve (65536,0);
LUTf rCurve (65536,0);
LUTf gCurve (65536,0);
LUTf bCurve (65536,0);
LUTu dummy;
CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, bright, params.toneCurve.contrast, imgsrc->getGamma(), true, params.toneCurve.curve,
CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, imgsrc->getGamma(), true, params.toneCurve.curve,
hist16, dummy, curve1, curve2, curve, dummy);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1);
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve);
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, expcomp, hlcompr, hlcomprthresh);
// Freeing baseImg because not used anymore
delete baseImg;
@ -199,13 +201,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// luminance processing
ipf.EPDToneMap(labView);
bool utili=false;
bool autili=false;
bool butili=false;
bool ccutili=false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1, utili);
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit,
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1);
ipf.luminanceCurve (labView, labView, curve);
ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve);
CurveFactory::complexsgnCurve (autili, butili, ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,/*params.labCurve.cbgcurve,*/curve1, curve2, satcurve,/*satbgcurve,*/ 1);
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,/*satbgcurve,*/curve, utili, autili, butili, ccutili);
ipf.vibrance(labView);
ipf.impulsedenoise (labView);

View File

@ -4,7 +4,7 @@ set (BASESOURCEFILES
exportpanel.cc cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc
ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc
cachemanager.cc cacheimagedata.cc shcselector.cc perspective.cc thresholdselector.cc thresholdadjuster.cc
clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc
clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc coloredbar.cc
coarsepanel.cc cacorrection.cc hlrec.cc chmixer.cc
resize.cc icmpanel.cc crop.cc shadowshighlights.cc
impulsedenoise.cc dirpyrdenoise.cc epd.cc

View File

@ -26,7 +26,7 @@
#define ADDSET_PERSPECTIVE 18
#define ADDSET_CA 19
#define ADDSET_VIGN_AMOUNT 20
#define ADDSET_LC_SATURATION 21
#define ADDSET_LC_CHROMATICITY 21
#define ADDSET_TC_SATURATION 22
#define ADDSET_TC_HLCOMPAMOUNT 23
#define ADDSET_TC_HLCOMPTHRESH 24

View File

@ -27,6 +27,7 @@ class Adjuster;
class AdjusterListener {
public:
virtual ~AdjusterListener() {};
virtual void adjusterChanged (Adjuster* a, double newval) {}
};
@ -71,13 +72,14 @@ class Adjuster : public Gtk::VBox {
void setAdjusterListener (AdjusterListener* alistener) { adjusterListener = alistener; }
// return the value trimmed to the limits at construction time
double getValue () { return spin->get_value (); }
double getValue () { return shapeValue(spin->get_value ()); }
// return the value trimmed to the limits at construction time
int getIntValue () { return spin->get_value_as_int (); }
// return the value trimmed to the limits at construction time,
// method only used by the history manager
Glib::ustring getTextValue () { return spin->get_text (); }
void setLabel (Glib::ustring lbl) { label->set_label(lbl); }
void setValue (double a);
void setLimits (double vmin, double vmax, double vstep, double vdefault);
void setEnabled (bool enabled);

View File

@ -145,7 +145,7 @@ void BatchToolPanelCoordinator::initSession () {
else {
toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]);
lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_SATURATION]);
lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_CHROMATICITY]);
whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]);
vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]);
rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]);
@ -179,7 +179,7 @@ void BatchToolPanelCoordinator::initSession () {
if (options.baBehav[ADDSET_LC_BRIGHTNESS]) pparams.labCurve.brightness = 0;
if (options.baBehav[ADDSET_LC_CONTRAST]) pparams.labCurve.contrast = 0;
if (options.baBehav[ADDSET_LC_SATURATION]) pparams.labCurve.saturation = 0;
if (options.baBehav[ADDSET_LC_CHROMATICITY]) pparams.labCurve.chromaticity = 0;
if (options.baBehav[ADDSET_SHARP_AMOUNT]) pparams.sharpening.amount = 0;
if (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT]) pparams.sharpenEdge.amount = 0;

135
rtgui/coloredbar.cc Normal file
View File

@ -0,0 +1,135 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "coloredbar.h"
ColoredBar::ColoredBar (eRTOrientation orient) {
orientation = orient;
dirty = true;
cp = NULL;
this->x = this->y = this->w = this->h = 0;
}
void ColoredBar::setColorProvider (ColorProvider* p) {
cp = p;
}
/*
* Redraw the bar to a Cairo::Surface
*/
void ColoredBar::expose(Cairo::RefPtr<Cairo::Surface> destSurface) {
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !destSurface)
return;
draw();
copySurface(destSurface);
}
/*
* Redraw the bar to a Gdk::Window
*/
void ColoredBar::expose(Glib::RefPtr<Gdk::Window> destWindow) {
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !destWindow)
return;
draw();
copySurface(destWindow);
}
/*
* Redraw the bar to a Gdk::Window
*/
void ColoredBar::expose(BackBuffer *backBuffer) {
// look out if the Surface has to be redrawn
if (!surfaceCreated() || !backBuffer)
return;
draw();
copySurface(backBuffer);
}
void ColoredBar::draw() {
if (isDirty()) {
Cairo::RefPtr<Cairo::Context> cr = getContext();
// the bar has to be drawn to the Surface first
if (!bgGradient.empty()) {
// a gradient has been set, we use it
cr->set_line_width(0.);
// gradient background
Cairo::RefPtr< Cairo::LinearGradient > bggradient;
switch (orientation) {
case (RTO_Left2Right):
bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.);
break;
case (RTO_Right2Left):
bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.);
break;
case (RTO_Bottom2Top):
bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.);
break;
case (RTO_Top2Bottom):
default:
bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h));
break;
}
for (std::vector<GradientMilestone>::iterator i=bgGradient.begin(); i!=bgGradient.end(); i++) {
bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b);
}
cr->set_source (bggradient);
cr->rectangle(0, 0, w, h);
cr->fill();
}
else {
// ask the ColorProvider to provide colors :) for each pixels
if (cp) {
cr->set_antialias(Cairo::ANTIALIAS_NONE);
cr->set_line_width(1.);
for (int x=0; x<w; x++) {
for (int y=0; y<h; y++) {
double x2 = double(x)+0.5;
double y2 = double(y)+0.5;
double x01 = x2/(w-1);
double y01 = y2/h;
cp->colorForValue (x01, y01);
cr->set_source_rgb(cp->red, cp->green, cp->blue);
cr->move_to(x2, y2);
cr->stroke();
}
}
}
}
// has it been updated or not, we assume that the Surface has been correctly set (we don't handle allocation error)
setDirty(false);
}
}
void ColoredBar::setBgGradient (const std::vector<GradientMilestone> &milestones) {
bgGradient = milestones;
setDirty(true);
}
void ColoredBar::clearBgGradient () {
bgGradient.clear();
setDirty(true);
}
bool ColoredBar::canGetColors() {
return cp!=NULL || bgGradient.size()>0;
}

56
rtgui/coloredbar.h Normal file
View File

@ -0,0 +1,56 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _COLOREDBAR_
#define _COLOREDBAR_
#include "colorprovider.h"
#include "guiutils.h"
/*
* Parent class for all colored bar type; a ColorProvider has to be set
* thanks to "setColorProvider" to be able to display colors inside the bar
*/
class ColoredBar : public BackBuffer {
private:
void draw();
protected:
ColorProvider* cp;
eRTOrientation orientation;
std::vector<GradientMilestone> bgGradient;
public:
ColoredBar (eRTOrientation orient);
void expose(Glib::RefPtr<Gdk::Window> destWindow);
void expose(Cairo::RefPtr<Cairo::Surface> destSurface);
void expose(BackBuffer *backBuffer);
void setColorProvider (ColorProvider* p);
bool canGetColors();
// Method for convenience; if no Gradient provided, the ColoredBar will ask colors on a per pixel basis
void setBgGradient (const std::vector<GradientMilestone> &milestones);
// by clearing the gradient, the ColorProvider will have to provide colors on a per pixel basis if a ColorProvider
// has been set, through ColorProvider::colorForValue on next ColoredBar::expose
void clearBgGradient ();
};
#endif

View File

@ -19,15 +19,22 @@
#ifndef _COLORPROVIDER_
#define _COLORPROVIDER_
/*
* Use it to let your widget feed a colored bar or graph lines with the wanted colors
* If you don't need to dynamically feed a widget with colors (e.g. curve's graph),
* you don't need to declare the instanciator class as BEING a ColorProvider, you'll
* still be able to set gradients for e.g. ColoredBar(s)
*/
class ColorProvider {
public:
public:
double red;
double green;
double blue;
virtual void colorForValue (double valX, double valY) {}
ColorProvider() { red = green = blue = 0.0; };
virtual ~ColorProvider() {};
virtual void colorForValue (double valX, double valY) {};
};
#endif

View File

@ -8,7 +8,6 @@
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@ -26,8 +25,6 @@
#include <cstring>
extern Glib::ustring argv0;
DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup) : CurveEditor::CurveEditor(text, static_cast<CurveEditorGroup*>(ceGroup), ceSubGroup) {
// Order set in the same order than "enum DiagonalCurveType". Shouldn't change, for compatibility reason
@ -37,6 +34,15 @@ DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup*
curveType->addEntry("curveType-NURBS.png", M("CURVEEDITOR_NURBS")); // 3 NURBS
curveType->setSelected(DCT_Linear);
curveType->show();
rangeLabels[0] = M("CURVEEDITOR_SHADOWS");
rangeLabels[1] = M("CURVEEDITOR_DARKS");
rangeLabels[2] = M("CURVEEDITOR_LIGHTS");
rangeLabels[3] = M("CURVEEDITOR_HIGHLIGHTS");
rangeMilestones[0] = 0.25;
rangeMilestones[1] = 0.50;
rangeMilestones[2] = 0.75;
}
std::vector<double> DiagonalCurveEditor::getCurve () {
@ -56,6 +62,39 @@ std::vector<double> DiagonalCurveEditor::getCurve () {
}
}
void DiagonalCurveEditor::setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) {
rangeLabels[0] = r1;
rangeLabels[1] = r2;
rangeLabels[2] = r3;
rangeLabels[3] = r4;
}
void DiagonalCurveEditor::getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4) {
r1 = rangeLabels[0];
r2 = rangeLabels[1];
r3 = rangeLabels[2];
r4 = rangeLabels[3];
}
/*
* Admittedly that this method is called just after the instantiation of this class, we set the shcselector's default values
*/
void DiagonalCurveEditor::setRangeDefaultMilestones(double m1, double m2, double m3) {
rangeMilestones[0] = m1;
rangeMilestones[1] = m2;
rangeMilestones[2] = m3;
paramCurveEd.at(1) = m1;
paramCurveEd.at(2) = m2;
paramCurveEd.at(3) = m3;
}
void DiagonalCurveEditor::getRangeDefaultMilestones(double &m1, double &m2, double &m3) {
m1 = rangeMilestones[0];
m2 = rangeMilestones[1];
m3 = rangeMilestones[2];
}
FlatCurveEditor::FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup, bool isPeriodic) : CurveEditor::CurveEditor(text, static_cast<CurveEditorGroup*>(ceGroup), ceSubGroup) {
periodic = isPeriodic;
@ -93,6 +132,9 @@ CurveEditor::CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEd
bgHistValid = false;
selected = DCT_Linear;
bottomBarCP = NULL;
leftBarCP = NULL;
curveCP = NULL;
group = ceGroup;
subGroup = ceSubGroup;
@ -161,3 +203,66 @@ bool CurveEditor::openIfNonlinear() {
return nonLinear;
}
// Handles markup tooltips
void CurveEditor::setTooltip(Glib::ustring ttip) {
curveType->set_tooltip_text(ttip.empty() ?
Glib::ustring::compose("<b>%1</b> ", M("CURVEEDITOR_TYPE")) :
Glib::ustring::compose("%1\n<b>%2</b>", ttip, M("CURVEEDITOR_TYPE")));
}
void CurveEditor::setLeftBarColorProvider(ColorProvider* cp) {
leftBarCP = cp;
}
void CurveEditor::setBottomBarColorProvider(ColorProvider* cp) {
bottomBarCP = cp;
}
void CurveEditor::setLeftBarBgGradient (const std::vector<GradientMilestone> &milestones) {
leftBarBgGradient = milestones;
}
void CurveEditor::setBottomBarBgGradient (const std::vector<GradientMilestone> &milestones) {
bottomBarBgGradient = milestones;
}
void CurveEditor::setCurveColorProvider(ColorProvider* cp) {
curveCP = cp;
}
ColorProvider* CurveEditor::getLeftBarColorProvider() {
return leftBarCP;
}
ColorProvider* CurveEditor::getBottomBarColorProvider() {
return bottomBarCP;
}
ColorProvider* CurveEditor::getCurveColorProvider() {
return curveCP;
}
std::vector<GradientMilestone> CurveEditor::getBottomBarBgGradient () const {
return bottomBarBgGradient;
}
std::vector<GradientMilestone> CurveEditor::getLeftBarBgGradient () const {
return leftBarBgGradient;
}
sigc::signal<void> CurveEditor::signal_curvegraph_enter() {
return sig_curvegraph_enter;
}
sigc::signal<void> CurveEditor::signal_curvegraph_leave() {
return sig_curvegraph_leave;
}
sigc::signal<void> CurveEditor::signal_curvepoint_click() {
return sig_curvepoint_click;
}
sigc::signal<void> CurveEditor::signal_curvepoint_release() {
return sig_curvepoint_release;
}

View File

@ -21,6 +21,7 @@
#include "popuptogglebutton.h"
#include "../rtengine/LUT.h"
#include "coloredbar.h"
class CurveEditorGroup;
class CurveEditorSubGroup;
@ -63,6 +64,17 @@ class CurveEditor {
std::vector<double> tempCurve;
sigc::connection typeconn;
ColorProvider* bottomBarCP;
ColorProvider* leftBarCP;
ColorProvider* curveCP;
std::vector<GradientMilestone> bottomBarBgGradient;
std::vector<GradientMilestone> leftBarBgGradient;
sigc::signal<void> sig_curvegraph_enter;
sigc::signal<void> sig_curvegraph_leave;
sigc::signal<void> sig_curvepoint_click;
sigc::signal<void> sig_curvepoint_release;
public:
CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup);
@ -73,10 +85,27 @@ class CurveEditor {
void setUnChanged (bool uc);
void updateBackgroundHistogram (LUTu & hist);
void setLeftBarColorProvider(ColorProvider* cp);
void setBottomBarColorProvider(ColorProvider* cp);
void setCurveColorProvider(ColorProvider* cp);
void setBottomBarBgGradient (const std::vector<GradientMilestone> &milestones);
void setLeftBarBgGradient (const std::vector<GradientMilestone> &milestones);
ColorProvider* getLeftBarColorProvider();
ColorProvider* getBottomBarColorProvider();
ColorProvider* getCurveColorProvider();
std::vector<GradientMilestone> getBottomBarBgGradient () const;
std::vector<GradientMilestone> getLeftBarBgGradient () const;
bool openIfNonlinear(); // Open up the curve if it has modifications and it's not already opened
void setCurve (const std::vector<double>& p);
virtual std::vector<double> getCurve () = 0;
void setTooltip(Glib::ustring ttip);
sigc::signal<void> signal_curvegraph_enter();
sigc::signal<void> signal_curvegraph_leave();
sigc::signal<void> signal_curvepoint_click();
sigc::signal<void> signal_curvepoint_release();
};
@ -94,10 +123,16 @@ class DiagonalCurveEditor : public CurveEditor {
std::vector<double> customCurveEd;
std::vector<double> paramCurveEd;
std::vector<double> NURBSCurveEd;
Glib::ustring rangeLabels[4];
double rangeMilestones[3];
public:
DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup);
std::vector<double> getCurve ();
void setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4);
void getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4);
void setRangeDefaultMilestones(double m1, double m2, double m3);
void getRangeDefaultMilestones(double &m1, double &m2, double &m3);
};

View File

@ -27,9 +27,7 @@
#include "../rtengine/safegtk.h"
#include "rtimage.h"
extern Glib::ustring argv0;
CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), cl(NULL), cp(NULL) {
CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), cl(NULL) {
curveEditors.clear();
displayedCurve = 0;
numberOfPackedCurve = 0;
@ -121,12 +119,6 @@ void CurveEditorGroup::newLine() {
void CurveEditorGroup::curveListComplete() {
newLine();
// Set the color provider
if (cp) {
if (flatSubGroup) flatSubGroup->setColorProvider(cp);
if (diagonalSubGroup) diagonalSubGroup->setColorProvider(cp);
}
// We check the length of the label ; if it contains only one char (':'), we set it to the right default string
if (curveGroupLabel->get_label().size()==1)
curveGroupLabel->set_label(M(curveEditors.size() > 1 ? "CURVEEDITOR_CURVES" : "CURVEEDITOR_CURVE") + ":");
@ -294,8 +286,15 @@ void CurveEditorGroup::setUnChanged (bool uc, CurveEditor* ce) {
}
}
CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) :
curveDir(curveDir), lastFilename("") {
CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), lastFilename("") {
leftBar = NULL;
bottomBar = NULL;
curveCP = NULL;
}
CurveEditorSubGroup::~CurveEditorSubGroup() {
if (leftBar) delete leftBar;
if (bottomBar) delete bottomBar;
}
Glib::ustring CurveEditorSubGroup::outputFile () {

View File

@ -58,7 +58,6 @@ protected:
DiagonalCurveEditorSubGroup* diagonalSubGroup;
CurveListener* cl;
ColorProvider* cp;
unsigned int numberOfPackedCurve;
@ -68,6 +67,7 @@ public:
* This variable will be updated with actions in the
* dialogs.
*/
CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = "");
~CurveEditorGroup();
void newLine();
@ -75,7 +75,6 @@ public:
void setBatchMode (bool batchMode);
void setCurveExternal (CurveEditor* ce, const std::vector<double>& c);
void setCurveListener (CurveListener* l) { cl = l; }
void setColorProvider (ColorProvider* p) { cp = p; }
CurveEditor* getDisplayedCurve () { return displayedCurve; }
//void on_realize ();
CurveEditor* addCurve(CurveType cType, Glib::ustring curveLabel, bool periodic = true);
@ -105,11 +104,16 @@ protected:
int valUnchanged;
CurveEditorGroup *parent;
ColoredBar* leftBar;
ColoredBar* bottomBar;
ColorProvider* curveCP;
public:
~CurveEditorSubGroup();
int getValUnchanged() { return valUnchanged; }
int getValLinear() { return valLinear; }
virtual void updateBackgroundHistogram (CurveEditor* ce) {}
virtual void setColorProvider (ColorProvider* p) = 0;
protected:

View File

@ -51,7 +51,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
Gtk::HBox* custombbox = Gtk::manage (new Gtk::HBox ());
custombbox->set_spacing(4);
pasteCustom = Gtk::manage (new Gtk::Button ());
pasteCustom = Gtk::manage (new Gtk::Button ());
pasteCustom->add (*Gtk::manage (new RTImage ("edit-paste.png")));
copyCustom = Gtk::manage (new Gtk::Button ());
copyCustom->add (*Gtk::manage (new RTImage ("edit-copy.png")));
@ -60,8 +60,8 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
loadCustom = Gtk::manage (new Gtk::Button ());
loadCustom->add (*Gtk::manage (new RTImage ("gtk-open.png")));
custombbox->pack_end (*pasteCustom, Gtk::PACK_SHRINK, 0);
custombbox->pack_end (*copyCustom, Gtk::PACK_SHRINK, 0);
custombbox->pack_end (*pasteCustom, Gtk::PACK_SHRINK, 0);
custombbox->pack_end (*copyCustom, Gtk::PACK_SHRINK, 0);
custombbox->pack_end (*saveCustom, Gtk::PACK_SHRINK, 0);
custombbox->pack_end (*loadCustom, Gtk::PACK_SHRINK, 0);
@ -70,13 +70,13 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
saveCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) );
loadCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) );
copyCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
pasteCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
copyCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
pasteCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
saveCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE"));
loadCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD"));
copyCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
pasteCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
copyCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
pasteCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
// Custom curve end
@ -92,7 +92,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
Gtk::HBox* NURBSbbox = Gtk::manage (new Gtk::HBox ());
NURBSbbox->set_spacing(4);
pasteNURBS = Gtk::manage (new Gtk::Button ());
pasteNURBS = Gtk::manage (new Gtk::Button ());
pasteNURBS->add (*Gtk::manage (new RTImage ("edit-paste.png")));
copyNURBS = Gtk::manage (new Gtk::Button ());
copyNURBS->add (*Gtk::manage (new RTImage ("edit-copy.png")));
@ -101,8 +101,8 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
loadNURBS = Gtk::manage (new Gtk::Button ());
loadNURBS->add (*Gtk::manage (new RTImage ("gtk-open.png")));
NURBSbbox->pack_end (*pasteNURBS, Gtk::PACK_SHRINK, 0);
NURBSbbox->pack_end (*copyNURBS, Gtk::PACK_SHRINK, 0);
NURBSbbox->pack_end (*pasteNURBS, Gtk::PACK_SHRINK, 0);
NURBSbbox->pack_end (*copyNURBS, Gtk::PACK_SHRINK, 0);
NURBSbbox->pack_end (*saveNURBS, Gtk::PACK_SHRINK, 0);
NURBSbbox->pack_end (*loadNURBS, Gtk::PACK_SHRINK, 0);
@ -111,26 +111,26 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
saveNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) );
loadNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) );
pasteNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
copyNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
pasteNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
copyNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
saveNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE"));
loadNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD"));
pasteNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
copyNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
pasteNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
copyNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
// NURBS curve end
// parametric curve
paramCurveBox = new Gtk::VBox ();
paramCurveBox->set_spacing(4);
paramCurveBox->set_spacing(0);
paramCurve = Gtk::manage (new MyDiagonalCurve ());
paramCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS);
paramCurve->setType (DCT_Parametric);
shcSelector = Gtk::manage (new SHCSelector ());
shcSelector->set_size_request (GRAPH_SIZE-100, 20); // width, height
shcSelector->set_size_request (GRAPH_SIZE-100, 12); // width, height
//* shcSelector->set_size_request ((GRAPH_SIZE+2*RADIUS)-20, 20);
paramCurveBox->pack_start (*paramCurve, Gtk::PACK_EXPAND_WIDGET, 0);
@ -138,7 +138,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
Gtk::HBox* Parambbox = Gtk::manage (new Gtk::HBox ());
Parambbox->set_spacing(4);
pasteParam = Gtk::manage (new Gtk::Button ());
pasteParam = Gtk::manage (new Gtk::Button ());
pasteParam->add (*Gtk::manage (new RTImage ("edit-paste.png")));
copyParam = Gtk::manage (new Gtk::Button ());
copyParam->add (*Gtk::manage (new RTImage ("edit-copy.png")));
@ -147,22 +147,21 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
loadParam = Gtk::manage (new Gtk::Button ());
loadParam->add (*Gtk::manage (new RTImage ("gtk-open.png")));
Parambbox->pack_end (*pasteParam, Gtk::PACK_SHRINK, 0);
Parambbox->pack_end (*copyParam, Gtk::PACK_SHRINK, 0);
Parambbox->pack_end (*pasteParam, Gtk::PACK_SHRINK, 0);
Parambbox->pack_end (*copyParam, Gtk::PACK_SHRINK, 0);
Parambbox->pack_end (*saveParam, Gtk::PACK_SHRINK, 0);
Parambbox->pack_end (*loadParam, Gtk::PACK_SHRINK, 0);
saveParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) );
loadParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) );
pasteParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
copyParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
pasteParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) );
copyParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) );
saveParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE"));
loadParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD"));
pasteParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
copyParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
pasteParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE"));
copyParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY"));
paramCurveBox->set_spacing(4);
paramCurveBox->pack_end (*Parambbox, Gtk::PACK_EXPAND_WIDGET, 0);
highlights = Gtk::manage (new Adjuster (M("CURVEEDITOR_HIGHLIGHTS"), -100, 100, 1, 0));
@ -218,9 +217,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt,
}
DiagonalCurveEditorSubGroup::~DiagonalCurveEditorSubGroup() {
delete customCurveBox;
delete paramCurveBox;
delete NURBSCurveBox;
delete customCurveBox;
delete paramCurveBox;
delete NURBSCurveBox;
}
/*
@ -253,30 +252,101 @@ void DiagonalCurveEditorSubGroup::switchGUI() {
// Initializing GUI values + repacking the appropriated widget
//dCurve->typeconn.block(true);
// first we update the colored bar
ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider();
std::vector<GradientMilestone> bgGradient = dCurve->getLeftBarBgGradient();
if (barColorProvider == NULL && bgGradient.size() == 0) {
// dCurve has no left colored bar, so we delete the object
if (leftBar) {
delete leftBar;
leftBar = NULL;
}
}
else {
// dCurve ave a ColorProvider or a background gradient defined, so we create/update the object
if (!leftBar) {
leftBar = new ColoredBar(RTO_Bottom2Top);
}
if (barColorProvider) {
bgGradient.clear();
leftBar->setColorProvider(barColorProvider);
leftBar->setBgGradient (bgGradient);
}
else {
leftBar->setColorProvider(NULL);
leftBar->setBgGradient (bgGradient);
}
}
barColorProvider = dCurve->getBottomBarColorProvider();
bgGradient = dCurve->getBottomBarBgGradient();
if (barColorProvider == NULL && bgGradient.size() == 0) {
// dCurve has no left colored bar, so we delete the object
if (bottomBar) {
delete bottomBar;
bottomBar = NULL;
}
}
else {
// dCurve ave a ColorProvider or a background gradient defined, so we create/update the object
if (!bottomBar) {
bottomBar = new ColoredBar(RTO_Left2Right);
}
if (barColorProvider) {
bgGradient.clear();
bottomBar->setColorProvider(barColorProvider);
bottomBar->setBgGradient (bgGradient);
}
else {
bottomBar->setColorProvider(NULL);
bottomBar->setBgGradient (bgGradient);
}
}
switch((DiagonalCurveType)(dCurve->curveType->getSelected())) {
case (DCT_Spline):
customCurve->setPoints (dCurve->customCurveEd);
customCurve->setColorProvider(dCurve->getCurveColorProvider());
customCurve->setColoredBar(leftBar, bottomBar);
parent->pack_start (*customCurveBox);
customCurveBox->check_resize();
customCurve->forceResize();
break;
case (DCT_Parametric):
{
Glib::ustring label[4];
dCurve->getRangeLabels(label[0], label[1], label[2], label[3]);
double mileStone[3];
dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]);
paramCurve->setPoints (dCurve->paramCurveEd);
shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]);
shcSelector->setPositions (
dCurve->paramCurveEd.at(1),
dCurve->paramCurveEd.at(2),
dCurve->paramCurveEd.at(3)
);
highlights->setValue (dCurve->paramCurveEd.at(4));
highlights->setLabel(label[3]);
lights->setValue (dCurve->paramCurveEd.at(5));
lights->setLabel(label[2]);
darks->setValue (dCurve->paramCurveEd.at(6));
darks->setLabel(label[1]);
shadows->setValue (dCurve->paramCurveEd.at(7));
shadows->setLabel(label[0]);
shcSelector->setColorProvider(barColorProvider);
shcSelector->setBgGradient(bgGradient);
shcSelector->setMargins( (leftBar ? CBAR_WIDTH+CBAR_MARGIN : RADIUS), RADIUS );
paramCurve->setColoredBar(leftBar, NULL);
parent->pack_start (*paramCurveBox);
paramCurve->forceResize();
break;
}
case (DCT_NURBS):
NURBSCurve->setPoints (dCurve->NURBSCurveEd);
NURBSCurve->setColorProvider(dCurve->getCurveColorProvider());
NURBSCurve->setColoredBar(leftBar, bottomBar);
parent->pack_start (*NURBSCurveBox);
NURBSCurveBox->check_resize();
NURBSCurve->forceResize();
@ -306,7 +376,7 @@ void DiagonalCurveEditorSubGroup::savePressed () {
p = NURBSCurve->getPoints ();
break;
case DCT_Parametric:
p = paramCurve->getPoints ();
p = paramCurve->getPoints ();
break;
default:
break;
@ -322,14 +392,14 @@ void DiagonalCurveEditorSubGroup::savePressed () {
else if (p[ix]==(double)(DCT_Parametric))
f << "Parametric\n";
if (p[ix]==(double)(DCT_Parametric)) {
ix++;
for (unsigned int i=0; i<p.size()-1; i++, ix++)
f << p[ix] << std::endl;
}
ix++;
for (unsigned int i=0; i<p.size()-1; i++, ix++)
f << p[ix] << std::endl;
}
else {
ix++;
for (unsigned int i=0; i<p.size()/2; i++, ix+=2)
f << p[ix] << ' ' << p[ix+1] << std::endl;
ix++;
for (unsigned int i=0; i<p.size()/2; i++, ix+=2)
f << p[ix] << ' ' << p[ix+1] << std::endl;
}
f.close ();
@ -372,90 +442,87 @@ void DiagonalCurveEditorSubGroup::loadPressed () {
NURBSCurve->notifyListener ();
}
else if (p[0] == (double)(DCT_Parametric)) {
shcSelector->setPositions (
p[1],
p[2],
p[3] );
highlights->setValue (p[4]);
lights->setValue (p[5]);
darks->setValue (p[6]);
shadows->setValue (p[7]);
paramCurve->setPoints (p);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
shcSelector->setPositions ( p[1], p[2], p[3] );
highlights->setValue (p[4]);
lights->setValue (p[5]);
darks->setValue (p[6]);
shadows->setValue (p[7]);
paramCurve->setPoints (p);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
}
}
}
}
}
void DiagonalCurveEditorSubGroup::copyPressed () {
// For compatibility use enum DiagonalCurveType here
std::vector<double> curve;
std::vector<double> curve;
switch (parent->displayedCurve->selected) {
case DCT_Spline: // custom
curve = customCurve->getPoints ();
clipboard.setCurveData (curve,DCT_Spline);
break;
case DCT_Parametric: // parametric
// ... do something, first add save/load functions
curve = paramCurve->getPoints ();
clipboard.setCurveData (curve,DCT_Parametric);
break;
case DCT_NURBS: // NURBS
curve = NURBSCurve->getPoints ();
clipboard.setCurveData (curve,DCT_NURBS);
break;
default: // (DCT_Linear, DCT_Unchanged)
// ... do nothing
break;
}
switch (parent->displayedCurve->selected) {
case DCT_Spline: // custom
curve = customCurve->getPoints ();
clipboard.setCurveData (curve,DCT_Spline);
break;
case DCT_Parametric: // parametric
// ... do something, first add save/load functions
curve = paramCurve->getPoints ();
clipboard.setCurveData (curve,DCT_Parametric);
break;
case DCT_NURBS: // NURBS
curve = NURBSCurve->getPoints ();
clipboard.setCurveData (curve,DCT_NURBS);
break;
default: // (DCT_Linear, DCT_Unchanged)
// ... do nothing
break;
}
}
void DiagonalCurveEditorSubGroup::pastePressed () {
// For compatibility use enum DiagonalCurveType here
std::vector<double> curve;
DiagonalCurveType type;
std::vector<double> curve;
DiagonalCurveType type;
type = clipboard.hasCurveData();
type = clipboard.hasCurveData();
if (type == (DiagonalCurveType)parent->displayedCurve->selected) {
curve = clipboard.getCurveData ();
switch (type) {
case DCT_Linear: // linear
break;
case DCT_Spline: // custom
customCurve->setPoints (curve);
customCurve->queue_draw ();
customCurve->notifyListener ();
break;
case DCT_Parametric: // parametric
// ... do something, first add save/load functions
shcSelector->setPositions (
curve[1],
curve[2],
curve[3] );
highlights->setValue (curve[4]);
lights->setValue (curve[5]);
darks->setValue (curve[6]);
shadows->setValue (curve[7]);
paramCurve->setPoints (curve);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
break;
case DCT_NURBS: // NURBS
NURBSCurve->setPoints (curve);
NURBSCurve->queue_draw ();
NURBSCurve->notifyListener ();
break;
default: // (DCT_Linear, DCT_Unchanged)
// ... do nothing
break;
}
}
return;
if (type == (DiagonalCurveType)parent->displayedCurve->selected) {
curve = clipboard.getCurveData ();
switch (type) {
case DCT_Linear: // linear
break;
case DCT_Spline: // custom
customCurve->setPoints (curve);
customCurve->queue_draw ();
customCurve->notifyListener ();
break;
case DCT_Parametric: // parametric
// ... do something, first add save/load functions
shcSelector->setPositions (
curve[1],
curve[2],
curve[3] );
highlights->setValue (curve[4]);
lights->setValue (curve[5]);
darks->setValue (curve[6]);
shadows->setValue (curve[7]);
paramCurve->setPoints (curve);
paramCurve->queue_draw ();
paramCurve->notifyListener ();
break;
case DCT_NURBS: // NURBS
NURBSCurve->setPoints (curve);
NURBSCurve->queue_draw ();
NURBSCurve->notifyListener ();
break;
default: // (DCT_Linear, DCT_Unchanged)
// ... do nothing
break;
}
}
return;
}
@ -529,9 +596,9 @@ const std::vector<double> DiagonalCurveEditorSubGroup::getCurveFromGUI (int type
return lcurve;
}
case (DCT_Spline):
return customCurve->getPoints ();
return customCurve->getPoints ();
case (DCT_NURBS):
return NURBSCurve->getPoints ();
return NURBSCurve->getPoints ();
default: {
// linear and other solutions
std::vector<double> lcurve (1);
@ -561,18 +628,26 @@ bool DiagonalCurveEditorSubGroup::curveReset(int cType) {
return true;
break;
case (DCT_Parametric) :
{
DiagonalCurveEditor* dCurve = static_cast<DiagonalCurveEditor*>(parent->displayedCurve);
double mileStone[3];
dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]);
highlights->resetPressed(NULL);
lights->resetPressed(NULL);
darks->resetPressed(NULL);
shadows->resetPressed(NULL);
shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]);
shcSelector->reset();
paramCurve->reset ();
return true;
break;
}
default:
return false;
break;
}
return true;
}
void DiagonalCurveEditorSubGroup::setColorProvider (ColorProvider* p) {
@ -596,7 +671,7 @@ void DiagonalCurveEditorSubGroup::shcChanged () {
*/
void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval) {
paramCurve->setPoints (getCurveFromGUI(DCT_Parametric));
paramCurve->setPoints (getCurveFromGUI(DCT_Parametric));
storeDisplayedCurve();
parent->curveChanged ();
}
@ -606,11 +681,11 @@ void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval) {
*/
bool DiagonalCurveEditorSubGroup::adjusterEntered (GdkEventCrossing* ev, int ac) {
if (ev->detail != GDK_NOTIFY_INFERIOR) {
activeParamControl = ac;
paramCurve->setActiveParam (activeParamControl);
}
return true;
if (ev->detail != GDK_NOTIFY_INFERIOR) {
activeParamControl = ac;
paramCurve->setActiveParam (activeParamControl);
}
return true;
}
/*
@ -618,11 +693,11 @@ bool DiagonalCurveEditorSubGroup::adjusterEntered (GdkEventCrossing* ev, int ac)
*/
bool DiagonalCurveEditorSubGroup::adjusterLeft (GdkEventCrossing* ev, int ac) {
if (ev->detail != GDK_NOTIFY_INFERIOR) {
activeParamControl = -1;
paramCurve->setActiveParam (activeParamControl);
}
return true;
if (ev->detail != GDK_NOTIFY_INFERIOR) {
activeParamControl = -1;
paramCurve->setActiveParam (activeParamControl);
}
return true;
}
void DiagonalCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) {
@ -632,3 +707,10 @@ void DiagonalCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) {
NURBSCurve->updateBackgroundHistogram (ce->histogram);
}
}
void DiagonalCurveEditorSubGroup::setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) {
shadows->setLabel(r1);
darks->setLabel(r2);
lights->setLabel(r3);
highlights->setLabel(r4);
}

View File

@ -66,6 +66,7 @@ public:
virtual void updateBackgroundHistogram (CurveEditor* ce);
virtual void setColorProvider (ColorProvider* p);
protected:
void storeCurveValues (CurveEditor* ce, const std::vector<double>& p);
void storeDisplayedCurve ();
@ -82,6 +83,8 @@ protected:
void adjusterChanged (Adjuster* a, double newval);
bool adjusterEntered (GdkEventCrossing* ev, int ac);
bool adjusterLeft (GdkEventCrossing* ev, int ac);
void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4);
void setSubGroupBottomBarBgGradient();
};
#endif

View File

@ -90,7 +90,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vsep1 = Gtk::manage (new Gtk::VSeparator ());
hidehp = Gtk::manage (new Gtk::ToggleButton ());
@ -107,13 +106,16 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
hidehp->set_image (*iHistoryShow);
}
tbTopPanel_1 = new Gtk::ToggleButton ();
iTopPanel_1_Show = new RTImage ("panel-to-bottom.png");
iTopPanel_1_Hide = new RTImage ("panel-to-top.png");
tbTopPanel_1->set_relief(Gtk::RELIEF_NONE);
tbTopPanel_1->set_active (true);
tbTopPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDETP1"));
tbTopPanel_1->set_image (*iTopPanel_1_Hide);
tbTopPanel_1 = NULL;
if (!simpleEditor && filePanel) {
tbTopPanel_1 = new Gtk::ToggleButton ();
iTopPanel_1_Show = new RTImage ("panel-to-bottom.png");
iTopPanel_1_Hide = new RTImage ("panel-to-top.png");
tbTopPanel_1->set_relief(Gtk::RELIEF_NONE);
tbTopPanel_1->set_active (true);
tbTopPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDETP1"));
tbTopPanel_1->set_image (*iTopPanel_1_Hide);
}
tbRightPanel_1 = new Gtk::ToggleButton ();
iRightPanel_1_Show = new RTImage ("panel-to-left.png");
@ -139,8 +141,11 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_end (*tbTopPanel_1, Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_end (*vsep1, Gtk::PACK_SHRINK, 2);
if (tbTopPanel_1) {
toolBarPanel->pack_end (*tbTopPanel_1, Gtk::PACK_SHRINK, 1);
Gtk::VSeparator* vsep1 = Gtk::manage (new Gtk::VSeparator ());
toolBarPanel->pack_end (*vsep1, Gtk::PACK_SHRINK, 2);
}
toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_end (*iareapanel->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0);
@ -286,12 +291,13 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) );
beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) );
hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) );
tbTopPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbTopPanel_1_toggled) );
tbRightPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbRightPanel_1_toggled) );
saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) );
queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) );
sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) );
ShowHideSidePanelsconn = tbShowHideSidePanels->signal_toggled().connect ( sigc::mem_fun(*this, &EditorPanel::toggleSidePanels), true);
if (tbTopPanel_1)
tbTopPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbTopPanel_1_toggled) );
}
EditorPanel::~EditorPanel () {
@ -332,6 +338,10 @@ EditorPanel::~EditorPanel () {
//delete saveAsDialog;
if(catalogPane)
delete catalogPane;
if (!iTopPanel_1_Show) delete iTopPanel_1_Show;
if (!iTopPanel_1_Hide) delete iTopPanel_1_Hide;
}
void EditorPanel::leftPaneButtonReleased(GdkEventButton *event) {
@ -751,6 +761,9 @@ void EditorPanel::tbRightPanel_1_toggled () {
}
void EditorPanel::tbTopPanel_1_visible (bool visible){
if (!tbTopPanel_1)
return;
if (visible)
tbTopPanel_1->show();
else
@ -760,9 +773,8 @@ void EditorPanel::tbTopPanel_1_visible (bool visible){
void EditorPanel::tbTopPanel_1_toggled () {
if (catalogPane){ // catalogPane does not exist in multitab mode
tbTopPanel_1_Active = tbTopPanel_1->get_active();
if (tbTopPanel_1_Active){
if (tbTopPanel_1->get_active()){
catalogPane->show();
tbTopPanel_1->set_image (*iTopPanel_1_Hide);
}
@ -775,6 +787,10 @@ void EditorPanel::tbTopPanel_1_toggled () {
}
}
/*
* WARNING: Take care of the simpleEditor value when adding or modifying shortcut keys,
* since handleShortcutKey is now also triggered in simple editor mode
*/
bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
bool ctrl = event->state & GDK_CONTROL_MASK;
@ -785,10 +801,12 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
// Editor Layout
switch(event->keyval) {
case GDK_L:
tbTopPanel_1->set_active (!tbTopPanel_1->get_active()); // toggle top panel
if (tbTopPanel_1)
tbTopPanel_1->set_active (!tbTopPanel_1->get_active()); // toggle top panel
if (ctrl) hidehp->set_active (!hidehp->get_active()); // toggle History (left panel)
if (alt) tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel
return true;
break;
case GDK_l:
if (!shift && !alt /*&& !ctrl*/){
hidehp->set_active (!hidehp->get_active()); // toggle History (left panel)
@ -803,16 +821,19 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
tbRightPanel_1->set_active (!tbRightPanel_1->get_active());
return true;
}
break;
case GDK_m: // Maximize preview panel: hide top AND right AND history panels
if (!ctrl && !alt) {
toggleSidePanels();
return true;
}
break;
case GDK_M: // Maximize preview panel: hide top AND right AND history panels AND (fit image preview)
if (!ctrl && !alt) {
toggleSidePanelsZoomFit();
return true;
}
break;
}
if (!alt){
@ -897,7 +918,8 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
saveAsPressed();
return true;
case GDK_q:
queueImgPressed();
if (!simpleEditor)
queueImgPressed();
return true;
case GDK_e:
sendToGimpPressed();
@ -1362,10 +1384,14 @@ void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & his
}
bool EditorPanel::CheckSidePanelsVisibility() {
if(tbTopPanel_1->get_active()==false && tbRightPanel_1->get_active()==false && hidehp->get_active()==false)
return false;
else
if (tbTopPanel_1) {
if(tbTopPanel_1->get_active()==false && tbRightPanel_1->get_active()==false && hidehp->get_active()==false)
return false;
return true;
}
if(tbRightPanel_1->get_active()==false && hidehp->get_active()==false)
return false;
return true;
}
void EditorPanel::toggleSidePanels(){
// Maximize preview panel:
@ -1374,7 +1400,8 @@ void EditorPanel::toggleSidePanels(){
bool bAllSidePanelsVisible;
bAllSidePanelsVisible= CheckSidePanelsVisibility();
tbTopPanel_1->set_active (!bAllSidePanelsVisible);
if (tbTopPanel_1)
tbTopPanel_1->set_active (!bAllSidePanelsVisible);
tbRightPanel_1->set_active (!bAllSidePanelsVisible);
hidehp->set_active (!bAllSidePanelsVisible);
if (bAllSidePanelsVisible == false)

View File

@ -61,8 +61,6 @@ class EditorPanel : public Gtk::VBox,
Gtk::ToggleButton* tbTopPanel_1;
Gtk::ToggleButton* tbRightPanel_1;
Gtk::ToggleButton* tbBeforeLock;
bool tbTopPanel_1_Active;
bool tbRightPanel_1_Active;
//bool bAllSidePanelsVisible;
Gtk::ToggleButton* beforeAfter;
Gtk::HPaned* hpanedl;

View File

@ -175,7 +175,7 @@ bool EditWindow::keyPressed (GdkEventKey* event) {
toggleFullscreen();
return true;
} else {
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
return ep->handleShortcutKey (event);
}
}

View File

@ -86,6 +86,7 @@ FilterPanel::FilterPanel () : listener (NULL) {
expcomp->set_headers_visible (false);
Gtk::ScrolledWindow* sexpcomp = Gtk::manage(new Gtk::ScrolledWindow());
sexpcomp->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
sexpcomp->set_size_request(-1, 80);
sexpcomp->add(*expcomp);
evb->pack_start (*sexpcomp, Gtk::PACK_SHRINK, 0);
pack_start (*evb, Gtk::PACK_SHRINK, 4);
@ -97,6 +98,7 @@ FilterPanel::FilterPanel () : listener (NULL) {
camera->set_headers_visible (false);
Gtk::ScrolledWindow* scamera = Gtk::manage(new Gtk::ScrolledWindow());
scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scamera->set_size_request(-1, 80);
scamera->add(*camera);
cvb->pack_start (*scamera, Gtk::PACK_SHRINK, 0);
pack_start (*cvb, Gtk::PACK_SHRINK, 4);
@ -108,6 +110,7 @@ FilterPanel::FilterPanel () : listener (NULL) {
lens->set_headers_visible (false);
Gtk::ScrolledWindow* slens = Gtk::manage(new Gtk::ScrolledWindow());
slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
slens->set_size_request(-1, 80);
slens->add(*lens);
lvb->pack_start (*slens, Gtk::PACK_SHRINK, 0);
pack_start (*lvb, Gtk::PACK_SHRINK, 4);
@ -119,6 +122,7 @@ FilterPanel::FilterPanel () : listener (NULL) {
filetype->set_headers_visible (false);
Gtk::ScrolledWindow* sfiletype = Gtk::manage(new Gtk::ScrolledWindow());
sfiletype->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
sfiletype->set_size_request(-1, 80);
sfiletype->add(*filetype);
ftvb->pack_start (*sfiletype, Gtk::PACK_SHRINK, 0);
pack_start (*ftvb, Gtk::PACK_SHRINK, 4);

View File

@ -37,19 +37,19 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u
parent = prt;
// ControlPoints curve
CPointsCurveBox = new Gtk::HBox ();
CPointsCurveBox = new Gtk::VBox ();
CPointsCurveBox->set_spacing(4);
CPointsCurve = Gtk::manage (new MyFlatCurve ());
//CPointsCurve->set_size_request (GRAPH_SIZE+2*RADIUS+1, GRAPH_SIZE+2*RADIUS+1);
CPointsCurve->set_size_request (GRAPH_SIZE+2*RADIUS+1, GRAPH_SIZE+2*RADIUS+1);
CPointsCurve->setType (FCT_MinMaxCPoints);
CPointsCurveBox->pack_start (*CPointsCurve, Gtk::PACK_EXPAND_WIDGET, 0);
Gtk::VBox* CPointsbbox = Gtk::manage (new Gtk::VBox ());
Gtk::HBox* CPointsbbox = Gtk::manage (new Gtk::HBox ());
CPointsbbox->set_spacing(4);
saveCPoints = Gtk::manage (new Gtk::Button ());
saveCPoints->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)));
saveCPoints->add (*Gtk::manage (new RTImage ("gtk-save-large.png")));
loadCPoints = Gtk::manage (new Gtk::Button ());
loadCPoints->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON)));
loadCPoints->add (*Gtk::manage (new RTImage ("gtk-open.png")));
CPointsbbox->pack_end (*saveCPoints, Gtk::PACK_SHRINK, 0);
CPointsbbox->pack_end (*loadCPoints, Gtk::PACK_SHRINK, 0);
@ -97,10 +97,64 @@ void FlatCurveEditorSubGroup::switchGUI() {
// Initializing GUI values + repacking the appropriated widget
//dCurve->typeconn.block(true);
// first we update the colored bar
ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider();
std::vector<GradientMilestone> bgGradient = dCurve->getLeftBarBgGradient();
if (barColorProvider == NULL && bgGradient.size() == 0) {
// dCurve has no left colored bar, so we delete the object
if (leftBar) {
delete leftBar;
leftBar = NULL;
}
}
else {
// dCurve ave a ColorProvider or a background gradient defined, so we create/update the object
if (!leftBar) {
leftBar = new ColoredBar(RTO_Bottom2Top);
}
if (barColorProvider) {
bgGradient.clear();
leftBar->setColorProvider(barColorProvider);
leftBar->setBgGradient (bgGradient);
}
else {
leftBar->setColorProvider(NULL);
leftBar->setBgGradient (bgGradient);
}
}
barColorProvider = dCurve->getBottomBarColorProvider();
bgGradient = dCurve->getBottomBarBgGradient();
if (barColorProvider == NULL && bgGradient.size() == 0) {
// dCurve has no left colored bar, so we delete the object
if (bottomBar) {
delete bottomBar;
bottomBar = NULL;
}
}
else {
// dCurve ave a ColorProvider or a background gradient defined, so we create/update the object
if (!bottomBar) {
bottomBar = new ColoredBar(RTO_Left2Right);
}
if (barColorProvider) {
bgGradient.clear();
bottomBar->setColorProvider(barColorProvider);
bottomBar->setBgGradient (bgGradient);
}
else {
bottomBar->setColorProvider(NULL);
bottomBar->setBgGradient (bgGradient);
}
}
switch((FlatCurveType)(dCurve->curveType->getSelected())) {
case (FCT_MinMaxCPoints):
CPointsCurve->setPeriodicity(dCurve->periodic); // Setting Periodicity before setting points
CPointsCurve->setPoints (dCurve->controlPointsCurveEd);
CPointsCurve->setColorProvider(dCurve->getCurveColorProvider());
CPointsCurve->setColoredBar(leftBar, bottomBar);
parent->pack_start (*CPointsCurveBox);
CPointsCurveBox->check_resize();
CPointsCurve->forceResize();

View File

@ -29,7 +29,7 @@ class FlatCurveEditorSubGroup: public CurveEditorSubGroup {
friend class FlatCurveEditor;
protected:
Gtk::HBox* CPointsCurveBox;
Gtk::VBox* CPointsCurveBox;
MyFlatCurve* CPointsCurve;

View File

@ -497,3 +497,89 @@ void TextOrIcon::switchTo(TOITypes type) {
}
show_all();
}
BackBuffer::BackBuffer() {
x = y = w = h = 0;
dirty = true;
}
bool BackBuffer::setDrawRectangle(Glib::RefPtr<Gdk::Window> window, int newX, int newY, int newW, int newH) {
bool newSize = w!=newW || h!=newH;
x = newX;
y = newY;
w = newW;
h = newH;
// WARNING: we're assuming that the surface type won't change during all the execution time of RT. I guess it may be wrong when the user change the gfx card display settings!?
if (newSize && window) {
// allocate a new Surface
if (newW>0 && newH>0) {
surface = window->create_similar_surface(Cairo::CONTENT_COLOR, w, h);
}
else {
// at least one dimension is null, so we delete the Surface
surface.clear();
// and we reset all dimensions
x = y = w = h = 0;
}
dirty = true;
}
return dirty;
}
/*
* Copy the backbuffer to a Gdk::Window
*/
void BackBuffer::copySurface(Glib::RefPtr<Gdk::Window> window, GdkRectangle *rectangle) {
if (surface && window) {
// TODO: look out if window can be different on each call, and if not, store a reference to the window
Cairo::RefPtr<Cairo::Context> crSrc = window->create_cairo_context();
Cairo::RefPtr<Cairo::Surface> destSurface = crSrc->get_target();
// now copy the off-screen Surface to the destination Surface
Cairo::RefPtr<Cairo::Context> crDest = Cairo::Context::create(destSurface);
crDest->set_source(surface, x, y);
crDest->set_line_width(0.);
if (rectangle)
crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height);
else
crDest->rectangle(x, y, w, h);
crDest->fill();
}
}
/*
* Copy the BackBuffer to another BackBuffer
*/
void BackBuffer::copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle) {
if (surface && destBackBuffer) {
// now copy the off-screen Surface to the destination Surface
Cairo::RefPtr<Cairo::Context> crDest = Cairo::Context::create(destBackBuffer->getSurface());
crDest->set_source(surface, x, y);
crDest->set_line_width(0.);
if (rectangle)
crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height);
else
crDest->rectangle(x, y, w, h);
crDest->fill();
}
}
/*
* Copy the BackBuffer to another Cairo::Surface
*/
void BackBuffer::copySurface(Cairo::RefPtr<Cairo::Surface> destSurface, GdkRectangle *rectangle) {
if (surface && destSurface) {
// now copy the off-screen Surface to the destination Surface
Cairo::RefPtr<Cairo::Context> crDest = Cairo::Context::create(destSurface);
crDest->set_source(surface, x, y);
crDest->set_line_width(0.);
if (rectangle)
crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height);
else
crDest->rectangle(x, y, w, h);
crDest->fill();
}
}

View File

@ -173,6 +173,13 @@ private:
};
typedef enum RTOrientation {
RTO_Left2Right,
RTO_Bottom2Top,
RTO_Right2Left,
RTO_Top2Bottom
} eRTOrientation;
enum TOITypes {
TOI_TEXT,
TOI_ICON
@ -213,4 +220,60 @@ public:
}
};
/**
* @brief Handle point coordinates
*/
template <class T>
class Point {
public:
T x, y;
Point() {
x = T(0);
y = T(0);
}
Point(T coordX, T coordY) {
x = coordX;
y = coordY;
}
void setCoords(T coordX, T coordY) {
x = coordX;
y = coordY;
}
};
/**
* @brief Handle backbuffers as automatically as possible
*/
class BackBuffer {
protected:
int x, y, w, h; // Rectangle where the colored bar has to be drawn
Cairo::RefPtr<Cairo::Surface> surface;
bool dirty; // mean that the Surface has to be (re)allocated
public:
BackBuffer();
// set the destination drawing rectangle; return true if the dimensions are different
bool setDrawRectangle(Glib::RefPtr<Gdk::Window> window, int newX, int newY, int newW, int newH);
void copySurface(Glib::RefPtr<Gdk::Window> window, GdkRectangle *rectangle=NULL);
void copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle=NULL);
void copySurface(Cairo::RefPtr<Cairo::Surface> destSurface, GdkRectangle *rectangle=NULL);
void setDirty(bool isDirty) { dirty = isDirty; if (!dirty && !surface) dirty = true; }
bool isDirty() { return dirty; }
// you have to check if the surface is created thanks to surfaceCreated before starting to draw on it
bool surfaceCreated() { return surface; }
Cairo::RefPtr<Cairo::Surface> getSurface() { return surface; }
void deleteSurface() { surface.clear(); dirty=true; }
// will let you get a Cairo::Context for Cairo drawing operations
Cairo::RefPtr<Cairo::Context> getContext() { return Cairo::Context::create(surface); }
int getWidth() { return w; }
int getHeight() { return h; }
};
#endif

View File

@ -27,13 +27,32 @@ using namespace rtengine::procparams;
HSVEqualizer::HSVEqualizer () : Gtk::VBox(), FoldableToolPanel(this) {
std::vector<GradientMilestone> bottomMilestones;
float R, G, B;
// -0.1 rad < Hue < 1.6 rad
for (int i=0; i<7; i++) {
float x = float(i)*(1.0f/6.0);
Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B);
bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) );
}
curveEditorG = new CurveEditorGroup (options.lastHsvCurvesDir, M("TP_HSVEQUALIZER_CHANNEL"));
curveEditorG->setCurveListener (this);
curveEditorG->setColorProvider (this);
hshape = static_cast<FlatCurveEditor*>(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_HUE")));
hshape->setBottomBarBgGradient(bottomMilestones);
//hshape->setLeftBarColorProvider(this); Not working yet
hshape->setCurveColorProvider(this);
sshape = static_cast<FlatCurveEditor*>(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_SAT")));
sshape->setBottomBarBgGradient(bottomMilestones);
//sshape->setLeftBarColorProvider(this); Not working yet
sshape->setCurveColorProvider(this);
vshape = static_cast<FlatCurveEditor*>(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_VAL")));
vshape->setBottomBarBgGradient(bottomMilestones);
//vshape->setLeftBarColorProvider(this); Not working yet
vshape->setCurveColorProvider(this);
// This will add the reset button at the end of the curveType buttons
curveEditorG->curveListComplete();

View File

@ -18,15 +18,18 @@
*/
#include "labcurve.h"
#include <iomanip>
#include "../rtengine/improcfun.h"
using namespace rtengine;
using namespace rtengine::procparams;
LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) {
brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100, 100, 1, 0));
contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100, 100, 1, 0));
saturation = Gtk::manage (new Adjuster (M("TP_LABCURVE_SATURATION"), -100, 100, 1, 5));
std::vector<GradientMilestone> bottomMilestones;
brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.));
contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.));
chromaticity = Gtk::manage (new Adjuster (M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.));
pack_start (*brightness);
brightness->show ();
@ -34,12 +37,12 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) {
pack_start (*contrast);
contrast->show ();
pack_start (*saturation);
saturation->show ();
pack_start (*chromaticity);
chromaticity->show ();
brightness->setAdjusterListener (this);
contrast->setAdjusterListener (this);
saturation->setAdjusterListener (this);
chromaticity->setAdjusterListener (this);
//%%%%%%%%%%%%%%%%%%
pack_start (*Gtk::manage (new Gtk::HSeparator()));
@ -48,24 +51,17 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) {
bwtoning->set_tooltip_markup (M("TP_LABCURVE_BWTONING_TIP"));
pack_start (*bwtoning);
avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORCLIP")));
avoidcolorshift = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORSHIFT")));
avoidcolorshift->set_tooltip_text (M("TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP"));
pack_start (*avoidcolorshift, Gtk::PACK_SHRINK, 4);
rstprotection = Gtk::manage ( new Adjuster (M("TP_LABCURVE_RSTPROTECTION"), 0., 100., 0.1, 0.) );
pack_start (*rstprotection);
rstprotection->show ();
pack_start (*avoidclip);
pack_start (*Gtk::manage (new Gtk::HSeparator()));
enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_ENABLESATLIMITER")));
pack_start (*enablelimiter);
saturationlimiter = Gtk::manage ( new Adjuster (M("TP_LABCURVE_SATLIMIT"), 0, 100, 1.0, 50) );
pack_start (*saturationlimiter);
saturationlimiter->show ();
saturationlimiter->reference ();
//saturation->setAdjusterListener (this);
saturationlimiter->setAdjusterListener (this);
rstprotection->setAdjusterListener (this);
bwtconn= bwtoning->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::bwtoning_toggled) );
acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidclip_toggled) );
elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::enablelimiter_toggled) );
acconn = avoidcolorshift->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidcolorshift_toggled) );
//%%%%%%%%%%%%%%%%%%%
Gtk::HSeparator *hsep3 = Gtk::manage (new Gtk::HSeparator());
@ -74,17 +70,52 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) {
curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir);
curveEditorG->setCurveListener (this);
curveEditorG->setColorProvider (this);
ccshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CC")));
ccshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP"));
ccshape->setRangeLabels(
M("TP_LABCURVE_CURVEEDITOR_CC_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE2"),
M("TP_LABCURVE_CURVEEDITOR_CC_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE4")
);
ccshape->setRangeDefaultMilestones(0.05, 0.2, 0.58);
//cbgshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CBG"));
//cbgshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CBG_TOOLTIP"));
// -0.1 rad < Hue < 1.6 rad
for (int i=0; i<7; i++) {
float R, G, B;
float x = float(i)*(1.0f/6.0);
Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B);
bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) );
}
chshape = static_cast<FlatCurveEditor*>(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_CH")));
chshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP"));
chshape->setBottomBarBgGradient(bottomMilestones);
chshape->setCurveColorProvider(this);
curveEditorG->newLine();
bottomMilestones.clear();
bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) );
bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) );
lshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, "L"));
lshape->setBottomBarBgGradient(bottomMilestones);
lshape->setLeftBarBgGradient(bottomMilestones);
ashape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, "a"));
ashape->setRangeLabels(
M("TP_LABCURVE_CURVEEDITOR_A_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE2"),
M("TP_LABCURVE_CURVEEDITOR_A_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE4")
);
bshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, "b"));
bshape->setRangeLabels(
M("TP_LABCURVE_CURVEEDITOR_B_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE2"),
M("TP_LABCURVE_CURVEEDITOR_B_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE4")
);
// This will add the reset button at the end of the curveType buttons
curveEditorG->curveListComplete();
pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4);
}
LCurve::~LCurve () {
@ -98,53 +129,63 @@ void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) {
if (pedited) {
brightness->setEditedState (pedited->labCurve.brightness ? Edited : UnEdited);
contrast->setEditedState (pedited->labCurve.contrast ? Edited : UnEdited);
saturation->setEditedState (pedited->labCurve.saturation ? Edited : UnEdited);
chromaticity->setEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited);
//%%%%%%%%%%%%%%%%%%%%%%
saturationlimiter->setEditedState (pedited->labCurve.saturationlimit ? Edited : UnEdited);
rstprotection->setEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited);
bwtoning->set_inconsistent (!pedited->labCurve.bwtoning);
avoidclip->set_inconsistent (!pedited->labCurve.avoidclip);
enablelimiter->set_inconsistent (!pedited->labCurve.enable_saturationlimiter);
avoidcolorshift->set_inconsistent (!pedited->labCurve.avoidcolorshift);
//%%%%%%%%%%%%%%%%%%%%%%
lshape->setUnChanged (!pedited->labCurve.lcurve);
ashape->setUnChanged (!pedited->labCurve.acurve);
bshape->setUnChanged (!pedited->labCurve.bcurve);
lshape->setUnChanged (!pedited->labCurve.lcurve);
ashape->setUnChanged (!pedited->labCurve.acurve);
bshape->setUnChanged (!pedited->labCurve.bcurve);
ccshape->setUnChanged (!pedited->labCurve.cccurve);
chshape->setUnChanged (!pedited->labCurve.chcurve);
//cbgshape->setUnChanged (!pedited->labCurve.cbgcurve);
}
else {
//if bwtoning is enabled, chromaticity value, avoid color shift and rstprotection has no effect
//ccshape->set_sensitive(!(!pp->labCurve.bwtoning));
//chshape->set_sensitive(!(!pp->labCurve.bwtoning));
chromaticity->set_sensitive(!pp->labCurve.bwtoning);
rstprotection->set_sensitive( !pp->labCurve.bwtoning && pp->labCurve.chromaticity!=0 );
avoidcolorshift->set_sensitive(!pp->labCurve.bwtoning);
}
brightness->setValue (pp->labCurve.brightness);
contrast->setValue (pp->labCurve.contrast);
saturation->setValue (pp->labCurve.saturation);
chromaticity->setValue (pp->labCurve.chromaticity);
//%%%%%%%%%%%%%%%%%%%%%%
saturationlimiter->setValue (pp->labCurve.saturationlimit);
rstprotection->setValue (pp->labCurve.rstprotection);
bwtconn.block (true);
acconn.block (true);
bwtoning->set_active (pp->labCurve.bwtoning);
saturation->set_sensitive(!(bwtoning->get_active ())); //at bwtoning enabled saturation value has no effect
avoidclip->set_active (pp->labCurve.avoidclip);
avoidcolorshift->set_active (pp->labCurve.avoidcolorshift);
bwtconn.block (false);
acconn.block (false);
elconn.block (true);
enablelimiter->set_active (pp->labCurve.enable_saturationlimiter);
elconn.block (false);
//removeIfThere (this, saturationlimiter, false);
// if (enablelimiter->get_active () || enablelimiter->get_inconsistent())
// pack_start (*saturationlimiter);
lastBWTVal = pp->labCurve.bwtoning;
lastACVal = pp->labCurve.avoidclip;
lastELVal = pp->labCurve.enable_saturationlimiter;
lastACVal = pp->labCurve.avoidcolorshift;
//%%%%%%%%%%%%%%%%%%%%%%
lshape->setCurve (pp->labCurve.lcurve);
ashape->setCurve (pp->labCurve.acurve);
bshape->setCurve (pp->labCurve.bcurve);
lshape->setCurve (pp->labCurve.lcurve);
ashape->setCurve (pp->labCurve.acurve);
bshape->setCurve (pp->labCurve.bcurve);
ccshape->setCurve (pp->labCurve.cccurve);
chshape->setCurve (pp->labCurve.chcurve);
//cbgshape->setCurve (pp->labCurve.cbgcurve);
// Open up the first curve if selected
bool active = lshape->openIfNonlinear();
if (!active) ashape->openIfNonlinear();
if (!active) bshape->openIfNonlinear();
if (!active) ccshape->openIfNonlinear();
if (!active) chshape->openIfNonlinear();
queue_draw();
enableListener ();
}
@ -153,34 +194,38 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) {
pp->labCurve.brightness = brightness->getValue ();
pp->labCurve.contrast = (int)contrast->getValue ();
pp->labCurve.saturation = (int)saturation->getValue ();
pp->labCurve.chromaticity = (int)chromaticity->getValue ();
//%%%%%%%%%%%%%%%%%%%%%%
pp->labCurve.bwtoning = bwtoning->get_active ();
pp->labCurve.avoidclip = avoidclip->get_active ();
pp->labCurve.enable_saturationlimiter = enablelimiter->get_active ();
pp->labCurve.saturationlimit = saturationlimiter->getValue ();
pp->labCurve.bwtoning = bwtoning->get_active ();
pp->labCurve.avoidcolorshift = avoidcolorshift->get_active ();
pp->labCurve.rstprotection = rstprotection->getValue ();
//%%%%%%%%%%%%%%%%%%%%%%
pp->labCurve.lcurve = lshape->getCurve ();
pp->labCurve.acurve = ashape->getCurve ();
pp->labCurve.bcurve = bshape->getCurve ();
pp->labCurve.lcurve = lshape->getCurve ();
pp->labCurve.acurve = ashape->getCurve ();
pp->labCurve.bcurve = bshape->getCurve ();
pp->labCurve.cccurve = ccshape->getCurve ();
pp->labCurve.chcurve = chshape->getCurve ();
//pp->labCurve.cbgcurve = cbgshape->getCurve ();
if (pedited) {
pedited->labCurve.brightness = brightness->getEditedState ();
pedited->labCurve.contrast = contrast->getEditedState ();
pedited->labCurve.saturation = saturation->getEditedState ();
pedited->labCurve.brightness = brightness->getEditedState ();
pedited->labCurve.contrast = contrast->getEditedState ();
pedited->labCurve.chromaticity = chromaticity->getEditedState ();
//%%%%%%%%%%%%%%%%%%%%%%
pedited->labCurve.bwtoning = !bwtoning->get_inconsistent();
pedited->labCurve.avoidclip = !avoidclip->get_inconsistent();
pedited->labCurve.enable_saturationlimiter = !enablelimiter->get_inconsistent();
pedited->labCurve.saturationlimit = saturationlimiter->getEditedState ();
pedited->labCurve.bwtoning = !bwtoning->get_inconsistent();
pedited->labCurve.avoidcolorshift = !avoidcolorshift->get_inconsistent();
pedited->labCurve.rstprotection = rstprotection->getEditedState ();
//%%%%%%%%%%%%%%%%%%%%%%
pedited->labCurve.lcurve = !lshape->isUnChanged ();
pedited->labCurve.acurve = !ashape->isUnChanged ();
pedited->labCurve.bcurve = !bshape->isUnChanged ();
pedited->labCurve.cccurve = !ccshape->isUnChanged ();
pedited->labCurve.chcurve = !chshape->isUnChanged ();
//pedited->labCurve.cbgcurve = !bshape->isUnChanged ();
}
}
@ -188,46 +233,46 @@ void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedit
brightness->setDefault (defParams->labCurve.brightness);
contrast->setDefault (defParams->labCurve.contrast);
saturation->setDefault (defParams->labCurve.saturation);
saturationlimiter->setDefault (defParams->labCurve.saturationlimit);
chromaticity->setDefault (defParams->labCurve.chromaticity);
rstprotection->setDefault (defParams->labCurve.rstprotection);
if (pedited) {
brightness->setDefaultEditedState (pedited->labCurve.brightness ? Edited : UnEdited);
contrast->setDefaultEditedState (pedited->labCurve.contrast ? Edited : UnEdited);
saturation->setDefaultEditedState (pedited->labCurve.saturation ? Edited : UnEdited);
saturationlimiter->setDefaultEditedState (pedited->labCurve.saturationlimit ? Edited : UnEdited);
chromaticity->setDefaultEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited);
rstprotection->setDefaultEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited);
}
else {
brightness->setDefaultEditedState (Irrelevant);
contrast->setDefaultEditedState (Irrelevant);
saturation->setDefaultEditedState (Irrelevant);
saturationlimiter->setDefaultEditedState (Irrelevant);
chromaticity->setDefaultEditedState (Irrelevant);
rstprotection->setDefaultEditedState (Irrelevant);
}
}
//%%%%%%%%%%%%%%%%%%%%%%
//Clipping control changed
void LCurve::avoidclip_toggled () {
//Color shift control changed
void LCurve::avoidcolorshift_toggled () {
if (batchMode) {
if (avoidclip->get_inconsistent()) {
avoidclip->set_inconsistent (false);
if (avoidcolorshift->get_inconsistent()) {
avoidcolorshift->set_inconsistent (false);
acconn.block (true);
avoidclip->set_active (false);
avoidcolorshift->set_active (false);
acconn.block (false);
}
else if (lastACVal)
avoidclip->set_inconsistent (true);
lastACVal = avoidclip->get_active ();
avoidcolorshift->set_inconsistent (true);
lastACVal = avoidcolorshift->get_active ();
}
if (listener) {
if (avoidclip->get_active ())
listener->panelChanged (EvLAvoidClip, M("GENERAL_ENABLED"));
if (avoidcolorshift->get_active ())
listener->panelChanged (EvLAvoidColorShift, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvLAvoidClip, M("GENERAL_DISABLED"));
listener->panelChanged (EvLAvoidColorShift, M("GENERAL_DISABLED"));
}
}
@ -247,8 +292,13 @@ void LCurve::bwtoning_toggled () {
lastBWTVal = bwtoning->get_active ();
}
saturation->set_sensitive(!(bwtoning->get_active ())); //at bwtoning enabled saturation value has no effect
else {
//ccshape->set_sensitive(!(!pp->labCurve.bwtoning));
//chshape->set_sensitive(!(!pp->labCurve.bwtoning));
chromaticity->set_sensitive( !(bwtoning->get_active ()) );
rstprotection->set_sensitive( !(bwtoning->get_active ()) && chromaticity->getIntValue()!=0 );
avoidcolorshift->set_sensitive( !(bwtoning->get_active ()) );
}
if (listener) {
if (bwtoning->get_active ())
@ -258,35 +308,8 @@ void LCurve::bwtoning_toggled () {
}
}
void LCurve::enablelimiter_toggled () {
if (batchMode) {
if (enablelimiter->get_inconsistent()) {
enablelimiter->set_inconsistent (false);
elconn.block (true);
enablelimiter->set_active (false);
elconn.block (false);
}
else if (lastELVal)
enablelimiter->set_inconsistent (true);
lastELVal = enablelimiter->get_active ();
}
//removeIfThere (this, saturationlimiter, false);
//if (enablelimiter->get_active () || enablelimiter->get_inconsistent())
// pack_start (*saturationlimiter);
if (listener) {
if (enablelimiter->get_active ())
listener->panelChanged (EvLSatLimiter, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvLSatLimiter, M("GENERAL_DISABLED"));
}
}
//%%%%%%%%%%%%%%%%%%%%%%
/*
* Curve listener
*
@ -296,13 +319,19 @@ void LCurve::enablelimiter_toggled () {
void LCurve::curveChanged (CurveEditor* ce) {
if (listener) {
if (ce == lshape)
listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == ashape)
listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == bshape)
listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE"));
}
if (ce == lshape)
listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == ashape)
listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == bshape)
listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == ccshape)
listener->panelChanged (EvLCCCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == chshape)
listener->panelChanged (EvLCHCurve, M("HISTORY_CUSTOMCURVE"));
//if (ce == cbgshape)
// listener->panelChanged (EvLCBGCurve, M("HISTORY_CUSTOMCURVE"));
}
}
void LCurve::adjusterChanged (Adjuster* a, double newval) {
@ -313,7 +342,7 @@ void LCurve::adjusterChanged (Adjuster* a, double newval) {
Glib::ustring costr;
if (a==brightness)
costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
else if (a==saturationlimiter)
else if (a==rstprotection)
costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(1), a->getValue());
else
costr = Glib::ustring::format ((int)a->getValue());
@ -322,10 +351,14 @@ void LCurve::adjusterChanged (Adjuster* a, double newval) {
listener->panelChanged (EvLBrightness, costr);
else if (a==contrast)
listener->panelChanged (EvLContrast, costr);
else if (a==saturation)
else if (a==chromaticity) {
if (!batchMode) {
rstprotection->set_sensitive( !(bwtoning->get_active ()) && chromaticity->getIntValue()!=0 );
}
listener->panelChanged (EvLSaturation, costr);
else if (a==saturationlimiter)
listener->panelChanged (EvLSatLimit, costr);
}
else if (a==rstprotection)
listener->panelChanged (EvLRSTProtection, costr);
}
void LCurve::colorForValue (double valX, double valY) {
@ -348,6 +381,22 @@ void LCurve::colorForValue (double valX, double valY) {
green = (double)valY;
blue = (double)valY;
}
else if (ce == ccshape) { // c = f(c)
red = (double)valY;
green = (double)valY;
blue = (double)valY;
}
else if (ce == chshape) { // c = f(h)
float r, g, b;
Color::hsv2rgb01(float(valX), float(valY), 0.5f, r, g, b);
red = double(r);
green = double(g);
blue = double(b);
}
else {
printf("Error: no curve displayed!\n");
}
@ -356,31 +405,31 @@ void LCurve::colorForValue (double valX, double valY) {
void LCurve::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
brightness->showEditedCB ();
contrast->showEditedCB ();
saturation->showEditedCB ();
saturationlimiter->showEditedCB ();
ToolPanel::setBatchMode (batchMode);
brightness->showEditedCB ();
contrast->showEditedCB ();
chromaticity->showEditedCB ();
rstprotection->showEditedCB ();
curveEditorG->setBatchMode (batchMode);
curveEditorG->setBatchMode (batchMode);
}
void LCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){
lshape->updateBackgroundHistogram (histLCurve);
lshape->updateBackgroundHistogram (histLCurve);
}
void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) {
brightness->setAddMode(bradd);
contrast->setAddMode(contradd);
saturation->setAddMode(satadd);
chromaticity->setAddMode(satadd);
}
void LCurve::trimValues (rtengine::procparams::ProcParams* pp) {
brightness->trimValue(pp->labCurve.brightness);
contrast->trimValue(pp->labCurve.contrast);
saturation->trimValue(pp->labCurve.saturation);
chromaticity->trimValue(pp->labCurve.chromaticity);
}

View File

@ -29,23 +29,24 @@
class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider {
protected:
CurveEditorGroup* curveEditorG;
CurveEditorGroup* curveEditorG;
Adjuster* brightness;
Adjuster* contrast;
Adjuster* saturation;
DiagonalCurveEditor* lshape;
DiagonalCurveEditor* ashape;
DiagonalCurveEditor* bshape;
//%%%%%%%%%%%%%%%%
Gtk::CheckButton* avoidclip;
Gtk::CheckButton* enablelimiter;
Adjuster* chromaticity;
DiagonalCurveEditor* lshape;
DiagonalCurveEditor* ashape;
DiagonalCurveEditor* bshape;
DiagonalCurveEditor* ccshape;
//DiagonalCurveEditor* cbgshape;
FlatCurveEditor* chshape;
//%%%%%%%%%%%%%%%%
Gtk::CheckButton* avoidcolorshift;
Gtk::CheckButton* bwtoning;
Adjuster* saturationlimiter;
bool cbAdd;
sigc::connection bwtconn, acconn, elconn;
bool lastBWTVal, lastACVal, lastELVal;
//%%%%%%%%%%%%%%%%
Adjuster* rstprotection;
sigc::connection bwtconn, acconn;
bool lastBWTVal, lastACVal;
//%%%%%%%%%%%%%%%%
public:
@ -61,8 +62,7 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPan
void curveChanged (CurveEditor* ce);
void adjusterChanged (Adjuster* a, double newval);
void avoidclip_toggled ();
void enablelimiter_toggled ();
void avoidcolorshift_toggled ();
void bwtoning_toggled();
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);

View File

@ -24,17 +24,21 @@
MyCurve::MyCurve () : listener(NULL) {
cursor_type = CSArrow;
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
prevInnerHeight = innerHeight;
graphX = get_allocation().get_width() - RADIUS * 2;
graphY = get_allocation().get_height() - RADIUS * 2;
prevGraphW = graphW;
prevGraphH = graphH;
buttonPressed = false;
snapTo = ST_None;
leftBar = NULL;
bottomBar = NULL;
colorProvider = NULL;
sized = RS_Pending;
snapToElmt = -100;
set_extension_events(Gdk::EXTENSION_EVENTS_ALL);
add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK);
signal_style_changed().connect( sigc::mem_fun(*this, &MyCurve::styleChanged) );
mcih = new MyCurveIdleHelper;
mcih->myCurve = this;
@ -50,6 +54,28 @@ MyCurve::~MyCurve () {
delete mcih;
}
int MyCurve::calcDimensions () {
int newRequestedW, newRequestedH;
newRequestedW = newRequestedH = get_allocation().get_width();
if (leftBar && !bottomBar)
newRequestedH -= CBAR_WIDTH + CBAR_MARGIN - RADIUS;
if (!leftBar && bottomBar)
newRequestedH += CBAR_WIDTH + CBAR_MARGIN - RADIUS;
graphW = newRequestedW - RADIUS - (leftBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS);
graphH = newRequestedH - RADIUS - (bottomBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS);
graphX = newRequestedW - RADIUS - graphW;
graphY = RADIUS + graphH;
return newRequestedH;
}
void MyCurve::setColoredBar (ColoredBar *left, ColoredBar *bottom) {
leftBar = left;
bottomBar = bottom;
}
void MyCurve::notifyListener () {
if (listener)
@ -68,3 +94,9 @@ bool MyCurve::snapCoordinate(double testedVal, double realVal) {
}
return false;
}
void MyCurve::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
setDirty(true);
queue_draw ();
}

View File

@ -23,10 +23,13 @@
#include <vector>
#include "curvelistener.h"
#include "cursormanager.h"
#include "colorprovider.h"
#include "coloredbar.h"
#include "../rtengine/LUT.h"
#include "guiutils.h"
#define RADIUS 3 /* radius of the control points */
#define CBAR_WIDTH 10 /* width of the colored bar (border included) */
#define CBAR_MARGIN 2 /* spacing between the colored bar and the graph */
#define SQUARE 2 /* half length of the square shape of the tangent handles */
#define MIN_DISTANCE 5 /* min distance between control points */
#define GRAPH_SIZE 200 /* size of the curve editor graphic */
@ -51,24 +54,24 @@ enum ResizeState {
class MyCurveIdleHelper;
class MyCurve : public Gtk::DrawingArea {
class MyCurve : public Gtk::DrawingArea, public BackBuffer {
friend class MyCurveIdleHelper;
protected:
CurveListener* listener;
ColoredBar *leftBar;
ColoredBar *bottomBar;
ColorProvider* colorProvider;
CursorShape cursor_type;
Glib::RefPtr<Gdk::Pixmap> pixmap;
int innerWidth; // inner width of the editor, allocated by the system
int innerHeight; // inner height of the editor, allocated by the system
int prevInnerHeight;// previous inner height of the editor
int graphX, graphY, graphW, graphH; // dimensions of the graphic area, excluding surrounding space for the points of for the colored bar
int prevGraphW, prevGraphH; // previous inner width and height of the editor
Gdk::ModifierType mod_type;
int cursorX; // X coordinate in the graph of the cursor
int cursorY; // Y coordinate in the graph of the cursor
std::vector<Gdk::Point> point;
std::vector<Gdk::Point> upoint;
std::vector<Gdk::Point> lpoint;
std::vector< Point<float> > point;
std::vector< Point<float> > upoint;
std::vector< Point<float> > lpoint;
bool buttonPressed;
/*
* snapToElmt must be interpreted like this:
@ -90,15 +93,20 @@ class MyCurve : public Gtk::DrawingArea {
int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; }
bool snapCoordinate(double testedVal, double realVal);
// return value = new requested height
int calcDimensions ();
public:
MyCurve ();
~MyCurve ();
void setCurveListener (CurveListener* cl) { listener = cl; }
void setColoredBar (ColoredBar *left, ColoredBar *bottom);
void setColorProvider (ColorProvider* cp) { colorProvider = cp; }
void notifyListener ();
void updateBackgroundHistogram (LUTu & hist) {return;} ;
void forceResize() { sized = RS_Force; }
void styleChanged (const Glib::RefPtr<Gtk::Style>& style);
virtual std::vector<double> getPoints () = 0;
virtual void setPoints (const std::vector<double>& p) = 0;
virtual bool handleEvents (GdkEvent* event) = 0;
@ -111,8 +119,7 @@ class MyCurveIdleHelper {
bool destroyed;
int pending;
void clearPixmap () { myCurve->pixmap.clear (); }
void clearPixmap () { myCurve->setDirty(true); }
};
#endif

View File

@ -23,9 +23,10 @@
MyDiagonalCurve::MyDiagonalCurve () : activeParam(-1), bghistvalid(false) {
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
prevInnerHeight = innerHeight;
graphW = get_allocation().get_width() - RADIUS * 2;
graphH = get_allocation().get_height() - RADIUS * 2;
prevGraphW = graphW;
prevGraphH = graphH;
grab_point = -1;
lit_point = -1;
buttonPressed = false;
@ -58,30 +59,30 @@ std::vector<double> MyDiagonalCurve::get_vector (int veclen) {
int active = 0;
int firstact = -1;
for (int i = 0; i < (int)curve.x.size(); ++i)
if (curve.x[i] > prev) {
if (curve.x.at(i) > prev) {
if (firstact < 0)
firstact = i;
prev = curve.x[i];
prev = curve.x.at(i);
++active;
}
// handle degenerate case:
if (active < 2) {
double ry;
if (active > 0)
ry = curve.y[firstact];
ry = curve.y.at(firstact);
else
ry = 0.0;
if (ry < 0.0) ry = 0.0;
if (ry > 1.0) ry = 1.0;
for (int x = 0; x < veclen; ++x)
vector[x] = ry;
vector.at(x) = ry;
return vector;
}
}
// calculate remaining points
std::vector<double> curveDescr = getPoints ();
rtengine::DiagonalCurve* rtcurve = new rtengine::DiagonalCurve (curveDescr, veclen*1.5);
rtengine::DiagonalCurve* rtcurve = new rtengine::DiagonalCurve (curveDescr, veclen*1.2);
std::vector<double> t;
t.resize (veclen);
for (int i = 0; i < veclen; i++)
@ -93,73 +94,89 @@ std::vector<double> MyDiagonalCurve::get_vector (int veclen) {
void MyDiagonalCurve::interpolate () {
prevInnerHeight = innerHeight;
point.resize (innerWidth);
std::vector<double> vector = get_vector (innerWidth);
prevInnerHeight = innerHeight;
for (int i = 0; i < innerWidth; ++i)
point[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5));
prevGraphW = graphW;
prevGraphH = graphH;
int nbPoints = graphW-2;
point.resize (nbPoints);
std::vector<double> vector = get_vector (nbPoints);
for (int i = 0; i < nbPoints; ++i) {
float currX = float(i)/float(nbPoints-1);
point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i)));
}
upoint.clear ();
lpoint.clear ();
if (curve.type==DCT_Parametric && activeParam>0) {
double tmp = curve.x[activeParam-1];
double tmp = curve.x.at(activeParam-1);
if (activeParam>=4) {
upoint.resize(innerWidth);
lpoint.resize(innerWidth);
curve.x[activeParam-1] = 100;
vector = get_vector (innerWidth);
for (int i = 0; i < innerWidth; ++i)
upoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5));
curve.x[activeParam-1] = -100;
vector = get_vector (innerWidth);
for (int i = 0; i < innerWidth; ++i)
lpoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5));
curve.x[activeParam-1] = tmp;
upoint.resize(nbPoints);
lpoint.resize(nbPoints);
curve.x.at(activeParam-1) = 100;
vector = get_vector (nbPoints);
for (int i = 0; i < nbPoints; ++i) {
float currX = float(i)/float(nbPoints-1);
upoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i)));
}
curve.x.at(activeParam-1) = -100;
vector = get_vector (nbPoints);
for (int i = 0; i < nbPoints; ++i) {
float currX = float(i)/float(nbPoints-1);
lpoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i)));
}
curve.x.at(activeParam-1) = tmp;
}
}
}
void MyDiagonalCurve::draw (int handle) {
if (!pixmap)
if (!isDirty()) {
return;
}
Glib::RefPtr<Gdk::Window > win = get_window();
if (!surfaceCreated() || !win)
return;
// re-calculate curve if dimensions changed
if (prevInnerHeight != innerHeight || (int)point.size() != innerWidth)
if (prevGraphW != graphW || prevGraphH != graphH || int(point.size()) != graphW-2)
interpolate ();
Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL;
Glib::RefPtr<Gtk::Style> style = get_style ();
Cairo::RefPtr<Cairo::Context> cr = pixmap->create_cairo_context();
Cairo::RefPtr<Cairo::Context> cr = getContext();
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
// bounding rectangle
// clear background
Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle (0, 0, innerWidth + RADIUS*2, innerHeight + RADIUS*2);
cr->rectangle (0., 0., double(getWidth()), double(getHeight()));
cr->fill ();
// histogram in the background
if (bghistvalid) {
// find highest bin
unsigned int histheight = 0;
unsigned int valMax = 0;
for (int i=0; i<256; i++)
if (bghist[i]>histheight)
histheight = bghist[i];
if (bghist[i]>valMax)
valMax = bghist[i];
// draw histogram
cr->set_line_width (1.0);
double stepSize = (innerWidth-1) / 256.0;
cr->move_to (RADIUS, innerHeight-1+RADIUS);
double stepSize = (graphW-3) / 255.0;
cr->move_to ( double(graphX+1), double(graphY-1) );
c = style->get_fg (Gtk::STATE_INSENSITIVE);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
for (int i=0; i<256; i++) {
double val = bghist[i] * (double)(innerHeight-2) / (double)histheight;
if (val>innerHeight-1)
val = innerHeight-1;
if (i>0)
cr->line_to (i*stepSize+RADIUS, innerHeight-1+RADIUS-val);
double val = double(bghist[i]) * double(graphH-2) / double(valMax);
/*
if (val>graphH-2)
val = graphH-2;
*/
//if (i>0)
cr->line_to (double(graphX)+1.5+double(i)*stepSize, double(graphY-1)-val);
}
cr->line_to (innerWidth-1+RADIUS, innerHeight-1+RADIUS);
cr->line_to (double(graphX)+1.5+255.*stepSize, double(graphY-1));
cr->close_path();
cr->fill ();
}
@ -168,17 +185,17 @@ void MyDiagonalCurve::draw (int handle) {
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->set_antialias (Cairo::ANTIALIAS_NONE);
for (int i = 0; i < 5; i++) { // + 0.5 to align well with f(x)=x so it will cut through the center
cr->move_to (RADIUS, max(0.0, i * (innerHeight + 0.5) / 4) + RADIUS);
cr->line_to (innerWidth + RADIUS, max(0.0,i * (innerHeight + 0.5) / 4) + RADIUS);
cr->move_to (max(0,i * innerWidth / 4) + RADIUS, RADIUS);
cr->line_to (max(0,i * innerWidth / 4) + RADIUS, innerHeight + RADIUS);
for (int i = 0; i < 5; i++) {
// horizontal lines
cr->move_to (double(graphX)+0.5 , double(graphY) - max(0.5, double(graphH*i/4) - 0.5));
cr->rel_line_to (double(graphW-1) , 0.);
// vertical lines
cr->move_to (double(graphX) + max(0.5, double(graphW*i/4) - 0.5), double(graphY));
cr->rel_line_to (0. , double(-graphH+1));
}
cr->stroke ();
// draw f(x)=x line
//c = style->get_light (state);
c = style->get_fg (state);
if (snapToElmt == -2)
cr->set_source_rgb (1.0, 0.0, 0.0);
else
@ -186,8 +203,8 @@ void MyDiagonalCurve::draw (int handle) {
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (RADIUS, innerHeight + RADIUS);
cr->line_to (innerWidth + RADIUS, RADIUS);
cr->move_to (double(graphX)+1.5, double(graphY)-1.5);
cr->rel_line_to (double(graphW-3), double(-graphH+3));
cr->stroke ();
cr->unset_dash ();
@ -197,32 +214,35 @@ void MyDiagonalCurve::draw (int handle) {
// draw upper and lower bounds
if (curve.type==DCT_Parametric && activeParam>0 && lpoint.size()>1 && upoint.size()>1) {
cr->set_source_rgba (0.0, 0.0, 0.0, 0.15);
cr->move_to (upoint[0].get_x(), upoint[0].get_y());
cr->move_to (upoint[0].x, upoint[0].y);
for (int i=1; i<(int)upoint.size(); i++)
cr->line_to (upoint[i].get_x(), upoint[i].get_y());
cr->line_to (lpoint[lpoint.size()-1].get_x(), lpoint[lpoint.size()-1].get_y());
cr->line_to (upoint[i].x, upoint[i].y);
cr->line_to (lpoint[lpoint.size()-1].x, lpoint[lpoint.size()-1].y);
for (int i=(int)lpoint.size()-2; i>=0; i--)
cr->line_to (lpoint[i].get_x(), lpoint[i].get_y());
cr->line_to (upoint[0].get_x(), upoint[0].get_y());
cr->line_to (lpoint[i].x, lpoint[i].y);
cr->line_to (upoint[0].x, upoint[0].y);
cr->fill ();
}
c = style->get_fg (state);
// draw the cage of the NURBS curve
if (curve.type==DCT_NURBS) {
unsigned int nbPoints;
unsigned int nbPoints;
std::valarray<double> ch_ds (1);
ch_ds[0] = 2;
cr->set_dash (ch_ds, 0);
cr->set_line_width (0.75);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
std::vector<double> points = getPoints();
nbPoints = ((int)points.size()-1)/2;
for (unsigned int i = 1; i < nbPoints; i++) {
int pos = i*2+1;
double x1 = ((innerWidth-1) * points[pos-2] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth);
double y1 = innerHeight - ((innerHeight-1) * points[pos-1] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight);
double x2 = ((innerWidth-1) * points[pos] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth);
double y2 = innerHeight - ((innerHeight-1) * points[pos+1] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight);
double x1 = double(graphX)+1.5 + double(graphW-3)*points[pos-2]; // project (curve.x[i], 0, 1, graphW);
double y1 = double(graphY)-1.5 - double(graphH-3)*points[pos-1]; // project (curve.y[i], 0, 1, graphH);
double x2 = double(graphX)+0.5 + double(graphW-3)*points[pos]; // project (curve.x[i], 0, 1, graphW);
double y2 = double(graphY)-1.5 - double(graphH-3)*points[pos+1]; // project (curve.y[i], 0, 1, graphH);
// set the color of the line when the point is snapped to the cage
if (curve.x.size() == nbPoints && snapToElmt >= 1000 && ((i == (snapToElmt-1000)) || (i == (snapToElmt-999))))
@ -234,17 +254,48 @@ void MyDiagonalCurve::draw (int handle) {
cr->stroke ();
}
cr->unset_dash ();
cr->set_line_width (1.0);
}
// draw curve
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->move_to (point[0].get_x(), point[0].get_y());
for (int i=1; i<(int)point.size(); i++)
cr->line_to (point[i].get_x(), point[i].get_y());
cr->move_to (double(point.at(0).x), double(point.at(0).y));
for (int i=1; i<(int)point.size(); i++) {
cr->line_to (double(point.at(i).x), double(point.at(i).y));
}
cr->stroke ();
// draw the left colored bar
if (leftBar) {
// first the background
BackBuffer *bb = this;
leftBar->setDrawRectangle(win, 1, graphY-graphH+1, CBAR_WIDTH-2, graphH-2);
leftBar->expose(bb);
// now the border
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle(0.5, graphY-graphH+0.5, CBAR_WIDTH-1, graphH-1);
cr->stroke();
}
// draw the bottom colored bar
if (bottomBar) {
// first the background
BackBuffer *bb = this;
bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, CBAR_WIDTH-2);
bottomBar->expose(bb);
// now the border
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, CBAR_WIDTH-1 );
cr->stroke();
}
// draw bullets
if (curve.type!=DCT_Parametric)
if (curve.type!=DCT_Parametric) {
c = style->get_fg (state);
for (int i = 0; i < (int)curve.x.size(); ++i) {
if (curve.x[i] == -1) continue;
if (snapToElmt >= 1000) {
@ -261,14 +312,15 @@ void MyDiagonalCurve::draw (int handle) {
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
}
double x = ((innerWidth-1) * curve.x[i] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth);
double y = innerHeight - ((innerHeight-1) * curve.y[i] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight);
double x = double(graphX+1) + double((graphW-2) * curve.x[i]); // project (curve.x[i], 0, 1, graphW);
double y = double(graphY-1) - double((graphH-2) * curve.y[i]); // project (curve.y[i], 0, 1, graphH);
cr->arc (x, y, RADIUS+0.5, 0, 2*M_PI);
cr->fill ();
}
get_window()->draw_drawable (style->get_fg_gc (state), pixmap, 0, 0, 0, 0, innerWidth + RADIUS * 2, innerHeight + RADIUS * 2);
}
setDirty(false);
queue_draw();
}
/*void MyDiagonalCurve::graphSizeRequest (Gtk::Requisition* req) {
@ -287,42 +339,42 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
bool retval = false;
int num = (int)curve.x.size();
/* innerWidth and innerHeight are the size of the graph */
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
/* graphW and graphH are the size of the graph */
calcDimensions();
double minDistanceX = (double)(MIN_DISTANCE) / (double)(innerWidth-1);
double minDistanceY = (double)(MIN_DISTANCE) / (double)(innerHeight-1);
double minDistanceX = double(MIN_DISTANCE) / double(graphW-1);
double minDistanceY = double(MIN_DISTANCE) / double(graphH-1);
if ((innerWidth < 0) || (innerHeight < 0))
if ((graphW < 0) || (graphH < 0))
return false;
switch (event->type) {
case Gdk::CONFIGURE: {
// Happen when the the window is resized
if (sized & (RS_Pending | RS_Force)) {
int size = get_allocation().get_width();
set_size_request(-1, size);
set_size_request(-1, calcDimensions());
sized = RS_Done;
}
if (pixmap)
pixmap.clear ();
retval = true;
break;
}
case Gdk::EXPOSE:
{
Glib::RefPtr<Gdk::Window> win = get_window();
if (sized & (RS_Pending | RS_Force)) {
int size = get_allocation().get_width();
set_size_request(-1, size);
set_size_request(-1, calcDimensions());
}
sized = RS_Pending;
if (!pixmap) {
pixmap = Gdk::Pixmap::create (get_window(), get_allocation().get_width(), get_allocation().get_height());
// setDrawRectangle will allocate the backbuffer Surface
if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height()))
interpolate ();
}
draw (lit_point);
GdkRectangle *rectangle = &(event->expose.area);
copySurface(win, rectangle);
retval = true;
break;
}
case Gdk::BUTTON_PRESS:
snapToElmt = -100;
@ -354,6 +406,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
curve.y[closest_point] = clampedY;
interpolate ();
setDirty(true);
draw (closest_point);
notifyListener ();
}
@ -395,6 +448,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
curve.x.push_back (0);
curve.y.push_back (0);
interpolate ();
setDirty(true);
draw (lit_point);
}
}
@ -406,8 +460,10 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
new_type = CSPlus;
lit_point = -1;
}
if (lit_point != previous_lit_point)
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
}
grab_point = -1;
retval = true;
notifyListener ();
@ -422,6 +478,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
if (grab_point == -1) {
new_type = CSArrow;
lit_point = -1;
setDirty(true);
draw (lit_point);
}
retval = true;
@ -442,7 +499,12 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
// there's no point currently being moved
int previous_lit_point = lit_point;
findClosestPoint();
if (distanceX <= minDistanceX) {
if (cursorX<0 || cursorX>graphW || cursorY<0 || cursorY>graphH) {
// the cursor has left the graph area
new_type = CSArrow;
lit_point = -1;
}
else if (distanceX <= minDistanceX) {
new_type = CSMove;
lit_point = closest_point;
}
@ -450,8 +512,10 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
new_type = CSPlus;
lit_point = -1;
}
if (lit_point != previous_lit_point)
if (lit_point != previous_lit_point) {
setDirty(true);
draw (lit_point);
}
}
else {
// a point is being moved
@ -533,6 +597,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
if (curve.x[grab_point] != prevPosX || curve.y[grab_point] != prevPosY) {
// we recalculate the curve only if we have to
interpolate ();
setDirty(true);
draw (lit_point);
notifyListener ();
}
@ -555,8 +620,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
void MyDiagonalCurve::getCursorPosition(GdkEvent* event) {
int tx, ty;
int prevCursorX, prevCursorY;
double incrementX = 1. / (double)(innerWidth-1);
double incrementY = 1. / (double)(innerHeight-1);
double incrementX = 1. / double(graphW);
double incrementY = 1. / double(graphH);
// getting the cursor position
switch (event->type) {
@ -565,15 +630,15 @@ void MyDiagonalCurve::getCursorPosition(GdkEvent* event) {
get_window()->get_pointer (tx, ty, mod_type);
}
else {
tx = (int)event->button.x;
ty = (int)event->button.y;
tx = int(event->button.x);
ty = int(event->button.y);
mod_type = (Gdk::ModifierType)event->button.state;
}
break;
case (Gdk::BUTTON_PRESS) :
case (Gdk::BUTTON_RELEASE) :
tx = (int)event->button.x;
ty = (int)event->button.y;
tx = int(event->button.x);
ty = int(event->button.y);
mod_type = (Gdk::ModifierType)event->button.state;
break;
default :
@ -585,32 +650,32 @@ void MyDiagonalCurve::getCursorPosition(GdkEvent* event) {
if (grab_point != -1) {
prevCursorX = cursorX;
prevCursorY = cursorY;
}
cursorX = tx - RADIUS;
cursorY = (innerHeight-1) - (ty - RADIUS);
}
cursorX = tx - graphX;
cursorY = graphY - ty;
snapTo = ST_None;
snapTo = ST_None;
// update deltaX/Y if the user drags a point
if (grab_point != -1) {
// set the dragging factor
int control_key = mod_type & GDK_CONTROL_MASK;
int shift_key = mod_type & GDK_SHIFT_MASK;
// update deltaX/Y if the user drags a point
if (grab_point != -1) {
// set the dragging factor
int control_key = mod_type & GDK_CONTROL_MASK;
int shift_key = mod_type & GDK_SHIFT_MASK;
// the increment get smaller if modifier key are used, and "snap to" may be enabled
if (control_key) { incrementX *= 0.05; incrementY *= 0.05; }
if (shift_key) { snapTo = true; }
// the increment get smaller if modifier key are used, and "snap to" may be enabled
if (control_key) { incrementX *= 0.05; incrementY *= 0.05; }
if (shift_key) { snapTo = true; }
deltaX = (double)(cursorX - prevCursorX) * incrementX;
deltaY = (double)(cursorY - prevCursorY) * incrementY;
}
// otherwise set the position of the new point (modifier keys has no effect here)
else {
deltaX = double(cursorX - prevCursorX) * incrementX;
deltaY = double(cursorY - prevCursorY) * incrementY;
}
// otherwise set the position of the new point (modifier keys has no effect here)
else {
double tempCursorX = cursorX * incrementX;
double tempCursorY = cursorY * incrementY;
clampedX = CLAMP (tempCursorX, 0., 1.); // X position of the pointer from the origin of the graph
clampedY = CLAMP (tempCursorY, 0., 1.); // Y position of the pointer from the origin of the graph
}
}
}
@ -630,9 +695,9 @@ void MyDiagonalCurve::findClosestPoint() {
closest_point = i;
}
else if (currDistX == distanceX && currDistY < distanceY) {
// there is more than 1 point for that X coordinate, we select the closest point to the cursor
distanceY = currDistY;
closest_point = i;
// there is more than 1 point for that X coordinate, we select the closest point to the cursor
distanceY = currDistY;
closest_point = i;
}
}
}
@ -647,13 +712,13 @@ std::vector<double> MyDiagonalCurve::getPoints () {
}
}
else {
// the first value gives the type of the curve
// the first value gives the type of the curve
if (curve.type==DCT_Linear)
result.push_back ((double)(DCT_Linear));
result.push_back (double(DCT_Linear));
else if (curve.type==DCT_Spline)
result.push_back ((double)(DCT_Spline));
result.push_back (double(DCT_Spline));
else if (curve.type==DCT_NURBS)
result.push_back ((double)(DCT_NURBS));
result.push_back (double(DCT_NURBS));
// then we push all the points coordinate
for (int i=0; i<(int)curve.x.size(); i++) {
if (curve.x[i]>=0) {
@ -672,32 +737,32 @@ void MyDiagonalCurve::setPoints (const std::vector<double>& p) {
if (t==DCT_Parametric) {
curve.x.clear ();
curve.y.clear ();
for (int i=1; i<(int)p.size(); i++)
for (size_t i=1; i<p.size(); i++)
curve.x.push_back (p[ix++]);
}
else {
curve.x.clear ();
curve.y.clear ();
for (int i=0; i<(int)p.size()/2; i++) {
for (size_t i=0; i<p.size()/2; i++) {
curve.x.push_back (p[ix++]);
curve.y.push_back (p[ix++]);
}
activeParam = -1;
}
pixmap.clear ();
setDirty(true);
queue_draw ();
}
void MyDiagonalCurve::setType (DiagonalCurveType t) {
curve.type = t;
pixmap.clear ();
setDirty(true);
}
void MyDiagonalCurve::setActiveParam (int ac) {
activeParam = ac;
pixmap.clear ();
setDirty(true);
queue_draw ();
}
@ -723,7 +788,7 @@ int diagonalmchistupdateUI (void* data) {
}
void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) {
if (hist) {
//memcpy (bghist, hist, 256*sizeof(unsigned int));
for (int i=0; i<256; i++) bghist[i]=hist[i];
@ -739,26 +804,25 @@ void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) {
}
void MyDiagonalCurve::reset() {
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
switch (curve.type) {
case DCT_Spline :
case DCT_NURBS :
curve.x.clear();
curve.y.clear();
curve.x.push_back(0.);
curve.y.push_back(0.);
curve.x.push_back(1.);
curve.y.push_back(1.);
grab_point = -1;
lit_point = -1;
switch (curve.type) {
case DCT_Spline :
case DCT_NURBS :
curve.x.clear();
curve.y.clear();
curve.x.push_back(0.);
curve.y.push_back(0.);
curve.x.push_back(1.);
curve.y.push_back(1.);
grab_point = -1;
lit_point = -1;
interpolate ();
break;
case DCT_Parametric :
// Nothing to do (?)
default:
break;
}
draw(-1);
break;
case DCT_Parametric :
// Nothing to do (?)
default:
break;
}
setDirty(true);
draw(-1);
}

View File

@ -23,9 +23,10 @@
MyFlatCurve::MyFlatCurve () {
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
prevInnerHeight = innerHeight;
graphW = get_allocation().get_width() - RADIUS * 2;
graphH = get_allocation().get_height() - RADIUS * 2;
prevGraphW = 0;
prevGraphH = 0;
lit_point = -1;
closest_point = 0;
buttonPressed = false;
@ -49,18 +50,18 @@ MyFlatCurve::MyFlatCurve () {
std::vector<double> MyFlatCurve::get_vector (int veclen) {
// Create the output variable
// Create the output variable
std::vector<double> convertedValues;
// Get the curve control points
std::vector<double> curveDescr = getPoints ();
rtengine::FlatCurve* rtcurve = new rtengine::FlatCurve (curveDescr, periodic, veclen*1.5 > 5000 ? 5000 : veclen*1.5);
rtengine::FlatCurve* rtcurve = new rtengine::FlatCurve (curveDescr, periodic, veclen*1.2 > 5000 ? 5000 : veclen*1.2);
// Create the sample values that will be converted
std::vector<double> samples;
samples.resize (veclen);
for (int i = 0; i < veclen; i++)
samples[i] = (double) i / (veclen - 1.0);
samples.at(i) = (double) i / (veclen - 1.0);
// Converting the values
rtcurve->getVal (samples, convertedValues);
@ -72,114 +73,57 @@ std::vector<double> MyFlatCurve::get_vector (int veclen) {
void MyFlatCurve::interpolate () {
prevInnerHeight = innerHeight;
point.resize (innerWidth+1);
std::vector<double> vector = get_vector (innerWidth+1);
for (int i = 0; i <= innerWidth; ++i)
point[i] = Gdk::Point ((double)RADIUS+0.5 + i, (double)RADIUS+0.5 + (double)innerHeight*(1.-vector[i]));
prevGraphW = graphW;
prevGraphH = graphH;
int nbPoints = graphW-2;
point.resize (nbPoints);
std::vector<double> vector = get_vector (nbPoints);
for (int i = 0; i < int(point.size()); ++i) {
float currX = float(i)/float(nbPoints-1);
point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i)));
}
upoint.clear ();
lpoint.clear ();
/*if (curve.type==FCT_Parametric && activeParam>0) {
double tmp = curve.x[activeParam-1];
if (activeParam>=4) {
upoint.resize(innerWidth);
lpoint.resize(innerWidth);
curve.x[activeParam-1] = 100;
vector = get_vector (innerWidth);
for (int i = 0; i < innerWidth; ++i)
upoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5));
curve.x[activeParam-1] = -100;
vector = get_vector (innerWidth);
for (int i = 0; i < innerWidth; ++i)
lpoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5));
curve.x[activeParam-1] = tmp;
}
}*/
}
void MyFlatCurve::draw () {
if (!pixmap)
if (!isDirty()) {
return;
}
Glib::RefPtr<Gdk::Window> win = get_window();
if (!surfaceCreated() || !win)
return;
// re-calculate curve if dimensions changed
if (prevInnerHeight != innerHeight || (int)point.size() != (innerWidth+1)) {
if (prevGraphW != graphW || prevGraphH != graphH || (int)point.size() != graphW-2)
interpolate ();
}
double innerW = double(graphW-2);
double innerH = double(graphH-2);
Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL;
Glib::RefPtr<Gtk::Style> style = get_style ();
Cairo::RefPtr<Cairo::Context> cr = pixmap->create_cairo_context();
// bounding rectangle
Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle (0, 0, innerWidth+RADIUS*2+1.5, innerHeight+RADIUS*2+1.5);
cr->fill ();
// histogram in the background
/*if (bghistvalid) {
// find highest bin
unsigned int histheight = 0;
for (int i=0; i<256; i++)
if (bghist[i]>histheight)
histheight = bghist[i];
// draw histogram
cr->set_line_width (1.0);
double stepSize = (innerWidth-1) / 256.0;
cr->move_to (RADIUS, innerHeight-1+RADIUS);
c = style->get_fg (Gtk::STATE_INSENSITIVE);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
for (int i=0; i<256; i++) {
double val = bghist[i] * (double)(innerHeight-2) / (double)histheight;
if (val>innerHeight-1)
val = innerHeight-1;
if (i>0)
cr->line_to (i*stepSize+RADIUS, innerHeight-1+RADIUS-val);
}
cr->line_to (innerWidth-1+RADIUS, innerHeight-1+RADIUS);
cr->fill ();
}*/
Cairo::RefPtr<Cairo::Context> cr = getContext();
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
// draw the grid lines:
cr->set_line_width (1.0);
cr->set_antialias (Cairo::ANTIALIAS_NONE);
c = style->get_dark (state);
// clear background
Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle (0, 0, double(getWidth()), double(getHeight()));
cr->fill ();
double x0 = (double)RADIUS-0.5;
double x1 = (double)RADIUS-0.5 + (double)innerWidth + 2.;
double y0 = (double)RADIUS-0.5;
double y1 = (double)RADIUS-0.5 + (double)innerHeight + 2.;
for (int i = 0; i < 5; i++) {
cr->move_to (x0, y0);
cr->line_to (x0, y1);
cr->line_to (x1, y1);
cr->line_to (x1, y0);
cr->line_to (x0, y0);
}
/*for (int i = 0; i < 5; i++) {
double currX = (double)RADIUS-0.5 + (double)i*((double)innerWidth + 2.)/4.;
double currY = (double)RADIUS-0.5 + (double)i*((double)innerHeight + 2.)/4.;
cr->move_to (x0, currY);
cr->line_to (x1, currY);
cr->move_to (currX, y0);
cr->line_to (currX, y1);
}*/
cr->stroke ();
cr->set_line_width (1.0);
// draw f(x)=0.5 line
c = style->get_fg (state);
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (x0, (double)RADIUS+0.5 + (double)innerHeight/2.);
cr->line_to (x1, (double)RADIUS+0.5 + (double)innerHeight/2.);
cr->move_to (double(graphX)+1.5, double(graphY-graphH/2)-0.5);
cr->rel_line_to (double(graphW-3), 0.);
cr->stroke ();
cr->unset_dash ();
@ -188,6 +132,36 @@ void MyFlatCurve::draw () {
cr->set_line_width (1.0);
// draw the left colored bar
if (leftBar) {
// first the background
BackBuffer *bb = this;
leftBar->setDrawRectangle(win, 1, graphY-graphH+1, CBAR_WIDTH-2, graphH-2);
leftBar->expose(bb);
// now the border
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle(0.5, graphY-graphH+0.5, CBAR_WIDTH-1, graphH-1);
cr->stroke();
}
// draw the bottom colored bar
if (bottomBar) {
// first the background
BackBuffer *bb = this;
bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, CBAR_WIDTH-2);
bottomBar->expose(bb);
// now the border
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, CBAR_WIDTH-1 );
cr->stroke();
}
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
// draw the color feedback of the control points
if (colorProvider) {
@ -200,20 +174,18 @@ void MyFlatCurve::draw () {
colorProvider->colorForValue(curve.x[i], 0.5);
cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue);
double x = (double)RADIUS+0.5 + innerWidth*curve.x[i];
if (i == lit_point && editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX)) {
if ( i==lit_point && (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX)) ) {
cr->set_line_width (4.0);
}
cr->move_to (x, (double)RADIUS+0.5);
cr->line_to (x, (double)RADIUS+0.5 + innerHeight);
cr->move_to (double(graphX)+1 + innerW*curve.x[i], double(graphY-1));
cr->rel_line_to (0., -innerH);
cr->stroke ();
cr->set_line_width (1.0);
// draw the lit_point's horizontal line
if (i == lit_point) {
if (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point) || editedHandle==FCT_EditedHandle_CPointUD) {
if ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD) {
if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) {
cr->set_line_width (4.0);
@ -222,49 +194,52 @@ void MyFlatCurve::draw () {
colorProvider->colorForValue(curve.x[i], curve.y[i]);
cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue);
double y = (double)RADIUS+0.5 + (double)innerHeight*(1.-curve.y[lit_point]);
cr->move_to ( RADIUS, y);
cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, y);
cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y[lit_point]);
cr->rel_line_to (innerW, 0.);
cr->stroke ();
}
}
}
}
// endif
cr->set_line_width (1.0);
cr->set_line_width (1.0);
}
else {
cr->set_source_rgb (0.5, 0.0, 0.0);
if (area==(FCT_Area_H|FCT_Area_V|FCT_Area_Point) || editedHandle==FCT_EditedHandle_CPointUD) {
double position;
if ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD ) {
// draw the lit_point's vertical line
if (editedHandle==(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) {
if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) {
cr->set_line_width (2.0);
}
position = (double)RADIUS+0.5 + (double)innerWidth*curve.x[lit_point];
cr->move_to (position, (double)RADIUS+0.5);
cr->line_to (position, (double)RADIUS+0.5 + (double)innerHeight);
cr->move_to (double(graphX)+1 + innerW*curve.x[lit_point], double(graphY-1));
cr->rel_line_to (0., -innerH);
cr->stroke ();
cr->set_line_width (1.0);
// draw the lit_point's horizontal line
if (editedHandle==(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) {
if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) {
cr->set_line_width (2.0);
}
position = (double)RADIUS+0.5 + (double)innerHeight*(1.-curve.y[lit_point]);
cr->move_to ((double)RADIUS+0.5 , position);
cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, position);
cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y[lit_point]);
cr->rel_line_to (innerW, 0.);
cr->stroke ();
cr->set_line_width (1.0);
}
}
double lineMinLength = 1. / innerWidth * SQUARE * 0.9;
cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
// draw the graph's borders:
c = style->get_dark (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle(double(graphX)+0.5, double(graphY)-0.5, double(graphW-1), double(-graphH+1));
cr->stroke ();
double lineMinLength = 1. / graphW * SQUARE * 0.9;
if (lit_point!=-1 && getHandles(lit_point) && curve.x[lit_point]!=-1.) {
double x = (double)RADIUS+0.5 + (double)innerWidth * curve.x[lit_point];
double y = (double)RADIUS+0.5 + (double)innerHeight * (1.-curve.y[lit_point]);
double x = double(graphX+1) + innerW*curve.x[lit_point];
double y = double(graphY) - innerH*curve.y[lit_point];
double x2;
double square;
bool crossingTheFrame;
@ -281,26 +256,22 @@ void MyFlatCurve::draw () {
leftTanX += 1.0;
crossingTheFrame = true;
}
x2 = (double)RADIUS+0.5 + (double)innerWidth * leftTanX;
x2 = double(graphX+1) + innerW*leftTanX;
if (curve.x[lit_point] - leftTanX > lineMinLength || crossingTheFrame) {
// The left tangential vector reappear on the right side
// draw the line
cr->move_to (x, y);
if (crossingTheFrame) {
cr->line_to ((double)RADIUS+0.5, y);
cr->line_to (double(graphX+1), y);
cr->stroke ();
cr->move_to ((double)RADIUS+0.5 + (double)innerWidth, y);
cr->move_to (double(graphX) + innerW, y);
}
cr->line_to (x2, y);
cr->stroke ();
}
// draw tangential knot
square = area == FCT_Area_LeftTan ? SQUARE*2. : SQUARE;
cr->move_to(x2-square, y+square);
cr->line_to(x2+square, y+square);
cr->line_to(x2+square, y-square);
cr->line_to(x2-square, y-square);
cr->line_to(x2-square, y+square);
cr->rectangle(x2-square, y-square, 2.*square, 2.*square);
cr->fill();
// right handle is blue
@ -315,34 +286,31 @@ void MyFlatCurve::draw () {
rightTanX -= 1.0;
crossingTheFrame = true;
}
x2 = (double)RADIUS+0.5 + (double)innerWidth * rightTanX;
x2 = double(graphX+1) +innerW*rightTanX;
if (rightTanX - curve.x[lit_point] > lineMinLength || crossingTheFrame) {
// The left tangential vector reappear on the right side
// draw the line
cr->move_to (x, y);
if (crossingTheFrame) {
cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, y);
cr->line_to (double(graphX) + innerW, y);
cr->stroke ();
cr->move_to ((double)RADIUS+0.5, y);
cr->move_to (double(graphX+1), y);
}
cr->line_to (x2, y);
cr->stroke ();
}
// draw tangential knot
square = area == FCT_Area_RightTan ? SQUARE*2. : SQUARE;
cr->move_to(x2-square, y+square);
cr->line_to(x2+square, y+square);
cr->line_to(x2+square, y-square);
cr->line_to(x2-square, y-square);
cr->line_to(x2-square, y+square);
cr->rectangle(x2-square, y-square, 2.*square, 2.*square);
cr->fill();
}
// draw curve
c = style->get_fg (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->move_to (point[0].get_x(), point[0].get_y());
cr->move_to (point.at(0).x, point.at(0).y);
for (int i=1; i<(int)point.size(); i++)
cr->line_to (point[i].get_x(), point[i].get_y());
cr->line_to (double(point.at(i).x), double(point.at(i).y));
cr->stroke ();
// draw bullets
@ -350,12 +318,12 @@ void MyFlatCurve::draw () {
for (int i = 0; i < (int)curve.x.size(); ++i) {
if (curve.x[i] != -1.) {
if (i == lit_point) {
if (colorProvider) {
if (colorProvider) {
colorProvider->colorForValue(curve.x[i], curve.y[i]);
cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue);
}
else
cr->set_source_rgb (1.0, 0.0, 0.0);
}
else
cr->set_source_rgb (1.0, 0.0, 0.0);
}
else if (i == snapToElmt) {
cr->set_source_rgb (1.0, 0.0, 0.0);
@ -364,8 +332,9 @@ void MyFlatCurve::draw () {
cr->set_source_rgb (0.0, 0.5, 0.0);
else
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
double x = (double)RADIUS+0.5 + (double)innerWidth * curve.x[i]; // project (curve.x[i], 0, 1, innerWidth);
double y = (double)RADIUS+0.5 + (double)innerHeight * (1.-curve.y[i]); // project (curve.y[i], 0, 1, innerHeight);
double x = double(graphX+1) + innerW * curve.x[i]; // project (curve.x[i], 0, 1, graphW);
double y = double(graphY-1) - innerH * curve.y[i]; // project (curve.y[i], 0, 1, graphH);
cr->arc (x, y, (double)RADIUS, 0, 2*M_PI);
cr->fill ();
@ -375,47 +344,32 @@ void MyFlatCurve::draw () {
// draw the left and right tangent handles
if (tanHandlesDisplayed) {
double top, bottom, left, right;
double halfSquareSizeX, halfSquareSizeY;
double halfSquareSizeX = minDistanceX/2.;
double halfSquareSizeY = minDistanceY/2.;
// LEFT handle
halfSquareSizeX = minDistanceX/2.;
halfSquareSizeY = minDistanceY/2.;
//halfSquareSizeX = area == FCT_Area_LeftTan ? minDistanceX : minDistanceX/2.;
//halfSquareSizeY = area == FCT_Area_LeftTan ? minDistanceY : minDistanceY/2.;
top = leftTanHandle.centerY + halfSquareSizeY;
bottom = leftTanHandle.centerY - halfSquareSizeY;
left = leftTanHandle.centerX - halfSquareSizeX;
right = leftTanHandle.centerX + halfSquareSizeX;
// LEFT handle
// yellow
// yellow
cr->set_source_rgb (1.0, 1.0, 0.0);
cr->move_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->rectangle(double(graphX+1) + innerW*(leftTanHandle.centerX-halfSquareSizeX),
double(graphY-1) - innerH*(leftTanHandle.centerY+halfSquareSizeY),
innerW*minDistanceX,
innerW*minDistanceY);
cr->fill();
// RIGHT handle
//halfSquareSizeX = area == FCT_Area_RightTan ? minDistanceX : minDistanceX/2.;
//halfSquareSizeY = area == FCT_Area_RightTan ? minDistanceY : minDistanceY/2.;
top = rightTanHandle.centerY + halfSquareSizeY;
bottom = rightTanHandle.centerY - halfSquareSizeY;
left = rightTanHandle.centerX - halfSquareSizeX;
right = rightTanHandle.centerX + halfSquareSizeX;
// blue
cr->set_source_rgb (0.0, 0.0, 1.0);
cr->move_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom));
cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top));
cr->rectangle(double(graphX+1) + innerW*(rightTanHandle.centerX-halfSquareSizeX),
double(graphY-1) - innerH*(rightTanHandle.centerY+halfSquareSizeY),
innerW*minDistanceX,
innerW*minDistanceY);
cr->fill();
}
get_window()->draw_drawable (style->get_fg_gc (state), pixmap, 0, 0, 0, 0, innerWidth + RADIUS * 2 + 1, innerHeight + RADIUS * 2 + 1);
setDirty(false);
queue_draw();
}
/*
@ -424,46 +378,28 @@ void MyFlatCurve::draw () {
bool MyFlatCurve::getHandles(int n) {
int N = curve.x.size();
double prevX, nextX;
double prevY, nextY;
double prevTan, nextTan;
double x, y, leftTan, rightTan;
double x, leftTan, rightTan;
if (n == -1) return false;
x = curve.x[n];
y = curve.y[n];
leftTan = curve.leftTangent[n];
rightTan = curve.rightTangent[n];
if (!n) {
// first point, the left handle is then computed with the last point's right handle
prevX = curve.x[N-1]-1.0;
prevY = curve.y[N-1];
prevTan = curve.rightTangent[N-1];
nextX = curve.x[n+1];
nextY = curve.y[n+1];
nextTan = curve.leftTangent[n+1];
}
else if (n == N-1) {
// last point, the right handle is then computed with the first point's left handle
prevX = curve.x[n-1];
prevY = curve.y[n-1];
prevTan = curve.rightTangent[n-1];
nextX = curve.x[0]+1.0;
nextY = curve.y[0];
nextTan = curve.leftTangent[0];
}
else {
// last point, the right handle is then computed with the first point's left handle
prevX = curve.x[n-1];
prevY = curve.y[n-1];
prevTan = curve.rightTangent[n-1];
nextX = curve.x[n+1];
nextY = curve.y[n+1];
nextTan = curve.leftTangent[n+1];
}
if (leftTan == 0.0) leftTanX = x;
@ -490,42 +426,42 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
bool retval = false;
int num = (int)curve.x.size();
/* innerWidth and innerHeight are the size of the graph */
innerWidth = get_allocation().get_width() - 2*RADIUS - 1;
innerHeight = get_allocation().get_height() - 2*RADIUS - 1;
/* graphW and graphH are the size of the graph */
calcDimensions();
minDistanceX = (double)(MIN_DISTANCE) / (double)innerWidth;
minDistanceY = (double)(MIN_DISTANCE) / (double)innerHeight;
minDistanceX = double(MIN_DISTANCE) / double(graphW-1);
minDistanceY = double(MIN_DISTANCE) / double(graphH-1);
if ((innerWidth < 0) || (innerHeight < 0))
if ((graphW < 0) || (graphH < 0))
return false;
switch (event->type) {
case Gdk::CONFIGURE: {
// Happen when the the window is resized
if (sized & (RS_Pending | RS_Force)) {
int size = get_allocation().get_width();
set_size_request(-1, size);
set_size_request(-1, calcDimensions());
sized = RS_Done;
}
if (pixmap)
pixmap.clear ();
retval = true;
break;
}
case Gdk::EXPOSE:
{
Glib::RefPtr<Gdk::Window> win = get_window();
if (sized & (RS_Pending | RS_Force)) {
int size = get_allocation().get_width();
set_size_request(-1, size);
set_size_request(-1, calcDimensions());
}
sized = RS_Pending;
if (!pixmap) {
pixmap = Gdk::Pixmap::create (get_window(), get_allocation().get_width(), get_allocation().get_height());
// setDrawRectangle will allocate the backbuffer Surface
if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height()))
interpolate ();
}
draw ();
retval = true;
GdkRectangle *rectangle = &(event->expose.area);
copySurface(win, rectangle);
retval = true;
break;
}
case Gdk::BUTTON_PRESS:
//if (curve.type!=FCT_Parametric) {
@ -569,6 +505,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
curve.rightTangent[closest_point] = 0.35;
interpolate ();
setDirty(true);
draw ();
notifyListener ();
@ -698,8 +635,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
break;
}
if ((lit_point != previous_lit_point) || (prevArea != area))
if ((lit_point != previous_lit_point) || (prevArea != area)) {
setDirty(true);
draw ();
}
retval = true;
//notifyListener ();
}
@ -741,7 +680,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
case (FCT_EditedHandle_None): {
if ((lit_point != -1 && previous_lit_point != lit_point) && area & (FCT_Area_V|FCT_Area_Point)) {
if ((lit_point != -1 && previous_lit_point != lit_point) && (area&(FCT_Area_V|FCT_Area_Point))) {
bool sameSide = false;
@ -821,8 +760,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
break;
}
if ((lit_point != previous_lit_point) || (prevArea != area))
if ((lit_point != previous_lit_point) || (prevArea != area)) {
setDirty(true);
draw ();
}
break;
}
@ -856,6 +797,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
if (curve.leftTangent[lit_point] != prevValue) {
interpolate ();
setDirty(true);
draw ();
notifyListener ();
}
@ -880,6 +822,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
if (curve.rightTangent[lit_point] != prevValue) {
interpolate ();
setDirty(true);
draw ();
notifyListener ();
}
@ -904,6 +847,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
new_type = CSArrow;
lit_point = -1;
tanHandlesDisplayed = false;
setDirty(true);
draw ();
}
retval = true;
@ -1089,6 +1033,7 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
if (curve.x[lit_point] != prevPosX || curve.y[lit_point] != prevPosY) {
// we recompute the curve only if we have to
interpolate ();
setDirty(true);
draw ();
notifyListener ();
}
@ -1098,8 +1043,8 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
void MyFlatCurve::getCursorPosition(GdkEvent* event) {
int tx, ty;
int prevCursorX, prevCursorY;
double incrementX = 1. / (double)innerWidth;
double incrementY = 1. / (double)innerHeight;
double incrementX = 1. / double(graphW);
double incrementY = 1. / double(graphH);
switch (event->type) {
case (Gdk::MOTION_NOTIFY) :
@ -1127,33 +1072,33 @@ void MyFlatCurve::getCursorPosition(GdkEvent* event) {
if (editedHandle != FCT_EditedHandle_None) {
prevCursorX = cursorX;
prevCursorY = cursorY;
}
cursorX = tx - RADIUS;
cursorY = innerHeight - (ty - RADIUS);
}
cursorX = tx - graphX;
cursorY = graphY - ty;
preciseCursorX = cursorX * incrementX;
preciseCursorY = cursorY * incrementY;
preciseCursorX = cursorX * incrementX;
preciseCursorY = cursorY * incrementY;
snapTo = false;
snapTo = false;
// update deltaX/Y if the user drags a point
if (editedHandle != FCT_EditedHandle_None) {
// set the dragging factor
int control_key = mod_type & GDK_CONTROL_MASK;
int shift_key = mod_type & GDK_SHIFT_MASK;
// update deltaX/Y if the user drags a point
if (editedHandle != FCT_EditedHandle_None) {
// set the dragging factor
int control_key = mod_type & GDK_CONTROL_MASK;
int shift_key = mod_type & GDK_SHIFT_MASK;
// the increment get smaller if modifier key are used, and "snap to" may be enabled
if (control_key) { incrementX *= 0.05; incrementY *= 0.05; }
if (shift_key) { snapTo = true; }
// the increment get smaller if modifier key are used, and "snap to" may be enabled
if (control_key) { incrementX *= 0.05; incrementY *= 0.05; }
if (shift_key) { snapTo = true; }
deltaX = (double)(cursorX - prevCursorX) * incrementX;
deltaY = (double)(cursorY - prevCursorY) * incrementY;
}
// otherwise set the position of the new point (modifier keys has no effect here)
else {
deltaX = (double)(cursorX - prevCursorX) * incrementX;
deltaY = (double)(cursorY - prevCursorY) * incrementY;
}
// otherwise set the position of the new point (modifier keys has no effect here)
else {
clampedX = CLAMP (preciseCursorX, 0., 1.); // X position of the pointer from the origin of the graph
clampedY = CLAMP (preciseCursorY, 0., 1.); // Y position of the pointer from the origin of the graph
}
}
}
@ -1235,7 +1180,7 @@ std::vector<double> MyFlatCurve::getPoints () {
}
}
else {*/
// the first value gives the type of the curve
// the first value gives the type of the curve
if (curve.type==FCT_Linear)
result.push_back ((double)(FCT_Linear));
else if (curve.type==FCT_MinMaxCPoints)
@ -1269,47 +1214,47 @@ void MyFlatCurve::setPoints (const std::vector<double>& p) {
curve.rightTangent.push_back (p[ix++]);
}
}
pixmap.clear ();
setDirty(true);
queue_draw ();
}
void MyFlatCurve::setType (FlatCurveType t) {
curve.type = t;
pixmap.clear ();
setDirty(true);
}
void MyFlatCurve::reset() {
innerWidth = get_allocation().get_width() - RADIUS * 2;
innerHeight = get_allocation().get_height() - RADIUS * 2;
calcDimensions();
switch (curve.type) {
case FCT_MinMaxCPoints :
defaultCurve();
lit_point = -1;
switch (curve.type) {
case FCT_MinMaxCPoints :
defaultCurve();
lit_point = -1;
interpolate ();
break;
//case Parametric :
// Nothing to do (?)
default:
break;
}
draw();
break;
//case Parametric :
// Nothing to do (?)
default:
break;
}
setDirty(true);
draw();
}
void MyFlatCurve::defaultCurve () {
curve.x.clear();
curve.y.clear();
curve.x.clear();
curve.y.clear();
curve.leftTangent.clear();
curve.rightTangent.clear();
// Point for RGBCMY colors
for (int i=0; i<6; i++) {
curve.x.push_back((1./6.)*i);
curve.y.push_back(0.5);
curve.leftTangent.push_back(0.35);
curve.rightTangent.push_back(0.35);
curve.x.push_back((1./6.)*i);
curve.y.push_back(0.5);
curve.leftTangent.push_back(0.35);
curve.rightTangent.push_back(0.35);
}
}

View File

@ -155,6 +155,8 @@ void Options::updatePaths() {
lastToneCurvesDir = preferredPath;
if (lastProfilingReferenceDir.empty() || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR))
lastProfilingReferenceDir = preferredPath;
if (lastVibranceCurvesDir.empty() || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR))
lastVibranceCurvesDir = preferredPath;
}
Glib::ustring Options::getPreferredProfilePath() {
@ -371,7 +373,7 @@ void Options::setDefaults () {
0, // ADDSET_PERSPECTIVE
0, // ADDSET_CA
0, // ADDSET_VIGN_AMOUNT
0, // ADDSET_LC_SATURATION
0, // ADDSET_LC_CHROMATICITY
0, // ADDSET_TC_SATURATION
0, // ADDSET_TC_HLCOMPAMOUNT
0, // ADDSET_TC_HLCOMPTHRESH
@ -422,7 +424,10 @@ void Options::setDefaults () {
rtSettings.beta = "BetaRGB";
rtSettings.best = "BestRGB";
rtSettings.verbose = false;
rtSettings.gamutICC = true;
rtSettings.gamutICC = true;
rtSettings.gamutLch = true;
rtSettings.protectred = 60;
rtSettings.protectredh = 0.4;
lastIccDir = rtSettings.iccDirectory;
lastDarkframeDir = rtSettings.darkFramesPath;
@ -437,6 +442,7 @@ void Options::setDefaults () {
lastLabCurvesDir = "";
lastHsvCurvesDir = "";
lastToneCurvesDir = "";
lastVibranceCurvesDir = "";
lastProfilingReferenceDir = "";
}
@ -642,6 +648,9 @@ if (keyFile.has_group ("Color Management")) {
if( keyFile.has_key ("Color Management", "Beta")) rtSettings.beta = keyFile.get_string("Color Management", "Beta");
if( keyFile.has_key ("Color Management", "Best")) rtSettings.best = keyFile.get_string("Color Management", "Best");
if( keyFile.has_key ("Color Management", "Bruce")) rtSettings.bruce = keyFile.get_string("Color Management", "Bruce");
if( keyFile.has_key ("Color Management", "GamutLch")) rtSettings.gamutLch = keyFile.get_boolean("Color Management", "GamutLch");
if( keyFile.has_key ("Color Management", "ProtectRed")) rtSettings.protectred = keyFile.get_integer("Color Management", "ProtectRed");
if( keyFile.has_key ("Color Management", "ProtectRedH")) rtSettings.protectredh = keyFile.get_double("Color Management", "ProtectRedH");
}
if (keyFile.has_group ("Batch Processing")) {
@ -696,6 +705,7 @@ if (keyFile.has_group ("Dialogs")) {
safeDirGet(keyFile, "Dialogs", "LastLabCurvesDir", lastLabCurvesDir);
safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir);
safeDirGet(keyFile, "Dialogs", "LastToneCurvesDir", lastToneCurvesDir);
safeDirGet(keyFile, "Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir);
safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
}
@ -879,6 +889,9 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce);
keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize);
keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC);
keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch);
keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred);
keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh);
Glib::ArrayHandle<int> bab = baBehav;
keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab);
@ -927,6 +940,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir);
keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir);
keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir);
keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir);
keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
FILE *f = safe_g_fopen (fname, "wt");

View File

@ -239,6 +239,7 @@ class Options {
Glib::ustring lastLabCurvesDir;
Glib::ustring lastHsvCurvesDir;
Glib::ustring lastToneCurvesDir;
Glib::ustring lastVibranceCurvesDir;
Glib::ustring lastProfilingReferenceDir;
Options ();

View File

@ -46,16 +46,18 @@ void ParamsEdited::set (bool v) {
labCurve.lcurve = v;
labCurve.acurve = v;
labCurve.bcurve = v;
labCurve.cccurve = v;
labCurve.chcurve = v;
//labCurve.cbgcurve = v;
labCurve.brightness = v;
labCurve.contrast = v;
labCurve.saturation = v;
labCurve.avoidclip = v;
labCurve.enable_saturationlimiter = v;
labCurve.saturationlimit = v;
labCurve.bwtoning =v;
rgbCurves.rcurve = v;
rgbCurves.gcurve = v;
rgbCurves.bcurve = v;
labCurve.chromaticity = v;
labCurve.avoidcolorshift = v;
labCurve.rstprotection = v;
labCurve.bwtoning = v;
rgbCurves.rcurve = v;
rgbCurves.gcurve = v;
rgbCurves.bcurve = v;
sharpening.enabled = v;
sharpening.radius = v;
sharpening.amount = v;
@ -85,6 +87,7 @@ void ParamsEdited::set (bool v) {
vibrance.protectskins = v;
vibrance.avoidcolorshift = v;
vibrance.pastsattog = v;
vibrance.skintonescurve = v;
//colorBoost.amount = v;
//colorBoost.avoidclip = v;
//colorBoost.enable_saturationlimiter = v;
@ -240,12 +243,14 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve;
labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve;
labCurve.bcurve = labCurve.bcurve && p.labCurve.bcurve == other.labCurve.bcurve;
labCurve.cccurve = labCurve.cccurve && p.labCurve.cccurve == other.labCurve.cccurve;
labCurve.chcurve = labCurve.chcurve && p.labCurve.chcurve == other.labCurve.chcurve;
//labCurve.cbgcurve = labCurve.cbgcurve && p.labCurve.cbgcurve == other.labCurve.cbgcurve;
labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness;
labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast;
labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation;
labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip;
labCurve.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter;
labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit;
labCurve.chromaticity = labCurve.chromaticity && p.labCurve.chromaticity == other.labCurve.chromaticity;
labCurve.avoidcolorshift = labCurve.avoidcolorshift && p.labCurve.avoidcolorshift == other.labCurve.avoidcolorshift;
labCurve.rstprotection = labCurve.rstprotection && p.labCurve.rstprotection == other.labCurve.rstprotection;
labCurve.bwtoning = labCurve.bwtoning && p.labCurve.bwtoning == other.labCurve.bwtoning;
rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve;
rgbCurves.gcurve = rgbCurves.gcurve && p.rgbCurves.gcurve == other.rgbCurves.gcurve;
@ -279,6 +284,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
vibrance.protectskins = vibrance.protectskins && p.vibrance.protectskins == other.vibrance.protectskins;
vibrance.avoidcolorshift = vibrance.avoidcolorshift && p.vibrance.avoidcolorshift == other.vibrance.avoidcolorshift;
vibrance.pastsattog = vibrance.pastsattog && p.vibrance.pastsattog == other.vibrance.pastsattog;
vibrance.skintonescurve = vibrance.skintonescurve && p.vibrance.skintonescurve == other.vibrance.skintonescurve;
//colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount;
//colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip;
//colorBoost.enable_saturationlimiter = colorBoost.enable_saturationlimiter && p.colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter;
@ -433,17 +439,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (labCurve.lcurve) toEdit.labCurve.lcurve = mods.labCurve.lcurve;
if (labCurve.acurve) toEdit.labCurve.acurve = mods.labCurve.acurve;
if (labCurve.bcurve) toEdit.labCurve.bcurve = mods.labCurve.bcurve;
if (labCurve.brightness) toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness;
if (labCurve.contrast) toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast;
if (labCurve.saturation) toEdit.labCurve.saturation = dontforceSet && options.baBehav[ADDSET_LC_SATURATION] ? toEdit.labCurve.saturation + mods.labCurve.saturation : mods.labCurve.saturation;
if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip;
if (labCurve.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter;
if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit;
if (labCurve.bwtoning) toEdit.labCurve.bwtoning = mods.labCurve.bwtoning;
if (labCurve.cccurve) toEdit.labCurve.cccurve = mods.labCurve.cccurve;
if (labCurve.chcurve) toEdit.labCurve.chcurve = mods.labCurve.chcurve;
//if (labCurve.cbgcurve) toEdit.labCurve.cbgcurve = mods.labCurve.cbgcurve;
if (labCurve.brightness) toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness;
if (labCurve.contrast) toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast;
if (labCurve.chromaticity) toEdit.labCurve.chromaticity = dontforceSet && options.baBehav[ADDSET_LC_CHROMATICITY] ? toEdit.labCurve.chromaticity + mods.labCurve.chromaticity : mods.labCurve.chromaticity;
if (labCurve.avoidcolorshift) toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift;
if (labCurve.rstprotection) toEdit.labCurve.rstprotection = mods.labCurve.rstprotection;
if (labCurve.bwtoning) toEdit.labCurve.bwtoning = mods.labCurve.bwtoning;
if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve;
if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve;
if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve;
if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve;
if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve;
if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve;
if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled;
if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes;
@ -482,6 +490,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (vibrance.protectskins) toEdit.vibrance.protectskins = mods.vibrance.protectskins;
if (vibrance.avoidcolorshift) toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift;
if (vibrance.pastsattog) toEdit.vibrance.pastsattog = mods.vibrance.pastsattog;
if (vibrance.skintonescurve) toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve;
//if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount;
//if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip;

View File

@ -53,14 +53,16 @@ class LCurveParamsEdited {
public:
bool brightness;
bool contrast;
bool saturation;
bool avoidclip;
bool enable_saturationlimiter;
bool saturationlimit;
bool chromaticity;
bool avoidcolorshift;
bool rstprotection;
bool lcurve;
bool acurve;
bool bcurve;
bool bwtoning;
bool cccurve;
bool chcurve;
//bool cbgcurve;
};
class RGBCurvesParamsEdited {
@ -118,6 +120,7 @@ class VibranceParamsEdited {
bool protectskins;
bool avoidcolorshift;
bool pastsattog;
bool skintonescurve;
};
/*class ColorBoostParamsEdited {
@ -126,7 +129,7 @@ class VibranceParamsEdited {
bool amount;
bool avoidclip;
bool enable_saturationlimiter;
bool saturationlimit;
bool rstprotection;
};*/
class WBParamsEdited {

View File

@ -24,8 +24,6 @@
#include "../rtengine/safegtk.h"
#include "rtimage.h"
extern Glib::ustring argv0;
PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) {
button = thisButton;
hasMenu = false;
@ -140,9 +138,9 @@ void PopUpCommon::show() {
}
void PopUpCommon::setButtonHint() {
Glib::ustring hint = buttonHint.size() ? buttonHint + " " + sItems.at(selected) : sItems.at(selected);
Glib::ustring hint = !buttonHint.empty() ? buttonHint + " " + sItems.at(selected) : sItems.at(selected);
// if (hasMenu) hint += "\n(" + M("POPUPBUTTON_SELECTOPTIONHINT") + ")";
button->set_tooltip_text(hint);
button->set_tooltip_markup(hint);
}
void PopUpCommon::showMenu(GdkEventButton* event) {

View File

@ -2,7 +2,7 @@
#define _PPVERSION_
// This number have to be incremented whenever the PP3 file format is modified
#define PPVERSION 302
#define PPVERSION 303
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
#endif

View File

@ -165,7 +165,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
mi->set_value (behavColumns.label, M("TP_LABCURVE_LABEL"));
appendBehavList (mi, M("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false);
appendBehavList (mi, M("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false);
appendBehavList (mi, M("TP_LABCURVE_SATURATION"), ADDSET_LC_SATURATION, false);
appendBehavList (mi, M("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_SHARPENING_LABEL"));

View File

@ -24,13 +24,26 @@ using namespace rtengine::procparams;
RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) {
std::vector<GradientMilestone> milestones;
curveEditorG = new CurveEditorGroup (options.lastRgbCurvesDir, M("TP_RGBCURVES_CHANNEL"));
curveEditorG->setCurveListener (this);
curveEditorG->setColorProvider (this);
Rshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_RED")));
milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) );
milestones.push_back( GradientMilestone(1.0, 1.0, 0.0, 0.0) );
Rshape->setBottomBarBgGradient(milestones);
Rshape->setLeftBarBgGradient(milestones);
milestones[1].r = 0.0; milestones[1].g = 1.0;
Gshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_GREEN")));
Gshape->setBottomBarBgGradient(milestones);
Gshape->setLeftBarBgGradient(milestones);
milestones[1].g = 0.0; milestones[1].b = 1.0;
Bshape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_BLUE")));
Bshape->setBottomBarBgGradient(milestones);
Bshape->setLeftBarBgGradient(milestones);
// This will add the reset button at the end of the curveType buttons
curveEditorG->curveListComplete();

View File

@ -30,6 +30,7 @@ RTWindow::RTWindow ()
,splash(NULL)
,epanel(NULL)
,fpanel(NULL)
,btn_fullscreen(NULL)
{
cacheMgr->init ();
@ -61,6 +62,7 @@ RTWindow::RTWindow ()
is_fullscreen = false;
property_destroy_with_parent().set_value(false);
signal_window_state_event().connect( sigc::mem_fun(*this, &RTWindow::on_window_state_event) );
signal_key_press_event().connect( sigc::mem_fun(*this, &RTWindow::keyPressed) );
if(simpleEditor)
{
@ -83,7 +85,7 @@ RTWindow::RTWindow ()
mainNB->set_scrollable (true);
mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &RTWindow::on_mainNB_switch_page) );
fpanel = new FilePanel () ;
fpanel = new FilePanel () ;
fpanel->setParent (this);
// decorate tab
@ -147,8 +149,6 @@ RTWindow::RTWindow ()
mainNB->set_current_page (mainNB->page_num (*fpanel));
signal_key_press_event().connect( sigc::mem_fun(*this, &RTWindow::keyPressed) );
Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ());
mainBox->pack_start (*mainNB);
@ -383,6 +383,13 @@ bool RTWindow::keyPressed (GdkEventKey* event) {
bool ctrl = event->state & GDK_CONTROL_MASK;
//bool shift = event->state & GDK_SHIFT_MASK;
if(event->keyval == GDK_F11)
toggle_fullscreen();
if (simpleEditor)
// in simpleEditor mode, there's no other tab that can handle pressed keys, so we can send the event to editor panel then return
return epanel->handleShortcutKey (event);;
if (ctrl) {
switch(event->keyval) {
case GDK_F2: // file browser panel
@ -399,10 +406,6 @@ bool RTWindow::keyPressed (GdkEventKey* event) {
}
}
if(event->keyval == GDK_F11) {
toggle_fullscreen();
}
if (mainNB->get_current_page() == mainNB->page_num(*fpanel)) {
return fpanel->handleShortcutKey (event);
}
@ -410,7 +413,7 @@ bool RTWindow::keyPressed (GdkEventKey* event) {
return false;
}
else {
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
EditorPanel* ep = static_cast<EditorPanel*>(mainNB->get_nth_page (mainNB->get_current_page()));
return ep->handleShortcutKey (event);
}
return false;
@ -500,15 +503,19 @@ void RTWindow::toggle_fullscreen () {
if (is_fullscreen) {
unfullscreen();
is_fullscreen = false;
//btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen);
if (btn_fullscreen) {
//btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen);
}
} else {
fullscreen();
is_fullscreen = true;
//btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen_exit);
if (btn_fullscreen) {
//btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen_exit);
}
}
}

View File

@ -18,14 +18,34 @@
*/
#include "shcselector.h"
#include "multilangmgr.h"
#include <iomanip>
#include "mycurve.h"
SHCSelector::SHCSelector() : movingPosition(-1), cl(NULL) {
SHCSelector::SHCSelector() : ColoredBar(RTO_Left2Right), movingPosition(-1), cl(NULL) {
positions[0] = 0.25;
positions[1] = 0.5;
positions[2] = 0.75;
positions[0] = defaults[0] = 0.25;
positions[1] = defaults[1] = 0.5;
positions[2] = defaults[2] = 0.75;
leftMargin = RADIUS;
rightMargin = RADIUS;
// TODO: This is a hack :) ; change this name to a specific one and create a new entry in all gtkrc theme files
set_name("ThresholdSelector");
set_can_focus(false);
set_size_request (-1, 12);
set_tooltip_text(M("SHCSELECTOR_TOOLTIP"));
}
void SHCSelector::setMargins(int left, int right) {
leftMargin = left;
rightMargin = right;
}
void SHCSelector::setDefaults (double spos, double cpos, double hpos) {
defaults[0] = spos;
defaults[1] = cpos;
defaults[2] = hpos;
}
void SHCSelector::setPositions (double spos, double cpos, double hpos) {
@ -53,46 +73,64 @@ void SHCSelector::on_realize() {
bool SHCSelector::on_expose_event(GdkEventExpose* event) {
Gdk::Color c;
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
int w = get_width () - RADIUS*2;
int w = get_width () - leftMargin - rightMargin;
int h = get_height ();
wslider = h *2.0 / 5.0;
wslider = std::max(int(h / 5), 10);
double hwslider = double(wslider)/2.;
Gdk::Color bgc = get_style()->get_bg (Gtk::STATE_NORMAL);
Gdk::Color fgc = get_style()->get_text (Gtk::STATE_NORMAL);
Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL;
Glib::RefPtr<Gtk::Style> style = get_style();
// clear bg
cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p());
cr->rectangle (0, 0, w, h);
cr->fill();
// draw gradient background
Cairo::RefPtr< Cairo::LinearGradient > bggradient = Cairo::LinearGradient::create (0, 0, w, 0);
bggradient->add_color_stop_rgb (0, 0, 0, 0);
bggradient->add_color_stop_rgb (1, 1, 1, 1);
// set the box's colors
cr->set_line_width (1.0);
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
if (is_sensitive() && canGetColors()) {
// gradient background
Glib::RefPtr<Gdk::Window> win = get_window();
// this will eventually create/update the off-screen pixmap
setDrawRectangle(win, leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f));
// that we're displaying here
ColoredBar::expose(win);
}
else {
// solid background
c = style->get_bg (state);
cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85);
cr->set_line_width (1.0);
cr->set_source (bggradient);
cr->rectangle (0.5+RADIUS, h*2.0/7.0 + 0.5, w-0.5, h*3.0/7.0-0.5);
cr->fill_preserve();
cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p());
cr->stroke ();
// draw the box's background
cr->rectangle (leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f));
cr->fill();
}
// draw the box's borders
cr->set_line_width (1.);
cr->rectangle (leftMargin+0.5, 0.5, w-1, int(float(h)*5.5f/7.f+0.5f)+1);
c = style->get_bg (state);
cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7);
cr->stroke ();
// draw sliders
cr->set_line_width (1.0);
//cr->set_line_width (1.0);
for (int i=0; i<3; i++) {
cr->move_to (RADIUS+w*positions[i]-wslider/2+0.5, h-0.5);
cr->line_to (RADIUS+w*positions[i]-wslider/2+0.5, wslider/2 + 0.5);
cr->line_to (RADIUS+w*positions[i], 0.5);
cr->line_to (RADIUS+w*positions[i]+wslider/2-0.5, wslider/2 + 0.5);
cr->line_to (RADIUS+w*positions[i]+wslider/2-0.5, h-0.5);
cr->line_to (RADIUS+w*positions[i]-wslider/2+0.5, h-0.5);
cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p());
cr->fill_preserve ();
cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p());
cr->stroke ();
cr->move_to (leftMargin+0.5+(w-1)*positions[i]+hwslider, double(h)-0.5);
cr->rel_line_to (0., double(-h/3));
cr->rel_line_to (-hwslider, double(-h/3));
cr->rel_line_to (-hwslider, double(h/3));
cr->rel_line_to (0., double(h/3));
cr->close_path();
// normal
c = style->get_bg (is_sensitive() ? Gtk::STATE_ACTIVE : Gtk::STATE_INSENSITIVE);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->fill_preserve ();
c = style->get_bg (state);
cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7);
cr->stroke ();
}
// draw text for the slider that is being moved
@ -104,21 +142,20 @@ bool SHCSelector::on_expose_event(GdkEventExpose* event) {
int layout_width, layout_height;
Glib::RefPtr<Pango::Layout> layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i]));
layout->get_pixel_size(layout_width, layout_height);
offset = positions[i] > 0.5 ? -layout_width-1-wslider/2 : 1+wslider/2;
cr->move_to (RADIUS+w*positions[i]+offset-0.5, 0);
cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p());
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
cr->move_to (RADIUS+w*positions[i]+offset+0.5, 1);
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p());
cr->move_to (RADIUS+w*positions[i]+offset, 0.5);
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
offset = positions[i] > 0.5 ? -layout_width-1-hwslider : 1+hwslider;
c = style->get_bg (state);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->set_line_width(3.);
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
cr->move_to (leftMargin+w*positions[i]+offset, 0.);
layout->add_to_cairo_context (cr);
cr->stroke_preserve();
c = style->get_fg (Gtk::STATE_PRELIGHT);
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->fill ();
}
return true;
}
@ -126,10 +163,10 @@ bool SHCSelector::on_expose_event(GdkEventExpose* event) {
bool SHCSelector::on_button_press_event (GdkEventButton* event) {
// check if a slider is under the cursor
int w = get_width ();
double w = double(get_width ()-leftMargin-rightMargin);
movingPosition = -1;
for (int i=0; i<3; i++)
if (event->x > w*positions[i]-wslider/2 && event->x < w*positions[i]+wslider/2) {
if (event->x > double(leftMargin)+w*positions[i]-wslider/2. && event->x < double(leftMargin)+w*positions[i]+wslider/2) {
movingPosition = i;
tmpX = event->x;
tmpPos = positions[i];
@ -141,9 +178,21 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event) {
bool SHCSelector::on_button_release_event (GdkEventButton* event) {
if (movingPosition >= 0) {
movingPosition = -1;
queue_draw ();
if (event->button == 1) {
if (movingPosition >= 0) {
movingPosition = -1;
queue_draw ();
}
}
else if (event->button == 3) {
if (movingPosition >= 0)
movingPosition = -1;
// right mouse button reset the selector to the stored default values
if (reset()) {
// rest has modified the values
if (cl)
cl->shcChanged ();
}
}
return true;
}
@ -174,9 +223,17 @@ void SHCSelector::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
queue_draw ();
}
void SHCSelector::reset () { // : movingPosition(-1), cl(NULL) {
positions[0] = 0.25;
positions[1] = 0.5;
positions[2] = 0.75;
queue_draw ();
bool SHCSelector::reset () { // : movingPosition(-1), cl(NULL) {
if ( positions[0] != defaults[0] ||
positions[1] != defaults[1] ||
positions[2] != defaults[2]
) {
positions[0] = defaults[0];
positions[1] = defaults[1];
positions[2] = defaults[2];
queue_draw ();
return true;
}
return false;
}

View File

@ -20,26 +20,34 @@
#define _SHCSELECTOR_
#include <gtkmm.h>
#include "coloredbar.h"
class SHCListener {
public:
virtual ~SHCListener() {}
virtual void shcChanged () {}
};
class SHCSelector : public Gtk::DrawingArea {
class SHCSelector : public Gtk::DrawingArea, public ColoredBar {
protected:
Glib::RefPtr<Gdk::GC> gc_;
Glib::RefPtr<Gdk::Pixmap> backBuffer;
int movingPosition;
double tmpX, tmpPos;
double defaults[3];
double positions[3];
double wslider;
SHCListener* cl;
// left margin, essentially a workaround to take care of an eventual right colored bar (e.g. for curves)
int leftMargin;
// right margin, essentially a workaround to take care of an eventual right colored bar
int rightMargin;
const static int hb = 3; // horizontal border
const static int vb = 2; // vertical border
SHCListener* cl;
public:
@ -47,6 +55,8 @@ class SHCSelector : public Gtk::DrawingArea {
void setSHCListener (SHCListener* l) { cl = l;; }
void setMargins(int left, int right);
void setDefaults (double spos, double cpos, double hpos);
void setPositions (double spos, double cpos, double hpos);
void getPositions (double& spos, double& cpos, double& hpos);
void on_realize();
@ -55,7 +65,7 @@ class SHCSelector : public Gtk::DrawingArea {
bool on_button_release_event (GdkEventButton* event);
bool on_motion_notify_event (GdkEventMotion* event);
void styleChanged (const Glib::RefPtr<Gtk::Style>& style);
void reset ();
bool reset ();
};
#endif

View File

@ -24,7 +24,9 @@
ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom,
double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop,
ThresholdCurveProvider* curveProvider) {
ThresholdCurveProvider* curveProvider)
: ColoredBar(RTO_Left2Right)
{
positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom;
positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop;
positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = 0; // unused
@ -47,7 +49,10 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBotto
initValues ();
}
ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottom, double defTop, unsigned int precision, bool startAtOne) {
ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottom,
double defTop, unsigned int precision, bool startAtOne)
: ColoredBar(RTO_Left2Right)
{
positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom;
positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop;
positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = maxValue;
@ -83,7 +88,10 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de
}
ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft, double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne) {
ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft,
double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne)
: ColoredBar(RTO_Left2Right)
{
positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottomLeft;
positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTopLeft;
positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = defBottomRight;
@ -178,11 +186,6 @@ void ThresholdSelector::setDefaults (double bottomLeft, double topLeft, double b
}
}
void ThresholdSelector::setBgGradient (const std::vector<GradientMilestone> &milestones) {
bgGradient.clear();
bgGradient = milestones;
}
void ThresholdSelector::on_realize() {
Gtk::DrawingArea::on_realize();
@ -202,8 +205,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) {
wslider = std::max(int(h / 5), 10);
int hwslider = wslider/2;
int iw = w-wslider-2*hb; // inner width (excluding padding for tabs)
int iw = w-wslider-2*hb; // inner width (excluding padding for sliders)
positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT);
positions01[TS_TOPLEFT] = to01(TS_TOPLEFT);
@ -216,19 +218,15 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) {
// set the box's colors
cr->set_line_width (1.0);
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
if (is_sensitive() && bgGradient.size()>1) {
if (is_sensitive() && canGetColors()) {
// gradient background
Cairo::RefPtr< Cairo::LinearGradient > bggradient = Cairo::LinearGradient::create (hwslider, 0, hwslider+iw, 0);
for (std::vector<GradientMilestone>::iterator i=bgGradient.begin(); i!=bgGradient.end(); i++) {
bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b);
}
cr->set_source (bggradient);
// draw the box's background
cr->rectangle (hb+hwslider-0.5, double(int(float(h)*1.5f/7.f))+0.5, iw+1, double(int(float(h)*4.f/7.f)));
cr->fill();
Glib::RefPtr<Gdk::Window> win = get_window();
// this will eventually create/update the off-screen Surface
setDrawRectangle(win, hb+hwslider, int(float(h)*1.5f/7.f+0.5f), iw+1, int(float(h)*4.f/7.f+0.5f));
// that we're displaying here
ColoredBar::expose(win);
}
else if (is_sensitive()) {
else {
// solid background
c = style->get_bg (state);
cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85);
@ -314,7 +312,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) {
// draw sliders
//if (!(litCursor == TS_UNDEFINED && movedCursor == TS_UNDEFINED)) {
cr->set_line_width (1.);
//cr->set_line_width (1.);
for (int i=0; i<(doubleThresh?4:2); i++) {
double posX = hb+hwslider+iw*positions01[i]+0.5;
double arrowY = i==0 || i==2 ? h-(h*2.5/7.-0.5)-vb : h*2.5/7.-0.5+vb;
@ -357,35 +355,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) {
}
}
//}
//printf("\n\n");
// draw text for the slider that is being moved
/*
* Original code from shcselector.cc
*
Glib::RefPtr<Pango::Context> context = get_pango_context () ;
cr->set_line_width (0.5);
if (litCursor != TS_UNDEFINED) {
int offset;
int layout_width, layout_height;
Glib::RefPtr<Pango::Layout> layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions01[litCursor]));
layout->get_pixel_size(layout_width, layout_height);
offset = positions01[litCursor] > 0.5 ? -layout_width-1-wslider/2 : 1+wslider/2;
cr->move_to (w*positions01[litCursor]+offset-0.5, 0);
cr->set_source_rgb (bgnc.get_red_p(), bgnc.get_green_p(), bgnc.get_blue_p());
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
cr->move_to (w*positions01[litCursor]+offset+0.5, 1);
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
cr->set_source_rgb (fgnc.get_red_p(), fgnc.get_green_p(), fgnc.get_blue_p());
cr->move_to (w*positions01[litCursor]+offset, 0.5);
layout->add_to_cairo_context (cr);
cr->fill_preserve ();
cr->stroke ();
}*/
return true;
}

View File

@ -21,6 +21,7 @@
#include "guiutils.h"
#include "../rtengine/procparams.h"
#include "coloredbar.h"
#include <iomanip>
class ThresholdSelector;
@ -30,6 +31,7 @@ class ThresholdSelector;
*/
class ThresholdCurveProvider {
public:
virtual ~ThresholdCurveProvider() {};
/*
* The curve provider has to send back a list of point (at least 2 points) in the [0.0 ; 1.0] range
* for both X and Y axis; X and Y values are streamlined ( X1, Y1, X2, Y2, X3, Y3, ...)
@ -57,7 +59,7 @@ class ThresholdCurveProvider {
* have to provide through the
*
*/
class ThresholdSelector : public Gtk::DrawingArea {
class ThresholdSelector : public Gtk::DrawingArea, public ColoredBar {
public:
@ -74,9 +76,6 @@ class ThresholdSelector : public Gtk::DrawingArea {
sigc::signal<void> sig_val_changed;
Glib::RefPtr<Gdk::GC> gc_;
Glib::RefPtr<Gdk::Pixmap> backBuffer;
std::vector<GradientMilestone> bgGradient;
ThresholdCurveProvider* bgCurveProvider;
Glib::ustring additionalTTip;
@ -183,7 +182,6 @@ class ThresholdSelector : public Gtk::DrawingArea {
void setSeparatedSliders(bool separated);
bool getSeparatedSliders();
void setBgGradient (const std::vector<GradientMilestone> &milestones);
void setBgCurveProvider (ThresholdCurveProvider* provider);
bool isStartAtOne() { return initalEq1; }
bool isDouble() { return doubleThresh; }

View File

@ -27,6 +27,10 @@ using namespace rtengine::procparams;
ToneCurve::ToneCurve () : Gtk::VBox(), FoldableToolPanel(this) {
std::vector<GradientMilestone> bottomMilestones;
bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) );
bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) );
//----------- Auto Levels ----------------------------------
abox = Gtk::manage (new Gtk::HBox ());
abox->set_border_width (2);
@ -89,6 +93,9 @@ ToneCurve::ToneCurve () : Gtk::VBox(), FoldableToolPanel(this) {
curveEditorG->setCurveListener (this);
shape = static_cast<DiagonalCurveEditor*>(curveEditorG->addCurve(CT_Diagonal, ""));
shape->setBottomBarBgGradient(bottomMilestones);
shape->setLeftBarBgGradient(bottomMilestones);
// This will add the reset button at the end of the curveType buttons
curveEditorG->curveListComplete();
@ -219,7 +226,9 @@ void ToneCurve::adjusterChanged (Adjuster* a, double newval) {
// Switch off auto exposure if user changes sliders manually
if (autolevels->get_active() && (a==expcomp || a==brightness || a==contrast || a==black || a==hlcompr || a==hlcomprthresh)) {
autoconn.block(true);
autolevels->set_active (false);
autoconn.block(false);
autolevels->set_inconsistent (false);
}
@ -294,35 +303,45 @@ void ToneCurve::autolevels_toggled () {
autolevels->set_inconsistent (true);
lastAuto = autolevels->get_active ();
}
if (!batchMode && autolevels->get_active() && listener) {
listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
waitForAutoExp ();
if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect
}
if (batchMode) {
expcomp->setEditedState (UnEdited);
brightness->setEditedState (UnEdited);
contrast->setEditedState (UnEdited);
brightness->setEditedState (UnEdited);
contrast->setEditedState (UnEdited);
black->setEditedState (UnEdited);
hlcompr->setEditedState (UnEdited);
hlcomprthresh->setEditedState (UnEdited);
if (expcomp->getAddMode())
expcomp->setValue (0);
if (brightness->getAddMode())
if (brightness->getAddMode())
brightness->setValue (0);
if (contrast->getAddMode())
if (contrast->getAddMode())
contrast->setValue (0);
if (black->getAddMode())
if (black->getAddMode())
black->setValue (0);
if (hlcompr->getAddMode())
hlcompr->setValue (0);
hlcompr->setValue (0);
if (hlcomprthresh->getAddMode())
hlcomprthresh->setValue (0);
listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
hlcomprthresh->setValue (0);
if (listener) {
if (!autolevels->get_inconsistent()) {
if (autolevels->get_active ())
listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED"));
}
}
}
else if (/* !batchMode && */ listener) {
if (autolevels->get_active()) {
listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
waitForAutoExp ();
if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect
}
else {
listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED"));
}
}
}
void ToneCurve::clip_changed () {

View File

@ -18,23 +18,33 @@
*/
#include "vibrance.h"
#include "../rtengine/color.h"
#include <iomanip>
using namespace rtengine;
using namespace rtengine::procparams;
Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) {
std::vector<GradientMilestone> milestones;
float R, G, B;
// -0.1 rad < Hue < 1.6 rad
Color::hsv2rgb01(0.92f, 0.45f, 0.6f, R, G, B);
milestones.push_back( GradientMilestone(0.0, double(R), double(G), double(B)) );
Color::hsv2rgb01(0.14056f, 0.45f, 0.6f, R, G, B);
milestones.push_back( GradientMilestone(1.0, double(R), double(G), double(B)) );
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
pack_start(*enabled, Gtk::PACK_SHRINK, 0);
saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100,100,1,50));
saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100.,100.,1.,0.));
saturated->setAdjusterListener (this);
saturated->set_sensitive(false);
//if (saturated->delay < 1000) saturated->delay = 1000;
pack_start( *saturated, Gtk::PACK_SHRINK, 0);
pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100,100,1,50));
pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100.,100.,1.,0.));
pastels->setAdjusterListener (this);
//if (pastels->delay < 1000) pastels->delay = 1000;
pack_start( *pastels, Gtk::PACK_SHRINK, 0);
@ -58,6 +68,22 @@ Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) {
pastSatTog->set_active (true);
pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0);
curveEditorGG = new CurveEditorGroup (options.lastVibranceCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL"));
curveEditorGG->setCurveListener (this);
skinTonesCurve = static_cast<DiagonalCurveEditor*>(curveEditorGG->addCurve(CT_Diagonal, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES")));
skinTonesCurve->setTooltip(M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP"));
skinTonesCurve->setBottomBarBgGradient(milestones);
skinTonesCurve->setLeftBarBgGradient(milestones);
skinTonesCurve->setRangeLabels(
M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2"),
M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4")
);
skinTonesCurve->setRangeDefaultMilestones(0.1, 0.4, 0.85);
curveEditorGG->curveListComplete();
pack_start (*curveEditorGG, Gtk::PACK_SHRINK, 4);
show ();
enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::enabled_toggled) );
@ -66,6 +92,10 @@ Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) {
pastsattogconn = pastSatTog->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::pastsattog_toggled) );
}
Vibrance::~Vibrance () {
delete curveEditorGG;
}
void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
@ -76,7 +106,8 @@ void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) {
psThreshold->setEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited);
protectSkins->set_inconsistent (!pedited->vibrance.protectskins);
avoidColorShift->set_inconsistent (!pedited->vibrance.avoidcolorshift);
pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog);
pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog);
skinTonesCurve->setUnChanged (!pedited->vibrance.skintonescurve);
}
enaconn.block (true);
@ -114,6 +145,8 @@ void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) {
saturated->set_sensitive(true);
saturated->setValue (pp->vibrance.saturated); // Pastels and Saturated are separate
}
skinTonesCurve->setCurve (pp->vibrance.skintonescurve);
skinTonesCurve->openIfNonlinear();
enableListener ();
}
@ -126,6 +159,7 @@ void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) {
pp->vibrance.protectskins = protectSkins->get_active ();
pp->vibrance.avoidcolorshift = avoidColorShift->get_active ();
pp->vibrance.pastsattog = pastSatTog->get_active ();
pp->vibrance.skintonescurve = skinTonesCurve->getCurve ();
if (pedited) {
pedited->vibrance.enabled = !enabled->get_inconsistent();
@ -135,9 +169,14 @@ void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) {
pedited->vibrance.protectskins = !protectSkins->get_inconsistent();
pedited->vibrance.avoidcolorshift = !avoidColorShift->get_inconsistent();
pedited->vibrance.pastsattog = !pastSatTog->get_inconsistent();
pedited->vibrance.skintonescurve = !skinTonesCurve->isUnChanged ();
}
}
void Vibrance::curveChanged () {
if (listener && enabled->get_active()) listener->panelChanged (EvVibranceSkinTonesCurve, M("HISTORY_CUSTOMCURVE"));
}
void Vibrance::enabled_toggled () {
if (batchMode) {
@ -252,8 +291,6 @@ void Vibrance::adjusterChanged (Adjuster* a, double newval) {
else if (a == saturated && !pastSatTog->get_active())
listener->panelChanged (EvVibranceSaturated, value );
}
if (pastSatTog->get_active())
psThreshold->queue_draw();
}
void Vibrance::adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop) {
@ -270,6 +307,8 @@ void Vibrance::setBatchMode(bool batchMode) {
pastels->showEditedCB ();
saturated->showEditedCB ();
psThreshold->showEditedCB ();
curveEditorGG->setBatchMode (batchMode);
}
void Vibrance::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) {
@ -294,6 +333,20 @@ void Vibrance::setAdjusterBehavior (bool pastelsadd, bool saturatedadd, bool pst
saturated->setAddMode (saturatedadd);
}
void Vibrance::colorForValue (double valX, double valY) {
CurveEditor* ce = curveEditorGG->getDisplayedCurve();
if (ce == skinTonesCurve) { // L = f(L)
red = double(valY);
green = double(valY);
blue = double(valY);
}
else {
printf("Error: no curve displayed!\n");
}
}
void Vibrance::trimValues (ProcParams* pp) {
pastels->trimValue (pp->vibrance.pastels);
saturated->trimValue (pp->vibrance.saturated);

View File

@ -22,11 +22,17 @@
#include <gtkmm.h>
#include "adjuster.h"
#include "thresholdadjuster.h"
#include "curveeditor.h"
#include "curveeditorgroup.h"
#include "toolpanel.h"
class Vibrance : public Gtk::VBox, public AdjusterListener, public ThresholdAdjusterListener, public FoldableToolPanel, public ThresholdCurveProvider {
class Vibrance : public Gtk::VBox, public AdjusterListener, public ThresholdCurveProvider, public ThresholdAdjusterListener,
public FoldableToolPanel, public CurveListener, public ColorProvider
{
protected:
CurveEditorGroup* curveEditorGG;
Gtk::CheckButton* enabled;
Adjuster* pastels;
Adjuster* saturated;
@ -34,7 +40,9 @@ protected:
Gtk::CheckButton* protectSkins;
Gtk::CheckButton* avoidColorShift;
Gtk::CheckButton* pastSatTog;
bool lastEnabled;
DiagonalCurveEditor* skinTonesCurve;
bool lastEnabled;
bool lastProtectSkins;
bool lastAvoidColorShift;
bool lastPastSatTog;
@ -47,6 +55,7 @@ protected:
public:
Vibrance ();
~Vibrance ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
@ -56,12 +65,14 @@ public:
void setAdjusterBehavior (bool amountadd, bool passadd, bool psthreshdadd);
void adjusterChanged (Adjuster* a, double newval);
void adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop);
void curveChanged ();
void enabled_toggled ();
void protectskins_toggled ();
void avoidcolorshift_toggled ();
void pastsattog_toggled ();
std::vector<double> getCurvePoints(ThresholdSelector* tAdjuster) const;
virtual void colorForValue (double valX, double valY);
};