Merge branch 'dev' into perspective
Resolve minor conflict in ImProcFunctions::transformGeneral and add new arguments for use of ImProcFunctions::needsTransform in PerspectiveCorrection::autocompute.
This commit is contained in:
commit
f16773eb3f
122
rtdata/images/svg/questionmark.svg
Normal file
122
rtdata/images/svg/questionmark.svg
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
id="SVGRoot"
|
||||
inkscape:export-filename="/tmp/template.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="questionmark.svg">
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#E0E1E2"
|
||||
bordercolor="#666768"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="17.125"
|
||||
inkscape:cx="2.4963333"
|
||||
inkscape:cy="9.7590888"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:object-nodes="false"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-bbox-midpoints="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid1374"
|
||||
originx="1"
|
||||
originy="1"
|
||||
empspacing="11"
|
||||
dotted="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs815" />
|
||||
<metadata
|
||||
id="metadata818">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Maciej Dworak</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:description>RawTherapee icon.</dc:description>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18.52196503px;line-height:125%;font-family:Georgia;-inkscape-font-specification:'Georgia Bold';letter-spacing:0px;word-spacing:0px;opacity:0.7;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-11.29845"
|
||||
y="19"
|
||||
id="text821"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan819"
|
||||
x="-11.29845"
|
||||
y="19"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18.52196503px;font-family:Georgia;-inkscape-font-specification:'Georgia Bold';fill:#ffffff;stroke-width:1px">?</tspan></text>
|
||||
<path
|
||||
style="opacity:0.7;fill:#2a7fff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 12 1 A 11 11 0 0 0 1 12 A 11 11 0 0 0 12 23 A 11 11 0 0 0 23 12 A 11 11 0 0 0 12 1 z M 11.804688 5.3027344 C 13.125101 5.3027344 14.193859 5.6466458 15.007812 6.3339844 C 15.827796 7.021323 16.236328 7.9291641 16.236328 9.0566406 C 16.236328 10.268527 15.820323 11.250246 14.988281 12.003906 C 14.156239 12.757567 13.046892 13.188348 11.660156 13.296875 L 11.607422 14.527344 L 10.800781 14.527344 L 10.800781 11.009766 C 11.675027 10.937414 12.361067 10.663813 12.855469 10.1875 C 13.349871 9.705157 13.595703 9.0506215 13.595703 8.2246094 C 13.595703 7.5674173 13.421964 7.0422942 13.072266 6.6503906 C 12.728596 6.2524578 12.264528 6.0527344 11.679688 6.0527344 C 11.432487 6.0527344 11.212469 6.0805023 11.019531 6.1347656 C 10.826594 6.1829996 10.639863 6.2625663 10.458984 6.3710938 C 10.519278 6.5640309 10.587635 6.8136002 10.666016 7.1210938 C 10.750426 7.422558 10.792969 7.7016782 10.792969 7.9609375 C 10.792969 8.3829875 10.6543 8.7121235 10.376953 8.9472656 C 10.105635 9.1763785 9.7247003 9.2910156 9.2363281 9.2910156 C 8.7781025 9.2910156 8.4176323 9.1468276 8.1523438 8.8574219 C 7.8930844 8.5680162 7.7636719 8.2130656 7.7636719 7.7910156 C 7.7636719 7.0976478 8.1574292 6.5096866 8.9472656 6.0273438 C 9.737102 5.5450009 10.689269 5.3027344 11.804688 5.3027344 z M 11.244141 15.332031 C 11.708396 15.332031 12.113362 15.502204 12.457031 15.839844 C 12.806729 16.171454 12.980469 16.565212 12.980469 17.023438 C 12.980469 17.481663 12.806729 17.877374 12.457031 18.208984 C 12.113362 18.534566 11.708396 18.697266 11.244141 18.697266 C 10.773857 18.697266 10.365324 18.534566 10.015625 18.208984 C 9.6719557 17.877374 9.5 17.481663 9.5 17.023438 C 9.5 16.565212 9.6719557 16.171454 10.015625 15.839844 C 10.365324 15.502204 10.773857 15.332031 11.244141 15.332031 z "
|
||||
id="path939" />
|
||||
<g
|
||||
aria-label="?"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18.52196503px;line-height:125%;font-family:Georgia;-inkscape-font-specification:'Georgia Bold';letter-spacing:0px;word-spacing:0px;opacity:0.7;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text943" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.3 KiB |
@ -977,6 +977,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: <b>-</b>
|
||||
!GENERAL_AUTO;Automatic
|
||||
!GENERAL_CLOSE;Close
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_OPEN;Open
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
|
@ -973,6 +973,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: <b>-</b>
|
||||
!FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: <b>Alt-0</b>
|
||||
!FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: <b>Shift-0</b>
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
!GENERAL_SLIDER;Slider
|
||||
|
@ -2323,6 +2323,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: <b>-</b>
|
||||
!FILEBROWSER_POPUPREMOVE;Delete permanently
|
||||
!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
|
||||
!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
|
||||
|
@ -2390,5 +2390,6 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: <b>-</b>
|
||||
! Untranslated keys follow; remove the ! prefix after an entry is translated.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations
|
||||
!TP_SHARPENING_ITERCHECK;Auto limit iterations
|
||||
|
@ -340,6 +340,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh
|
||||
!GENERAL_ENABLE;Enable
|
||||
!GENERAL_ENABLED;Enabled
|
||||
!GENERAL_FILE;File
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_LANDSCAPE;Landscape
|
||||
!GENERAL_NA;n/a
|
||||
!GENERAL_NO;No
|
||||
|
@ -226,6 +226,7 @@
|
||||
!GENERAL_ENABLE;Enable
|
||||
!GENERAL_ENABLED;Enabled
|
||||
!GENERAL_FILE;File
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_LANDSCAPE;Landscape
|
||||
!GENERAL_NA;n/a
|
||||
!GENERAL_NO;No
|
||||
|
@ -2321,6 +2321,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: <b>-</b>
|
||||
!FILEBROWSER_POPUPREMOVE;Delete permanently
|
||||
!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
|
||||
!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
|
||||
|
@ -2266,6 +2266,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: <b>-</b>
|
||||
!FILEBROWSER_POPUPREMOVE;Delete permanently
|
||||
!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
|
||||
!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
|
||||
|
@ -1285,6 +1285,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: <b>-</b>
|
||||
!GENERAL_APPLY;Apply
|
||||
!GENERAL_ASIMAGE;As Image
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_OPEN;Open
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
|
@ -8,30 +8,6 @@
|
||||
#08 2012-12-22 a3novy
|
||||
#09 2013-04-01 a3novy
|
||||
#10 2013-04-19 a3novy
|
||||
#11 2013-09-10 firefly
|
||||
#12 2013-10-28 firefly
|
||||
#13 2014-01-07 firefly
|
||||
#14 2014-01-15 firefly
|
||||
#15 2014-02-25 firefly
|
||||
#16 2014-04-07 firefly
|
||||
#17 2014-04-08 firefly
|
||||
#18 2014-05-16 firefly
|
||||
#19 2014-07-13 firefly
|
||||
#20 2014-07-24 firefly
|
||||
#21 2014-09-11 firefly
|
||||
#22 2014-10-21 firefly
|
||||
#23 2014-11-07 firefly
|
||||
#24 2014-11-18 firefly
|
||||
#25 2015-01-05 firefly
|
||||
#26 2015-02-17 firefly
|
||||
#27 2015-02-21 firefly
|
||||
#28 2015-03-03 firefly
|
||||
#29 2015-04-20 firefly
|
||||
#30 2015-05-01 firefly
|
||||
#31 2015-05-31 firefly
|
||||
#32 2015-06-13 firefly
|
||||
#33 2015-07-20 firefly
|
||||
#34 2015-08-12 firefly
|
||||
|
||||
ABOUT_TAB_BUILD;バージョン
|
||||
ABOUT_TAB_CREDITS;クレジット
|
||||
@ -49,7 +25,7 @@ CURVEEDITOR_CURVE;カーブ
|
||||
CURVEEDITOR_CURVES;カーブ
|
||||
CURVEEDITOR_CUSTOM;カスタム
|
||||
CURVEEDITOR_DARKS;ダーク
|
||||
CURVEEDITOR_EDITPOINT_HINT;ボタンを押すと数値で入出力を編集出来ます\n\n編集したいカーブ上のポイントを右クリックします\n編集を無効にする場合はポイント以外の部分んで右クリックします
|
||||
CURVEEDITOR_EDITPOINT_HINT;ボタンを押すと数値で入出力を編集出来ます\n\n編集したいカーブ上のポイントを右クリックします\n編集を無効にする場合はポイント以外の部分で右クリックします
|
||||
CURVEEDITOR_HIGHLIGHTS;ハイライト
|
||||
CURVEEDITOR_LIGHTS;ライト
|
||||
CURVEEDITOR_LINEAR;リニア
|
||||
@ -489,8 +465,8 @@ HISTORY_MSG_205;CAM02 ホット/バッドピクセル
|
||||
HISTORY_MSG_206;CAT02 - 自動で順応
|
||||
HISTORY_MSG_207;フリンジ低減 - 色相カーブ
|
||||
HISTORY_MSG_208;ブルー/レッド イコライザ
|
||||
HISTORY_MSG_210;グラデーションフィルター - 角度
|
||||
HISTORY_MSG_211;グラデーションフィルター
|
||||
HISTORY_MSG_210;減光フィルター - 角度
|
||||
HISTORY_MSG_211;減光フィルター
|
||||
HISTORY_MSG_212;ビネットフィルター - 強さ
|
||||
HISTORY_MSG_213;ビネットフィルター
|
||||
HISTORY_MSG_214;白黒
|
||||
@ -517,10 +493,10 @@ HISTORY_MSG_234;白黒 ‘後の‘カーブのタイプ
|
||||
HISTORY_MSG_235;白黒 チャンネルミキサー 自動
|
||||
HISTORY_MSG_236;--未使用--
|
||||
HISTORY_MSG_237;白黒 チャンネルミキサー
|
||||
HISTORY_MSG_238;グラデーションフィルター フェザー処理
|
||||
HISTORY_MSG_239;グラデーションフィルター 強さ
|
||||
HISTORY_MSG_240;グラデーションフィルター 中央
|
||||
HISTORY_MSG_241;ビネットフィルター フェザー処理
|
||||
HISTORY_MSG_238;減光フィルター フェザー
|
||||
HISTORY_MSG_239;減光フィルター 強さ
|
||||
HISTORY_MSG_240;減光フィルター 中央
|
||||
HISTORY_MSG_241;ビネットフィルター フェザー
|
||||
HISTORY_MSG_242;ビネットフィルター 形状
|
||||
HISTORY_MSG_243;半径
|
||||
HISTORY_MSG_244;ビネットフィルター 強さ
|
||||
@ -757,6 +733,7 @@ HISTORY_MSG_490;DRC - 量
|
||||
HISTORY_MSG_491;ホワイトバランス
|
||||
HISTORY_MSG_492;RGBカーブ
|
||||
HISTORY_MSG_493;L*a*b*調整
|
||||
HISTORY_MSG_494;キャプチャーシャープニング
|
||||
HISTORY_MSG_CLAMPOOG;色域外の色を切り取る
|
||||
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - カラー補正
|
||||
HISTORY_MSG_COLORTONING_LABREGION_AB;CT - 色の補正
|
||||
@ -774,6 +751,7 @@ HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - マスクの表示
|
||||
HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - スロープ
|
||||
HISTORY_MSG_DEHAZE_DEPTH;霞除去 - 深度
|
||||
HISTORY_MSG_DEHAZE_ENABLED;霞除去
|
||||
HISTORY_MSG_DEHAZE_LUMINANCE;霞除去 - 輝度のみ
|
||||
HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;霞除去 - 深度マップの表示
|
||||
HISTORY_MSG_DEHAZE_STRENGTH;霞除去 - 強さ
|
||||
HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;デュアルデモザイク - 自動しきい値
|
||||
@ -794,6 +772,13 @@ HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;ローカルコントラスト - 明るい
|
||||
HISTORY_MSG_LOCALCONTRAST_RADIUS;ローカルコントラスト - 半径
|
||||
HISTORY_MSG_METADATA_MODE;メタデータ コピーモード
|
||||
HISTORY_MSG_MICROCONTRAST_CONTRAST;マイクロコントラスト - コントラストのしきい値
|
||||
HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - しきい値の自動設定
|
||||
HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - シグマの自動設定
|
||||
HISTORY_MSG_PDSHARPEN_CHECKITER;CS - 繰り返しの自動制限
|
||||
HISTORY_MSG_PDSHARPEN_CONTRAST;CS - コントラストのしきい値
|
||||
HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - 繰り返し
|
||||
HISTORY_MSG_PDSHARPEN_RADIUS;CS - シグマ
|
||||
HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - 周辺のシグマを増やす
|
||||
HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - 振れに対するデモザイクの方式
|
||||
HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;ラインノイズフィルタの方向
|
||||
HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAFラインフィルタ
|
||||
@ -960,8 +945,8 @@ MAIN_TOOLTIP_BACKCOLOR2;プレビューの背景色を指定します: <b>白</b
|
||||
MAIN_TOOLTIP_BACKCOLOR3;プレビューの背景色を指定します: <b>中間のグレー</b>\nショートカット: <b>9</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_HIDEHP;左パネル 表示/非表示 (履歴含む)\nショートカット: <b>l</b>
|
||||
MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: <b>></b>
|
||||
MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: <b><</b>
|
||||
MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: <b><</b>
|
||||
MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: <b>></b>
|
||||
MAIN_TOOLTIP_PREVIEWB;<b>ブルー チャンネル</b>表示\nショートカット: <b>b</b>
|
||||
MAIN_TOOLTIP_PREVIEWFOCUSMASK;<b>フォーカス・マスク</b>表示\nショートカット: <b>Shift-f</b>\n\n浅い被写界深度、低ノイズ、高ズームの画像の場合は、より正確に\n\nノイズの多い画像に対しては、検出精度を向上させるため10から30%縮小して評価します\n\nフォーカス・マスクをオンにすると表示に時間が掛かります
|
||||
MAIN_TOOLTIP_PREVIEWG;<b>グリーン チャンネル</b>表示\nショートカット: <b>g</b>
|
||||
@ -1023,7 +1008,7 @@ PARTIALPASTE_FLATFIELDBLURRADIUS;フラットフィールド ぼかし半径
|
||||
PARTIALPASTE_FLATFIELDBLURTYPE;フラットフィールド ぼかしタイプ
|
||||
PARTIALPASTE_FLATFIELDCLIPCONTROL;フラットフィールド クリップコントロール
|
||||
PARTIALPASTE_FLATFIELDFILE;フラットフィールド ファイル
|
||||
PARTIALPASTE_GRADIENT;グラデーションフィルター
|
||||
PARTIALPASTE_GRADIENT;減光フィルター
|
||||
PARTIALPASTE_HSVEQUALIZER;HSV イコライザ
|
||||
PARTIALPASTE_ICMSETTINGS;ICM 設定
|
||||
PARTIALPASTE_IMPULSEDENOISE;インパルス・ノイズ低減
|
||||
@ -1562,6 +1547,7 @@ TP_DEFRINGE_RADIUS;半径
|
||||
TP_DEFRINGE_THRESHOLD;しきい値
|
||||
TP_DEHAZE_DEPTH;深度
|
||||
TP_DEHAZE_LABEL;霞除去
|
||||
TP_DEHAZE_LUMINANCE;輝度のみ
|
||||
TP_DEHAZE_SHOW_DEPTH_MAP;深度マップの表示
|
||||
TP_DEHAZE_STRENGTH;強さ
|
||||
TP_DIRPYRDENOISE_CHROMINANCE_AMZ;自動(多分割方式)
|
||||
@ -1672,9 +1658,9 @@ TP_EXPOS_BLACKPOINT_LABEL;raw ブラック・ポイント
|
||||
TP_EXPOS_WHITEPOINT_LABEL;raw ホワイト・ポイント
|
||||
TP_FILMNEGATIVE_BLUE;ブルーの比率
|
||||
TP_FILMNEGATIVE_GREEN;参考指数(コントラスト)
|
||||
TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picking two patches which had a neutral hue (no color) in the original scene. The patches should differ in brightness. Set the white balance afterwards.
|
||||
TP_FILMNEGATIVE_GUESS_TOOLTIP;原画像の中で色相がニュートラルな部分2か所をピックすることでレッドとブルーの比率を自動で設定します。明るさが異なる2か所をピックします。その後、ホワイトバランスを設定します。
|
||||
TP_FILMNEGATIVE_LABEL;ネガフィルム
|
||||
TP_FILMNEGATIVE_PICK;Pick neutral spots
|
||||
TP_FILMNEGATIVE_PICK;ニュートラルなポイントをピック
|
||||
TP_FILMNEGATIVE_RED;レッドの比率
|
||||
TP_FILMSIMULATION_LABEL;フィルムシミュレーション
|
||||
TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapeeはフィルムシミュレーション機能に使う画像をHald CLUTフォルダーの中から探すよう設計されています(プログラムに組み込むにはフォルダーが大き過ぎるため)。\n変更するには、環境設定 > 画像処理 > フィルムシミュレーションと進み\nどのフォルダーが使われているか確認します。機能を利用する場合は、Hald CLUTだけが入っているフォルダーを指定するか、 この機能を使わない場合はそのフォルダーを空にしておきます。\n\n詳しくはRawPediaを参照して下さい。\n\nフィルム画像のスキャンを止めますか?
|
||||
@ -1698,9 +1684,9 @@ TP_GRADIENT_CENTER_Y;中央 Y軸
|
||||
TP_GRADIENT_CENTER_Y_TOOLTIP;アンカーポイントの位置 y軸: -100=上端, 0=中央, +100=下端
|
||||
TP_GRADIENT_DEGREE;角度
|
||||
TP_GRADIENT_DEGREE_TOOLTIP;回転角度の度数
|
||||
TP_GRADIENT_FEATHER;フェザー処理
|
||||
TP_GRADIENT_FEATHER_TOOLTIP;対角線に対するグラデーションの幅の割合
|
||||
TP_GRADIENT_LABEL;グラデーションフィルター
|
||||
TP_GRADIENT_FEATHER;フェザー
|
||||
TP_GRADIENT_FEATHER_TOOLTIP;対角線に対する減光の幅の割合
|
||||
TP_GRADIENT_LABEL;減光フィルター
|
||||
TP_GRADIENT_STRENGTH;強さ
|
||||
TP_GRADIENT_STRENGTH_TOOLTIP;終点位置でのフィルターの強さ
|
||||
TP_HLREC_BLEND;ブレンド
|
||||
@ -1817,13 +1803,14 @@ TP_METADATA_STRIP;メタデータを全て取り除く
|
||||
TP_METADATA_TUNNEL;変更なしでコピー
|
||||
TP_NEUTRAL;リセット
|
||||
TP_NEUTRAL_TIP;露光量補正のスライダー値をニュートラルにリセットします。\n自動露光補正の調整値ついても同様にリセットされます
|
||||
TP_PCVIGNETTE_FEATHER;フェザー処理
|
||||
TP_PCVIGNETTE_FEATHER_TOOLTIP;フェザー処理: 0=四隅だけ、50=中央までの半分、100=中央まで
|
||||
TP_PCVIGNETTE_FEATHER;フェザー
|
||||
TP_PCVIGNETTE_FEATHER_TOOLTIP;フェザー: 0=四隅だけ、50=中央までの半分、100=中央まで
|
||||
TP_PCVIGNETTE_LABEL;ビネットフィルター
|
||||
TP_PCVIGNETTE_ROUNDNESS;フィルター形状
|
||||
TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;形状: 0=長方形、50=楕円形、100=円形
|
||||
TP_PCVIGNETTE_STRENGTH;強さ
|
||||
TP_PCVIGNETTE_STRENGTH_TOOLTIP;終点位置でのフィルターの強さ(四隅)
|
||||
TP_PDSHARPENING_LABEL;キャプチャーシャープニング
|
||||
TP_PERSPECTIVE_HORIZONTAL;水平
|
||||
TP_PERSPECTIVE_LABEL;パースペクティブ
|
||||
TP_PERSPECTIVE_VERTICAL;垂直
|
||||
@ -2054,10 +2041,12 @@ TP_SHARPENING_EDRADIUS;半径
|
||||
TP_SHARPENING_EDTOLERANCE;エッジ許容
|
||||
TP_SHARPENING_HALOCONTROL;ハロ抑制
|
||||
TP_SHARPENING_HCAMOUNT;適用量
|
||||
TP_SHARPENING_ITERCHECK;繰り返しの自動制限
|
||||
TP_SHARPENING_LABEL;シャープニング
|
||||
TP_SHARPENING_METHOD;方式
|
||||
TP_SHARPENING_ONLYEDGES;エッジのみシャープニング
|
||||
TP_SHARPENING_RADIUS;半径
|
||||
TP_SHARPENING_RADIUS_BOOST;周辺のシグマを増やす
|
||||
TP_SHARPENING_RLD;RL デコンボリューション
|
||||
TP_SHARPENING_RLD_AMOUNT;適用量
|
||||
TP_SHARPENING_RLD_DAMPING;減衰
|
||||
@ -2311,6 +2300,7 @@ TP_WBALANCE_TUNGSTEN;タングステン
|
||||
TP_WBALANCE_WATER1;水中 1
|
||||
TP_WBALANCE_WATER2;水中 2
|
||||
TP_WBALANCE_WATER_HEADER;水中
|
||||
The last update by firefly 2019-12-21
|
||||
ZOOMPANEL_100;(100%)
|
||||
ZOOMPANEL_NEWCROPWINDOW;新規ディテール ウィンドウを開く
|
||||
ZOOMPANEL_ZOOM100;100%にズーム\nショートカット: <b>z</b>
|
||||
@ -2323,16 +2313,4 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: <b>-</b>
|
||||
! Untranslated keys follow; remove the ! prefix after an entry is translated.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
|
||||
!HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold
|
||||
!HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius
|
||||
!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations
|
||||
!HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrast threshold
|
||||
!HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterations
|
||||
!HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius
|
||||
!HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost
|
||||
!TP_DEHAZE_LUMINANCE;Luminance only
|
||||
!TP_PDSHARPENING_LABEL;Capture Sharpening
|
||||
!TP_SHARPENING_ITERCHECK;Auto limit iterations
|
||||
!TP_SHARPENING_RADIUS_BOOST;Corner radius boost
|
||||
!GENERAL_HELP;Help
|
||||
|
@ -908,6 +908,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés <b>-</b>
|
||||
!GENERAL_AUTO;Automatic
|
||||
!GENERAL_CLOSE;Close
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_OPEN;Open
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
|
@ -1982,6 +1982,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: <b>-</b>
|
||||
!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
!GENERAL_SLIDER;Slider
|
||||
|
@ -1407,6 +1407,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: <b>-</b>
|
||||
!GENERAL_APPLY;Apply
|
||||
!GENERAL_ASIMAGE;As Image
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_OPEN;Open
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
|
@ -2264,6 +2264,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: <b>-</b>
|
||||
!FILEBROWSER_POPUPREMOVE;Delete permanently
|
||||
!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
|
||||
!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
|
||||
|
@ -2269,6 +2269,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: <b>-</b>
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
!FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply "find" keywords.
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_494;Capture Sharpening
|
||||
!HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset
|
||||
!HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power
|
||||
|
@ -1475,6 +1475,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: <b>-</b>
|
||||
!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions.
|
||||
!FILECHOOSER_FILTER_PP;Processing profiles
|
||||
!FILECHOOSER_FILTER_SAME;Same format as current photo
|
||||
!GENERAL_HELP;Help
|
||||
!GIMP_PLUGIN_INFO;Welcome to the RawTherapee GIMP plugin!\nOnce you are done editing, simply close the main RawTherapee window and the image will be automatically imported in GIMP.
|
||||
!HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram.
|
||||
!HISTORY_MSG_235;B&W - CM - Auto
|
||||
|
@ -1257,6 +1257,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике <b>-</b>
|
||||
!GENERAL_APPLY;Apply
|
||||
!GENERAL_ASIMAGE;As Image
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_OPEN;Open
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
|
@ -2306,5 +2306,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: <b>-</b>
|
||||
! Untranslated keys follow; remove the ! prefix after an entry is translated.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
!GENERAL_HELP;Help
|
||||
!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations
|
||||
!TP_SHARPENING_ITERCHECK;Auto limit iterations
|
||||
|
@ -1772,6 +1772,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: <b>-</b>
|
||||
!FILEBROWSER_RESETDEFAULTPROFILE;Reset to default
|
||||
!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash.
|
||||
!GENERAL_CURRENT;Current
|
||||
!GENERAL_HELP;Help
|
||||
!GENERAL_RESET;Reset
|
||||
!GENERAL_SAVE_AS;Save as...
|
||||
!GENERAL_SLIDER;Slider
|
||||
|
@ -225,6 +225,7 @@ GENERAL_DISABLED;Disabled
|
||||
GENERAL_ENABLE;Enable
|
||||
GENERAL_ENABLED;Enabled
|
||||
GENERAL_FILE;File
|
||||
GENERAL_HELP;Help
|
||||
GENERAL_LANDSCAPE;Landscape
|
||||
GENERAL_NA;n/a
|
||||
GENERAL_NO;No
|
||||
@ -794,6 +795,7 @@ HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
|
||||
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
|
||||
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
|
||||
HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor
|
||||
HISTORY_MSG_TRANS_Method;Geometry - Method
|
||||
HISTORY_NEWSNAPSHOT;Add
|
||||
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
|
||||
HISTORY_SNAPSHOT;Snapshot
|
||||
@ -1782,6 +1784,8 @@ TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve.
|
||||
TP_LENSGEOM_AUTOCROP;Auto-Crop
|
||||
TP_LENSGEOM_FILL;Auto-fill
|
||||
TP_LENSGEOM_LABEL;Lens / Geometry
|
||||
TP_LENSGEOM_LIN;Linear
|
||||
TP_LENSGEOM_LOG;Logarithmic
|
||||
TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected
|
||||
TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file
|
||||
TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected
|
||||
|
@ -188,6 +188,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void fill(const T val, bool multiThread = false)
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for if(multiThread)
|
||||
#endif
|
||||
for (int i = 0; i < x * y; ++i) {
|
||||
data[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
if ((owner) && (data)) {
|
||||
|
@ -195,7 +195,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
/* Create an object/array that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
@ -253,7 +253,7 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model)
|
||||
}
|
||||
|
||||
if (i % 4 != 0) {
|
||||
fprintf(stderr, "\"masked_areas\" array length must be divisable by 4\n");
|
||||
fprintf(stderr, "\"masked_areas\" array length must be divisible by 4\n");
|
||||
goto parse_error;
|
||||
}
|
||||
}
|
||||
|
@ -99,31 +99,7 @@ void compute3x3kernel(float sigma, float kernel[3][3]) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void initTile(float** dst, const int tileSize)
|
||||
{
|
||||
|
||||
// first rows
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < tileSize; ++j) {
|
||||
dst[i][j] = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
// left and right border
|
||||
for (int i = 3; i < tileSize - 3; ++i) {
|
||||
dst[i][0] = dst[i][1] = dst[i][2] = 1.f;
|
||||
dst[i][tileSize - 3] = dst[i][tileSize - 2] = dst[i][tileSize - 1] = 1.f;
|
||||
}
|
||||
|
||||
// last rows
|
||||
for (int i = tileSize - 3 ; i < tileSize; ++i) {
|
||||
for (int j = 0; j < tileSize; ++j) {
|
||||
dst[i][j] = 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[3][3])
|
||||
void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[3][3])
|
||||
{
|
||||
|
||||
const float c11 = kernel[0][0];
|
||||
@ -131,6 +107,11 @@ inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
||||
const float c00 = kernel[1][1];
|
||||
|
||||
for (int i = 1; i < tileSize - 1; i++) {
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 1; j < tileSize - 1; j++) {
|
||||
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||
@ -140,7 +121,7 @@ inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
||||
}
|
||||
}
|
||||
|
||||
inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[5][5])
|
||||
void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[5][5])
|
||||
{
|
||||
|
||||
const float c21 = kernel[0][1];
|
||||
@ -151,6 +132,11 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
||||
|
||||
for (int i = 2; i < tileSize - 2; ++i) {
|
||||
// I tried hand written SSE code but gcc vectorizes better
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 2; j < tileSize - 2; ++j) {
|
||||
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
||||
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||
@ -163,7 +149,7 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
||||
}
|
||||
}
|
||||
|
||||
inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[7][7])
|
||||
void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[7][7])
|
||||
{
|
||||
|
||||
const float c31 = kernel[0][2];
|
||||
@ -177,6 +163,11 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST
|
||||
|
||||
for (int i = 3; i < tileSize - 3; ++i) {
|
||||
// I tried hand written SSE code but gcc vectorizes better
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 3; j < tileSize - 3; ++j) {
|
||||
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
||||
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||
@ -192,13 +183,18 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST
|
||||
}
|
||||
}
|
||||
|
||||
inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[3][3])
|
||||
void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[3][3])
|
||||
{
|
||||
const float c11 = kernel[0][0];
|
||||
const float c10 = kernel[0][1];
|
||||
const float c00 = kernel[1][1];
|
||||
|
||||
for (int i = 1; i < tileSize - 1; i++) {
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 1; j < tileSize - 1; j++) {
|
||||
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||
@ -209,7 +205,7 @@ inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int t
|
||||
|
||||
}
|
||||
|
||||
inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[5][5])
|
||||
void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[5][5])
|
||||
{
|
||||
|
||||
const float c21 = kernel[0][1];
|
||||
@ -220,6 +216,11 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int
|
||||
|
||||
for (int i = 2; i < tileSize - 2; ++i) {
|
||||
// I tried hand written SSE code but gcc vectorizes better
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 2; j < tileSize - 2; ++j) {
|
||||
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
||||
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||
@ -232,7 +233,7 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int
|
||||
}
|
||||
}
|
||||
|
||||
inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[7][7])
|
||||
void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[7][7])
|
||||
{
|
||||
|
||||
const float c31 = kernel[0][2];
|
||||
@ -246,6 +247,11 @@ inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int t
|
||||
|
||||
for (int i = 3; i < tileSize - 3; ++i) {
|
||||
// I tried hand written SSE code but gcc vectorizes better
|
||||
#if defined(__clang__)
|
||||
#pragma clang loop vectorize(assume_safety)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC ivdep
|
||||
#endif
|
||||
for (int j = 3; j < tileSize - 3; ++j) {
|
||||
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
||||
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||
@ -495,28 +501,25 @@ float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLi
|
||||
|
||||
bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int border)
|
||||
{
|
||||
bool stopped = false;
|
||||
for (int ii = border; !stopped && ii < fullTileSize - border; ++ii) {
|
||||
for (int ii = border; ii < fullTileSize - border; ++ii) {
|
||||
#ifdef __SSE2__
|
||||
for (int jj = border; jj < fullTileSize - border; jj += 4) {
|
||||
if (_mm_movemask_ps((vfloat)vmaskf_lt(LVFU(tmpIThr[ii][jj]), LVFU(iterCheck[ii - border][jj - border])))) {
|
||||
stopped = true;
|
||||
break;
|
||||
if (UNLIKELY(_mm_movemask_ps((vfloat)vmaskf_lt(LVFU(tmpIThr[ii][jj]), LVFU(iterCheck[ii - border][jj - border]))))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int jj = border; jj < fullTileSize - border; ++jj) {
|
||||
if (tmpIThr[ii][jj] < iterCheck[ii - border][jj - border]) {
|
||||
stopped = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return stopped;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CaptureDeconvSharpening (float ** clipmask, float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
||||
void CaptureDeconvSharpening (float** luminance, const float* const * oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
||||
{
|
||||
BENCHFUN
|
||||
const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0);
|
||||
@ -541,6 +544,7 @@ BENCHFUN
|
||||
|
||||
double progress = startVal;
|
||||
const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H);
|
||||
|
||||
constexpr float minBlend = 0.01f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
@ -550,9 +554,9 @@ BENCHFUN
|
||||
int progresscounter = 0;
|
||||
array2D<float> tmpIThr(fullTileSize, fullTileSize);
|
||||
array2D<float> tmpThr(fullTileSize, fullTileSize);
|
||||
tmpThr.fill(1.f);
|
||||
array2D<float> lumThr(fullTileSize, fullTileSize);
|
||||
array2D<float> iterCheck(tileSize, tileSize);
|
||||
initTile(tmpThr, fullTileSize);
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16) collapse(2)
|
||||
#endif
|
||||
@ -567,14 +571,14 @@ BENCHFUN
|
||||
if (checkIterStop) {
|
||||
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
||||
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
||||
iterCheck[k][l] = oldLuminance[ii][jj] * clipmask[ii][jj] * 0.5f;
|
||||
maxVal = std::max(maxVal, clipmask[ii][jj]);
|
||||
iterCheck[k][l] = oldLuminance[ii][jj] * blend[ii][jj] * 0.5f;
|
||||
maxVal = std::max(maxVal, blend[ii][jj]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
||||
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
||||
maxVal = std::max(maxVal, clipmask[ii][jj]);
|
||||
maxVal = std::max(maxVal, blend[ii][jj]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -593,14 +597,14 @@ BENCHFUN
|
||||
if (checkIterStop) {
|
||||
for (int ii = 0; ii < tileSize; ++ii) {
|
||||
for (int jj = 0; jj < tileSize; ++jj) {
|
||||
iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * clipmask[i + ii][j + jj] * 0.5f;
|
||||
maxVal = std::max(maxVal, clipmask[i + ii][j + jj]);
|
||||
iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * blend[i + ii][j + jj] * 0.5f;
|
||||
maxVal = std::max(maxVal, blend[i + ii][j + jj]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int ii = 0; ii < tileSize; ++ii) {
|
||||
for (int jj = 0; jj < tileSize; ++jj) {
|
||||
maxVal = std::max(maxVal, clipmask[i + ii][j + jj]);
|
||||
maxVal = std::max(maxVal, blend[i + ii][j + jj]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -615,23 +619,22 @@ BENCHFUN
|
||||
}
|
||||
}
|
||||
}
|
||||
bool stopped = false;
|
||||
if (is3x3) {
|
||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
||||
for (int k = 0; k < iterations; ++k) {
|
||||
// apply 3x3 gaussian blur and divide luminance by result of gaussian blur
|
||||
gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3);
|
||||
gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3);
|
||||
if (checkIterStop) {
|
||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
||||
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (is5x5) {
|
||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
||||
for (int k = 0; k < iterations; ++k) {
|
||||
// apply 5x5 gaussian blur and divide luminance by result of gaussian blur
|
||||
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5);
|
||||
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5);
|
||||
if (checkIterStop) {
|
||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
||||
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -642,34 +645,34 @@ BENCHFUN
|
||||
if (sigmaTile > 0.84) { // have to use 7x7 kernel
|
||||
float lkernel7[7][7];
|
||||
compute7x7kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
||||
for (int k = 0; k < iterations; ++k) {
|
||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7);
|
||||
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, lkernel7);
|
||||
if (checkIterStop) {
|
||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
||||
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else { // can use 5x5 kernel
|
||||
float lkernel7[5][5];
|
||||
compute5x5kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
||||
float lkernel5[5][5];
|
||||
compute5x5kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel5);
|
||||
for (int k = 0; k < iterations; ++k) {
|
||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7);
|
||||
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, lkernel7);
|
||||
if (checkIterStop) {
|
||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
||||
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel5);
|
||||
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, lkernel5);
|
||||
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
||||
for (int k = 0; k < iterations; ++k) {
|
||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel7);
|
||||
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, kernel7);
|
||||
if (checkIterStop) {
|
||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
||||
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -678,23 +681,23 @@ BENCHFUN
|
||||
// special handling for small tiles at end of row or column
|
||||
for (int k = border, ii = endOfCol ? H - fullTileSize : i - border; k < fullTileSize - border; ++k) {
|
||||
for (int l = border, jj = endOfRow ? W - fullTileSize : j - border; l < fullTileSize - border; ++l) {
|
||||
luminance[ii + k][jj + l] = rtengine::intp(blend[ii + k][jj + l], std::max(tmpIThr[k][l], 0.0f), luminance[ii + k][jj + l]);
|
||||
luminance[ii + k][jj + l] = rtengine::intp(blend[ii + k][jj + l], tmpIThr[k][l], luminance[ii + k][jj + l]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int ii = border; ii < fullTileSize - border; ++ii) {
|
||||
for (int jj = border; jj < fullTileSize - border; ++jj) {
|
||||
luminance[i + ii - border][j + jj - border] = rtengine::intp(blend[i + ii - border][j + jj - border], std::max(tmpIThr[ii][jj], 0.0f), luminance[i + ii - border][j + jj - border]);
|
||||
luminance[i + ii - border][j + jj - border] = rtengine::intp(blend[i + ii - border][j + jj - border], tmpIThr[ii][jj], luminance[i + ii - border][j + jj - border]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plistener) {
|
||||
if (++progresscounter % 16 == 0) {
|
||||
if (++progresscounter % 32 == 0) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical(csprogress)
|
||||
#endif
|
||||
{
|
||||
progress += 16.0 * progressStep;
|
||||
progress += 32.0 * progressStep;
|
||||
progress = rtengine::min(progress, endVal);
|
||||
plistener->setProgress(progress);
|
||||
}
|
||||
@ -721,6 +724,7 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams
|
||||
plistener->setProgress(0.0);
|
||||
}
|
||||
BENCHFUN
|
||||
|
||||
constexpr float xyz_rgb[3][3] = { // XYZ from RGB
|
||||
{ 0.412453, 0.357580, 0.180423 },
|
||||
{ 0.212671, 0.715160, 0.072169 },
|
||||
@ -799,8 +803,7 @@ BENCHFUN
|
||||
plistener->setProgress(0.1);
|
||||
}
|
||||
|
||||
array2D<float>& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask
|
||||
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast, clipMask);
|
||||
buildBlendMask(L, clipMask, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
||||
if (plistener) {
|
||||
plistener->setProgress(0.2);
|
||||
}
|
||||
@ -810,7 +813,7 @@ BENCHFUN
|
||||
#endif
|
||||
for (int i = 0; i < H; ++i) {
|
||||
for (int j = 0; j < W; ++j) {
|
||||
red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f;
|
||||
red[i][j] = green[i][j] = blue[i][j] = clipMask[i][j] * 16384.f;
|
||||
}
|
||||
}
|
||||
if (plistener) {
|
||||
@ -847,18 +850,18 @@ BENCHFUN
|
||||
if (plistener) {
|
||||
plistener->setProgress(0.1);
|
||||
}
|
||||
|
||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||
array2D<float>& blend = clipMask; // we can share blend and clipMask buffer here
|
||||
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast, clipMask);
|
||||
buildBlendMask(L, clipMask, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
||||
if (plistener) {
|
||||
plistener->setProgress(0.2);
|
||||
}
|
||||
conrastThreshold = contrast * 100.f;
|
||||
|
||||
CaptureDeconvSharpening(clipMask, YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9);
|
||||
CaptureDeconvSharpening(YNew, YOld, clipMask, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9);
|
||||
if (plistener) {
|
||||
plistener->setProgress(0.9);
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic, 16)
|
||||
#endif
|
||||
@ -866,7 +869,7 @@ BENCHFUN
|
||||
int j = 0;
|
||||
#ifdef __SSE2__
|
||||
for (; j < W - 3; j += 4) {
|
||||
const vfloat factor = vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f));
|
||||
const vfloat factor = LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f));
|
||||
STVFU(red[i][j], LVFU(redVals[i][j]) * factor);
|
||||
STVFU(green[i][j], LVFU(greenVals[i][j]) * factor);
|
||||
STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor);
|
||||
@ -874,7 +877,7 @@ BENCHFUN
|
||||
|
||||
#endif
|
||||
for (; j < W; ++j) {
|
||||
const float factor = std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f);
|
||||
const float factor = YNew[i][j] / std::max(YOld[i][j], 0.00001f);
|
||||
red[i][j] = redVals[i][j] * factor;
|
||||
green[i][j] = greenVals[i][j] * factor;
|
||||
blue[i][j] = blueVals[i][j] * factor;
|
||||
|
@ -1372,7 +1372,7 @@ public:
|
||||
* @param HH hue before [-PI ; +PI]
|
||||
* @param Chprov1 chroma after [0 ; 180 (can be superior)]
|
||||
* @param CC chroma before [0 ; 180]
|
||||
* @param corectionHuechroma hue correction depending on chromaticity (saturation), in radians [0 ; 0.45] (return value)
|
||||
* @param correctionHueChroma hue correction depending on chromaticity (saturation), in radians [0 ; 0.45] (return value)
|
||||
* @param correctlum hue correction depending on luminance (brightness, contrast,...), in radians [0 ; 0.45] (return value)
|
||||
* @param munsDbgInfo (Debug target only) object to collect information
|
||||
*/
|
||||
|
@ -4433,6 +4433,10 @@ void CLASS foveon_interpolate()
|
||||
|
||||
void CLASS crop_masked_pixels()
|
||||
{
|
||||
if (data_error) {
|
||||
return;
|
||||
}
|
||||
|
||||
int row, col;
|
||||
unsigned r, c, m, mblack[8], zero, val;
|
||||
|
||||
|
@ -173,8 +173,6 @@ void Crop::update(int todo)
|
||||
int widIm = parent->fw;//full image
|
||||
int heiIm = parent->fh;
|
||||
|
||||
bool needstransform = parent->ipf.needsTransform();
|
||||
|
||||
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
|
||||
MyMutex::MyLock lock(parent->minit); // Also used in improccoord
|
||||
|
||||
@ -766,8 +764,9 @@ void Crop::update(int todo)
|
||||
}
|
||||
}
|
||||
|
||||
const bool needstransform = parent->ipf.needsTransform(skips(parent->fw, skip), skips(parent->fh, skip), parent->imgsrc->getRotateDegree(), parent->imgsrc->getMetaData());
|
||||
// transform
|
||||
if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) {
|
||||
if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) {
|
||||
if (!transCrop) {
|
||||
transCrop = new Imagefloat(cropw, croph);
|
||||
}
|
||||
@ -784,10 +783,7 @@ void Crop::update(int todo)
|
||||
baseCrop = transCrop;
|
||||
}
|
||||
} else {
|
||||
if (transCrop) {
|
||||
delete transCrop;
|
||||
}
|
||||
|
||||
delete transCrop;
|
||||
transCrop = nullptr;
|
||||
}
|
||||
|
||||
@ -1167,41 +1163,42 @@ bool Crop::setCropSizes(int rcx, int rcy, int rcw, int rch, int skip, bool inter
|
||||
|
||||
parent->ipf.transCoord(parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh);
|
||||
|
||||
if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, *parent->params)) {
|
||||
// TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise
|
||||
int dW = int (double (parent->fw) * 0.15 / (2 * skip));
|
||||
int dH = int (double (parent->fh) * 0.15 / (2 * skip));
|
||||
int x1 = orx - dW;
|
||||
int x2 = orx + orw + dW;
|
||||
int y1 = ory - dH;
|
||||
int y2 = ory + orh + dH;
|
||||
if (parent->ipf.needsTransform(skips(parent->fw, skip), skips(parent->fh, skip), parent->imgsrc->getRotateDegree(), parent->imgsrc->getMetaData())) {
|
||||
if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, *parent->params)) {
|
||||
// TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise
|
||||
int dW = int (double (parent->fw) * 0.15 / (2 * skip));
|
||||
int dH = int (double (parent->fh) * 0.15 / (2 * skip));
|
||||
int x1 = orx - dW;
|
||||
int x2 = orx + orw + dW;
|
||||
int y1 = ory - dH;
|
||||
int y2 = ory + orh + dH;
|
||||
|
||||
if (x1 < 0) {
|
||||
x2 += -x1;
|
||||
x1 = 0;
|
||||
if (x1 < 0) {
|
||||
x2 += -x1;
|
||||
x1 = 0;
|
||||
}
|
||||
|
||||
if (x2 > parent->fw) {
|
||||
x1 -= x2 - parent->fw;
|
||||
x2 = parent->fw;
|
||||
}
|
||||
|
||||
if (y1 < 0) {
|
||||
y2 += -y1;
|
||||
y1 = 0;
|
||||
}
|
||||
|
||||
if (y2 > parent->fh) {
|
||||
y1 -= y2 - parent->fh;
|
||||
y2 = parent->fh;
|
||||
}
|
||||
|
||||
orx = max(x1, 0);
|
||||
ory = max(y1, 0);
|
||||
orw = min(x2 - x1, parent->fw - orx);
|
||||
orh = min(y2 - y1, parent->fh - ory);
|
||||
}
|
||||
|
||||
if (x2 > parent->fw) {
|
||||
x1 -= x2 - parent->fw;
|
||||
x2 = parent->fw;
|
||||
}
|
||||
|
||||
if (y1 < 0) {
|
||||
y2 += -y1;
|
||||
y1 = 0;
|
||||
}
|
||||
|
||||
if (y2 > parent->fh) {
|
||||
y1 -= y2 - parent->fh;
|
||||
y2 = parent->fh;
|
||||
}
|
||||
|
||||
orx = max(x1, 0);
|
||||
ory = max(y1, 0);
|
||||
orw = min(x2 - x1, parent->fw - orx);
|
||||
orh = min(y2 - y1, parent->fh - ory);
|
||||
}
|
||||
|
||||
leftBorder = skips(rqx1 - bx1, skip);
|
||||
upperBorder = skips(rqy1 - by1, skip);
|
||||
|
||||
|
@ -105,7 +105,7 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
|
||||
JaggedArray<float> blend(winw, winh);
|
||||
float contrastf = contrast / 100.f;
|
||||
|
||||
buildBlendMask(L, blend, winw, winh, contrastf, 1.f, autoContrast);
|
||||
buildBlendMask(L, blend, winw, winh, contrastf, autoContrast);
|
||||
contrast = contrastf * 100.f;
|
||||
|
||||
array2D<float>& redTmp = L; // L is not needed anymore => reuse it
|
||||
|
@ -106,7 +106,18 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
|
||||
const auto f_subsample =
|
||||
[multithread](array2D<float> &d, const array2D<float> &s) -> void
|
||||
{
|
||||
rescaleBilinear(s, d, multithread);
|
||||
if (d.width() == s.width() && d.height() == s.height()) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for if (multithread)
|
||||
#endif
|
||||
for (int y = 0; y < s.height(); ++y) {
|
||||
for (int x = 0; x < s.width(); ++x) {
|
||||
d[y][x] = s[y][x];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rescaleBilinear(s, d, multithread);
|
||||
}
|
||||
};
|
||||
|
||||
const auto f_mean =
|
||||
|
@ -545,7 +545,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
oprevi = orig_prev;
|
||||
|
||||
// Remove transformation if unneeded
|
||||
bool needstransform = ipf.needsTransform();
|
||||
bool needstransform = ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData());
|
||||
|
||||
if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) {
|
||||
assert(oprevi);
|
||||
@ -1349,7 +1349,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
|
||||
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw);
|
||||
ImProcFunctions ipf(&ppar, true);
|
||||
|
||||
if (ipf.needsTransform()) {
|
||||
if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {
|
||||
Imagefloat* trImg = new Imagefloat(fW, fH);
|
||||
ipf.transform(im, trImg, 0, 0, 0, 0, fW, fH, fW, fH,
|
||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
||||
|
@ -5131,11 +5131,11 @@ void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wi
|
||||
if (!params->epd.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if (params->wavelet.enabled && params->wavelet.tmrs != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
float stren = params->epd.strength;
|
||||
float edgest = params->epd.edgeStopping;
|
||||
float sca = params->epd.scale;
|
||||
@ -5245,11 +5245,11 @@ void ImProcFunctions::EPDToneMap (LabImage *lab, unsigned int Iterates, int skip
|
||||
if (!params->epd.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if (params->wavelet.enabled && params->wavelet.tmrs != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
float stren = params->epd.strength;
|
||||
float edgest = params->epd.edgeStopping;
|
||||
float sca = params->epd.scale;
|
||||
@ -5590,7 +5590,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
||||
|
||||
whiteclipg = CurveFactory::igamma2 ((float) (whiteclipg / 65535.0)) * 65535.0; //need to inverse gamma transform to get correct exposure compensation parameter
|
||||
|
||||
//corection with gamma
|
||||
//correction with gamma
|
||||
black = (int) ((65535 * black) / whiteclipg);
|
||||
//expcomp = log(65535.0 / (whiteclipg)) / log(2.0);
|
||||
|
||||
|
@ -84,8 +84,8 @@ class ImProcFunctions
|
||||
void calcVignettingParams(int oW, int oH, const procparams::VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul);
|
||||
|
||||
void transformLuminanceOnly(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH);
|
||||
void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap);
|
||||
void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap);
|
||||
void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer);
|
||||
void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer);
|
||||
|
||||
bool needsCA() const;
|
||||
bool needsDistortion() const;
|
||||
@ -119,7 +119,7 @@ public:
|
||||
}
|
||||
void setScale(double iscale);
|
||||
|
||||
bool needsTransform() const;
|
||||
bool needsTransform(int oW, int oH, int rawRotationDeg, const FramesMetaData *metadata) const;
|
||||
bool needsPCVignetting() const;
|
||||
|
||||
void firstAnalysis(const Imagefloat* const working, const procparams::ProcParams ¶ms, LUTu & vhist16);
|
||||
@ -156,7 +156,7 @@ public:
|
||||
// void colorCurve (LabImage* lold, LabImage* lnew);
|
||||
void sharpening(LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask = false);
|
||||
void sharpeningcam(CieImage* ncie, float** buffer, bool showMask = false);
|
||||
void transform(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage);
|
||||
void transform(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage, bool useOriginalBuffer = false);
|
||||
float resizeScale(const procparams::ProcParams* params, int fw, int fh, int &imw, int &imh);
|
||||
void lab2monitorRgb(LabImage* lab, Image8* image);
|
||||
void resize(Imagefloat* src, Imagefloat* dst, float dScale);
|
||||
|
@ -38,14 +38,8 @@ namespace {
|
||||
|
||||
inline void copyAndClampLine(const float *src, unsigned char *dst, const int W)
|
||||
{
|
||||
for (int j = 0, iy = 0; j < W; ++j) {
|
||||
float r = src[iy] * MAXVALF;
|
||||
float g = src[iy+1] * MAXVALF;
|
||||
float b = src[iy+2] * MAXVALF;
|
||||
dst[iy] = uint16ToUint8Rounded(CLIP(r));
|
||||
dst[iy+1] = uint16ToUint8Rounded(CLIP(g));
|
||||
dst[iy+2] = uint16ToUint8Rounded(CLIP(b));
|
||||
iy += 3;
|
||||
for (int j = 0; j < W * 3; ++j) {
|
||||
dst[j] = uint16ToUint8Rounded(CLIP(src[j] * MAXVALF));
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,8 +84,8 @@ void ImProcFunctions::lab2monitorRgb(LabImage* lab, Image8* image)
|
||||
{
|
||||
if (monitorTransform) {
|
||||
|
||||
int W = lab->W;
|
||||
int H = lab->H;
|
||||
const int W = lab->W;
|
||||
const int H = lab->H;
|
||||
unsigned char * data = image->data;
|
||||
|
||||
// cmsDoTransform is relatively expensive
|
||||
@ -100,18 +94,19 @@ void ImProcFunctions::lab2monitorRgb(LabImage* lab, Image8* image)
|
||||
#endif
|
||||
{
|
||||
AlignedBuffer<float> pBuf(3 * lab->W);
|
||||
AlignedBuffer<float> mBuf(3 * lab->W);
|
||||
|
||||
AlignedBuffer<float> mBuf;
|
||||
AlignedBuffer<float> gwBuf1;
|
||||
AlignedBuffer<float> gwBuf2;
|
||||
|
||||
if (gamutWarning) {
|
||||
gwBuf1.resize(3 * lab->W);
|
||||
gwBuf2.resize(3 * lab->W);
|
||||
mBuf.resize(3 * lab->W);
|
||||
}
|
||||
|
||||
float *buffer = pBuf.data;
|
||||
float *outbuffer = mBuf.data;
|
||||
float *outbuffer = gamutWarning ? mBuf.data : pBuf.data; // make in place transformations when gamutWarning is not needed
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16)
|
||||
@ -132,7 +127,7 @@ void ImProcFunctions::lab2monitorRgb(LabImage* lab, Image8* image)
|
||||
buffer[iy++] = rb[j] / 327.68f;
|
||||
}
|
||||
|
||||
cmsDoTransform (monitorTransform, buffer, outbuffer, W);
|
||||
cmsDoTransform(monitorTransform, buffer, outbuffer, W);
|
||||
copyAndClampLine(outbuffer, data + ix, W);
|
||||
|
||||
if (gamutWarning) {
|
||||
|
@ -256,7 +256,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const procparams::SharpeningPar
|
||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||
JaggedArray<float> blend(W, H);
|
||||
float contrast = sharpenParam.contrast / 100.f;
|
||||
buildBlendMask(lab->L, blend, W, H, contrast, 1.f);
|
||||
buildBlendMask(lab->L, blend, W, H, contrast);
|
||||
|
||||
if(showMask) {
|
||||
#ifdef _OPENMP
|
||||
|
@ -87,6 +87,29 @@ float normn (float a, float b, int n)
|
||||
}
|
||||
}
|
||||
|
||||
void logEncode(rtengine::Imagefloat *src, rtengine::Imagefloat *dest, bool multiThread) {
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic, 16) if(multiThread)
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < src->getHeight(); ++y) {
|
||||
int x = 0;
|
||||
#ifdef __SSE2__
|
||||
for (; x < src->getWidth() - 3; x += 4) {
|
||||
STVFU(dest->r(y, x), xlogf1(LVFU(src->r(y, x))));
|
||||
STVFU(dest->g(y, x), xlogf1(LVFU(src->g(y, x))));
|
||||
STVFU(dest->b(y, x), xlogf1(LVFU(src->b(y, x))));
|
||||
}
|
||||
#endif
|
||||
for (; x < src->getWidth(); ++x) {
|
||||
dest->r(y, x) = xlogf1(src->r(y, x));
|
||||
dest->g(y, x) = xlogf1(src->g(y, x));
|
||||
dest->b(y, x) = xlogf1(src->b(y, x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||
{
|
||||
@ -112,6 +135,33 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys,
|
||||
g = vhadd(weight * gv);
|
||||
b = vhadd(weight * bv);
|
||||
}
|
||||
|
||||
inline void interpolateTransformCubicLog(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||
{
|
||||
constexpr float A = -0.85f;
|
||||
|
||||
// Vertical
|
||||
const float t1Vert = A * (Dy - Dy * Dy);
|
||||
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||
const vfloat w3Vert = F2V(t1Vert * Dy);
|
||||
const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert);
|
||||
const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert);
|
||||
const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy));
|
||||
|
||||
const vfloat rv = (w0Vert * LVFU(src->r(ys, xs)) + w1Vert * LVFU(src->r(ys + 1, xs))) + (w2Vert * LVFU(src->r(ys + 2, xs)) + w3Vert * LVFU(src->r(ys + 3, xs)));
|
||||
const vfloat gv = (w0Vert * LVFU(src->g(ys, xs)) + w1Vert * LVFU(src->g(ys + 1, xs))) + (w2Vert * LVFU(src->g(ys + 2, xs)) + w3Vert * LVFU(src->g(ys + 3, xs)));
|
||||
const vfloat bv = (w0Vert * LVFU(src->b(ys, xs)) + w1Vert * LVFU(src->b(ys + 1, xs))) + (w2Vert * LVFU(src->b(ys + 2, xs)) + w3Vert * LVFU(src->b(ys + 3, xs)));
|
||||
|
||||
// Horizontal
|
||||
const float t1Hor = A * (Dx - Dx * Dx);
|
||||
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||
const vfloat tempv = _mm_setr_ps(vhadd(weight * rv), vhadd(weight * gv), vhadd(weight * bv), 0.f);
|
||||
const vfloat resultv = xexpf(tempv);
|
||||
r = mul * resultv[0];
|
||||
g = mul * resultv[1];
|
||||
b = mul * resultv[2];
|
||||
}
|
||||
#else
|
||||
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||
{
|
||||
@ -144,6 +194,38 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys,
|
||||
g = mul * (gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor);
|
||||
b = mul * (bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor);
|
||||
}
|
||||
|
||||
inline void interpolateTransformCubicLog(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||
{
|
||||
constexpr float A = -0.85f;
|
||||
|
||||
// Vertical
|
||||
const float t1Vert = A * (Dy - Dy * Dy);
|
||||
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||
const float w3Vert = t1Vert * Dy;
|
||||
const float w2Vert = t1Vert * Dy - t1Vert + t2Vert;
|
||||
const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert;
|
||||
const float w0Vert = t1Vert - (t1Vert * Dy);
|
||||
|
||||
float rv[4], gv[4], bv[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
rv[i] = w0Vert * src->r(ys, xs + i) + w1Vert * src->r(ys + 1, xs + i) + w2Vert * src->r(ys + 2, xs + i) + w3Vert * src->r(ys + 3, xs + i);
|
||||
gv[i] = w0Vert * src->g(ys, xs + i) + w1Vert * src->g(ys + 1, xs + i) + w2Vert * src->g(ys + 2, xs + i) + w3Vert * src->g(ys + 3, xs + i);
|
||||
bv[i] = w0Vert * src->b(ys, xs + i) + w1Vert * src->b(ys + 1, xs + i) + w2Vert * src->b(ys + 2, xs + i) + w3Vert * src->b(ys + 3, xs + i);
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
const float t1Hor = A * (Dx - Dx * Dx);
|
||||
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||
const float w3Hor = t1Hor * Dx;
|
||||
const float w2Hor = t1Hor * Dx - t1Hor + t2Hor;
|
||||
const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor;
|
||||
const float w0Hor = t1Hor - (t1Hor * Dx);
|
||||
|
||||
r = mul * xexpf(rv[0] * w0Hor + rv[1] * w1Hor + rv[2] * w2Hor + rv[3] * w3Hor);
|
||||
g = mul * xexpf(gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor);
|
||||
b = mul * xexpf(bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor);
|
||||
}
|
||||
#endif
|
||||
#ifdef __SSE2__
|
||||
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||
@ -166,6 +248,27 @@ inline void interpolateTransformChannelsCubic(const float* const* src, int xs, i
|
||||
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||
dest = mul * vhadd(weight * cv);
|
||||
}
|
||||
|
||||
inline void interpolateTransformChannelsCubicLog(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||
{
|
||||
constexpr float A = -0.85f;
|
||||
|
||||
// Vertical
|
||||
const float t1Vert = A * (Dy - Dy * Dy);
|
||||
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||
const vfloat w3Vert = F2V(t1Vert * Dy);
|
||||
const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert);
|
||||
const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert);
|
||||
const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy));
|
||||
|
||||
const vfloat cv = (w0Vert * LVFU(src[ys][xs]) + w1Vert * LVFU(src[ys + 1][xs])) + (w2Vert * LVFU(src[ys + 2][xs]) + w3Vert * LVFU(src[ys + 3][xs]));
|
||||
|
||||
// Horizontal
|
||||
const float t1Hor = A * (Dx - Dx * Dx);
|
||||
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||
dest = mul * xexpf(vhadd(weight * cv));
|
||||
}
|
||||
#else
|
||||
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||
{
|
||||
@ -194,6 +297,34 @@ inline void interpolateTransformChannelsCubic(const float* const* src, int xs, i
|
||||
|
||||
dest = mul * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor);
|
||||
}
|
||||
|
||||
inline void interpolateTransformChannelsCubicLog(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||
{
|
||||
constexpr float A = -0.85f;
|
||||
|
||||
// Vertical
|
||||
const float t1Vert = A * (Dy - Dy * Dy);
|
||||
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||
const float w3Vert = t1Vert * Dy;
|
||||
const float w2Vert = t1Vert * Dy - t1Vert + t2Vert;
|
||||
const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert;
|
||||
const float w0Vert = t1Vert - (t1Vert * Dy);
|
||||
|
||||
float cv[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
cv[i] = w0Vert * src[ys][xs + i] + w1Vert * src[ys + 1][xs + i] + w2Vert * src[ys + 2][xs + i] + w3Vert * src[ys + 3][xs + i];
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
const float t1Hor = A * (Dx - Dx * Dx);
|
||||
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||
const float w3Hor = t1Hor * Dx;
|
||||
const float w2Hor = t1Hor * Dx - t1Hor + t2Hor;
|
||||
const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor;
|
||||
const float w0Hor = t1Hor - (t1Hor * Dx);
|
||||
|
||||
dest = mul * xexpf(cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -522,7 +653,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
||||
|
||||
void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
||||
const FramesMetaData *metadata,
|
||||
int rawRotationDeg, bool fullImage)
|
||||
int rawRotationDeg, bool fullImage, bool useOriginalBuffer)
|
||||
{
|
||||
double focalLen = metadata->getFocalLen();
|
||||
double focalLen35mm = metadata->getFocalLen35mm();
|
||||
@ -570,10 +701,10 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed,
|
||||
dest = tmpimg.get();
|
||||
}
|
||||
}
|
||||
transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get());
|
||||
transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get(), useOriginalBuffer);
|
||||
|
||||
if (highQuality && dest != transformed) {
|
||||
transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get());
|
||||
transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get(), useOriginalBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -962,8 +1093,9 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
|
||||
}
|
||||
|
||||
|
||||
void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap)
|
||||
void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer)
|
||||
{
|
||||
|
||||
// set up stuff, depending on the mode we are
|
||||
enum PerspType { NONE, SIMPLE, CAMERA_BASED };
|
||||
const bool enableLCPDist = pLCPMap && params->lensProf.useDist;
|
||||
@ -994,11 +1126,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
||||
}
|
||||
|
||||
const std::array<const float* const*, 3> chOrig = {
|
||||
original->r.ptrs,
|
||||
original->g.ptrs,
|
||||
original->b.ptrs
|
||||
};
|
||||
const std::array<float* const*, 3> chTrans = {
|
||||
transformed->r.ptrs,
|
||||
transformed->g.ptrs,
|
||||
@ -1023,12 +1150,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
const double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||
const double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||
|
||||
const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0;
|
||||
|
||||
const bool darkening = (params->vignetting.amount <= 0.0);
|
||||
const double centerFactorx = cx - w2;
|
||||
const double centerFactory = cy - h2;
|
||||
|
||||
// auxiliary variables for perspective correction
|
||||
// Simple.
|
||||
const double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
||||
@ -1064,6 +1185,30 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
p_projection_rotate, p_projection_shift_horiz,
|
||||
p_projection_shift_vert, p_projection_scale);
|
||||
|
||||
const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0;
|
||||
|
||||
const bool darkening = (params->vignetting.amount <= 0.0);
|
||||
const bool useLog = params->commonTrans.method == "log" && highQuality;
|
||||
const double centerFactorx = cx - w2;
|
||||
const double centerFactory = cy - h2;
|
||||
|
||||
std::unique_ptr<Imagefloat> tempLog;
|
||||
if (useLog) {
|
||||
if (!useOriginalBuffer) {
|
||||
tempLog.reset(new Imagefloat(original->getWidth(), original->getHeight()));
|
||||
logEncode(original, tempLog.get(), multiThread);
|
||||
original = tempLog.get();
|
||||
} else {
|
||||
logEncode(original, original, multiThread);
|
||||
}
|
||||
}
|
||||
|
||||
const std::array<const float* const*, 3> chOrig = {
|
||||
original->r.ptrs,
|
||||
original->g.ptrs,
|
||||
original->b.ptrs
|
||||
};
|
||||
|
||||
// main cycle
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic, 16) if(multiThread)
|
||||
@ -1161,14 +1306,22 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
|
||||
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
||||
// all interpolation pixels inside image
|
||||
if (enableCA) {
|
||||
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
||||
} else if (!highQuality) {
|
||||
if (!highQuality) {
|
||||
transformed->r(y, x) = vignmul * (original->r(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r(yc, xc + 1) * Dx * (1.0 - Dy) + original->r(yc + 1, xc) * (1.0 - Dx) * Dy + original->r(yc + 1, xc + 1) * Dx * Dy);
|
||||
transformed->g(y, x) = vignmul * (original->g(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g(yc, xc + 1) * Dx * (1.0 - Dy) + original->g(yc + 1, xc) * (1.0 - Dx) * Dy + original->g(yc + 1, xc + 1) * Dx * Dy);
|
||||
transformed->b(y, x) = vignmul * (original->b(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b(yc, xc + 1) * Dx * (1.0 - Dy) + original->b(yc + 1, xc) * (1.0 - Dx) * Dy + original->b(yc + 1, xc + 1) * Dx * Dy);
|
||||
} else if (!useLog) {
|
||||
if (enableCA) {
|
||||
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
||||
} else {
|
||||
interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
||||
}
|
||||
} else {
|
||||
interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
||||
if (enableCA) {
|
||||
interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
||||
} else {
|
||||
interpolateTransformCubicLog(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// edge pixels
|
||||
@ -1177,12 +1330,22 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
const int x1 = LIM(xc, 0, original->getWidth() - 1);
|
||||
const int x2 = LIM(xc + 1, 0, original->getWidth() - 1);
|
||||
|
||||
if (enableCA) {
|
||||
chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
if (useLog) {
|
||||
if (enableCA) {
|
||||
chTrans[c][y][x] = vignmul * xexpf(chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
} else {
|
||||
transformed->r(y, x) = vignmul * xexpf(original->r(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r(y1, x2) * Dx * (1.0 - Dy) + original->r(y2, x1) * (1.0 - Dx) * Dy + original->r(y2, x2) * Dx * Dy);
|
||||
transformed->g(y, x) = vignmul * xexpf(original->g(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g(y1, x2) * Dx * (1.0 - Dy) + original->g(y2, x1) * (1.0 - Dx) * Dy + original->g(y2, x2) * Dx * Dy);
|
||||
transformed->b(y, x) = vignmul * xexpf(original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
||||
}
|
||||
} else {
|
||||
transformed->r(y, x) = vignmul * (original->r(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r(y1, x2) * Dx * (1.0 - Dy) + original->r(y2, x1) * (1.0 - Dx) * Dy + original->r(y2, x2) * Dx * Dy);
|
||||
transformed->g(y, x) = vignmul * (original->g(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g(y1, x2) * Dx * (1.0 - Dy) + original->g(y2, x1) * (1.0 - Dx) * Dy + original->g(y2, x2) * Dx * Dy);
|
||||
transformed->b(y, x) = vignmul * (original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
||||
if (enableCA) {
|
||||
chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
} else {
|
||||
transformed->r(y, x) = vignmul * (original->r(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r(y1, x2) * Dx * (1.0 - Dy) + original->r(y2, x1) * (1.0 - Dx) * Dy + original->r(y2, x2) * Dx * Dy);
|
||||
transformed->g(y, x) = vignmul * (original->g(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g(y1, x2) * Dx * (1.0 - Dy) + original->g(y2, x1) * (1.0 - Dx) * Dy + original->g(y2, x2) * Dx * Dy);
|
||||
transformed->b(y, x) = vignmul * (original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1201,19 +1364,24 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
||||
}
|
||||
|
||||
|
||||
void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap)
|
||||
void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer)
|
||||
{
|
||||
assert(pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable());
|
||||
const bool useLog = params->commonTrans.method == "log";
|
||||
|
||||
float** chOrig[3];
|
||||
chOrig[0] = original->r.ptrs;
|
||||
chOrig[1] = original->g.ptrs;
|
||||
chOrig[2] = original->b.ptrs;
|
||||
float** chTrans[3] = {transformed->r.ptrs, transformed->g.ptrs, transformed->b.ptrs};
|
||||
|
||||
float** chTrans[3];
|
||||
chTrans[0] = transformed->r.ptrs;
|
||||
chTrans[1] = transformed->g.ptrs;
|
||||
chTrans[2] = transformed->b.ptrs;
|
||||
std::unique_ptr<Imagefloat> tempLog;
|
||||
if (useLog) {
|
||||
if (!useOriginalBuffer) {
|
||||
tempLog.reset(new Imagefloat(original->getWidth(), original->getHeight()));
|
||||
logEncode(original, tempLog.get(), multiThread);
|
||||
original = tempLog.get();
|
||||
} else {
|
||||
logEncode(original, original, multiThread);
|
||||
}
|
||||
}
|
||||
float** chOrig[3] = {original->r.ptrs, original->g.ptrs, original->b.ptrs};
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for if (multiThread)
|
||||
@ -1239,15 +1407,22 @@ void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *trans
|
||||
// multiplier for vignetting correction
|
||||
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
||||
// all interpolation pixels inside image
|
||||
interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
||||
if (!useLog) {
|
||||
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
||||
} else {
|
||||
interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
||||
}
|
||||
} else {
|
||||
// edge pixels
|
||||
int y1 = LIM (yc, 0, original->getHeight() - 1);
|
||||
int y2 = LIM (yc + 1, 0, original->getHeight() - 1);
|
||||
int x1 = LIM (xc, 0, original->getWidth() - 1);
|
||||
int x2 = LIM (xc + 1, 0, original->getWidth() - 1);
|
||||
|
||||
chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
if (!useLog) {
|
||||
chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
} else {
|
||||
chTrans[c][y][x] = xexpf(chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// not valid (source pixel x,y not inside source image, etc.)
|
||||
@ -1341,9 +1516,14 @@ bool ImProcFunctions::needsLensfun() const
|
||||
return params->lensProf.useLensfun();
|
||||
}
|
||||
|
||||
bool ImProcFunctions::needsTransform () const
|
||||
bool ImProcFunctions::needsTransform (int oW, int oH, int rawRotationDeg, const FramesMetaData *metadata) const
|
||||
{
|
||||
return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLensfun();
|
||||
bool needsLf = needsLensfun();
|
||||
if (needsLf) {
|
||||
std::unique_ptr<const LensCorrection> pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg);
|
||||
needsLf = pLCPMap.get();
|
||||
}
|
||||
return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLf;
|
||||
}
|
||||
|
||||
|
||||
|
@ -271,7 +271,7 @@ PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *sr
|
||||
neutral.distortion = pparams->distortion;
|
||||
neutral.lensProf = pparams->lensProf;
|
||||
ImProcFunctions ipf(&neutral, true);
|
||||
if (ipf.needsTransform()) {
|
||||
if (ipf.needsTransform(w, h, src->getRotateDegree(), src->getMetaData())) {
|
||||
Imagefloat *tmp = new Imagefloat(w, h);
|
||||
ipf.transform(img.get(), tmp, 0, 0, 0, 0, w, h, w, h,
|
||||
src->getMetaData(), src->getRotateDegree(), false);
|
||||
|
@ -1732,13 +1732,14 @@ bool CoarseTransformParams::operator !=(const CoarseTransformParams& other) cons
|
||||
}
|
||||
|
||||
CommonTransformParams::CommonTransformParams() :
|
||||
method("log"),
|
||||
autofill(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool CommonTransformParams::operator ==(const CommonTransformParams& other) const
|
||||
{
|
||||
return autofill == other.autofill;
|
||||
return method == other.method && autofill == other.autofill;
|
||||
}
|
||||
|
||||
bool CommonTransformParams::operator !=(const CommonTransformParams& other) const
|
||||
@ -3350,6 +3351,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
|
||||
saveToKeyfile(!pedited || pedited->coarse.vflip, "Coarse Transformation", "VerticalFlip", coarse.vflip, keyFile);
|
||||
|
||||
// Common properties for transformations
|
||||
saveToKeyfile(!pedited || pedited->commonTrans.method, "Common Properties for Transformations", "Method", commonTrans.method, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->commonTrans.autofill, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, keyFile);
|
||||
|
||||
// Rotation
|
||||
@ -4403,6 +4405,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
||||
}
|
||||
|
||||
if (keyFile.has_group("Common Properties for Transformations")) {
|
||||
if (keyFile.has_key("Common Properties for Transformations", "Method")) {
|
||||
assignFromKeyfile(keyFile, "Common Properties for Transformations", "Method", pedited, commonTrans.method, pedited->commonTrans.method);
|
||||
} else {
|
||||
commonTrans.method = "lin";
|
||||
}
|
||||
assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", pedited, commonTrans.autofill, pedited->commonTrans.autofill);
|
||||
}
|
||||
|
||||
|
@ -837,6 +837,7 @@ struct CoarseTransformParams {
|
||||
* Common transformation parameters
|
||||
*/
|
||||
struct CommonTransformParams {
|
||||
Glib::ustring method;
|
||||
bool autofill;
|
||||
|
||||
CommonTransformParams();
|
||||
|
@ -263,10 +263,9 @@ void cfaboxblur(const float* const * riFlatFile, float* cfablur, int boxH, int b
|
||||
namespace rtengine
|
||||
{
|
||||
|
||||
void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const unsigned short black[4])
|
||||
void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const float black[4])
|
||||
{
|
||||
// BENCHFUN
|
||||
const float fblack[4] = {static_cast<float>(black[0]), static_cast<float>(black[1]), static_cast<float>(black[2]), static_cast<float>(black[3])};
|
||||
std::unique_ptr<float[]> cfablur(new float[H * W]);
|
||||
|
||||
const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1);
|
||||
@ -292,7 +291,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
const int col = 2 * (W >> 2) + n;
|
||||
const int c = ri->get_colors() != 1 ? FC(row, col) : 0;
|
||||
const int c4 = ri->get_colors() != 1 ? ((c == 1 && !(row & 1)) ? 3 : c) : 0;
|
||||
refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - fblack[c4]);
|
||||
refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - black[c4]);
|
||||
}
|
||||
|
||||
float limitFactor = 1.f;
|
||||
@ -315,16 +314,16 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
clippedBefore = true;
|
||||
break;
|
||||
}
|
||||
const float tempval = (rawVal - fblack[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - fblack[c4]));
|
||||
const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]));
|
||||
maxval = std::max(maxval, tempval);
|
||||
}
|
||||
}
|
||||
|
||||
// now we have the max value for the channel
|
||||
// if it clips, calculate factor to avoid clipping
|
||||
if (maxval + fblack[c4] >= ri->get_white(c4)) {
|
||||
if (maxval + black[c4] >= ri->get_white(c4)) {
|
||||
if (!clippedBefore) {
|
||||
limitFactor = std::min(limitFactor, ri->get_white(c4) / (maxval + fblack[c4]));
|
||||
limitFactor = std::min(limitFactor, ri->get_white(c4) / (maxval + black[c4]));
|
||||
} else {
|
||||
limitFactor = 1.f;
|
||||
}
|
||||
@ -361,8 +360,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
const vfloat refcolorv[2] = {_mm_set_ps(refcolor[0][1], refcolor[0][0], refcolor[0][1], refcolor[0][0]),
|
||||
_mm_set_ps(refcolor[1][1], refcolor[1][0], refcolor[1][1], refcolor[1][0])
|
||||
};
|
||||
const vfloat blackv[2] = {_mm_set_ps(fblack[c4[0][1]], fblack[c4[0][0]], fblack[c4[0][1]], fblack[c4[0][0]]),
|
||||
_mm_set_ps(fblack[c4[1][1]], fblack[c4[1][0]], fblack[c4[1][1]], fblack[c4[1][0]])
|
||||
const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
|
||||
_mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]])
|
||||
};
|
||||
|
||||
const vfloat onev = F2V(1.f);
|
||||
@ -389,9 +388,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
#endif
|
||||
|
||||
for (; col < W; ++col) {
|
||||
const float blur = cfablur[row * W + col] - fblack[c4[row & 1][col & 1]];
|
||||
const float blur = cfablur[row * W + col] - black[c4[row & 1][col & 1]];
|
||||
const float vignettecorr = blur <= minValue ? 1.f : refcolor[row & 1][col & 1] / blur;
|
||||
rawData[row][col] = (rawData[row][col] - fblack[c4[row & 1][col & 1]]) * vignettecorr + fblack[c4[row & 1][col & 1]];
|
||||
rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * vignettecorr + black[c4[row & 1][col & 1]];
|
||||
}
|
||||
}
|
||||
} else if (ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
@ -404,7 +403,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
const int row = 2 * (H >> 2) + m;
|
||||
const int col = 2 * (W >> 2) + n;
|
||||
const int c = riFlatFile->XTRANSFC(row, col);
|
||||
refcolor[c] += std::max(0.0f, cfablur[row * W + col] - fblack[c]);
|
||||
refcolor[c] += std::max(0.0f, cfablur[row * W + col] - black[c]);
|
||||
cCount[c] ++;
|
||||
}
|
||||
|
||||
@ -430,14 +429,14 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
clippedBefore = true;
|
||||
break;
|
||||
}
|
||||
const float tempval = (rawVal - fblack[0]) * (refcolor[ri->XTRANSFC(row, col)] / std::max(1e-5f, cfablur[(row) * W + col] - fblack[0]));
|
||||
const float tempval = (rawVal - black[0]) * (refcolor[ri->XTRANSFC(row, col)] / std::max(1e-5f, cfablur[(row) * W + col] - black[0]));
|
||||
maxval = std::max(maxval, tempval);
|
||||
}
|
||||
}
|
||||
|
||||
// there's only one white level for xtrans
|
||||
if (!clippedBefore && maxval + fblack[0] > ri->get_white(0)) {
|
||||
limitFactor = ri->get_white(0) / (maxval + fblack[0]);
|
||||
if (!clippedBefore && maxval + black[0] > ri->get_white(0)) {
|
||||
limitFactor = ri->get_white(0) / (maxval + black[0]);
|
||||
flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
|
||||
}
|
||||
} else {
|
||||
@ -458,9 +457,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
for (int row = 0; row < H; ++row) {
|
||||
for (int col = 0; col < W; ++col) {
|
||||
const int c = ri->XTRANSFC(row, col);
|
||||
const float blur = cfablur[(row) * W + col] - fblack[c];
|
||||
const float blur = cfablur[(row) * W + col] - black[c];
|
||||
const float vignettecorr = blur <= minValue ? 1.f : refcolor[c] / blur;
|
||||
rawData[row][col] = (rawData[row][col] - fblack[c]) * vignettecorr + fblack[c];
|
||||
rawData[row][col] = (rawData[row][col] - black[c]) * vignettecorr + black[c];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -488,8 +487,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
const vfloat blackv[2] = {_mm_set_ps(fblack[c4[0][1]], fblack[c4[0][0]], fblack[c4[0][1]], fblack[c4[0][0]]),
|
||||
_mm_set_ps(fblack[c4[1][1]], fblack[c4[1][0]], fblack[c4[1][1]], fblack[c4[1][0]])
|
||||
const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]),
|
||||
_mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]])
|
||||
};
|
||||
|
||||
const vfloat epsv = F2V(1e-5f);
|
||||
@ -513,9 +512,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
#endif
|
||||
|
||||
for (; col < W; ++col) {
|
||||
const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - fblack[c4[row & 1][col & 1]])) /
|
||||
(std::max(1e-5f, cfablur1[row * W + col] - fblack[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - fblack[c4[row & 1][col & 1]]));
|
||||
rawData[row][col] = (rawData[row][col] - fblack[c4[row & 1][col & 1]]) * linecorr + fblack[c4[row & 1][col & 1]];
|
||||
const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - black[c4[row & 1][col & 1]])) /
|
||||
(std::max(1e-5f, cfablur1[row * W + col] - black[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - black[c4[row & 1][col & 1]]));
|
||||
rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * linecorr + black[c4[row & 1][col & 1]];
|
||||
}
|
||||
}
|
||||
} else if (ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
@ -526,9 +525,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra
|
||||
for (int row = 0; row < H; ++row) {
|
||||
for (int col = 0; col < W; ++col) {
|
||||
const int c = ri->XTRANSFC(row, col);
|
||||
const float hlinecorr = std::max(1e-5f, cfablur[(row) * W + col] - fblack[c]) / std::max(1e-5f, cfablur1[(row) * W + col] - fblack[c]);
|
||||
const float vlinecorr = std::max(1e-5f, cfablur[(row) * W + col] - fblack[c]) / std::max(1e-5f, cfablur2[(row) * W + col] - fblack[c]);
|
||||
rawData[row][col] = (rawData[row][col] - fblack[c]) * hlinecorr * vlinecorr + fblack[c];
|
||||
const float hlinecorr = std::max(1e-5f, cfablur[(row) * W + col] - black[c]) / std::max(1e-5f, cfablur1[(row) * W + col] - black[c]);
|
||||
const float vlinecorr = std::max(1e-5f, cfablur[(row) * W + col] - black[c]) / std::max(1e-5f, cfablur2[(row) * W + col] - black[c]);
|
||||
rawData[row][col] = (rawData[row][col] - black[c]) * hlinecorr * vlinecorr + black[c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "../rtgui/options.h"
|
||||
|
||||
//#define BENCHMARK
|
||||
//#include "StopWatch.h"
|
||||
#include "StopWatch.h"
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
@ -2397,11 +2397,10 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp)
|
||||
*/
|
||||
void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData )
|
||||
{
|
||||
// TODO: Change type of black[] to float to avoid conversions
|
||||
unsigned short black[4] = {
|
||||
(unsigned short)ri->get_cblack(0), (unsigned short)ri->get_cblack(1),
|
||||
(unsigned short)ri->get_cblack(2), (unsigned short)ri->get_cblack(3)
|
||||
};
|
||||
const float black[4] = {
|
||||
static_cast<float>(ri->get_cblack(0)), static_cast<float>(ri->get_cblack(1)),
|
||||
static_cast<float>(ri->get_cblack(2)), static_cast<float>(ri->get_cblack(3))
|
||||
};
|
||||
|
||||
if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
if (!rawData) {
|
||||
@ -2409,11 +2408,22 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw
|
||||
}
|
||||
|
||||
if (riDark && W == riDark->get_width() && H == riDark->get_height()) { // This works also for xtrans-sensors, because black[0] to black[4] are equal for these
|
||||
StopWatch Stop1("darkframe subtraction");
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
int c = FC(row, col);
|
||||
int c4 = ( c == 1 && !(row & 1) ) ? 3 : c;
|
||||
rawData[row][col] = max(src->data[row][col] + black[c4] - riDark->data[row][col], 0.0f);
|
||||
const int c0 = FC(row, 0);
|
||||
const float black0 = black[(c0 == 1 && !(row & 1) ) ? 3 : c0];
|
||||
const int c1 = FC(row, 1);
|
||||
const float black1 = black[(c1 == 1 && !(row & 1) ) ? 3 : c1];
|
||||
int col;
|
||||
for (col = 0; col < W - 1; col += 2) {
|
||||
rawData[row][col] = max(src->data[row][col] + black0 - riDark->data[row][col], 0.0f);
|
||||
rawData[row][col + 1] = max(src->data[row][col + 1] + black1 - riDark->data[row][col + 1], 0.0f);
|
||||
}
|
||||
if (col < W) {
|
||||
rawData[row][col] = max(src->data[row][col] + black0 - riDark->data[row][col], 0.0f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -136,7 +136,7 @@ public:
|
||||
return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified
|
||||
}
|
||||
|
||||
void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const unsigned short black[4]);
|
||||
void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const float black[4]);
|
||||
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
|
||||
void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D<float> &rawData); // raw for cblack
|
||||
|
||||
|
@ -299,7 +299,7 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float&
|
||||
maxOut = rtengine::LIM(maxOut, minVal, maxVal);
|
||||
}
|
||||
|
||||
void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast, float ** clipMask) {
|
||||
void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, bool autoContrast, float ** clipMask) {
|
||||
|
||||
if (autoContrast) {
|
||||
constexpr float minLuminance = 2000.f;
|
||||
@ -403,7 +403,7 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H,
|
||||
if(contrastThreshold == 0.f) {
|
||||
for(int j = 0; j < H; ++j) {
|
||||
for(int i = 0; i < W; ++i) {
|
||||
blend[j][i] = amount;
|
||||
blend[j][i] = 1.f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -415,7 +415,6 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H,
|
||||
#ifdef __SSE2__
|
||||
const vfloat contrastThresholdv = F2V(contrastThreshold);
|
||||
const vfloat scalev = F2V(scale);
|
||||
const vfloat amountv = F2V(amount);
|
||||
#endif
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16)
|
||||
@ -429,14 +428,14 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H,
|
||||
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
|
||||
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
|
||||
|
||||
STVFU(blend[j][i], LVFU(clipMask[j][i]) * amountv * calcBlendFactor(contrastv, contrastThresholdv));
|
||||
STVFU(blend[j][i], LVFU(clipMask[j][i]) * calcBlendFactor(contrastv, contrastThresholdv));
|
||||
}
|
||||
} else {
|
||||
for(; i < W - 5; i += 4) {
|
||||
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
|
||||
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
|
||||
|
||||
STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv));
|
||||
STVFU(blend[j][i], calcBlendFactor(contrastv, contrastThresholdv));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -445,7 +444,7 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H,
|
||||
float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) +
|
||||
rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale;
|
||||
|
||||
blend[j][i] = (clipMask ? clipMask[j][i] : 1.f) * amount * calcBlendFactor(contrast, contrastThreshold);
|
||||
blend[j][i] = (clipMask ? clipMask[j][i] : 1.f) * calcBlendFactor(contrast, contrastThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,5 +24,5 @@
|
||||
namespace rtengine
|
||||
{
|
||||
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
|
||||
void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false, float ** clipmask = nullptr);
|
||||
void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, bool autoContrast = false, float ** clipmask = nullptr);
|
||||
}
|
||||
|
@ -1247,12 +1247,12 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
|
||||
ipf.ToneMapFattal02(baseImg);
|
||||
|
||||
// perform transform
|
||||
if (ipf.needsTransform()) {
|
||||
int origFW;
|
||||
int origFH;
|
||||
double tscale = 0.0;
|
||||
getDimensions (origFW, origFH, tscale);
|
||||
if (ipf.needsTransform(origFW * tscale + 0.5, origFH * tscale + 0.5, 0, metadata)) {
|
||||
Imagefloat* trImg = new Imagefloat (fw, fh);
|
||||
int origFW;
|
||||
int origFH;
|
||||
double tscale = 0.0;
|
||||
getDimensions (origFW, origFH, tscale);
|
||||
ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, origFW * tscale + 0.5, origFH * tscale + 0.5, metadata, 0, true); // Raw rotate degree not detectable here
|
||||
delete baseImg;
|
||||
baseImg = trImg;
|
||||
|
@ -872,7 +872,7 @@ private:
|
||||
ipf.ToneMapFattal02(baseImg);
|
||||
|
||||
// perform transform (excepted resizing)
|
||||
if (ipf.needsTransform()) {
|
||||
if (ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {
|
||||
Imagefloat* trImg = nullptr;
|
||||
if (ipf.needsLuminanceOnly()) {
|
||||
trImg = baseImg;
|
||||
@ -880,7 +880,7 @@ private:
|
||||
trImg = new Imagefloat (fw, fh);
|
||||
}
|
||||
ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh,
|
||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true, true);
|
||||
if(trImg != baseImg) {
|
||||
delete baseImg;
|
||||
baseImg = trImg;
|
||||
|
@ -532,7 +532,7 @@ __inline double xlog(double d) {
|
||||
|
||||
x = x * t + 0.693147180559945286226764 * e;
|
||||
|
||||
if (xisinf(d)) x = rtengine::RT_INFINITY;
|
||||
if (xispinf(d)) x = rtengine::RT_INFINITY;
|
||||
if (d < 0) x = rtengine::RT_NAN;
|
||||
if (d == 0) x = -rtengine::RT_INFINITY;
|
||||
|
||||
@ -864,7 +864,7 @@ __inline double xlog10(double a) {
|
||||
double2 d = mul_dd(logk(a), dd(0.43429448190325176116, 6.6494347733425473126e-17));
|
||||
double x = d.x + d.y;
|
||||
|
||||
if (xisinf(a)) x = rtengine::RT_INFINITY;
|
||||
if (xispinf(a)) x = rtengine::RT_INFINITY;
|
||||
if (a < 0) x = rtengine::RT_NAN;
|
||||
if (a == 0) x = -rtengine::RT_INFINITY;
|
||||
|
||||
@ -875,7 +875,7 @@ __inline double xlog1p(double a) {
|
||||
double2 d = logk2(add2_ss(a, 1));
|
||||
double x = d.x + d.y;
|
||||
|
||||
if (xisinf(a)) x = rtengine::RT_INFINITY;
|
||||
if (xispinf(a)) x = rtengine::RT_INFINITY;
|
||||
if (a < -1) x = rtengine::RT_NAN;
|
||||
if (a == -1) x = -rtengine::RT_INFINITY;
|
||||
|
||||
@ -894,6 +894,15 @@ __inline double xlog1p(double a) {
|
||||
|
||||
#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f
|
||||
|
||||
#ifdef __SSE2__
|
||||
__inline int xrintf(float x) {
|
||||
return _mm_cvt_ss2si(_mm_set_ss(x));
|
||||
}
|
||||
#else
|
||||
__inline int xrintf(float x) {
|
||||
return x + (x < 0 ? -0.5f : 0.5f);
|
||||
}
|
||||
#endif
|
||||
__inline int32_t floatToRawIntBits(float d) {
|
||||
union {
|
||||
float f;
|
||||
@ -980,7 +989,7 @@ __inline float xsinf(float d) {
|
||||
int q;
|
||||
float u, s;
|
||||
|
||||
q = rint(d * rtengine::RT_1_PI_F);
|
||||
q = xrintf(d * rtengine::RT_1_PI_F);
|
||||
|
||||
d = mlaf(q, -PI4_Af*4, d);
|
||||
d = mlaf(q, -PI4_Bf*4, d);
|
||||
@ -1009,7 +1018,7 @@ __inline float xcosf(float d) {
|
||||
int q;
|
||||
float u, s;
|
||||
|
||||
q = 1 + 2*rint(d * rtengine::RT_1_PI_F - 0.5f);
|
||||
q = 1 + 2*xrintf(d * rtengine::RT_1_PI_F - 0.5f);
|
||||
|
||||
d = mlaf(q, -PI4_Af*2, d);
|
||||
d = mlaf(q, -PI4_Bf*2, d);
|
||||
@ -1041,7 +1050,7 @@ __inline float2 xsincosf(float d) {
|
||||
float u, s, t;
|
||||
float2 r;
|
||||
|
||||
q = rint(d * rtengine::RT_2_PI_F);
|
||||
q = xrintf(d * rtengine::RT_2_PI_F);
|
||||
|
||||
s = d;
|
||||
|
||||
@ -1083,7 +1092,7 @@ __inline float xtanf(float d) {
|
||||
int q;
|
||||
float u, s, x;
|
||||
|
||||
q = rint(d * (float)(2 * rtengine::RT_1_PI));
|
||||
q = xrintf(d * (float)(2 * rtengine::RT_1_PI));
|
||||
|
||||
x = d;
|
||||
|
||||
@ -1199,17 +1208,41 @@ __inline float xlogf(float d) {
|
||||
|
||||
x = x * t + 0.693147180559945286226764f * e;
|
||||
|
||||
if (xisinff(d)) x = rtengine::RT_INFINITY_F;
|
||||
if (xispinff(d)) x = rtengine::RT_INFINITY_F;
|
||||
if (d < 0) x = rtengine::RT_NAN_F;
|
||||
if (d == 0) x = -rtengine::RT_INFINITY_F;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
__inline float xlogf1(float d) { // does xlogf(vmaxf(d, 1.f)) but faster
|
||||
float x, x2, t, m;
|
||||
int e;
|
||||
|
||||
e = ilogbp1f(d * 0.7071f);
|
||||
m = ldexpkf(d, -e);
|
||||
|
||||
x = (m-1.0f) / (m+1.0f);
|
||||
x2 = x * x;
|
||||
|
||||
t = 0.2371599674224853515625f;
|
||||
t = mlaf(t, x2, 0.285279005765914916992188f);
|
||||
t = mlaf(t, x2, 0.400005519390106201171875f);
|
||||
t = mlaf(t, x2, 0.666666567325592041015625f);
|
||||
t = mlaf(t, x2, 2.0f);
|
||||
|
||||
x = x * t + 0.693147180559945286226764f * e;
|
||||
|
||||
if (xispinff(d)) x = rtengine::RT_INFINITY_F;
|
||||
if (d <= 1.f) x = 0;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
__inline float xexpf(float d) {
|
||||
if(d<=-104.0f) return 0.0f;
|
||||
|
||||
int q = rint(d * R_LN2f);
|
||||
int q = xrintf(d * R_LN2f);
|
||||
float s, u;
|
||||
|
||||
s = mlaf(q, -L2Uf, d);
|
||||
|
@ -1253,6 +1253,30 @@ static INLINE vfloat xlogf(vfloat d) {
|
||||
return x;
|
||||
}
|
||||
|
||||
static INLINE vfloat xlogf1(vfloat d) { // does xlogf(vmaxf(d, 1.f)) but faster
|
||||
vfloat x, x2, t, m;
|
||||
vint2 e;
|
||||
|
||||
e = vilogbp1f(vmulf(d, vcast_vf_f(0.7071f)));
|
||||
m = vldexpf(d, vsubi2(vcast_vi2_i(0), e));
|
||||
|
||||
x = vdivf(vaddf(vcast_vf_f(-1.0f), m), vaddf(vcast_vf_f(1.0f), m));
|
||||
x2 = vmulf(x, x);
|
||||
|
||||
t = vcast_vf_f(0.2371599674224853515625f);
|
||||
t = vmlaf(t, x2, vcast_vf_f(0.285279005765914916992188f));
|
||||
t = vmlaf(t, x2, vcast_vf_f(0.400005519390106201171875f));
|
||||
t = vmlaf(t, x2, vcast_vf_f(0.666666567325592041015625f));
|
||||
t = vmlaf(t, x2, vcast_vf_f(2.0f));
|
||||
|
||||
x = vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e)));
|
||||
|
||||
x = vself(vmaskf_ispinf(d), vcast_vf_f(INFINITYf), x);
|
||||
x = vselfnotzero(vmaskf_le(d, vcast_vf_f(1.f)), x);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static INLINE vfloat xlogf0(vfloat d) {
|
||||
vfloat x, x2, t, m;
|
||||
vint2 e;
|
||||
|
@ -1492,9 +1492,9 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
|
||||
const float kernel_size2 = SQR(2.f * blur_radius2 + 1.f); // count of pixels in the small blur kernel
|
||||
const float rkernel_size2 = 1.0f / kernel_size2; // reciprocal of kernel_size to avoid divisions
|
||||
|
||||
// aloocate buffer for precalculated Luminance
|
||||
// allocate buffer for precalculated Luminance
|
||||
float* tmpL = (float*)malloc(bHeight * bWidth * sizeof(float) );
|
||||
// aloocate buffers for sums and sums of squares of small kernel
|
||||
// allocate buffers for sums and sums of squares of small kernel
|
||||
float* tmpLsum = (float*)malloc((bHeight) * (bWidth) * sizeof(float) );
|
||||
float* tmpLsumSq = (float*)malloc((bHeight) * (bWidth) * sizeof(float) );
|
||||
float* tmpstdDev2 = (float*)malloc((bHeight) * (bWidth) * sizeof(float) );
|
||||
@ -1631,7 +1631,7 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
|
||||
&& stdDev_L2 > stdDev_L //this is the key to select fine detail within lower contrast on larger scale
|
||||
&& stdDev_L > focus_threshby10 //options.highlightThreshold
|
||||
) {
|
||||
// transpareny depends on sdtDev_L2 and maxstdDev_L2
|
||||
// transparency depends on sdtDev_L2 and maxstdDev_L2
|
||||
float transparency = 1.f - std::min(stdDev_L2 / maxstdDev_L2, 1.0f) ;
|
||||
// first row of circle
|
||||
guint8* currtmp = &curr[0] + (-3 * pixRowStride);
|
||||
|
@ -55,7 +55,7 @@ class RTSurface;
|
||||
* - drag1
|
||||
* - button1Released
|
||||
*
|
||||
* Actually, only curves does use this class, and everything is handled for curve implementor (as much as possible).
|
||||
* Actually, only curves does use this class, and everything is handled for curve implementer (as much as possible).
|
||||
* See the curve's class documentation to see how to implement the curve's pipette feature.
|
||||
*
|
||||
* ### Event handling
|
||||
|
22
rtgui/epd.cc
22
rtgui/epd.cc
@ -69,17 +69,18 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite
|
||||
|
||||
setEnabled(pp->epd.enabled);
|
||||
strength->set_sensitive (true);
|
||||
|
||||
if(pp->wavelet.enabled) {
|
||||
if(pp->wavelet.tmrs == 0) {
|
||||
gamma->set_sensitive (true);
|
||||
/*
|
||||
if(pp->wavelet.enabled) {
|
||||
if(pp->wavelet.tmrs == 0 || pp->wavelet.TMmethod == "cont") {
|
||||
strength->set_sensitive (true);
|
||||
gamma->set_sensitive (true);
|
||||
} else {
|
||||
} else if(pp->wavelet.tmrs != 0 && pp->wavelet.TMmethod == "tm") {
|
||||
strength->set_sensitive (false);
|
||||
gamma->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
strength->setValue(pp->epd.strength);
|
||||
gamma->setValue(pp->epd.gamma);
|
||||
edgeStopping->setValue(pp->epd.edgeStopping);
|
||||
@ -98,17 +99,18 @@ void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited)
|
||||
pp->epd.reweightingIterates = reweightingIterates->getValue();
|
||||
pp->epd.enabled = getEnabled();
|
||||
strength->set_sensitive (true);
|
||||
|
||||
if(pp->wavelet.enabled) {
|
||||
if(pp->wavelet.tmrs == 0) {
|
||||
gamma->set_sensitive (true);
|
||||
/*
|
||||
if(pp->wavelet.enabled) {
|
||||
if(pp->wavelet.tmrs == 0 || pp->wavelet.TMmethod == "cont") {
|
||||
strength->set_sensitive (true);
|
||||
gamma->set_sensitive (true);
|
||||
} else {
|
||||
} else if(pp->wavelet.tmrs != 0 && pp->wavelet.TMmethod == "tm") {
|
||||
strength->set_sensitive (false);
|
||||
gamma->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
if(pedited) {
|
||||
pedited->epd.strength = strength->getEditedState();
|
||||
pedited->epd.gamma = gamma->getEditedState();
|
||||
|
@ -14,7 +14,7 @@
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "filterpanel.h"
|
||||
#include "multilangmgr.h"
|
||||
@ -107,8 +107,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
||||
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);
|
||||
cvb->pack_start (*scamera, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||
pack_start (*cvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
|
||||
enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS") + ":"));
|
||||
Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ());
|
||||
@ -119,8 +119,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
||||
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);
|
||||
lvb->pack_start (*slens, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||
pack_start (*lvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
|
||||
enaFiletype = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FILETYPE") + ":"));
|
||||
Gtk::VBox* ftvb = Gtk::manage(new Gtk::VBox ());
|
||||
@ -131,8 +131,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
||||
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);
|
||||
ftvb->pack_start (*sfiletype, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||
pack_start (*ftvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
|
||||
// add panel ending
|
||||
Gtk::VBox* vboxpe = Gtk::manage (new Gtk::VBox ());
|
||||
|
@ -17,6 +17,8 @@
|
||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "lensgeom.h"
|
||||
|
||||
#include "eventmapper.h"
|
||||
#include "guiutils.h"
|
||||
#include "rtimage.h"
|
||||
|
||||
@ -28,6 +30,18 @@ using namespace rtengine::procparams;
|
||||
LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false)
|
||||
{
|
||||
|
||||
auto m = ProcEventMapper::getInstance();
|
||||
EvTransMethod = m->newEvent(TRANSFORM, "HISTORY_MSG_TRANS_METHOD");
|
||||
|
||||
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
|
||||
hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4);
|
||||
method = Gtk::manage (new MyComboBoxText ());
|
||||
method->append(M("TP_LENSGEOM_LOG"));
|
||||
method->append(M("TP_LENSGEOM_LIN"));
|
||||
method->set_active(0);
|
||||
hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL")));
|
||||
pack_start (*fill);
|
||||
|
||||
@ -39,8 +53,9 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGE
|
||||
packBox = Gtk::manage (new ToolParamBlock ());
|
||||
pack_start (*packBox);
|
||||
|
||||
autoCrop->signal_pressed().connect( sigc::mem_fun(*this, &LensGeometry::autoCropPressed) );
|
||||
fillConn = fill->signal_toggled().connect( sigc::mem_fun(*this, &LensGeometry::fillPressed) );
|
||||
method->connect(method->signal_changed().connect(sigc::mem_fun(*this, &LensGeometry::methodChanged)));
|
||||
autoCrop->signal_pressed().connect(sigc::mem_fun(*this, &LensGeometry::autoCropPressed));
|
||||
fillConn = fill->signal_toggled().connect(sigc::mem_fun(*this, &LensGeometry::fillPressed));
|
||||
|
||||
fill->set_active (true);
|
||||
show_all ();
|
||||
@ -55,8 +70,14 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
{
|
||||
|
||||
disableListener ();
|
||||
method->block (true);
|
||||
method->set_active(pp->commonTrans.method == "log" ? 0 : 1);
|
||||
|
||||
if (pedited) {
|
||||
if(!pedited->commonTrans.method) {
|
||||
method->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
}
|
||||
|
||||
fill->set_inconsistent (!pedited->commonTrans.autofill);
|
||||
}
|
||||
|
||||
@ -67,15 +88,20 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
|
||||
lastFill = pp->commonTrans.autofill;
|
||||
|
||||
method->block (false);
|
||||
enableListener ();
|
||||
}
|
||||
|
||||
void LensGeometry::write (ProcParams* pp, ParamsEdited* pedited)
|
||||
{
|
||||
|
||||
int currentRow = method->get_active_row_number();
|
||||
if( currentRow >= 0 && method->get_active_text() != M("GENERAL_UNCHANGED")) {
|
||||
pp->commonTrans.method = currentRow == 0 ? "log" : "lin";
|
||||
}
|
||||
pp->commonTrans.autofill = fill->get_active ();
|
||||
|
||||
if (pedited) {
|
||||
pedited->commonTrans.method = method->get_active_text() != M("GENERAL_UNCHANGED");
|
||||
pedited->commonTrans.autofill = !fill->get_inconsistent();
|
||||
}
|
||||
}
|
||||
@ -115,6 +141,14 @@ void LensGeometry::fillPressed ()
|
||||
}
|
||||
}
|
||||
|
||||
void LensGeometry::methodChanged ()
|
||||
{
|
||||
|
||||
if (listener && method->get_active_row_number() >= 0) {
|
||||
listener->panelChanged(EvTransMethod, method->get_active_text());
|
||||
}
|
||||
}
|
||||
|
||||
void LensGeometry::setBatchMode (bool batchMode)
|
||||
{
|
||||
|
||||
|
@ -29,6 +29,7 @@ class LensGeometry final :
|
||||
{
|
||||
|
||||
protected:
|
||||
MyComboBoxText* method;
|
||||
Gtk::Button* autoCrop;
|
||||
LensGeomListener* rlistener;
|
||||
Gtk::CheckButton* fill;
|
||||
@ -36,6 +37,7 @@ protected:
|
||||
sigc::connection fillConn;
|
||||
ToolParamBlock* packBox;
|
||||
|
||||
rtengine::ProcEvent EvTransMethod;
|
||||
public:
|
||||
|
||||
LensGeometry ();
|
||||
@ -50,6 +52,7 @@ public:
|
||||
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override;
|
||||
void setBatchMode (bool batchMode) override;
|
||||
|
||||
void methodChanged();
|
||||
void fillPressed ();
|
||||
void autoCropPressed ();
|
||||
void setLensGeomListener (LensGeomListener* l)
|
||||
|
@ -586,6 +586,9 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged)
|
||||
|
||||
LensProfilePanel::LFDbHelper::LFDbHelper()
|
||||
{
|
||||
lensfunCameraModel = Gtk::TreeStore::create(lensfunModelCam);
|
||||
lensfunLensModel = Gtk::TreeStore::create(lensfunModelLens);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel sections if (!settings->verbose)
|
||||
#endif
|
||||
@ -594,14 +597,12 @@ LensProfilePanel::LFDbHelper::LFDbHelper()
|
||||
#pragma omp section
|
||||
#endif
|
||||
{
|
||||
lensfunCameraModel = Gtk::TreeStore::create(lensfunModelCam);
|
||||
fillLensfunCameras();
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp section
|
||||
#endif
|
||||
{
|
||||
lensfunLensModel = Gtk::TreeStore::create(lensfunModelLens);
|
||||
fillLensfunLenses();
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ Glib::ustring Options::getPreferredProfilePath()
|
||||
*
|
||||
*@param profName path + filename of the procparam to look for. A filename without path can be provided for backward compatibility.
|
||||
* In this case, this parameter will be updated with the new format.
|
||||
*@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementor will have
|
||||
*@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementer will have
|
||||
* to test for this particular value. If the absolute path is invalid (e.g. the file doesn't exist), it will return an empty string.
|
||||
*/
|
||||
Glib::ustring Options::findProfilePath(Glib::ustring &profName)
|
||||
|
@ -321,6 +321,7 @@ void ParamsEdited::set(bool v)
|
||||
coarse.rotate = v;
|
||||
coarse.hflip = v;
|
||||
coarse.vflip = v;
|
||||
commonTrans.method = v;
|
||||
commonTrans.autofill = v;
|
||||
rotate.degree = v;
|
||||
distortion.amount = v;
|
||||
@ -918,6 +919,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
|
||||
coarse.rotate = coarse.rotate && p.coarse.rotate == other.coarse.rotate;
|
||||
coarse.hflip = coarse.hflip && p.coarse.hflip == other.coarse.hflip;
|
||||
coarse.vflip = coarse.vflip && p.coarse.vflip == other.coarse.vflip;
|
||||
commonTrans.method = commonTrans.method && p.commonTrans.method == other.commonTrans.method;
|
||||
commonTrans.autofill = commonTrans.autofill && p.commonTrans.autofill == other.commonTrans.autofill;
|
||||
rotate.degree = rotate.degree && p.rotate.degree == other.rotate.degree;
|
||||
distortion.amount = distortion.amount && p.distortion.amount == other.distortion.amount;
|
||||
@ -2293,6 +2295,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
|
||||
toEdit.coarse.vflip = mods.coarse.vflip;
|
||||
}
|
||||
|
||||
if (commonTrans.method) {
|
||||
toEdit.commonTrans.method = mods.commonTrans.method;
|
||||
}
|
||||
|
||||
if (commonTrans.autofill) {
|
||||
toEdit.commonTrans.autofill = mods.commonTrans.autofill;
|
||||
}
|
||||
|
@ -365,6 +365,7 @@ struct CoarseTransformParamsEdited {
|
||||
};
|
||||
|
||||
struct CommonTransformParamsEdited {
|
||||
bool method;
|
||||
bool autofill;
|
||||
};
|
||||
|
||||
|
@ -383,8 +383,13 @@ RTWindow::RTWindow ()
|
||||
iccProfileCreator->set_tooltip_markup (M ("MAIN_BUTTON_ICCPROFCREATOR"));
|
||||
iccProfileCreator->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::showICCProfileCreator) );
|
||||
|
||||
//Gtk::LinkButton* rtWeb = Gtk::manage (new Gtk::LinkButton ("http://rawtherapee.com")); // unused... but fail to be linked anyway !?
|
||||
//Gtk::Button* preferences = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PREFERENCES")+"..."));
|
||||
Gtk::Button* helpBtn = Gtk::manage (new Gtk::Button ());
|
||||
setExpandAlignProperties (helpBtn, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||
helpBtn->set_relief(Gtk::RELIEF_NONE);
|
||||
helpBtn->set_image (*Gtk::manage (new RTImage ("questionmark.png")));
|
||||
helpBtn->set_tooltip_markup (M ("GENERAL_HELP"));
|
||||
helpBtn->signal_clicked().connect (sigc::mem_fun (*this, &RTWindow::showRawPedia));
|
||||
|
||||
Gtk::Button* preferences = Gtk::manage (new Gtk::Button ());
|
||||
setExpandAlignProperties (preferences, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||
preferences->set_relief(Gtk::RELIEF_NONE);
|
||||
@ -392,7 +397,6 @@ RTWindow::RTWindow ()
|
||||
preferences->set_tooltip_markup (M ("MAIN_BUTTON_PREFERENCES"));
|
||||
preferences->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::showPreferences) );
|
||||
|
||||
//btn_fullscreen = Gtk::manage( new Gtk::Button(M("MAIN_BUTTON_FULLSCREEN")));
|
||||
btn_fullscreen = Gtk::manage ( new Gtk::Button());
|
||||
setExpandAlignProperties (btn_fullscreen, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||
btn_fullscreen->set_relief(Gtk::RELIEF_NONE);
|
||||
@ -414,6 +418,7 @@ RTWindow::RTWindow ()
|
||||
actionGrid->set_orientation (Gtk::ORIENTATION_VERTICAL);
|
||||
actionGrid->attach_next_to (prProgBar, Gtk::POS_BOTTOM, 1, 1);
|
||||
actionGrid->attach_next_to (*iccProfileCreator, Gtk::POS_BOTTOM, 1, 1);
|
||||
actionGrid->attach_next_to (*helpBtn, Gtk::POS_BOTTOM, 1, 1);
|
||||
actionGrid->attach_next_to (*preferences, Gtk::POS_BOTTOM, 1, 1);
|
||||
actionGrid->attach_next_to (*btn_fullscreen, Gtk::POS_BOTTOM, 1, 1);
|
||||
mainNB->set_action_widget (actionGrid, Gtk::PACK_END);
|
||||
@ -422,6 +427,7 @@ RTWindow::RTWindow ()
|
||||
actionGrid->set_orientation (Gtk::ORIENTATION_HORIZONTAL);
|
||||
actionGrid->attach_next_to (prProgBar, Gtk::POS_RIGHT, 1, 1);
|
||||
actionGrid->attach_next_to (*iccProfileCreator, Gtk::POS_RIGHT, 1, 1);
|
||||
actionGrid->attach_next_to (*helpBtn, Gtk::POS_RIGHT, 1, 1);
|
||||
actionGrid->attach_next_to (*preferences, Gtk::POS_RIGHT, 1, 1);
|
||||
actionGrid->attach_next_to (*btn_fullscreen, Gtk::POS_RIGHT, 1, 1);
|
||||
mainNB->set_action_widget (actionGrid, Gtk::PACK_END);
|
||||
@ -913,6 +919,12 @@ void RTWindow::writeToolExpandedStatus (std::vector<int> &tpOpen)
|
||||
}
|
||||
|
||||
|
||||
void RTWindow::showRawPedia()
|
||||
{
|
||||
GError* gerror = nullptr;
|
||||
gtk_show_uri(nullptr, "https://rawpedia.rawtherapee.com/", GDK_CURRENT_TIME, &gerror);
|
||||
}
|
||||
|
||||
void RTWindow::showICCProfileCreator ()
|
||||
{
|
||||
ICCProfileCreator *iccpc = new ICCProfileCreator (this);
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
bool on_window_state_event (GdkEventWindowState* event) override;
|
||||
void on_mainNB_switch_page (Gtk::Widget* widget, guint page_num);
|
||||
|
||||
void showRawPedia();
|
||||
void showICCProfileCreator ();
|
||||
void showPreferences ();
|
||||
void on_realize () override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user