diff --git a/.travis.yml.fixme b/.travis.yml.fixme deleted file mode 100644 index 0aa85f3b4..000000000 --- a/.travis.yml.fixme +++ /dev/null @@ -1,44 +0,0 @@ -sudo: required -dist: trusty - -language: cpp - -compiler: - - gcc - -os: - - linux - -#branches: -# only: -# - master - -notifications: - irc: - channels: - - "chat.freenode.net#rawtherapee" - skip_join: true - template: - - "%{repository}/%{branch} (%{commit} - %{author}): %{build_url}: %{message}" - email: - on_success: change - on_failure: always - -env: - global: - - OMP_NUM_THREADS=4 - -before_install: - - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - - sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ xenial main" - - sudo apt-get -qq update - - sudo apt-get install gcc-6 g++-6 - - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6 - - sudo apt-get install build-essential cmake curl git libbz2-dev libcanberra-gtk3-dev libexiv2-dev libexpat-dev libfftw3-dev libglibmm-2.4-dev libgtk-3-dev libgtkmm-3.0-dev libiptcdata0-dev libjpeg8-dev liblcms2-dev libpng12-dev libsigc++-2.0-dev libtiff5-dev zlib1g-dev - -before_script: - - mkdir build - - cd build - - cmake -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" -DWITH_LTO="OFF" -DPROC_TARGET_NUMBER="2" .. - -script: make diff --git a/AUTHORS.txt b/AUTHORS.txt index 160869776..227390faa 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -39,6 +39,7 @@ Development contributors, in last name alphabetical order: Other contributors (profiles, ideas, mockups, testing, forum activity, translations, etc.), in last name alphabetical order: Marcin Bajor + Javier Bartol Thorsten Bartolomäus Patrik Brunner Fernando Carello diff --git a/CMakeLists.txt b/CMakeLists.txt index b027ea5f7..d7368f115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PROC_FLAGS}") # Stop compilation on typos such as std:swap (missing colon will be detected as unused label): set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=unused-label") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=delete-incomplete") # Special treatment for x87 and x86-32 SSE (see GitHub issue #4324) include(FindX87Math) @@ -136,6 +137,9 @@ option(TRACE_MYRWMUTEX "Trace custom R/W Mutex (Debug builds only); redirecting option(AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF) #option(TARGET32BIT "Build for 32-bit architecture when ON, otherwise 64-bit. Default is OFF" OFF) +option(ENABLE_TCMALLOC "Use the tcmalloc library if available" OFF) +set(TCMALLOC_LIB_DIR "" CACHE PATH "Custom path for the tcmalloc library") + # Set installation directories: if(WIN32 OR APPLE) if(BUILD_BUNDLE) @@ -564,6 +568,23 @@ int main() return 0; }" LENSFUN_HAS_LOAD_DIRECTORY) +set(TCMALLOC_LIB_DIR) +if(ENABLE_TCMALLOC) + if(TCMALLOC_LIB_DIR) + find_library(TCMALLOC_LIBRARIES tcmalloc PATHS ${TCMALLOC_LIB_DIR} NO_DEFAULT_PATH) + else() + find_library(TCMALLOC_LIBRARIES tcmalloc) + endif() + if(TCMALLOC_LIBRARIES) + message(STATUS "using tcmalloc library in ${TCMALLOC_LIBRARIES}") + else() + set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) + message(STATUS "tcmalloc not found") + endif() +else() + set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) +endif() + add_subdirectory(rtexif) add_subdirectory(rtengine) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 0e5dfef50..3a55109ba 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -8,31 +8,17 @@ Zaawansowany program do wywoływania zdjęć typu raw rawtherapee -

- RawTherapee is a powerful, cross-platform raw photo processing program. It is written mostly in C++ using a GTK+ front-end. It uses a patched version of dcraw for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process. -

-

- RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as HDR DNG files and non-raw image formats (JPEG, TIFF and PNG). The target audience ranges from enthusiast newcomers who wish to broaden their understanding of how digital imaging works to semi-professional photographers. Knowledge in color science is not compulsory, but it is recommended that you are eager to learn and ready to read our documentation (RawPedia) as well as look up basic concepts which lie outside the scope of RawPedia, such as color balance, elsewhere. -

-

- Of course, professionals may use RawTherapee too while enjoying complete freedom, but will probably lack some peripheral features such as Digital Asset Management, printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the open-source community is sufficiently developed by now to offer all those peripheral features in other specialized software. -

+

RawTherapee is a powerful, cross-platform raw photo processing program. It is written mostly in C++ using a GTK+ front-end. It uses a patched version of dcraw for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process.

+

RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as HDR DNG files and non-raw image formats (JPEG, TIFF and PNG). The target audience ranges from enthusiast newcomers who wish to broaden their understanding of how digital imaging works to semi-professional photographers. Knowledge in color science is not compulsory, but it is recommended that you are eager to learn and ready to read our documentation (RawPedia) as well as look up basic concepts which lie outside the scope of RawPedia, such as color balance, elsewhere.

+

Of course, professionals may use RawTherapee too while enjoying complete freedom, but will probably lack some peripheral features such as Digital Asset Management, printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the open-source community is sufficiently developed by now to offer all those peripheral features in other specialized software.

- - raw - photo - photography - develop - pp3 - graphics - CC-BY-SA-4.0 GPL-3.0+ - https://github.com/Beep6581/RawTherapee/issues/new + https://github.com/Beep6581/RawTherapee/issues https://www.paypal.me/rawtherapee - https://rawpedia.rawtherapee.com/ - https://www.rawtherapee.com/ + https://rawpedia.rawtherapee.com + https://www.rawtherapee.com https://discuss.pixls.us/t/localization-how-to-translate-rawtherapee-and-rawpedia/2594 rawtherapee.desktop @@ -48,20 +34,20 @@ - Color-correcting a drosera rotundifolia in RawTherapee 5.7. - https://rawtherapee.com/images/screenshots/rt570_1.jpg + Color correction + https://rawtherapee.com/images/screenshots/rt57_drosera_rotundifolia.png - HDR DNG of a misty morning in the countryside - https://rawtherapee.com/images/screenshots/rt540_1.jpg + File browser + https://rawtherapee.com/images/screenshots/rt57_file_browser.png - - Straight-out-of-camera vs RawTherapee - https://rawtherapee.com/images/screenshots/rt540_2.jpg + + High dynamic range compression + https://rawtherapee.com/images/screenshots/rt57_field_sunset.png - - RawTherapee using the Auto-Matched Tone Curve tool - https://rawtherapee.com/images/screenshots/rt540_3.jpg + + Developing a film negative + https://rawtherapee.com/images/screenshots/rt57_film_negative.png contactus@rawtherapee.com diff --git a/rtdata/dcpprofiles/FUJIFILM X-T2.dcp b/rtdata/dcpprofiles/FUJIFILM X-T2.dcp new file mode 100644 index 000000000..5a4e11688 Binary files /dev/null and b/rtdata/dcpprofiles/FUJIFILM X-T2.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-GX7.dcp b/rtdata/dcpprofiles/Panasonic DMC-GX7.dcp new file mode 100644 index 000000000..25f4e6eab Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-GX7.dcp differ diff --git a/rtdata/dcpprofiles/RICOH GR III.dcp b/rtdata/dcpprofiles/RICOH GR III.dcp new file mode 100644 index 000000000..f226e62b4 Binary files /dev/null and b/rtdata/dcpprofiles/RICOH GR III.dcp differ diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 407348417..36666a533 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1293,6 +1293,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1310,6 +1311,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1330,6 +1332,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1786,6 +1795,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1856,16 +1866,16 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength !TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -1935,6 +1945,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. !TP_PCVIGNETTE_STRENGTH;Strength !TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PFCURVE_CURVEEDITOR_CH;Hue !TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -2110,6 +2121,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index b93aed7af..89a4dd9b4 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1340,6 +1340,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1357,6 +1358,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1377,6 +1379,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1732,6 +1741,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_DEFRINGE_THRESHOLD;Threshold !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1803,16 +1813,16 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength !TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). !TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). @@ -1896,6 +1906,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. !TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. !TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PFCURVE_CURVEEDITOR_CH;Hue !TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -2078,6 +2089,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_RETINEX_VIEW_UNSHARP;Unsharp mask !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index d0b4d89f3..0ce34e3ee 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -961,8 +961,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Barva pozadí náhledu: bílá\nZkratka: 9 MAIN_TOOLTIP_BACKCOLOR3;Barva pozadí náhledu: středně šedá\nZkratka: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Zamknout / Odemknout pohled Před\n\nZamknout: ponechá pohled Před nezměněn.\nUžitečné pro posouzení výsledného efektu po použití více nástrojů.\nNavíc může být porovnání provedeno proti kterémukoli stavu v historii.\n\nOdemknout: pohled Před bude následovat pohled Poté, vždy jen o jeden krok zpět, představí vliv právě použitého nástroje. MAIN_TOOLTIP_HIDEHP;Zobrazit či schovat levý panel (obsahující historii).\nZkratka: l -MAIN_TOOLTIP_INDCLIPPEDH;Zvýraznit oříznutá světla.\nZkratka: < -MAIN_TOOLTIP_INDCLIPPEDS;Zvýraznit oříznuté stíny.\nZkratka: > +MAIN_TOOLTIP_INDCLIPPEDH;Zvýraznit oříznutá světla.\nZkratka: > +MAIN_TOOLTIP_INDCLIPPEDS;Zvýraznit oříznuté stíny.\nZkratka: < MAIN_TOOLTIP_PREVIEWB;Náhled modrého kanálu.\nZkratka: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Náhled masky zaostření.\nZkratka: Shift-f\n\nVíce přesné u snímků s nízkou hloubkou ostrosti, nízkým šumem a na vyšších úrovních zvětšení.\n\nPoužijte přiblížení v rozsahu 10 až 30% pro zlepšení přesnosti detekce u zašuměných snímků. MAIN_TOOLTIP_PREVIEWG;Náhled zeleného kanálu.\nZkratka: g @@ -2323,13 +2323,26 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_494;Capture Sharpening +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!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 !PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!TP_DEHAZE_LUMINANCE;Luminance only !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio +!TP_PDSHARPENING_LABEL;Capture Sharpening +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 57236e1e6..9122d5984 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -82,6 +82,7 @@ #81 15.04.2019 Erweiterung (TooWaBoo) RT 5.6 #82 25.05.2019 Erweiterung (TooWaBoo) RT 5.6 #83 06.07.2019 Erweiterung (TooWaBoo) RT 5.6 +#84 06.10.2019 Erweiterung (TooWaBoo) RT 5.7 #84 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 ABOUT_TAB_BUILD;Version @@ -808,6 +809,7 @@ HISTORY_MSG_490;(Dynamikkompression)\nIntensität HISTORY_MSG_491;(Weißabgleich) HISTORY_MSG_492;(RGB-Kurven) HISTORY_MSG_493;(L*a*b*) +HISTORY_MSG_494;(Eingangsschärfung) HISTORY_MSG_CLAMPOOG;(Belichtung) - Farben\nauf Farbraum beschränken HISTORY_MSG_COLORTONING_LABGRID_VALUE;(Farbanpassungen)\nL*a*b*-Farbkorrektur HISTORY_MSG_COLORTONING_LABREGION_AB;(Farbanpassungen)\nL*a*b*-Farbkorrektur\nBereich @@ -825,6 +827,7 @@ HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;(Farbanpassungen)\nL*a*b*-Farbkorrekt HISTORY_MSG_COLORTONING_LABREGION_SLOPE;(Farbanpassungen)\nL*a*b*-Farbkorrektur\nBereich - Steigung HISTORY_MSG_DEHAZE_DEPTH;(Bildschleier entfernen)\nTiefe HISTORY_MSG_DEHAZE_ENABLED;(Bildschleier entfernen) +HISTORY_MSG_DEHAZE_LUMINANCE;(Bildschleier entfernen)\nNur Luminanz HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;(Bildschleier entfernen)\nMaske anzeigen HISTORY_MSG_DEHAZE_STRENGTH;(Bildschleier entfernen)\nIntensität HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;(Sensor—Matrix)\nFarbinterpolation\nAuto-Kontrastschwelle @@ -845,6 +848,13 @@ HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;(Lokaler Kontrast)\nHelle Bereiche HISTORY_MSG_LOCALCONTRAST_RADIUS;(Lokaler Kontrast)\nRadius HISTORY_MSG_METADATA_MODE;(Metadaten)\nKopiermodus HISTORY_MSG_MICROCONTRAST_CONTRAST;(Mikrokontrast)\nKontrastschwelle +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;(Eingangsschärfung)\nAuto-Schwelle +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;(Eingangsschärfung)\nAuto-Radius +HISTORY_MSG_PDSHARPEN_CONTRAST;(Eingangsschärfung)\nKontrastschwelle +HISTORY_MSG_PDSHARPEN_GAMMA;(Eingangsschärfung)\nGamma +HISTORY_MSG_PDSHARPEN_ITERATIONS;(Eingangsschärfung)\nIterationen +HISTORY_MSG_PDSHARPEN_RADIUS;(Eingangsschärfung)\nRadius +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;(Eingangsschärfung)\nRandschärfe erhöhen HISTORY_MSG_PIXELSHIFT_DEMOSAIC;(Sensor-Matrix)\nFarbinterpolation - PS\nBewegungsmethode HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;(Sensor-Matrix)\nVorverarbeitung\nRichtung HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;(Sensor-Matrix)\nVorverarbeitung\nPDAF-Zeilenfilter @@ -855,6 +865,7 @@ HISTORY_MSG_RAW_BORDER;(Sensor-Matrix)\nFarbinterpolation\nBildrand HISTORY_MSG_RESIZE_ALLOWUPSCALING;(Skalieren)\nHochskalieren zulassen HISTORY_MSG_SHARPENING_BLUR;(Schärfung)\nWeichzeichnerradius HISTORY_MSG_SHARPENING_CONTRAST;(Schärfung)\nKontrastschwelle +HISTORY_MSG_SHARPENING_GAMMA;(Schärfung) - Gamma HISTORY_MSG_SH_COLORSPACE;Farbraum HISTORY_MSG_SOFTLIGHT_ENABLED;(Weiches Licht) HISTORY_MSG_SOFTLIGHT_STRENGTH;(Weiches Licht)\nIntensität @@ -1011,8 +1022,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Hintergrundfarbe der Vorschau: Weiß\nTaste: 9 MAIN_TOOLTIP_BACKCOLOR3;Hintergrundfarbe der Vorschau: Mittleres Grau\nTaste: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Vorher-Ansicht: Sperren / Entsperren\n\nGesperrt: Friert die Vorher-Ansicht ein, so\ndass sich die Gesamtwirkung mehrerer\nBearbeitungsschritte beurteilen lässt.\n\nEntsperrt: Die Vorher-Ansicht hinkt dem\naktuellen Bild immer einen Bearbeitungs-\nschritt hinterher. MAIN_TOOLTIP_HIDEHP;Linkes Bedienfeld ein-/ausblenden.\nTaste: l -MAIN_TOOLTIP_INDCLIPPEDH;Anzeige zu heller Bereiche ein-/ausschalten.\nTaste: < -MAIN_TOOLTIP_INDCLIPPEDS;Anzeige zu dunkler Bereiche ein-/ausschalten.\nTaste: > +MAIN_TOOLTIP_INDCLIPPEDH;Anzeige zu heller Bereiche ein-/ausschalten.\nTaste: > +MAIN_TOOLTIP_INDCLIPPEDS;Anzeige zu dunkler Bereiche ein-/ausschalten.\nTaste: < MAIN_TOOLTIP_PREVIEWB;Vorschau Blau-Kanal\nTaste: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Vorschau Fokusmaske\nTaste: Umschalt + f\n\nPräziser bei Bildern mit geringer Tiefenschärfe,\nniedrigem Rauschen und bei hoher Vergrößerung. MAIN_TOOLTIP_PREVIEWG;Vorschau Grün-Kanal\nTaste: g @@ -1613,6 +1624,7 @@ TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Schwelle TP_DEHAZE_DEPTH;Tiefe TP_DEHAZE_LABEL;Bildschleier entfernen +TP_DEHAZE_LUMINANCE;Nur Luminanz TP_DEHAZE_SHOW_DEPTH_MAP;Maske anzeigen TP_DEHAZE_STRENGTH;Intensität TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto-Multizonen @@ -1723,9 +1735,9 @@ TP_EXPOS_BLACKPOINT_LABEL;Schwarzpunkt TP_EXPOS_WHITEPOINT_LABEL;Weißpunkt TP_FILMNEGATIVE_BLUE;Blauverhältnis TP_FILMNEGATIVE_GREEN;Bezugsexponent (Kontrast) -TP_FILMNEGATIVE_GUESS_TOOLTIP;Berechnet die Exponenten durch Auswahl zweier neutraler\nReferenzpunkte im Bild. Weiß (Hellgrau) und Schwarz (Dunkelgrau).\nDie Reihenfolge spielt keine Rolle. Die Exponenten werden aktualisiert,\nnachdem der zweite Punkt ausgewählt wurde. +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_LABEL;Filmnegativ -TP_FILMNEGATIVE_PICK;Weißen und schwarzen Bereich auswählen +TP_FILMNEGATIVE_PICK;Pick neutral spots TP_FILMNEGATIVE_RED;Rotverhältnis TP_FILMSIMULATION_LABEL;Filmsimulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee sucht nach Hald-CLUT-Bildern, die für die Filmsimulation benötigt werden, in einem Ordner, der viel Zeit benötigt.\nGehen Sie zu\n< Einstellungen > Bildbearbeitung > Filmsimulation >\nund prüfen Sie welcher Order benutzt wird. Wählen Sie den Ordner aus, der nur die Hald-CLUT-Bilder beinhaltet, oder einen leeren Ordner, wenn Sie die Filsimulation nicht verwenden möchten.\n\nWeitere Informationen über die Filmsimulation finden Sie auf RawPedia.\n\nMöchten Sie die Suche beenden? @@ -1875,6 +1887,7 @@ TP_PCVIGNETTE_ROUNDNESS;Form TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Form:\n0 = Rechteck\n50 = Ellipse\n100 = Kreis TP_PCVIGNETTE_STRENGTH;Intensität TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filterstärke in Blendenstufen (bezogen auf die Bildecken). +TP_PDSHARPENING_LABEL;Eingangsschärfung TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspektive TP_PERSPECTIVE_VERTICAL;Vertikal @@ -2104,12 +2117,14 @@ TP_SHARPENING_BLUR;Weichzeichnerradius TP_SHARPENING_CONTRAST;Kontrastschwelle TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Kantentoleranz +TP_SHARPENING_GAMMA;Gamma TP_SHARPENING_HALOCONTROL;Halokontrolle TP_SHARPENING_HCAMOUNT;Intensität TP_SHARPENING_LABEL;Schärfung TP_SHARPENING_METHOD;Methode TP_SHARPENING_ONLYEDGES;Nur Kanten schärfen TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RADIUS_BOOST;Randschärfe erhöhen TP_SHARPENING_RLD;RL-Dekonvolution TP_SHARPENING_RLD_AMOUNT;Intensität TP_SHARPENING_RLD_DAMPING;Dämpfung @@ -2371,3 +2386,9 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: Alt + f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations +!TP_SHARPENING_ITERCHECK;Auto limit iterations diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index c6b521c12..1fc07391e 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -88,7 +88,7 @@ TP_DIRPYREQUALIZER_ALGO;Skin Colour Range TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colours of the skin, minimizing the action on other colours\nLarge: avoid more artifacts. TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colours (hue, chroma, luma) and the rest of the image. TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colours -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to colour cast. +TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picking two patches which had a neutral hue (no colour) in the original scene. The patches should differ in brightness. Set the white balance afterwards. TP_GRADIENT_CENTER;Centre TP_GRADIENT_CENTER_X;Centre X TP_GRADIENT_CENTER_Y;Centre Y @@ -820,6 +820,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Channel !HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - region C mask !HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H mask @@ -834,6 +835,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -854,6 +856,13 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1012,8 +1021,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l -!MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: < -!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +!MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: > +!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: < !MAIN_TOOLTIP_PREVIEWB;Preview the blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the focus mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\nZoom out to 10-30% to improve detection accuracy on noisy images. !MAIN_TOOLTIP_PREVIEWG;Preview the green channel.\nShortcut: g @@ -1568,6 +1577,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_DEFRINGE_THRESHOLD;Threshold !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1670,9 +1680,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? @@ -1686,6 +1695,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). @@ -1808,6 +1818,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. !TP_PCVIGNETTE_STRENGTH;Strength !TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PERSPECTIVE_HORIZONTAL;Horizontal !TP_PERSPECTIVE_LABEL;Perspective !TP_PERSPECTIVE_VERTICAL;Vertical @@ -2033,10 +2044,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_SHARPENING_EDTOLERANCE;Edge tolerance !TP_SHARPENING_HALOCONTROL;Halo control !TP_SHARPENING_HCAMOUNT;Amount +!TP_SHARPENING_ITERCHECK;Auto limit iterations !TP_SHARPENING_LABEL;Sharpening !TP_SHARPENING_METHOD;Method !TP_SHARPENING_ONLYEDGES;Sharpen only edges !TP_SHARPENING_RADIUS;Radius +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENING_RLD;RL Deconvolution !TP_SHARPENING_RLD_AMOUNT;Amount !TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 9b8eda038..63dff83da 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -727,6 +727,7 @@ !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -744,6 +745,7 @@ !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -764,6 +766,13 @@ !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -929,8 +938,8 @@ !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l -!MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: < -!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +!MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: > +!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: < !MAIN_TOOLTIP_PREVIEWB;Preview the blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the focus mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\nZoom out to 10-30% to improve detection accuracy on noisy images. !MAIN_TOOLTIP_PREVIEWG;Preview the green channel.\nShortcut: g @@ -1531,6 +1540,7 @@ !TP_DEFRINGE_THRESHOLD;Threshold !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1641,9 +1651,9 @@ !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? @@ -1657,7 +1667,7 @@ !TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center @@ -1793,6 +1803,7 @@ !TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. !TP_PCVIGNETTE_STRENGTH;Strength !TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PERSPECTIVE_HORIZONTAL;Horizontal !TP_PERSPECTIVE_LABEL;Perspective !TP_PERSPECTIVE_VERTICAL;Vertical @@ -2023,10 +2034,12 @@ !TP_SHARPENING_EDTOLERANCE;Edge tolerance !TP_SHARPENING_HALOCONTROL;Halo control !TP_SHARPENING_HCAMOUNT;Amount +!TP_SHARPENING_ITERCHECK;Auto limit iterations !TP_SHARPENING_LABEL;Sharpening !TP_SHARPENING_METHOD;Method !TP_SHARPENING_ONLYEDGES;Sharpen only edges !TP_SHARPENING_RADIUS;Radius +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENING_RLD;RL Deconvolution !TP_SHARPENING_RLD_AMOUNT;Amount !TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index 1e3b84371..96bce0cdf 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -979,8 +979,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Color de fondo de la previsualización: Blanco\nT MAIN_TOOLTIP_BACKCOLOR3;Color de fondo de la vista previa: Medio gris \nMétodo rápido: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Bloquear / Desbloquear la vista Antes\n\nBloquear: la vista Antes permanece inalterada - \nútil para evaluar el efecto acumulativo de varias herramientas.\nAdemás, se puede hacer una comparación con cualquier estado en el Historial\n\nDesbloquear: la vista Antes seguirá a la vista Después un paso por detrás, mostrando la imagen antes del efecto de la herramienta que se está usando MAIN_TOOLTIP_HIDEHP;Mostrar/Ocultar panel izquierdo (incluyendo historial).\nTecla de Atajo: i -MAIN_TOOLTIP_INDCLIPPEDH;Indicación de luces altas recortadas.\nTecla de Atajo: < -MAIN_TOOLTIP_INDCLIPPEDS;Indicación de sombras recortadas.\nTecla de Atajo: > +MAIN_TOOLTIP_INDCLIPPEDH;Indicación de luces altas recortadas.\nTecla de Atajo: > +MAIN_TOOLTIP_INDCLIPPEDS;Indicación de sombras recortadas.\nTecla de Atajo: < MAIN_TOOLTIP_PREVIEWB;Previsualización Canal azul.\nTecla de Atajo: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Previsualización Máscara de Foco.\nTecla de Atajo: Shift-F\n\nMás preciso en imágenes con poca profundidad de campo, bajo ruido y a mayores niveles de aumento\n\nPara mejorar la precisión en imágenes con ruido evalúe usando menor aumento (10%-30%)\n\nLa vista previa es realizada más lentamente cuando la Máscara de Foco esta activa. MAIN_TOOLTIP_PREVIEWG;Previsualización Canal verde.\nTecla de Atajo: g @@ -2321,8 +2321,17 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_494;Capture Sharpening +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!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 !HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius !MAIN_FRAME_PLACES_DEL;Remove !MAIN_TAB_FAVORITES;Favorites @@ -2345,18 +2354,22 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_DEHAZE_LUMINANCE;Luminance only !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_RAW_IMAGENUM_SN;SN mode !TP_RAW_XTRANS;X-Trans !TP_RAW_XTRANSFAST;Fast X-Trans !TP_SHARPENING_BLUR;Blur radius +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 508604d98..363feacb9 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -918,8 +918,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Couleur de fond de l'aperçu: Blanc\nRaccourci: < MAIN_TOOLTIP_BACKCOLOR3;Couleur de fond de l'aperçu: Gris moyen\nRaccourci : 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Vérouille / déverouille la vue Avant\n\nVérouille: garde la vue Avant inchangée - \nutile pour évaluer l'effet cumulatif de plusieurs outils.\nDe plus, une comparaison peut être faite à partir de n'importe quelle étape de l'historique\n\nDéverouille: la vue Avant représentera l'étape précédant la vue Après, montrant l'effet qui vient d'être modifié MAIN_TOOLTIP_HIDEHP;Montrer/cacher le panneau gauche (incluant l'historique)\nRaccourci: l -MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine\nRaccourci: < -MAIN_TOOLTIP_INDCLIPPEDS;Indication ombres hors domaine\nRaccourci: > +MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine\nRaccourci: > +MAIN_TOOLTIP_INDCLIPPEDS;Indication ombres hors domaine\nRaccourci: < MAIN_TOOLTIP_PREVIEWB;Affichage du canal Bleu\nRaccourci: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Affichage du Masque du focus\nRaccourci: Shift-f\n\nPlus précis sur les images avec une faible profondeur de champ, à faible bruit et à des niveaux de zoom élevé\n\nPour améliorer la précision de détection des images bruitées, évaluez les à un facteur de zoom de 10-30%\n\nLa prévisualisation met plus de temps à se calculer lorsque cet outil est actif. MAIN_TOOLTIP_PREVIEWG;Affichage du canal Vert\nRaccourci: g @@ -2272,8 +2272,17 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_494;Capture Sharpening +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!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 !MAIN_FRAME_PLACES_DEL;Remove !PARTIALPASTE_FILMNEGATIVE;Film Negative !PROGRESSBAR_DECODING;Decoding... @@ -2284,16 +2293,20 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_DEHAZE_LUMINANCE;Luminance only !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_RAW_XTRANS;X-Trans !TP_RAW_XTRANSFAST;Fast X-Trans +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index f11423d7a..db09b5d3a 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -519,8 +519,8 @@ MAIN_TOOLTIP_BACKCOLOR1;Colore di sfondo dell'anteprima: Nero\nScorciatoi MAIN_TOOLTIP_BACKCOLOR2;Colore di sfondo dell'anteprima: Bianco\nScorciatoia: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Blocca/Sblocca la vista Prima\n\nBlocca: Conserva la vista Prima.\nUtile per valutare l'effetto cumulativo di diversi strumenti.\nIn più, possono essere confrontati diversi passi della cronologia.\n\nSblocca: la vista Prima segue di un passo la vista Dopo, mostrando l'immagine prima dell'effetto dello strumento corrente. MAIN_TOOLTIP_HIDEHP;Mostra/Nascondi il pannello sinistro (inclusa la cronologia)\nScorciatoia: l -MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate.\nScorciatoia: < -MAIN_TOOLTIP_INDCLIPPEDS;Indicazione delle ombre tosate.\nScorciatoia: > +MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate.\nScorciatoia: > +MAIN_TOOLTIP_INDCLIPPEDS;Indicazione delle ombre tosate.\nScorciatoia: < MAIN_TOOLTIP_PREVIEWB;Anteprima del Canale Blu.\nScorciatoia: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Anteprima della Focus Mask.\nScorciatoia: Maiuscolo-F\n\nPiù accurato su immagini con bassa profondità di campo, poco rumore e ad elevati livelli di zoom.\n\nPer aumentare l'accuratezza della rilevazione su immagini con molto rumore, riduci le dimensioni del 10-30%. MAIN_TOOLTIP_PREVIEWG;Anteprima del Canale Verde.\nScorciatoia: g @@ -1518,6 +1518,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1535,6 +1536,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1555,6 +1557,13 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1852,6 +1861,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1908,16 +1918,16 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength !TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. !TP_ICM_APPLYHUESATMAP;Base table @@ -1954,6 +1964,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_METADATA_STRIP;Strip all metadata !TP_METADATA_TUNNEL;Copy unchanged !TP_NEUTRAL;Reset +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter !TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. !TP_PREPROCESS_HOTPIXFILT;Hot pixel filter @@ -2119,6 +2130,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_VIEW_UNSHARP;Unsharp mask !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 16dafb297..91ef2e931 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -960,8 +960,8 @@ MAIN_TOOLTIP_BACKCOLOR2;プレビューの背景色を指定します: 中間のグレー\nショートカット: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;固定 / 固定解除 - 補正前 の表示設定\n\n固定: 補正前をそのまま表示し変更されません\n複数のツールの累積効果を評価するのに役立ちます\nさらに、比較は履歴上のどこからでも行うことができます\n\n固定解除: 現在使用のツールの効果が 補正後 に表示され、その1段階前が 補正前 に表示されます MAIN_TOOLTIP_HIDEHP;左パネル 表示/非表示 (履歴含む)\nショートカット: l -MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: < -MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: > +MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: > +MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: < MAIN_TOOLTIP_PREVIEWB;ブルー チャンネル表示\nショートカット: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;フォーカス・マスク表示\nショートカット: Shift-f\n\n浅い被写界深度、低ノイズ、高ズームの画像の場合は、より正確に\n\nノイズの多い画像に対しては、検出精度を向上させるため10から30%縮小して評価します\n\nフォーカス・マスクをオンにすると表示に時間が掛かります MAIN_TOOLTIP_PREVIEWG;グリーン チャンネル表示\nショートカット: g @@ -1672,9 +1672,9 @@ TP_EXPOS_BLACKPOINT_LABEL;raw ブラック・ポイント TP_EXPOS_WHITEPOINT_LABEL;raw ホワイト・ポイント TP_FILMNEGATIVE_BLUE;ブルーの比率 TP_FILMNEGATIVE_GREEN;参考指数(コントラスト) -TP_FILMNEGATIVE_GUESS_TOOLTIP;画像の中でニュートラルな参考ポイントを2点選んで指数を計算します;白い(明るいグレー)1点と黒い(暗いグレー)1点を選びます。順番は関係ありません。2つ目のポイントが選択されると指数が更新されます。 +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_LABEL;ネガフィルム -TP_FILMNEGATIVE_PICK;白と黒のポイントをピックアップする +TP_FILMNEGATIVE_PICK;Pick neutral spots TP_FILMNEGATIVE_RED;レッドの比率 TP_FILMSIMULATION_LABEL;フィルムシミュレーション TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapeeはフィルムシミュレーション機能に使う画像をHald CLUTフォルダーの中から探すよう設計されています(プログラムに組み込むにはフォルダーが大き過ぎるため)。\n変更するには、環境設定 > 画像処理 > フィルムシミュレーションと進み\nどのフォルダーが使われているか確認します。機能を利用する場合は、Hald CLUTだけが入っているフォルダーを指定するか、 この機能を使わない場合はそのフォルダーを空にしておきます。\n\n詳しくはRawPediaを参照して下さい。\n\nフィルム画像のスキャンを止めますか? @@ -2319,3 +2319,20 @@ ZOOMPANEL_ZOOMFITSCREEN;画像全体を画面に合わせる\nショートカッ ZOOMPANEL_ZOOMIN;ズームイン\nショートカット: + ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - +!!!!!!!!!!!!!!!!!!!!!!!!! +! 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 diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 5879bf130..43a4ae1e1 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1227,6 +1227,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1244,6 +1245,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1264,6 +1266,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1741,6 +1750,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1821,16 +1831,16 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength !TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -1928,6 +1938,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. !TP_PCVIGNETTE_STRENGTH;Strength !TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PFCURVE_CURVEEDITOR_CH;Hue !TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -2103,6 +2114,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index d39173a52..07e40256f 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -788,8 +788,8 @@ MAIN_TOOLTIP_BACKCOLOR1;Achtergrond kleur van het voorbeeld: Zwart\nSnelt MAIN_TOOLTIP_BACKCOLOR2;Achtergrond kleur van het voorbeeld: Wit\nSneltoets: 0 MAIN_TOOLTIP_BEFOREAFTERLOCK;Vergrendel / Ontgrendel de Voorafbeelding.\n\nVergrendel: hou de Voorafbeelding ongewijzigd.\nDit is handig om het cumulatieve effect van meerdere gereedschappen te beoordelen.\nBovendien kan er worden vergeleken met elke stap in de geschiedenislijst.\n\nOntgrendel: de Voorafbeelding volgt een stap achter de Naafbeelding en laat de afbeelding zien zonder het effect van het huidige gereedschap. MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis).\nSneltoets: H -MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: < -MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: > +MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: > +MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: < MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focus Masker.\nSneltoets: Shift-F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focus Masker aanstaat. MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: g @@ -2015,6 +2015,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2032,6 +2033,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -2052,6 +2054,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2226,6 +2235,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. @@ -2235,9 +2245,9 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_CUSTOM;Custom @@ -2263,6 +2273,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_METADATA_MODE;Metadata copy mode !TP_METADATA_STRIP;Strip all metadata !TP_METADATA_TUNNEL;Copy unchanged +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_LINEDENOISE_DIRECTION;Direction !TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both !TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontal @@ -2300,6 +2311,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_RETINEX_MAP;Method !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index a631353c3..c923c3bad 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -563,8 +563,8 @@ MAIN_TOOLTIP_BACKCOLOR1;Kolor tła podglądu: Czarny\nSkrót: 9 MAIN_TOOLTIP_BACKCOLOR2;Kolor tła podglądu: Biały\nSkrót: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Zablokuj / Odblokuj widok Przed\n\nZablokuj: nie zmieniaj widoku Przed - \nPrzydatne w porównywaniu zablokowanego obrazu z obrazem na ktorym wykonano wiele zmian.\n\nOdblokuj: widok Przed będzie śledził widok Po o jeden krok do tyłu, pokazując obraz przed efektem aktualnie użytego narzędzia. MAIN_TOOLTIP_HIDEHP;Pokaż/ukryj lewy panel (razem z historią).\nSkrót: l -MAIN_TOOLTIP_INDCLIPPEDH;Pokaż obcięte prześwietlenia.\nSkrót: < -MAIN_TOOLTIP_INDCLIPPEDS;Pokaż obcięte niedoświetlenia.\nSkrót: > +MAIN_TOOLTIP_INDCLIPPEDH;Pokaż obcięte prześwietlenia.\nSkrót: > +MAIN_TOOLTIP_INDCLIPPEDS;Pokaż obcięte niedoświetlenia.\nSkrót: < MAIN_TOOLTIP_PREVIEWB;Podgląd kanału niebieskiego.\nSkrót: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Podgląd maski ostrości.\nSkrót: Shift-f\n\nDokładniejsze w przypadku zdjęc o płytkiej głębi ostrości, niskim pozimie szumów i o większym przybliżeniu. W przypadku zdjęć o wyższym poziomie szumów maska ostrości będzie dokładniejsza przy mniejszym zoomie (10-30%). MAIN_TOOLTIP_PREVIEWG;Podgląd kanału zielonego.\nSkrót: g @@ -1600,6 +1600,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1617,6 +1618,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1637,6 +1639,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1892,6 +1901,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1934,9 +1944,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure @@ -1975,6 +1985,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_METADATA_STRIP;Strip all metadata !TP_METADATA_TUNNEL;Copy unchanged !TP_NEUTRAL;Reset +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_LINEDENOISE_DIRECTION;Direction !TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both !TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontal @@ -2125,6 +2136,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_VIEW_UNSHARP;Unsharp mask !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 766b14e0b..efe3214f8 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -916,8 +916,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Cor de fundo da pré-visualização: branco\nAtal MAIN_TOOLTIP_BACKCOLOR3;Cor de fundo da pré-visualização: cinza médio\nAtalho: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Bloquear / desbloquear a visualização antes\n\nBloquear: manter a visualização antes inalterada.\nÚtil para avaliar o efeito cumulativo de várias ferramentas.\nAlém disso, podem ser feitas comparações a qualquer momento no histórico.\n\nDesbloquear: a visualização antes seguirá a visualização depois um passo antes, mostrando a imagem antes do efeito da ferramenta atualmente utilizada. MAIN_TOOLTIP_HIDEHP;Mostrar o painel esquerdo (incluindo o histórico).\nAtalho: l -MAIN_TOOLTIP_INDCLIPPEDH;Ver altas luzes cortadas.\nAtalho: < -MAIN_TOOLTIP_INDCLIPPEDS;Ver sombras cortadas.\nAtalho: > +MAIN_TOOLTIP_INDCLIPPEDH;Ver altas luzes cortadas.\nAtalho: > +MAIN_TOOLTIP_INDCLIPPEDS;Ver sombras cortadas.\nAtalho: < MAIN_TOOLTIP_PREVIEWB;Pré-visualizar o canal azul.\nAtalho: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Pré-visualizar a máscara de foco.\nAtalho: Shift-f\n\nMais preciso em imagens com pouca profundidade de campo, baixo ruído e níveis de zoom mais altos.\n\nUtilize um zoom menor entre 10-30% para melhorar a precisão da deteção de imagens com muito ruído. MAIN_TOOLTIP_PREVIEWG;Pré-visualizar o canal verde.\nAtalho: g @@ -2264,8 +2264,17 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_494;Capture Sharpening +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!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 !MAIN_FRAME_PLACES_DEL;Remove !PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode @@ -2277,16 +2286,20 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_DEHAZE_LUMINANCE;Luminance only !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_RAW_XTRANS;X-Trans !TP_RAW_XTRANSFAST;Fast X-Trans +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index aef5fcde9..e6adf3bc4 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -119,8 +119,12 @@ FILEBROWSER_COLORLABEL_TOOLTIP;Etiqueta de cor.\n\nUse o menu suspenso ou atalho FILEBROWSER_COPYPROFILE;Copiar perfil FILEBROWSER_CURRENT_NAME;Nome atual: FILEBROWSER_DARKFRAME;Quadro escuro +FILEBROWSER_DELETEDIALOG_ALL;Você tem certeza que quer deletas permanentemente todos os %1 arquivos na lixeira? FILEBROWSER_DELETEDIALOG_HEADER;Confirmação de exclusão de arquivo +FILEBROWSER_DELETEDIALOG_SELECTED;Você tem certeza que quer deletar permanentemente os %1 arquivos selecionados? +FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Você tem certeza que quer deletar permanentemente os %1 arquivos selecionados, incluindo a versão processada em fila? FILEBROWSER_EMPTYTRASH;Esvaziar lixeira +FILEBROWSER_EMPTYTRASHHINT;Deletar permanentemente todos os arquivos na lixeira. FILEBROWSER_EXTPROGMENU;Abrir com FILEBROWSER_FLATFIELD;Flat-Field FILEBROWSER_MOVETODARKFDIR;Mover para o diretório de quadros escuros @@ -154,6 +158,8 @@ FILEBROWSER_POPUPRANK2;Classificação 2 ** FILEBROWSER_POPUPRANK3;Classificação 3 *** FILEBROWSER_POPUPRANK4;Classificação 4 **** FILEBROWSER_POPUPRANK5;Classificação 5 ***** +FILEBROWSER_POPUPREMOVE;Deletar permanentemente +FILEBROWSER_POPUPREMOVEINCLPROC;Excluir permanentemente, incluindo a versão processada em fila FILEBROWSER_POPUPRENAME;Renomear FILEBROWSER_POPUPSELECTALL;Selecionar tudo FILEBROWSER_POPUPTRASH;Mover para a lixeira @@ -180,6 +186,7 @@ FILEBROWSER_SHOWDIRHINT;Limpar todos os filtros.\nAtalho: d FILEBROWSER_SHOWEDITEDHINT;Mostrar imagens editadas.\nAtalho: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Mostrar imagens não editadas.\nAtalho: 6 FILEBROWSER_SHOWEXIFINFO;Mostrar informações Exif.\n\nAtalhos:\ni - Modo de Guias de Editores Múltiplos,\nAlt-i - Modo de Guia de Editor Único. +FILEBROWSER_SHOWNOTTRASHHINT;Mostrar apenas imagens que não estão no lixo. FILEBROWSER_SHOWORIGINALHINT;Mostre somente imagens originais.\n\nQuando existem várias imagens com o mesmo nome de arquivo, mas extensões diferentes, a única considerada original é aquela cuja extensão está mais próxima da parte superior da lista de extensões analisadas em Preferências > Navegador de Arquivos > Extensões Analisadas. FILEBROWSER_SHOWRANK1HINT;Mostrar imagens classificadas com 1 estrela.\nAtalho: 1 FILEBROWSER_SHOWRANK2HINT;Mostrar imagens classificadas com 2 estrelas.\nAtalho: 2 @@ -870,6 +877,7 @@ MAIN_FRAME_FILEBROWSER;Navegador de Arquivos MAIN_FRAME_FILEBROWSER_TOOLTIP;Navegador de arquivos.\nAtalho: Ctrl-F2 MAIN_FRAME_PLACES;Locais MAIN_FRAME_PLACES_ADD;Adicionar +MAIN_FRAME_PLACES_DEL;Remover MAIN_FRAME_QUEUE;Fila MAIN_FRAME_QUEUE_TOOLTIP;Processando fila.\nAtalho: Ctrl-F3 MAIN_FRAME_RECENT;Pastas Recentes @@ -915,8 +923,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Cor de fundo da pré-visualização: Branco\nAtal MAIN_TOOLTIP_BACKCOLOR3;Cor de fundo da pré-visualização: Cinza médio\nAtalho: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Travar / Destravar a Antes visualização\n\nTravar: mantenha o Antes visualização inalterada.\nÚtil para avaliar o efeito cumulativo de várias ferramentas.\nAlém disso, comparações podem ser feitas a qualquer momento.\n\nDestravar: o Antes visualização seguinte Depois visualização anterior, mostrando a imagem antes do efeito da ferramenta atualmente utilizada. MAIN_TOOLTIP_HIDEHP;Mostrar/Ocultar o painel esquerdo (incluindo o histórico).\nAtalho: l -MAIN_TOOLTIP_INDCLIPPEDH;Indicação de realce recortado.\nAtalho: < -MAIN_TOOLTIP_INDCLIPPEDS;Indicação de sombra recortada.\nAtalho: > +MAIN_TOOLTIP_INDCLIPPEDH;Indicação de realce recortado.\nAtalho: > +MAIN_TOOLTIP_INDCLIPPEDS;Indicação de sombra recortada.\nAtalho: < MAIN_TOOLTIP_PREVIEWB;Pré-visualize o Canal Azul.\nAtalho: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Pré-visualize a Máscara de Foco.\nAtalho: Shift-f\n\nMais preciso em imagens com pouca profundidade de campo, baixo ruído e níveis de zoom mais altos.\n\nPara melhorar a precisão da detecção de imagens ruidosas, avalie com zoom menor, cerca de 10-30%. MAIN_TOOLTIP_PREVIEWG;Pré-visualize o Canal verde.\nAtalho: g @@ -1029,6 +1037,7 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Fonte do seletor de cor PREFERENCES_APPEARANCE_CROPMASKCOLOR;Cor da máscara de corte PREFERENCES_APPEARANCE_MAINFONT;Fonte principal PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Cor do guia do navegador +PREFERENCES_APPEARANCE_PSEUDOHIDPI;Modo pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Tema PREFERENCES_APPLNEXTSTARTUP;é necessário reiniciar PREFERENCES_AUTOMONPROFILE;Usar o perfil de cores do monitor principal do sistema operacional @@ -1215,6 +1224,9 @@ PROFILEPANEL_TOOLTIPCOPY;Copie o perfil de processamento atual para a área de t PROFILEPANEL_TOOLTIPLOAD;Carregue um perfil do arquivo.\nCtrl-click para selecionar os parâmetros a serem carregados. PROFILEPANEL_TOOLTIPPASTE;Cole o perfil da área de transferência.\nCtrl-click para selecionar os parâmetros a serem colados. PROFILEPANEL_TOOLTIPSAVE;Salvar o perfil atual.\nCtrl-click para selecionar os parâmetros a serem salvos. +PROGRESSBAR_GREENEQUIL;Equilíbrio de verde... +PROGRESSBAR_HLREC;Reconstrução de realces... +PROGRESSBAR_LINEDENOISE;Filtro de ruído de linha... PROGRESSBAR_LOADING;Carregando imagem... PROGRESSBAR_LOADINGTHUMBS;Carregando miniaturas... PROGRESSBAR_LOADJPEG;Carregando arquivo JPEG... @@ -1241,6 +1253,7 @@ QUEUE_FORMAT_TITLE;Formato de arquivo QUEUE_LOCATION_FOLDER;Salvar na pasta QUEUE_LOCATION_TEMPLATE;Use modelo QUEUE_LOCATION_TEMPLATE_TOOLTIP;Podes usar as seguintes sequências de formatação:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nEssas cadeias de formatação referem-se às diferentes partes do endereço do nome da foto, alguns atributos da foto ou um índice de sequência arbitrário no processamento em lote.\n\nPor exemplo, se a foto que está sendo processada tiver o seguinte endereço do nome:\n/inicio/rodrigo/fotos/2010-10-31/dsc0042.nef\no significado das cadeias de formatação são:\n%d4 = inicio\n%d3 = rodrigo\n%d2 = fotos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /inicio/rodrigo/fotos/2010-10-31/\n%p2 = /inicio/rodrigo/fotos/\n%p3 = /inicio/rodrigo/\n%p4 = /inicio/\n\n%r será substituído pela classificação da foto. Se a foto não tiver classificação, %r será substituído por '0'. Se a foto estiver na lixeira, %r será substituído por 'x'.\n\n%s1, %s2, etc. será substituído por um índice de sequência que é preenchido entre 1 e 9 dígitos. O índice de sequência iniciará em 1 sempre que o processamento da fila for iniciado e será incrementado em 1 para cada imagem processada.\n\nSe quiseres salvar a imagem de saída no local onde se encontra a original, escreva:\n%p1/%f\n\nSe quiseres salvar a imagem de saída num diretório chamado "convertido" localizado no diretório da imagem aberta, escreva:\n%p1/convertido/%f\n\nSe quiseres salvar a imagem de saída num diretório chamado\n"/inicio/rodrigo/fotos/convertido/2010-10-31", escreva:\n%p2/convertido/%d1/%f +QUEUE_LOCATION_TITLE;Local da Saída QUEUE_STARTSTOP_TOOLTIP;Inicia ou para o processamento das imagens na fila.\n\nAtalho: Ctrl+s SAMPLEFORMAT_0;Formato de dados desconhecido SAMPLEFORMAT_1;8 bits sem assinatura @@ -1612,6 +1625,9 @@ TP_EXPOSURE_TCMODE_STANDARD;Padrão TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Padrão Ponderado TP_EXPOS_BLACKPOINT_LABEL;Pontos Pretos Raw TP_EXPOS_WHITEPOINT_LABEL;Pontos Brancos Raw +TP_FILMNEGATIVE_BLUE;Relação de azul +TP_FILMNEGATIVE_PICK;Pick neutral spots +TP_FILMNEGATIVE_RED;Relação de vermelho TP_FILMSIMULATION_LABEL;Simulação de Filme TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee está configurado para procurar por imagens Hald CLUT, que são usadas para a ferramenta Simulação de Filme, numa pasta que está demorando para carregar.\nVá para Preferências > Processamento de Imagem > Simulação de Filme\npara ver qual pasta está sendo usada. Deves apontar RawTherapee para uma pasta que contenha apenas imagens Hald CLUT e nada mais, ou para uma pasta vazia, se não quiseres usar a ferramenta Simulação de Filme.\n\nLeia o artigo sobre Simulação de Filme na RawPedia para mais informações.\n\nDesejas cancelar a verificação agora? TP_FILMSIMULATION_STRENGTH;Intensidade @@ -1732,9 +1748,13 @@ TP_LABCURVE_RSTPRO_TOOLTIP;Funciona no controle deslizante de cromaticidade e na TP_LENSGEOM_AUTOCROP;Corte automático TP_LENSGEOM_FILL;Preenchimento automático TP_LENSGEOM_LABEL;Lente / Geometria +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Selecionado automaticamente TP_LENSPROFILE_CORRECTION_LCPFILE;Ficheiro LCP +TP_LENSPROFILE_CORRECTION_MANUAL;Selecionado manualmente TP_LENSPROFILE_LABEL;Correção de lente perfilada +TP_LENSPROFILE_MODE_HEADER;Perfil da Lente TP_LENSPROFILE_USE_CA;Aberração cromática +TP_LENSPROFILE_USE_GEOMETRIC;Distorção geométrica TP_LENSPROFILE_USE_VIGNETTING;Vinhetagem TP_LOCALCONTRAST_AMOUNT;Montante TP_LOCALCONTRAST_DARKNESS;Nível de escuridão @@ -2249,45 +2269,38 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !!!!!!!!!!!!!!!!!!!!!!!!! !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply "find" keywords. -!FILEBROWSER_DELETEDIALOG_ALL;Are you sure you want to permanently delete all %1 files in trash? -!FILEBROWSER_DELETEDIALOG_SELECTED;Are you sure you want to permanently delete the selected %1 files? -!FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? -!FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. -!FILEBROWSER_POPUPREMOVE;Delete permanently -!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset !HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values -!MAIN_FRAME_PLACES_DEL;Remove +!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 !PARTIALPASTE_FILMNEGATIVE;Film Negative -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. !PROGRESSBAR_DECODING;Decoding... -!PROGRESSBAR_GREENEQUIL;Green equilibration... -!PROGRESSBAR_HLREC;Highlight reconstruction... !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... -!PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... -!QUEUE_LOCATION_TITLE;Output Location !TP_COLORTONING_LABREGION_OFFSET;Offset !TP_COLORTONING_LABREGION_POWER;Power !TP_CROP_PPI;PPI -!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_DEHAZE_LUMINANCE;Luminance only !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red ratio -!TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected -!TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. -!TP_LENSPROFILE_MODE_HEADER;Lens Profile -!TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_RAWCACORR_AUTOIT_TOOLTIP;This setting is available if "Auto-correction" is checked.\nAuto-correction is conservative, meaning that it often does not correct all chromatic aberration.\nTo correct the remaining chromatic aberration, you can use up to five iterations of automatic chromatic aberration correction.\nEach iteration will reduce the remaining chromatic aberration from the last iteration at the cost of additional processing time. !TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;If the checkbox is checked (recommended), RawTherapee calculates an optimum value based on flat regions in the image.\nIf there is no flat region in the image or the image is too noisy, the value will be set to 0.\nTo set the value manually, uncheck the checkbox first (reasonable values depend on the image). !TP_RAW_XTRANS;X-Trans !TP_RAW_XTRANSFAST;Fast X-Trans !TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce the transmission map to achieve the desired luminance.\nThe x-axis is the transmission.\nThe y-axis is the gain. +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 79c6bebfc..a4e501a77 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -613,8 +613,8 @@ MAIN_TOOLTIP_BACKCOLOR1;Фоновый цвет предпросмотра: MAIN_TOOLTIP_BACKCOLOR2;Фоновый цвет предпросмотра: Белый\nГорячая клавиша: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Заблокировать / Разблокировать предыдущий вид\n\nЗаблокировать: сохраняет предыдущий вид неизменным.\nПолезно для оценки общего эффекта от применения нескольких инструментов.\nК тому же, сравнения могут быть произведены на любом состоянии истории\n\nРазблокировать: предыдущий вид будет следовать сразу за следующим, показывая состояние изображения до применения текущего инструмента. MAIN_TOOLTIP_HIDEHP;Показать/скрыть левую панель (включая историю).\nГорячая клавиша l -MAIN_TOOLTIP_INDCLIPPEDH;Индикатор пересветов.\nГорячая клавиша: < -MAIN_TOOLTIP_INDCLIPPEDS;Индикатор затемнений.\nГорячая клавиша: > +MAIN_TOOLTIP_INDCLIPPEDH;Индикатор пересветов.\nГорячая клавиша: > +MAIN_TOOLTIP_INDCLIPPEDS;Индикатор затемнений.\nГорячая клавиша: < MAIN_TOOLTIP_PREVIEWB;Просмотреть канал синего.\nГорячая клавиша: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Просмотреть Маску резкости.\nГорячая клавиша: Shift-F\n\nБолее точна на изображениях с небольшой глубиной резкости, малым шумом и при большем приближении изображения\n\nДля улучшения определения на шумных изображениях используйте на маленьком зуме 10-30% MAIN_TOOLTIP_PREVIEWG;Просмотреть канал зеленого.\nГорячая клавиша: g @@ -1690,6 +1690,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene !HISTORY_MSG_489;DRC - Detail +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Channel @@ -1704,6 +1705,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation !HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative @@ -1715,6 +1717,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_ICM_WORKING_SLOPE;Working - Slope !HISTORY_MSG_ICM_WORKING_TRC_METHOD;Working - TRC method !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1947,6 +1956,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_COLORTONING_TWOCOLOR_TOOLTIP;Standard chroma:\nLinear response, a* = b*.\n\nSpecial chroma:\nLinear response, a* = b*, but unbound - try under the diagonal.\n\nSpecial a* and b*:\nLinear response unbound with separate curves for a* and b*. Intended for special effects.\n\nSpecial chroma 2 colors:\nMore predictable. !TP_COLORTONING_TWOSTD;Standard chroma !TP_CROP_PPI;PPI +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones !TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. !TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. @@ -1979,13 +1989,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. !TP_ICM_APPLYHUESATMAP;Base table @@ -2008,6 +2018,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_LINEDENOISE_DIRECTION;Direction !TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both !TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontal @@ -2135,6 +2146,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask !TP_SHARPENING_BLUR;Blur radius +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 2b98cfe2a..9ec7c998b 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1493,6 +1493,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1510,6 +1511,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1530,6 +1532,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1843,6 +1852,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1907,16 +1917,16 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength !TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. !TP_ICM_APPLYHUESATMAP;Base table @@ -1954,6 +1964,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_METADATA_MODE;Metadata copy mode !TP_METADATA_STRIP;Strip all metadata !TP_METADATA_TUNNEL;Copy unchanged +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter !TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. !TP_PREPROCESS_HOTPIXFILT;Hot pixel filter @@ -2119,6 +2130,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_VIEW_UNSHARP;Unsharp mask !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian new file mode 100644 index 000000000..b015cb6f1 --- /dev/null +++ b/rtdata/languages/Slovenian @@ -0,0 +1,2310 @@ +#01 2019-10-05 Matjaž Jeran + +ABOUT_TAB_BUILD;Verzija +ABOUT_TAB_CREDITS;Zasluge +ABOUT_TAB_LICENSE;Licenca +ABOUT_TAB_RELEASENOTES;Opombe ob izdaji +ABOUT_TAB_SPLASH;Uvodni zaslon +ADJUSTER_RESET_TO_DEFAULT;Klik - nastavi na privzeto vrednost.\nCtrl+klik - nastavi na začetno vrednost. +BATCH_PROCESSING;Paketna obdelava +CURVEEDITOR_AXIS_IN;I: +CURVEEDITOR_AXIS_LEFT_TAN;LT: +CURVEEDITOR_AXIS_OUT;O: +CURVEEDITOR_AXIS_RIGHT_TAN;RT: +CURVEEDITOR_CATMULLROM;Fleksibilno +CURVEEDITOR_CURVE;Krivulja +CURVEEDITOR_CURVES;Krivulje +CURVEEDITOR_CUSTOM;Standard +CURVEEDITOR_DARKS;Temine +CURVEEDITOR_EDITPOINT_HINT;Omogoči urejanje vhodno/izhodnih vrednosti v vozlišču.\n\nDesni klik v vozlišču za njgovo izbiro.\nDesni klik v prazno za izbris izbire vozlišča. +CURVEEDITOR_HIGHLIGHTS;Bleščave +CURVEEDITOR_LIGHTS;Osvetljenosti +CURVEEDITOR_LINEAR;Linearno +CURVEEDITOR_LOADDLGLABEL;naloži krivuljo ... +CURVEEDITOR_MINMAXCPOINTS;Ekvalizator +CURVEEDITOR_NURBS;Kontrolna kletka +CURVEEDITOR_PARAMETRIC;Parametrična +CURVEEDITOR_SAVEDLGLABEL;Shrani krivuljo... +CURVEEDITOR_SHADOWS;Sence +CURVEEDITOR_TOOLTIPCOPY;Kopiraj trenutno krivuljo na odložišče. +CURVEEDITOR_TOOLTIPLINEAR;Poravnaj krivuljo v daljico.. +CURVEEDITOR_TOOLTIPLOAD;Naloži krivuljo iz datoteke. +CURVEEDITOR_TOOLTIPPASTE;Prilepi krivuljo iz odlagališča. +CURVEEDITOR_TOOLTIPSAVE;Shrani tenutno krivuljo. +CURVEEDITOR_TYPE;Tip: +DIRBROWSER_FOLDERS;Mape +DONT_SHOW_AGAIN;Ne kaži več tega sporočila. +DYNPROFILEEDITOR_DELETE;Briši +DYNPROFILEEDITOR_EDIT;Uredi +DYNPROFILEEDITOR_EDIT_RULE;Uredi pravilo dinamičnega profila +DYNPROFILEEDITOR_ENTRY_TOOLTIP;Iskanje je neobčutljivo na velike/male črke.\nUporabite "re:" prefiks za\nregularni izraz. +DYNPROFILEEDITOR_IMGTYPE_ANY;Katerikoli +DYNPROFILEEDITOR_IMGTYPE_HDR;HDR +DYNPROFILEEDITOR_IMGTYPE_PS;Pomik pikslov +DYNPROFILEEDITOR_IMGTYPE_STD;Standardni +DYNPROFILEEDITOR_MOVE_DOWN;Pomakni dol +DYNPROFILEEDITOR_MOVE_UP;Pomakni gor +DYNPROFILEEDITOR_NEW;Novo +DYNPROFILEEDITOR_NEW_RULE;Novo pravilo dinamičnega profila +DYNPROFILEEDITOR_PROFILE;Profilo obdelovanja +EDITWINDOW_TITLE;Uredi sliko +EDIT_OBJECT_TOOLTIP;Prikaže gradnik v predoglednem oknu in vam omogoča prilagoditev tega orodja. +EDIT_PIPETTE_TOOLTIP;Če želite krivulji dodati prilagoditveno točko, pridržite tipko Ctrl, medtem ko levo kliknete želeno mesto v predogledu slike.\nČe želite prilagoditi točko, pridržite tipko Ctrl, medtem ko levo kliknete ustrezno območje v predogledu, nato pa jo pustite Ctrl (razen če želite natančen nadzor) in medtem ko držite levi gumb miške, miško premikate navzgor ali navzdol, da to točko v krivulji premaknete navzgor ali navzdol. +EXIFFILTER_APERTURE;Zaslonka +EXIFFILTER_CAMERA;Fotoaparat +EXIFFILTER_EXPOSURECOMPENSATION;Prilagajanje osvetlitve (EV) +EXIFFILTER_FILETYPE;Tip datoteke +EXIFFILTER_FOCALLEN;Goriščna razdalja +EXIFFILTER_IMAGETYPE;Tip slike +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_METADATAFILTER;Omogoči filtriranje metapodatkov +EXIFFILTER_SHUTTER;Čas +EXIFPANEL_ADDEDIT;Dodaj/Uredi +EXIFPANEL_ADDEDITHINT;Dodaj novo značko ali uredi značko. +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Vnesi vrednost +EXIFPANEL_ADDTAGDLG_SELECTTAG;Izberi značko +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Uredi značko +EXIFPANEL_KEEP;Ohrani +EXIFPANEL_KEEPHINT;Ohrani izbrane značke ob pisanju izhodne datoteke. +EXIFPANEL_REMOVE;Odstrani +EXIFPANEL_REMOVEHINT;Odstrani izbrane značke ob pisanju izhodne datoteke. +EXIFPANEL_RESET;Ponastavi +EXIFPANEL_RESETALL;Ponastavi vse +EXIFPANEL_RESETALLHINT;Ponastavi vse značke na njihove izvirne vrednosti. +EXIFPANEL_RESETHINT;Ponastavi izbrane značke na njihove izvirne vrednosti. +EXIFPANEL_SHOWALL;Prikaži vse +EXIFPANEL_SUBDIRECTORY;Podmapa +EXPORT_BYPASS;Koraki obdelave za obvoz +EXPORT_BYPASS_ALL;Izberi / Odizberi vse +EXPORT_BYPASS_DEFRINGE;Izpusti odstranjevanje napak robov +EXPORT_BYPASS_DIRPYRDENOISE;Izpusti zmanjšanje šuma +EXPORT_BYPASS_DIRPYREQUALIZER;xxIzpusti kontrast by Detail Levels +EXPORT_BYPASS_EQUALIZER;Izpusti Podrobnosti valovčkov +EXPORT_BYPASS_RAW_CA;Izpusti [surovo] Popravek kromatske aberacije +EXPORT_BYPASS_RAW_CCSTEPS;Izpusti [surovo] Zatiranje napačnih barv +EXPORT_BYPASS_RAW_DCB_ENHANCE;Izpusti [surovo] DCB koraki izboljšav +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Izpusti [surovo] DCB iteracije +EXPORT_BYPASS_RAW_DF;Izpusti [surovo] Dark-frame +EXPORT_BYPASS_RAW_FF;Izpusti [surovo] Flat-field +EXPORT_BYPASS_RAW_GREENTHRESH;Izpusti [surovo] Uravnoteženje zelene +EXPORT_BYPASS_RAW_LINENOISE;Izpusti [surovo] Filtriranje šuma na liniji +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Izpusti [surovo] LMMSE Korake izboljšav +EXPORT_BYPASS_SHARPENEDGE;Izpusti ostrenje robov +EXPORT_BYPASS_SHARPENING;Izpusti ostrenje +EXPORT_BYPASS_SHARPENMICRO;Izpusti mikrokontrast +EXPORT_FASTEXPORTOPTIONS;Nastavitve hitrega izvoza +EXPORT_INSTRUCTIONS;Nastavite hitrega izvoza nudijo možnost izogiba zahtevnih nastavitev gleda časa in virov za obdelavo slik namesto hitrih nastavitev v čakalnih vrstah za obdelavo. Ta način priporočam za hitro izdelavo slik manjše natančnosti kadar se mudi in je izhod zgolj drugačne velikosti od izvirnika brez siceršnjih sprememb vsebine. +EXPORT_MAXHEIGHT;Maksimalna višina: +EXPORT_MAXWIDTH;Maksimalna širina: +EXPORT_PIPELINE;Vrstni red obdelav +EXPORT_PUTTOQUEUEFAST; Vstavi v čakalno vrsto za hiter izvoz +EXPORT_RAW_DMETHOD;Demosaic method +EXPORT_USE_FAST_PIPELINE;Namenska (polna obdelava na sliki spremenjene velikosti) +EXPORT_USE_FAST_PIPELINE_TIP;Uporabite namenski tok obdelav za hitri izvoz za primer, kjer je hitrost pomembnejša od kakovosti. Sprememba velikosti slike se izvede čimprej namesto na koncu kot pri običajnem toku obdelav. Delovanje je bistveno hitrejše a bodite pripravljeni na pojav artefaktov in splošno znužanje kakovosti izdelanih slik. +EXPORT_USE_NORMAL_PIPELINE;Standardno (preskoči nekatere korake, spremeni velikost na koncu) +EXTPROGTARGET_1;surovo +EXTPROGTARGET_2;čakalna vrsta-obdelano +FILEBROWSER_APPLYPROFILE;Izvedi +FILEBROWSER_APPLYPROFILE_PARTIAL;Delno - izvedi +FILEBROWSER_AUTODARKFRAME;Avto dark-frame +FILEBROWSER_AUTOFLATFIELD;Avto flat-field +FILEBROWSER_BROWSEPATHBUTTONHINT;Klik, da odprem določeno pot, naložim mapo in uporabim ključne besede iskanja. +FILEBROWSER_BROWSEPATHHINT;Vnesite pot kamor nameravate.\n\nBližnjice:\nCtrl-o osredotočenje na polje iskanja.\nEnter / Ctrl-Enter da bi brskali tam\nEsc za brisanje sprememb.\nShift-Esc prekinitev osredotočenosti.\n\nBližnjice poti:\n~ - uporabnikova domača mapa.\n! - uporabnikova mapa s slikami +FILEBROWSER_CACHE;Predpomnilnik +FILEBROWSER_CACHECLEARFROMFULL;Počistite vse vključno s predpomnjenimi profili +FILEBROWSER_CACHECLEARFROMPARTIAL;Počistite vse razen predpomnjenih profilov +FILEBROWSER_CLEARPROFILE;Očisti +FILEBROWSER_COLORLABEL_TOOLTIP;Barvna oznaka.\n\nUporabi roletni menu ali funkcionalne tipke:\nShift-Ctrl-0 Brez barve\nShift-Ctrl-1 Rdeča\nShift-Ctrl-2 Rumena\nShift-Ctrl-3 Zelena\nShift-Ctrl-4 Modra\nShift-Ctrl-5 Škrlatna +FILEBROWSER_COPYPROFILE;Kopiraj +FILEBROWSER_CURRENT_NAME;Trenutno ime: +FILEBROWSER_DARKFRAME;Dark-frame +FILEBROWSER_DELETEDIALOG_ALL;Ali ste prepričani, da želite trajno izbrisati vse datoteke %1 v smetnjaku? +FILEBROWSER_DELETEDIALOG_HEADER;Potrditev izbrisa datoteke: +FILEBROWSER_DELETEDIALOG_SELECTED;Ali ste prepričani, da želite trajno izbrisati izbrane datoteke %1? +FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Ali ste prepričani, da želite trajno izbrisati izbrane datoteke %1, vključno z obdelano različico iz čakalne vrste? +FILEBROWSER_DELETEDLGLABEL;Potrditev brisanja datoteke +FILEBROWSER_DELETEDLGMSG;Ali ste prepričani, da želite brisati izbrane %1 datoteke? +FILEBROWSER_DELETEDLGMSGINCLPROC;Ali ste prepričani, da želite brisati izbrane %1 datoteke vključno z verzijo v čakalni vrsti za obdelavo? +FILEBROWSER_EMPTYTRASH;Izprazni smetnjak +FILEBROWSER_EMPTYTRASHHINT;Nepreklicno briši datoteke v smetnjaku. +FILEBROWSER_EXTPROGMENU;Odpri z +FILEBROWSER_FLATFIELD;Flat-field +FILEBROWSER_MOVETODARKFDIR;Prestavi v mapo za dark-frame +FILEBROWSER_MOVETOFLATFIELDDIR;Premakni se v mapo za flat-field +FILEBROWSER_NEW_NAME;Novo ime: +FILEBROWSER_OPENDEFAULTVIEWER;Privzeti pregledovalnik v oknu (obdeluje čakalne vrste) +FILEBROWSER_PARTIALPASTEPROFILE;Delno - prilepi +FILEBROWSER_PASTEPROFILE;Prilepi +FILEBROWSER_POPUPCANCELJOB;Prekliči ukaz +FILEBROWSER_POPUPCOLORLABEL;Barvna oznaka +FILEBROWSER_POPUPCOLORLABEL0;Label: Brez +FILEBROWSER_POPUPCOLORLABEL1;Label: Rdeča +FILEBROWSER_POPUPCOLORLABEL2;Label: Rumena +FILEBROWSER_POPUPCOLORLABEL3;Label: Zelena +FILEBROWSER_POPUPCOLORLABEL4;Label: Modra +FILEBROWSER_POPUPCOLORLABEL5;Label: Škrlatna +FILEBROWSER_POPUPCOPYTO;Kopiraj na... +FILEBROWSER_POPUPFILEOPERATIONS;Delo z datotekami +FILEBROWSER_POPUPMOVEEND;Prestavi na konec čakalne vrste +FILEBROWSER_POPUPMOVEHEAD;Prestavi na začetek čakalne vrste +FILEBROWSER_POPUPMOVETO;Prestavi na... +FILEBROWSER_POPUPOPEN;Odpri +FILEBROWSER_POPUPOPENINEDITOR;Odpri v urejevalniku +FILEBROWSER_POPUPPROCESS;Postavi v čakalno vrsto +FILEBROWSER_POPUPPROCESSFAST;Postavi v čakalno vrsto (Hiter izvoz) +FILEBROWSER_POPUPPROFILEOPERATIONS;Obdelujem profile +FILEBROWSER_POPUPRANK;Rangiraj +FILEBROWSER_POPUPRANK0;Unrank +FILEBROWSER_POPUPRANK1;Rang 1 * +FILEBROWSER_POPUPRANK2;Rang 2 ** +FILEBROWSER_POPUPRANK3;Rang 3 *** +FILEBROWSER_POPUPRANK4;Rang 4 **** +FILEBROWSER_POPUPRANK5;Rang 5 ***** +FILEBROWSER_POPUPREMOVE;Briši +FILEBROWSER_POPUPREMOVEINCLPROC;Briši vključno z izhodom iz čakalne vrste +FILEBROWSER_POPUPRENAME;Preimenuj +FILEBROWSER_POPUPSELECTALL;Izberi vse +FILEBROWSER_POPUPTRASH;Prestavi v smetnjak +FILEBROWSER_POPUPUNRANK;Odstrani rang +FILEBROWSER_POPUPUNTRASH;Odstrani iz smetnjaka +FILEBROWSER_QUERYBUTTONHINT;Očisti poizvedbo iskanja +FILEBROWSER_QUERYHINT;Vnesi imena iskanih datotek. Dovolj je že del imena. Loči iskalne termine z vejicami, npr.\n1001,1004,1199\n\nIzloči termine iskanje s predpono !=\nnpr.\n!=1001,1004,1199\n\nBližnjice:\nCtrl-f - fokusiraj rubriko iskanja,\nEnter - išči,\nEsc - očisti rubriko iskanja,\nShift-Esc - sprosti fokus na rubriki iskanja. +FILEBROWSER_QUERYLABEL; Išči: +FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nBližnjica: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nBližnjica: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nBližnjica: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nBližnjica: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nBližnjica: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Preimenuj datoteko +FILEBROWSER_RESETDEFAULTPROFILE;Nastavi na privzeto vrednost +FILEBROWSER_SELECTDARKFRAME;Izberi dark-frame... +FILEBROWSER_SELECTFLATFIELD;Izberite flat-field... +FILEBROWSER_SHOWCOLORLABEL1HINT;Prikaži slike označene z rdečo.\nBližnjica: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Prikaži slike označene z rumeno.\nBližnjica: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Prikaži slike označene z zeleno.\nBližnjica: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Prikaži slike označene z modro.\nBližnjica: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Prikaži slike označene s škrlatno.\nBližnjica: Alt-5 +FILEBROWSER_SHOWDIRHINT;Odstrani vse filtre.\nBližnjica: d +FILEBROWSER_SHOWEDITEDHINT;Prikaži spremenjene slike.\nBližnjica: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Prikaži nespremenjene slike.\nBližnjica: 6 +FILEBROWSER_SHOWEXIFINFO;Prikaži Exif informacije.\n\nBližnjice:\ni - Način zavihkov več urejevalnikov,\nAlt-i - Način enega zavihka urejevalnika. +FILEBROWSER_SHOWNOTTRASHHINT;Prikaži samo nezbrisane slike. +FILEBROWSER_SHOWORIGINALHINT;Prikaži samo izvirne slike.\n\nKadar obstaja več slik z enakim imenom a različnimi podaljški imena, smatram za izvirnik tisto, katere podaljšek je najvišje v seznamu podaljškov v nastavitvah > File Browser > Parsed Extensions. +FILEBROWSER_SHOWRANK1HINT;Prikaži slike označene z 1 zvezdico.\nBližnjica: 1 +FILEBROWSER_SHOWRANK2HINT;Prikaži slike označene z 2 zvezdicama.\nBližnjica: 2 +FILEBROWSER_SHOWRANK3HINT;Prikaži slike označene z 3 zvezdicami.\nBližnjica: 3 +FILEBROWSER_SHOWRANK4HINT;Prikaži slike označene z 4 zvezdicami.\nBližnjica: 4 +FILEBROWSER_SHOWRANK5HINT;Prikaži slike označene z 5 zvezdicami.\nBližnjica: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Pokaži shranjene slike.\nBližnjica: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Pokaži neshranjene slike.\nBližnjica: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Pokaži vsebino smetnjaka.\nBližnjica: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Pokaži slike brez barvne oznake.\nShortcut: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Prikaži nerangirane slike.\nShortcut: 0 +FILEBROWSER_THUMBSIZE;Velikost predogledne sličice +FILEBROWSER_UNRANK_TOOLTIP;Odstrani rang.\nShortcut: Shift-0 +FILEBROWSER_ZOOMINHINT;Povečaj velikost predogledne sličice.\n\nBližnjice:\n+ - Način z več zavihki urejevalnika,\nAlt-+ - Način z enim zavihkom in urejevalnikom. +FILEBROWSER_ZOOMOUTHINT;Pomanjšaj velikost predogledne sličice.\n\nBližnjice:\n- - Način z več zavihki urejevalnika,\nAlt-- - Način z enim zavihkom in urejevalnikom. +FILECHOOSER_FILTER_ANY;Vse datoteke +FILECHOOSER_FILTER_COLPROF;Barvni profili (*.icc) +FILECHOOSER_FILTER_CURVE;Profili krivulj +FILECHOOSER_FILTER_LCP;Profili popravkov lečij +FILECHOOSER_FILTER_PP;Profili obdelovanja +FILECHOOSER_FILTER_SAME;Enak format kot trenutna slika +FILECHOOSER_FILTER_TIFF;Datoteke TIFF +GENERAL_ABOUT;O programu +GENERAL_AFTER;Po +GENERAL_APPLY;Uveljavi +GENERAL_ASIMAGE;Kot slika +GENERAL_AUTO;Avtomatsko +GENERAL_BEFORE;Pred +GENERAL_CANCEL;Prekliči +GENERAL_CLOSE;Zapri +GENERAL_CURRENT;Trenutno +GENERAL_DISABLE;Onemogoči +GENERAL_DISABLED;Onemogočeno +GENERAL_ENABLE;Omogoči +GENERAL_ENABLED;Omogočeno +GENERAL_FILE;Datoteka +GENERAL_LANDSCAPE;Ležeči format +GENERAL_NA;n/a +GENERAL_NO;Ne +GENERAL_NONE;Nič +GENERAL_OK;OK +GENERAL_OPEN;Odpri +GENERAL_PORTRAIT;Pokončni format +GENERAL_RESET;Reset +GENERAL_SAVE;Shrani +GENERAL_SAVE_AS;Shrani kot... +GENERAL_SLIDER;Drsnik +GENERAL_UNCHANGED;(Nespremenjeno) +GENERAL_WARNING;Opozorilo +GIMP_PLUGIN_INFO;Dobrodošli v RawTherapee vtičniku za GIMP!\nKo boste končali z urejanjem enostavno zaprite glavno okno in slika se bo avtomatično uvozila v GIMP. +HISTOGRAM_TOOLTIP_B;Prikaži/Skrij histogram za modro. +HISTOGRAM_TOOLTIP_BAR;Prikaži/Skrij stolpce RGB indikatorjev. +HISTOGRAM_TOOLTIP_CHRO;Prikaži/Skrij histogram barvitosti. +HISTOGRAM_TOOLTIP_G;Prikaži/Skrij histogram za zeleno. +HISTOGRAM_TOOLTIP_L;Prikaži/Skrij histogram CIELab svetlosti. +HISTOGRAM_TOOLTIP_MODE;Preklopi med linearno, log-linearno in log-log merilom histograma. +HISTOGRAM_TOOLTIP_R;Prikaži/Skrij histogram za rdečo. +HISTOGRAM_TOOLTIP_RAW;Prikaži/Skrij surovi histogram. +HISTORY_CHANGED;Spremenjeno +HISTORY_CUSTOMCURVE;Prilagojena krivulja +HISTORY_FROMCLIPBOARD;Iz odložišča +HISTORY_LABEL;Zgodovina +HISTORY_MSG_1;Slika naložena +HISTORY_MSG_2;PP3 naložena +HISTORY_MSG_3;PP3 spremenjena +HISTORY_MSG_4;Brskanje po zgodovini +HISTORY_MSG_5;Ekspozicija - Osvetljenost +HISTORY_MSG_6;Ekspozicija - Kontrast +HISTORY_MSG_7;Ekspozicija - Črnina +HISTORY_MSG_8;Ekspozicija - Prilagoditev +HISTORY_MSG_9;Ekspozicija - Stiskanje bleščav +HISTORY_MSG_10;Ekspozicija - Stiskanje senc +HISTORY_MSG_11;Ekspozicija - Krivulja tonov 1 +HISTORY_MSG_12;Ekspozicija - Avtomatski nivoji +HISTORY_MSG_13;Ekspozicija - Klip +HISTORY_MSG_14;L*a*b* - Osvetljenost +HISTORY_MSG_15;L*a*b* - Kontrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;L*a*b* - krivulja L* +HISTORY_MSG_20;Ostrenje +HISTORY_MSG_21;USM - Radij +HISTORY_MSG_22;USM - Količina +HISTORY_MSG_23;USM - Prag +HISTORY_MSG_24;USM - Naostri samo robove +HISTORY_MSG_25;USM - Radij detekcije roba +HISTORY_MSG_26;USM - Toleranca roba +HISTORY_MSG_27;USM - Kontrola haloja +HISTORY_MSG_28;USM - Kontrolna velikost haloja +HISTORY_MSG_29;Methoda - ostrenja +HISTORY_MSG_30;RLD - Radiij +HISTORY_MSG_31;RLD - Količina +HISTORY_MSG_32;RLD - Blaženje +HISTORY_MSG_33;RLD - Iteracije +HISTORY_MSG_34;Popravki lečja - Popačenje +HISTORY_MSG_35;Popravki lečja - Vinjetiranje +HISTORY_MSG_36;Popravki lečja - - CA +HISTORY_MSG_37;Ekspozicija - Avtomatski nivoji +HISTORY_MSG_38;Ravnotežje beline - Metoda +HISTORY_MSG_39;WB - Temperatura +HISTORY_MSG_40;WB - Odtenek +HISTORY_MSG_41;Ekspozicija - način krivulje odtenkov 1 +HISTORY_MSG_42;Ekspozicija - krivulja odtenkov 2 +HISTORY_MSG_43;Ekspozicija - način krivulje odtenkov 2 +HISTORY_MSG_44;Lum. radij odstranjevanja šuma +HISTORY_MSG_45;Lum. toleranca roba odstranjevanja šuma +HISTORY_MSG_46;Odstranjevanje barvnega šuma +HISTORY_MSG_47;Zmešaj ICC bleščave z matriko +HISTORY_MSG_48;DCP - Krivulja tonov +HISTORY_MSG_49;DCP osvetljava +HISTORY_MSG_50;Sence/bleščave +HISTORY_MSG_51;S/H - Bleščave +HISTORY_MSG_52;S/H - Sence +HISTORY_MSG_53;S/H - Tonska širina bleščav +HISTORY_MSG_54;S/H - Tonska širina senc +HISTORY_MSG_55;S/H - Lokalni kontrast +HISTORY_MSG_56;S/H - Radij +HISTORY_MSG_57;Groba rotacija +HISTORY_MSG_58;Horizontalni preobrat +HISTORY_MSG_59;Vertikalni preobrat +HISTORY_MSG_60;Rotacija +HISTORY_MSG_61;Avtomatsko polnenje +HISTORY_MSG_62;Popravki popačenja +HISTORY_MSG_63;Izbran posnetek stanja +HISTORY_MSG_64;Izrez +HISTORY_MSG_65;CA popravki +HISTORY_MSG_66;Ekspozicija - Rekonstrukcija bleščav +HISTORY_MSG_67;Ekspozicija - HLR količina +HISTORY_MSG_68;Ekspozicija - HLR metoda +HISTORY_MSG_69;Delovni barvni prostor +HISTORY_MSG_70;Izhodni barvni prostor +HISTORY_MSG_71;Vhodni barvni prostor +HISTORY_MSG_72;VC - Količina +HISTORY_MSG_73;Mešalnik kanalov +HISTORY_MSG_74;Sprememba velikosti - Merilo +HISTORY_MSG_75;Spremeba velikosti - Metoda +HISTORY_MSG_76;Exif metapodatki +HISTORY_MSG_77;IPTC metapodatki +HISTORY_MSG_78;- +HISTORY_MSG_79;Sprememba velikosti - Širina +HISTORY_MSG_80;Sprememba velikosti - Višina +HISTORY_MSG_81;Spremeni velikost +HISTORY_MSG_82;Profil spremenjen +HISTORY_MSG_83;S/H - maska ostrenja +HISTORY_MSG_84;Popravek perspektive +HISTORY_MSG_85;Popravek objektiva - datoteka LCP +HISTORY_MSG_86;RGB krivulje - Način svetilnosti +HISTORY_MSG_87;Impulzno zmanjšanje šuma +HISTORY_MSG_88;Prag impulznega zmanjšanja šuma +HISTORY_MSG_89;Zmanjšanje šuma +HISTORY_MSG_90;Zmanjšanje šuma - Svetlost +HISTORY_MSG_91;Zmanjšanje šuma - glavna barvitost +HISTORY_MSG_92;Zmanjšanje šuma - Gama +HISTORY_MSG_93;CbDL - Vrednost +HISTORY_MSG_94;Kontrast po nivojih podrobnosti +HISTORY_MSG_95;L*a*b* - Barvitost +HISTORY_MSG_96;L*a*b* - a* krivulja +HISTORY_MSG_97;L*a*b* - b* krivulja +HISTORY_MSG_98;Metoda odstranjevanja mozaičnosti +HISTORY_MSG_99;Filtriranje vročih pikslov +HISTORY_MSG_100;Ekspozicija - Nasičenje +HISTORY_MSG_101;HSV - Odtenek +HISTORY_MSG_102;HSV - Nasičenost +HISTORY_MSG_103;HSV - Vrednost +HISTORY_MSG_104;HSV Ekvalizator +HISTORY_MSG_105;Odstranjevanje napak robov +HISTORY_MSG_106;Odstranjevanje napak robov - Radij +HISTORY_MSG_107;Odstranjevanje napak robov - Prag +HISTORY_MSG_108;Ekspozicija - prag HLC +HISTORY_MSG_109;Sprememba velikosti - Velikostni okvir +HISTORY_MSG_110;Sprememba velikosti - Uporabi na +HISTORY_MSG_111;L*a*b* - Izogibanje barvnega premika +HISTORY_MSG_112;--neuporabljeno-- +HISTORY_MSG_113;L*a*b* - Zaščita rdeče kože +HISTORY_MSG_114;DCB iteracije +HISTORY_MSG_115;Zatiranje napačne barve +HISTORY_MSG_116;DCB izboljšave +HISTORY_MSG_117;Surovi CA popravek - Rdeča +HISTORY_MSG_118;Surovi CA popravek - Modra +HISTORY_MSG_119;Filtriranje šuma na črti +HISTORY_MSG_120;Uravnoteženje zelene +HISTORY_MSG_121;Surovi CA popravek - Avtomatski +HISTORY_MSG_122;Dark-frame - Avtomatski izbor +HISTORY_MSG_123;Dark-frame - Datoteka +HISTORY_MSG_124;Popravek točke beline +HISTORY_MSG_126;Flat-field - Datoteka +HISTORY_MSG_127;Flat-field - Avto-selekcija +HISTORY_MSG_128;Flat-field - Radij zameglevanja +HISTORY_MSG_129;Flat-field - Tip zameglevanja +HISTORY_MSG_130;Avtomatski popravek popačenja +HISTORY_MSG_131;Zmanjšanje šuma - Luma +HISTORY_MSG_132;Zmanjšanje šuma - Barvitost +HISTORY_MSG_133;Gama izhoda +HISTORY_MSG_134;Svobodni gama +HISTORY_MSG_135;Svobodni gama +HISTORY_MSG_136;Strmina proste game +HISTORY_MSG_137;Nivo črnine - Zelena 1 +HISTORY_MSG_138;Nivo črnine - Rdeča +HISTORY_MSG_139;Nivo črnine - Modra +HISTORY_MSG_140;Nivo črnine - Zelena 2 +HISTORY_MSG_141;Nivo črnine - Poveži zelene +HISTORY_MSG_142;ES - Iteracije +HISTORY_MSG_143;ES - Količina +HISTORY_MSG_144;Mikrokontrast - Količina +HISTORY_MSG_145;Mikrokontrast - Enotnost +HISTORY_MSG_146;Ostrenje robov +HISTORY_MSG_147;ES - Samo svetlost +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - matrika 3×3 +HISTORY_MSG_150;Zmanjševanje šuma in artefaktov po odstr. mozaičnosti +HISTORY_MSG_151;Vibranca +HISTORY_MSG_152;Vib - Pastelni toni +HISTORY_MSG_153;Vib - Nasičeni toni +HISTORY_MSG_154;Vib - Zavaruj tone kože +HISTORY_MSG_155;Vib - Izogibaj se pomiku barv +HISTORY_MSG_156;Vib - Poveži pastelne/nasičene +HISTORY_MSG_157;Vib - Prag pastelnih/nasičenih +HISTORY_MSG_158;TM - Moč +HISTORY_MSG_159;TM - Zaustavljanje roba +HISTORY_MSG_160;TM - Merilo +HISTORY_MSG_161;TM - Ponovno uteževanje iteracij +HISTORY_MSG_162;Preslikava tonov +HISTORY_MSG_163;RGB Krivulje - Rdeča +HISTORY_MSG_164;RGB Krivulje - Zelena +HISTORY_MSG_165;RGB Krivulje - Modra +HISTORY_MSG_166;Ekspozicija - Ponastavitev +HISTORY_MSG_167;Metoda odstranjevanja mozaičnosti +HISTORY_MSG_168;L*a*b* - CC krivulja +HISTORY_MSG_169;L*a*b* - CH krivulja +HISTORY_MSG_170;Vibrance - HH krivulja +HISTORY_MSG_171;L*a*b* - LC krivulja +HISTORY_MSG_172;L*a*b* - Omeji LC +HISTORY_MSG_173;NR - Obnova podrobnosti +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 adaptacija +HISTORY_MSG_176;CAM02 - Pogled okolice +HISTORY_MSG_177;CAM02 - Svetlost scene +HISTORY_MSG_178;CAM02 - Ogled svetlosti +HISTORY_MSG_179;CAM02 - Model bele točke +HISTORY_MSG_180;CAM02 - Lightness (J) +HISTORY_MSG_181;CAM02 - Barvitost (C) +HISTORY_MSG_182;CAM02 - Avtomatski CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Obkroži sceno +HISTORY_MSG_185;CAM02 - Kontrola barvnega obsega +HISTORY_MSG_186;CAM02 - Algoritem +HISTORY_MSG_187;CAM02 - Zaščita rdeče/kožne +HISTORY_MSG_188;CAM02 - Svetlost (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Nasičenost (S) +HISTORY_MSG_191;CAM02 - Polnost barv (M) +HISTORY_MSG_192;CAM02 - Odtenek (h) +HISTORY_MSG_193;CAM02 - Krivulja tona 1 +HISTORY_MSG_194;CAM02 - Krivulja tona 2 +HISTORY_MSG_195;CAM02 - Krivulja tona 1 +HISTORY_MSG_196;CAM02 - Krivulja tona 2 +HISTORY_MSG_197;CAM02 - Barvna krivulja +HISTORY_MSG_198;CAM02 - Barvna krivulja +HISTORY_MSG_199;CAM02 - Izhodni histogrami +HISTORY_MSG_200;CAM02 - Preslikava tonov +HISTORY_MSG_201;NR - Barvitost - R&G +HISTORY_MSG_202;NR - Barvitost - B&Y +HISTORY_MSG_203;NR - Barvni prostor +HISTORY_MSG_204;LMMSE koraki izboljšav +HISTORY_MSG_205;CAM02 - Filtriranje vročih/slabih pikslov +HISTORY_MSG_206;CAT02 - Avtomatska svetilnost scene +HISTORY_MSG_207;Odstranjevanje napak robov - Krivulja odtenkov +HISTORY_MSG_208;WB - B/R ekvalizator +HISTORY_MSG_210;GF - Kot +HISTORY_MSG_211;Postopno Filtriranje +HISTORY_MSG_212;VF - Moč +HISTORY_MSG_213;Filter vinjete +HISTORY_MSG_214;Črno-belo +HISTORY_MSG_215;B&W - CM - Rdeče +HISTORY_MSG_216;B&W - CM - Zeleno +HISTORY_MSG_217;B&W - CM - Modro +HISTORY_MSG_218;B&W - Gama - Rdeče +HISTORY_MSG_219;B&W - Gama - Zeleno +HISTORY_MSG_220;B&W - Gama - Modro +HISTORY_MSG_221;B&W - barvni filter +HISTORY_MSG_222;B&W - Prednastavitve +HISTORY_MSG_223;B&W - CM - Oranžno +HISTORY_MSG_224;B&W - CM - Rumeno +HISTORY_MSG_225;B&W - CM - Cian +HISTORY_MSG_226;B&W - CM - Magenta +HISTORY_MSG_227;B&W - CM - Vijolična +HISTORY_MSG_228;B&W - Ekvalizator svetlosti +HISTORY_MSG_229;B&W - Ekvalizator svetlosti +HISTORY_MSG_230;B&W - Način +HISTORY_MSG_231;B&W - Krivulja 'pred' +HISTORY_MSG_232;B&W - Tip krivulje 'pred' +HISTORY_MSG_233;B&W - Krivulja 'po' +HISTORY_MSG_234;B&W - Tip krivulje 'po' +HISTORY_MSG_235;B&W - CM - Avto +HISTORY_MSG_236;--neuporabljeno-- +HISTORY_MSG_237;B&W - CM +HISTORY_MSG_238;GF - Pero +HISTORY_MSG_239;GF - Moč +HISTORY_MSG_240;GF - Center +HISTORY_MSG_241;VF - Pero +HISTORY_MSG_242;VF - Okroglost +HISTORY_MSG_243;VC - Radij +HISTORY_MSG_244;VC - Moč +HISTORY_MSG_245;VC - Center +HISTORY_MSG_246;L*a*b* - CL krivulja +HISTORY_MSG_247;L*a*b* - LH krivulja +HISTORY_MSG_248;L*a*b* - HH krivulja +HISTORY_MSG_249;CbDL - Prag +HISTORY_MSG_250;NR - Izboljšano +HISTORY_MSG_251;B&W - Algoritem +HISTORY_MSG_252;CbDL - Skin tar/prot +HISTORY_MSG_253;CbDL - Reduciraj artefakte +HISTORY_MSG_254;CbDL - Odtenek kože +HISTORY_MSG_255;NR - Filter mediane +HISTORY_MSG_256;NR - Mediana - Tip +HISTORY_MSG_257;Toniranje barve +HISTORY_MSG_258;CT - Barvna krivulja +HISTORY_MSG_259;CT - Krivulja neprosojnosti +HISTORY_MSG_260;CT - a*[b*] neprosojnost +HISTORY_MSG_261;CT - Metoda +HISTORY_MSG_262;CT - b* neprosojnost +HISTORY_MSG_263;CT - Sence - Rdeča +HISTORY_MSG_264;CT - Sence - Zelena +HISTORY_MSG_265;CT - Sence - Modra +HISTORY_MSG_266;CT - srednje - Rdeča +HISTORY_MSG_267;CT - Srednje - Zelena +HISTORY_MSG_268;CT - Srednje - Modra +HISTORY_MSG_269;CT - Svetle - Rdeča +HISTORY_MSG_270;CT - Svetle - Zelena +HISTORY_MSG_271;CT - Svetle - Modra +HISTORY_MSG_272;CT - Uravnoteži +HISTORY_MSG_273;CT - Uravnoteženost barv SMH +HISTORY_MSG_274;CT - Nasičenost senc +HISTORY_MSG_275;CT - Nasičenost svetlih delov +HISTORY_MSG_276;CT - Neprosojnost +HISTORY_MSG_277;--neuporabljeno-- +HISTORY_MSG_278;CT - Ohrani svetlost +HISTORY_MSG_279;CT - Sence +HISTORY_MSG_280;CT - Bleščave +HISTORY_MSG_281;CT - Moč nasičenosti +HISTORY_MSG_282;CT - Prag nasičenosti +HISTORY_MSG_283;CT - Moč +HISTORY_MSG_284;CT - Avtomatsko varovanje nasičenosti +HISTORY_MSG_285;NR - Mediana - Metoda +HISTORY_MSG_286;NR - Mediana - Tip +HISTORY_MSG_287;NR - Mediana - Iteracije +HISTORY_MSG_288;Flat-Field - Kontrola obrezave +HISTORY_MSG_289;Flat-Field - Kontrola obrezave - Avto +HISTORY_MSG_290;Nivo črnine - Rdeča +HISTORY_MSG_291;Nivo črnine - Zelena +HISTORY_MSG_292;Nivo črnine - Modra +HISTORY_MSG_293;Simulacija filma +HISTORY_MSG_294;Simulacija filma - Moč +HISTORY_MSG_295;Simulacija filma - Film +HISTORY_MSG_296;NR - Krivulja svetlosti +HISTORY_MSG_297;NR - Način +HISTORY_MSG_298;Filter mrtvih pikslov +HISTORY_MSG_299;NR - Krivulja svetlosti +HISTORY_MSG_300;- +HISTORY_MSG_301;NR - Kontrola lume +HISTORY_MSG_302;NR - Metoda barvitosti +HISTORY_MSG_303;NR - Metoda barvitosti +HISTORY_MSG_304;W - Nivoji kontrastov +HISTORY_MSG_305;Nivoji valovčkov +HISTORY_MSG_306;W - Obdelava +HISTORY_MSG_307;W - Obdelava +HISTORY_MSG_308;W - Smer obdelave +HISTORY_MSG_309;W - ES - Podrobnost +HISTORY_MSG_310;W - Residual - Nebo tar/prot +HISTORY_MSG_311;W - Nivoji valovčkov +HISTORY_MSG_312;W - Residual - Prag senc +HISTORY_MSG_313;W - Barvitost - Sat/past +HISTORY_MSG_314;W - Barvni obseg - Reduciraj artefakte +HISTORY_MSG_315;W - Residual - Kontrast +HISTORY_MSG_316;W - Barvni obseg - Koža tar/prot +HISTORY_MSG_317;W - Barvni obseg - Koža hue +HISTORY_MSG_318;W - Kontrast - Nivoji bleščav +HISTORY_MSG_319;W - Kontrast - Obseg bleščav +HISTORY_MSG_320;W - Kontrast - Obseg senc +HISTORY_MSG_321;W - Kontrast - Nivoji senc +HISTORY_MSG_322;W - Barvni obseg - Izogibanje barvnega pomika +HISTORY_MSG_323;W - ES - Lokalni kontrast +HISTORY_MSG_324;W - Barvitost - Pastel +HISTORY_MSG_325;W - Barvitost - Nasičenje +HISTORY_MSG_326;W - Barvitost - Metoda +HISTORY_MSG_327;W - Kontrast - Uporabi za +HISTORY_MSG_328;W - Barvitost - Moč povezave +HISTORY_MSG_329;W - Toniranje - Neprosojnost RG +HISTORY_MSG_330;W - Toniranje - Neprosojnost BY +HISTORY_MSG_331;W - Nivoji kontrastov - Ekstra +HISTORY_MSG_332;W - Metoda prekrivanja +HISTORY_MSG_333;W - Residual - Sence +HISTORY_MSG_334;W - Residual - Barvitost +HISTORY_MSG_335;W - Residual - Bleščave +HISTORY_MSG_336;W - Residual - Prag bleščav +HISTORY_MSG_337;W - Residual - Odtenek neba +HISTORY_MSG_338;W - ES - Radij +HISTORY_MSG_339;W - ES - Moč +HISTORY_MSG_340;W - Moč +HISTORY_MSG_341;W - Izvedba robov +HISTORY_MSG_342;W - ES - Prvi nivo +HISTORY_MSG_343;W - Nivoji barvitosti +HISTORY_MSG_344;W - Metoda barvitost sl/cur +HISTORY_MSG_345;W - ES - Lokalni kontrast +HISTORY_MSG_346;W - ES - Metoda lokalnega kontrasta +HISTORY_MSG_347;W - Odstranjevanje šuma - Nivo 1 +HISTORY_MSG_348;W - Odstranjevanje šuma - Nivo 2 +HISTORY_MSG_349;W - Odstranjevanje šuma - Nivo 3 +HISTORY_MSG_350;W - ES - Detekcija roba +HISTORY_MSG_351;W - Residual - HH krivulja +HISTORY_MSG_352;W - Ozadje +HISTORY_MSG_353;W - ES - Občutljivost gradienta +HISTORY_MSG_354;W - ES - Izboljšan +HISTORY_MSG_355;W - ES - Nizki prag +HISTORY_MSG_356;W - ES - Visoki prag +HISTORY_MSG_357;W - Odstrani šum - Povezava z ES +HISTORY_MSG_358;W - Barvni obseg - CH +HISTORY_MSG_359;Vroč/Mrtev - Prag +HISTORY_MSG_360;TM - Gama +HISTORY_MSG_361;W - Končno - uravnoteženje barvitosti +HISTORY_MSG_362;W - Residual - Metoda stiskanja +HISTORY_MSG_363;W - Residual - Moč stiskanja +HISTORY_MSG_364;W - Končno - Uravnoteženost kontrasta +HISTORY_MSG_365;W - Končno - Delta uravnoteženje +HISTORY_MSG_366;W - Residual - Stiskanje game +HISTORY_MSG_367;W - Končno - Krivulja kontrastov 'Po' +HISTORY_MSG_368;W - Končno - Uravnoteženje kontrastov +HISTORY_MSG_369;W - Končno - Metoda uravnoteženja +HISTORY_MSG_370;W - Končno - Krivulja lokalnega kontrasta +HISTORY_MSG_371;Post-Resize Ostrenje +HISTORY_MSG_372;PRS USM - Radij +HISTORY_MSG_373;PRS USM - Količina +HISTORY_MSG_374;PRS USM - Prag +HISTORY_MSG_375;PRS USM - Naostri samo robove +HISTORY_MSG_376;PRS USM - Radij detekcije roba +HISTORY_MSG_377;PRS USM - Toleranca roba +HISTORY_MSG_378;PRS USM - Kontrola haloja +HISTORY_MSG_379;PRS USM - Količina kontrole haloja +HISTORY_MSG_380;PRS - Metoda +HISTORY_MSG_381;PRS RLD - Radij +HISTORY_MSG_382;PRS RLD - Količina +HISTORY_MSG_383;PRS RLD - Dušenje +HISTORY_MSG_384;PRS RLD - Iteracij +HISTORY_MSG_385;W - Residual - Uravnoteženost barv +HISTORY_MSG_386;W - Residual - CB močne zelene +HISTORY_MSG_387;W - Residual - CB močne modre +HISTORY_MSG_388;W - Residual - CB srednje zelene +HISTORY_MSG_389;W - Residual - CB srednje modre +HISTORY_MSG_390;W - Residual - CB šibke zelene +HISTORY_MSG_391;W - Residual - CB šibke modre +HISTORY_MSG_392;W - Residual - Uravnoteženost barv +HISTORY_MSG_393;DCP - Iskalna tabela +HISTORY_MSG_394;DCP - Osnovna ekspozicija +HISTORY_MSG_395;DCP - Osnovna tabela +HISTORY_MSG_396;W - pod-orodje kontrasta +HISTORY_MSG_397;W - Pod-orodje barvitosti +HISTORY_MSG_398;W - ES sub-tool +HISTORY_MSG_399;W - Residual sub-tool +HISTORY_MSG_400;W - Končno sub-tool +HISTORY_MSG_401;W - Pod-orodje toniranja +HISTORY_MSG_402;W - Pod-orodje odstranjevanja šuma +HISTORY_MSG_403;W - ES - Občutljivost na robove +HISTORY_MSG_404;W - ES - Ojačevanje osnove +HISTORY_MSG_405;W - Odstranjevanje šuma - Nivo 4 +HISTORY_MSG_406;W - ES - Sosednji piksli +HISTORY_MSG_407;Retinex - Metoda +HISTORY_MSG_408;Retinex - Radij +HISTORY_MSG_409;Retinex - Kontrast +HISTORY_MSG_410;Retinex - Odmik +HISTORY_MSG_411;Retinex - Moč +HISTORY_MSG_412;Retinex - Gaussov gradient +HISTORY_MSG_413;Retinex - Kontrast +HISTORY_MSG_414;Retinex - Histogram - Lab +HISTORY_MSG_415;Retinex - Prenos +HISTORY_MSG_416;Retinex +HISTORY_MSG_417;Retinex - Mediana prenosa +HISTORY_MSG_418;Retinex - Prag +HISTORY_MSG_419;Retinex - Barvni prostor +HISTORY_MSG_420;Retinex - Histogram - HSL +HISTORY_MSG_421;Retinex - Gama +HISTORY_MSG_422;Retinex - Gama +HISTORY_MSG_423;Retinex - Gama strmina +HISTORY_MSG_424;Retinex - HL prag +HISTORY_MSG_425;Retinex - Log base +HISTORY_MSG_426;Retinex - Ekvalizator odtenkov +HISTORY_MSG_427;Namen izrisovanja izhoda +HISTORY_MSG_428;Namen izrisovanja zaslona +HISTORY_MSG_429;Retinex - Iteracij +HISTORY_MSG_430;Retinex - Gradient prenosa +HISTORY_MSG_431;Retinex - Moč gradienta +HISTORY_MSG_432;Retinex - M - Bleščave +HISTORY_MSG_433;Retinex - M - Bleščave TW +HISTORY_MSG_434;Retinex - M - Sence +HISTORY_MSG_435;Retinex - M - Sence TW +HISTORY_MSG_436;Retinex - M - Radij +HISTORY_MSG_437;Retinex - M - Metoda +HISTORY_MSG_438;Retinex - M - Ekvalizator +HISTORY_MSG_439;Retinex - Obdelava +HISTORY_MSG_440;CbDL - Metoda +HISTORY_MSG_441;Retinex - Prenos povečanja +HISTORY_MSG_442;Retinex - Merilo +HISTORY_MSG_443;Prilagoditev črne točke izhoda +HISTORY_MSG_444;WB - Začasna pristranost +HISTORY_MSG_445;Raw sub-image +HISTORY_MSG_449;PS - prilagoditev ISO +HISTORY_MSG_452;PS - Prikaži gibanje +HISTORY_MSG_453;PS - Prikaži samo masko +HISTORY_MSG_457;PS - Preveri redečo/modro +HISTORY_MSG_462;PS - Preveri zeleno +HISTORY_MSG_464;PS - Zamegli masko gibanja +HISTORY_MSG_465;PS - Zamegli radij +HISTORY_MSG_468;PS - Zapolni luknje +HISTORY_MSG_469;PS - Mediana +HISTORY_MSG_471;PS - Popravek gibanja +HISTORY_MSG_472;PS - Gladki prehodi +HISTORY_MSG_473;PS - Uporabi LMMSE +HISTORY_MSG_474;PS - Izenači +HISTORY_MSG_475;PS - Izenači kanal +HISTORY_MSG_476;CAM02 - Začasno ven +HISTORY_MSG_477;CAM02 - Zeleno ven +HISTORY_MSG_478;CAM02 - Yb ven +HISTORY_MSG_479;CAM02 - CAT02 prilagoditev ven +HISTORY_MSG_480;CAM02 - Avtomatska CAT02 ven +HISTORY_MSG_481;CAM02 - Začasna scena +HISTORY_MSG_482;CAM02 - Zelena scena +HISTORY_MSG_483;CAM02 - Yb scena +HISTORY_MSG_484;CAM02 - Avto Yb scena +HISTORY_MSG_485;Popravek objektiva +HISTORY_MSG_486;Popravek objektiva - Fotoaparat +HISTORY_MSG_487;Popravek objektiva - Objektiv +HISTORY_MSG_488;Zmanjšanje dinamičnega obsega +HISTORY_MSG_489;DRC - Podrobnost +HISTORY_MSG_490;DRC - Količina +HISTORY_MSG_491;Ravnotežje beline +HISTORY_MSG_492;RGB krivulje +HISTORY_MSG_493;L*a*b* prilagoditve +HISTORY_MSG_494;Ujemite ostrenje +HISTORY_MSG_CLAMPOOG;Izrežite barve izven obsega +HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Popravek barv +HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Popravek barv +HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Kanal +HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - maska regije C +HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H maska +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Svetlost +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L maska +HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - Seznam +HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - zamegljevanje regijske maske +HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - odmik regije +HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - moč regije +HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Nasičenost +HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - prikaz maske regije +HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - strmina regije +HISTORY_MSG_DEHAZE_DEPTH;Odstranjevanje zamegljenosti - Globina +HISTORY_MSG_DEHAZE_ENABLED;Odstranjevanje zamegljenosti +HISTORY_MSG_DEHAZE_LUMINANCE;Odstranjevanje zamegljenosti - samo svetlost +HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Odstranjevanje zamegljenosti - Prikaži globino mape +HISTORY_MSG_DEHAZE_STRENGTH;Odstranjevanje zamegljenosti - Moč +HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dualno odstranjevanje mozaičnosti - Avtomatski prag +HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dualno odstranjevanje mozaičnosti - Prag kontrasta +HISTORY_MSG_FILMNEGATIVE_ENABLED;Filmski negativ +HISTORY_MSG_FILMNEGATIVE_VALUES;Film negativne vrednosti +HISTORY_MSG_HISTMATCHING;Avto-usklajena krivulja tonov +HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries +HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 osvetljevalnik D +HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Tip +HISTORY_MSG_ICM_WORKING_GAMMA;Delovanje - Gama +HISTORY_MSG_ICM_WORKING_SLOPE;Delovanje - Strmina +HISTORY_MSG_ICM_WORKING_TRC_METHOD;Delovanje - Metoda TRC +HISTORY_MSG_LOCALCONTRAST_AMOUNT;Lokalni kontrast - Količina +HISTORY_MSG_LOCALCONTRAST_DARKNESS;Lokalni kontrast - Temina +HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokalni kontrast +HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokalni kontrast - Svetlost +HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokalni kontrast - Radij +HISTORY_MSG_METADATA_MODE;Način kopiranja metapodatkov +HISTORY_MSG_MICROCONTRAST_CONTRAST;Mikrokontrast - Prag kontrasta +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Avtomatski prag +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Avtomatski radij +HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Prag kontrasta +HISTORY_MSG_PDSHARPEN_GAMMA;CS - Gama +HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iteracije +HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radij +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Povečanje polmera vogala +HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - metoda odstranjevanje mozaičnosti za gibanje +HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Smer linijskega filtra šuma +HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF linijski filter +HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Prag kontrasta +HISTORY_MSG_RAWCACORR_AUTOIT;Surovi CA popravek - Iteracije +HISTORY_MSG_RAWCACORR_COLORSHIFT;Surovi CA popravek - Izogibanje pomika barv +HISTORY_MSG_RAW_BORDER;Surova meja +HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Dovoli povečevanje +HISTORY_MSG_SHARPENING_BLUR;Ostrenje - Zamegli radij +HISTORY_MSG_SHARPENING_CONTRAST;Ostrenje - Prag kontrasta +HISTORY_MSG_SHARPENING_GAMMA;Ostrenje - Gama +HISTORY_MSG_SH_COLORSPACE;S/H - Barvni prostor +HISTORY_MSG_SOFTLIGHT_ENABLED;Mehka svetloba +HISTORY_MSG_SOFTLIGHT_STRENGTH;Mehka svetloba - Moč +HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Sidro +HISTORY_NEWSNAPSHOT;Dodaj +HISTORY_NEWSNAPSHOT_TOOLTIP;Bližnjica: Alt-s +HISTORY_SNAPSHOT;Posnetek +HISTORY_SNAPSHOTS;Posnetek +ICCPROFCREATOR_COPYRIGHT;Copyright: +ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Ponastavi na privzeti copyright, dodeljen "RawTherapee, CC0" +ICCPROFCREATOR_CUSTOM;Po meri +ICCPROFCREATOR_DESCRIPTION;Opis: +ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Dodaj vrednosti game and strmine k opisu +ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Pusti prazno in nastavi privzeti opis. +ICCPROFCREATOR_GAMMA;Gama +ICCPROFCREATOR_ICCVERSION;ICC verzija: +ICCPROFCREATOR_ILL;Illuminant: +ICCPROFCREATOR_ILL_41;D41 +ICCPROFCREATOR_ILL_50;D50 +ICCPROFCREATOR_ILL_55;D55 +ICCPROFCREATOR_ILL_60;D60 +ICCPROFCREATOR_ILL_65;D65 +ICCPROFCREATOR_ILL_80;D80 +ICCPROFCREATOR_ILL_DEF;Privzeto +ICCPROFCREATOR_ILL_INC;StdA 2856K +ICCPROFCREATOR_ILL_TOOLTIP;Nastaviš lahko samo svetlobe iz profilov ICC v4. +ICCPROFCREATOR_PRIMARIES;Primaries: +ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 +ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 +ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) +ICCPROFCREATOR_PRIM_BEST;BestRGB +ICCPROFCREATOR_PRIM_BETA;BetaRGB +ICCPROFCREATOR_PRIM_BLUX;Blue X +ICCPROFCREATOR_PRIM_BLUY;Blue Y +ICCPROFCREATOR_PRIM_BRUCE;BruceRGB +ICCPROFCREATOR_PRIM_GREX;Green X +ICCPROFCREATOR_PRIM_GREY;Green Y +ICCPROFCREATOR_PRIM_PROPH;Prophoto +ICCPROFCREATOR_PRIM_REC2020;Rec2020 +ICCPROFCREATOR_PRIM_REDX;Red X +ICCPROFCREATOR_PRIM_REDY;Red Y +ICCPROFCREATOR_PRIM_SRGB;sRGB +ICCPROFCREATOR_PRIM_TOOLTIP;Primarne prilagojene vrednosti lahko nastavite samo za profile ICC v4. +ICCPROFCREATOR_PRIM_WIDEG;Široki barvni prostor +ICCPROFCREATOR_PROF_V2;ICC v2 +ICCPROFCREATOR_PROF_V4;ICC v4 +ICCPROFCREATOR_SAVEDIALOG_TITLE;Shrani ICC profil kot... +ICCPROFCREATOR_SLOPE;Strmina +ICCPROFCREATOR_TRC_PRESET;Krivulja odzivnosti tonov: +IPTCPANEL_CATEGORY;Kategorija +IPTCPANEL_CATEGORYHINT;Določa temo slike po mnenju punudnika. +IPTCPANEL_CITY;Mesto +IPTCPANEL_CITYHINT;Vnesi ime mesta na tej sliki. +IPTCPANEL_COPYHINT;Kopiraj nastavitve IPTC na odložišče. +IPTCPANEL_COPYRIGHT;Obvestilo copyrighta +IPTCPANEL_COPYRIGHTHINT;Vnesi določilo trenutnega nosilca Copyrighta te slike kot npr. ©2019 Janez Novak. +IPTCPANEL_COUNTRY;Država +IPTCPANEL_COUNTRYHINT;Vnesi ime države na tej sliki. +IPTCPANEL_CREATOR;Avtor +IPTCPANEL_CREATORHINT;Vnesi ime avtorja te slike. +IPTCPANEL_CREATORJOBTITLE;Uradni naziv avtorja +IPTCPANEL_CREATORJOBTITLEHINT;Vnesi službeni naziv avtorja te slike, ki je zabeležen v polju avtorja. +IPTCPANEL_CREDIT;Zasluge +IPTCPANEL_CREDITHINT;Vnesi osebo zaslužno za objavo te slike. +IPTCPANEL_DATECREATED;Datum nastanka +IPTCPANEL_DATECREATEDHINT;Vnesi datum, ko je bila slika posneta. +IPTCPANEL_DESCRIPTION;Opis +IPTCPANEL_DESCRIPTIONHINT;Vnesi naslov, ki opisuje kdo, kaj in zakaj to dogaja na tej sliki, kar vključuje imena oseb in njihove vloge pri tem, kar se dogaja na sliki. +IPTCPANEL_DESCRIPTIONWRITER;Zapisnikar opisa +IPTCPANEL_DESCRIPTIONWRITERHINT;Vnesi ime osebe, ki je napisala, uredila ali popravila opis slike. +IPTCPANEL_EMBEDDED;Vdelano +IPTCPANEL_EMBEDDEDHINT;Nastavi nazaj na podatke IPTC, ki so vdelani v datoteki slike. +IPTCPANEL_HEADLINE;Naslov +IPTCPANEL_HEADLINEHINT;Vnesi kratek objavljiv opis vsebine te slike. +IPTCPANEL_INSTRUCTIONS;Navodila +IPTCPANEL_INSTRUCTIONSHINT;Vnesi informacije o morebitnem embargu ali drugih omejitvah, ki niso omenjene v polju Copyright. +IPTCPANEL_KEYWORDS;Ključne besede +IPTCPANEL_KEYWORDSHINT;Vstavi poljubno število terminov ali fraz, ki opisujejo vsebino slike. +IPTCPANEL_PASTEHINT;Prilepi nastavitve IPTC iz odložišča. +IPTCPANEL_PROVINCE;Provinca ali država +IPTCPANEL_PROVINCEHINT;Vnesi ime province ali države v povezavi s to sliko. +IPTCPANEL_RESET;Ponastavi +IPTCPANEL_RESETHINT;Ponastavi na privzeti profil +IPTCPANEL_SOURCE;Vir +IPTCPANEL_SOURCEHINT;Vnesi ali uredi ime osebe ali skupine, ki je imela vlogo pri dobavi slike kot npr. oseba od katere si dobil sliko. +IPTCPANEL_SUPPCATEGORIES;Dodatki kategorije +IPTCPANEL_SUPPCATEGORIESHINT;Podrobneje določa vsebino slike. +IPTCPANEL_TITLE;Naslov +IPTCPANEL_TITLEHINT;Vnesi kratko človeku prijazno ime slike, lahko je tudi ime datoteke. +IPTCPANEL_TRANSREFERENCE;ID delovnega mesta +IPTCPANEL_TRANSREFERENCEHINT;Vnesite številko ali identifikator za delovnega toka ali omogočanje sledenja. +MAIN_BUTTON_FULLSCREEN;Celotni zaslon +MAIN_BUTTON_ICCPROFCREATOR;Ustvarjalec ICC profila +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigacija do naslednje slike odprte v urejevalniku.\nBližnjica: Shift-F4\n\nNavigacija do naslednje slike glede na trenutno izbrano predogledno sličico v brskalniku datotek:\nBližnjica: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigacija do prejšnje slike odprte v urejevalniku.\nBližnjica: Shift-F3\n\nNavigacija do prejšnje slike glede na trenutno izbrano predogledno sličico v brskalniku datotek:\nBližnjica: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Sinhroniziraj pregledovalnik datotek z urejevalnikom, tako da se vidi predogledna sličica trenutno odprte slike in deaktivira aktivne filtre.\nBližnjica: x\n\nKot zgoraj, a brez deaktivranja filtrov:\nBližnjica: y\n(Zavedajte se predogledna sličica odprte slike ne bo pokazana, če je sfiltrirana). +MAIN_BUTTON_PREFERENCES;Preference +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Postavi trenutno sliko v čakalno vrsto za obdelavo.\nBližnjica: Ctrl+b +MAIN_BUTTON_SAVE_TOOLTIP;Shrani trenutno sliko.\nBližnjica: Ctrl+s\nShrani trenutni profil (.pp3).\nBližnjica: Ctrl+Shift+s +MAIN_BUTTON_SENDTOEDITOR;Uredi sliko v zunanjem urejevalniku +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Uredi sliko v zunanjem urejevalniku.\nBližnjica: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Prikaži/skrij stranske panele.\nBližnjica: m +MAIN_BUTTON_UNFULLSCREEN;Izhod iz celotnega zaslona +MAIN_FRAME_EDITOR;Urejevalnik +MAIN_FRAME_EDITOR_TOOLTIP;Urejevalnik.\nBližnjica: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Prikazovalnik datotek +MAIN_FRAME_FILEBROWSER_TOOLTIP;Prikazovalnik datotek.\nBližnjica: Ctrl-F2 +MAIN_FRAME_PLACES;Lokacije slik +MAIN_FRAME_PLACES_ADD;Dodaj +MAIN_FRAME_PLACES_DEL;Odstrani +MAIN_FRAME_QUEUE;Čakalna vrsta +MAIN_FRAME_QUEUE_TOOLTIP;Čakalna vrsta obdelav.\nBližnjica: Ctrl-F3 +MAIN_FRAME_RECENT;Zadnje uporabljene mape +MAIN_MSG_ALREADYEXISTS;Datoteka že obstaja. +MAIN_MSG_CANNOTLOAD;Ne morem naložiti slike +MAIN_MSG_CANNOTSAVE;Napaka pri shranjevanju datoteke +MAIN_MSG_CANNOTSTARTEDITOR;Ne morem zagnati urejevalnika. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Prosim nastavi ustrezno pot v preferencah. +MAIN_MSG_EMPTYFILENAME;Datoteka ni določena! +MAIN_MSG_IMAGEUNPROCESSED;Ta ukaz zahteva, da so vse slike najprej obdelane v čakalni vrsti. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_OPERATIONCANCELLED;Operacija preklicana +MAIN_MSG_PATHDOESNTEXIST;Pot\n\n%1\n\nne obstaja. Prosim postavi pravilno pot v preferencah. +MAIN_MSG_QOVERWRITE;Ali jo želiš prepisati? +MAIN_MSG_SETPATHFIRST;Najprej moraš nastaviti pot v preferencah za uporabo te funkcije! +MAIN_MSG_TOOMANYOPENEDITORS;Preveč odprtih urejevalnikov.\nZa nadaljevanje dela prosim zapri urejevalnik. +MAIN_MSG_WRITEFAILED;Izpad pri pisanju\n"%1"\n\nPreveri, da mapa obstaja in da imaš pravico pisanja v njej. +MAIN_TAB_ADVANCED;Napredno +MAIN_TAB_ADVANCED_TOOLTIP;Bližnjica: Alt-w +MAIN_TAB_COLOR;Barva +MAIN_TAB_COLOR_TOOLTIP;Bližnjica: Alt-c +MAIN_TAB_DETAIL;Podrobnost +MAIN_TAB_DETAIL_TOOLTIP;Bližnjica: Alt-d +MAIN_TAB_DEVELOP; Paketno urejanje +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Hitri izvoz +MAIN_TAB_EXPOSURE;Ekspozicija +MAIN_TAB_EXPOSURE_TOOLTIP;Bližnjica: Alt-e +MAIN_TAB_FAVORITES;Priljubljene +MAIN_TAB_FAVORITES_TOOLTIP;Bližnjica: Alt-u +MAIN_TAB_FILTER; Filter +MAIN_TAB_INSPECT; Pregled +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metapodatki +MAIN_TAB_METADATA_TOOLTIP;Bližnjica: Alt-m +MAIN_TAB_RAW;Surove +MAIN_TAB_RAW_TOOLTIP;Bližnjica: Alt-r +MAIN_TAB_TRANSFORM;Transformiraj +MAIN_TAB_TRANSFORM_TOOLTIP;Bližnjica: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Barva ozadja predpregleda: theme-based\nBližnjica: 9 +MAIN_TOOLTIP_BACKCOLOR1;Barva ozadja predpregleda: črna\nBližnjica: 9 +MAIN_TOOLTIP_BACKCOLOR2;Barva ozadja predpregleda: bela\nBližnjica: 9 +MAIN_TOOLTIP_BACKCOLOR3;Barva ozadja predpregleda: srednje siva\nBližnjica: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zakleni / Odkleni the Pred pogled\n\nZakleni: ohranjaj pogled Pred nespremenjen.\nUporabno za oceno skupnega učinka več orodij.\nPoleg tega je mogoče opraviti primerjave s katerim koli stanjem v zgodovini.\n\nOdkleni: Pred prikaz bo sledil pogledu Po z enim korakom zamude, prikazuje sliko pred učinkom zadnje uporabljenega orodja. +MAIN_TOOLTIP_HIDEHP;Prikaži/skrij levo ploščo (vključno z zgodovino).\nBližnjica: l +MAIN_TOOLTIP_INDCLIPPEDH;Obrezana oznaka osvetlitve.\nBližnjica: < +MAIN_TOOLTIP_INDCLIPPEDS;Obrezana oznaka senc.\nBližnjica: > +MAIN_TOOLTIP_PREVIEWB;Predogled modrega kanala.\nBližnjica: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Predogled maske ostrenja.\nBližnjica: Shift-f \n\nBolj natančne pri slikah z majhno globinsko ostrino, nizkim šumom in višjo stopnjo povečave.\nZa povečavo 10-30% za izboljšanje natančnosti odkrivanja šumnih slik. +MAIN_TOOLTIP_PREVIEWG;Predogled zelenega kanala.\nBližnjica: g +MAIN_TOOLTIP_PREVIEWL;Predogled osvetljenosti.\nBližnjica: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Predogled rdečega kanala.\nBližnjica: r +MAIN_TOOLTIP_PREVIEWSHARPMASK;Predogled maske ostrinskega kontrasta.\nBližnjica: p\n\nDeluje samo, kadar je omogočeno ostrenje in zoom >= 100%. +MAIN_TOOLTIP_QINFO;Hitre informacije o sliki.\nBližnjica: i +MAIN_TOOLTIP_SHOWHIDELP1;Prikaži/skrij levi panel.\nBližnjica: l +MAIN_TOOLTIP_SHOWHIDERP1;Prikaži/skrij desni panel.\nBližnjica: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Prikaži/skrij vrhnji panel.\nBližnjica: Shift-l +MAIN_TOOLTIP_THRESHOLD;Prag +MAIN_TOOLTIP_TOGGLE;Preklopi pogled Pred/Po.\nBližnjica: Shift-b +MONITOR_PROFILE_SYSTEM;Sistemska privzeta vrednost +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Širina: %1, Višina: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_BUNDLED_MISSING;Že pripravljenih profilov "%1" ne morem najti!\n\nVaša namestitev je morda poškodovana.\n\nUporabljene bodo privzete programske vrednosti. +OPTIONS_DEFIMG_MISSING;Privzetega profila za ne-surove fotografije ne morem najti ali ni nastavljen.\n\nProsim preverite vašo mapo profilov, morda manjka ali je poškodovan.\n\n"%1" bo uporabljena kot nadomestek. +OPTIONS_DEFRAW_MISSING;Privzetega profila za surove fotografije ne morem najti ali ni nastavljen.\n\nProsim preverite vašo mapo profilov, morda manjka ali je poškodovan.\n\n"%1" bo uporabljena kot nadomestek. +PARTIALPASTE_ADVANCEDGROUP;Napredne nastavitve +PARTIALPASTE_BASICGROUP;Osnovne nastavitve +PARTIALPASTE_CACORRECTION;Popravek barvne aberacije +PARTIALPASTE_CHANNELMIXER;Mešalnik kanalov +PARTIALPASTE_CHANNELMIXERBW;Črno-belo +PARTIALPASTE_COARSETRANS;Groba rotacija/preklop +PARTIALPASTE_COLORAPP;CIECAM02 +PARTIALPASTE_COLORGROUP;Nastavitev barv +PARTIALPASTE_COLORTONING;Toniranje barv +PARTIALPASTE_COMMONTRANSFORMPARAMS;Avto-polnjenje +PARTIALPASTE_COMPOSITIONGROUP;Nastavitev kompozicije +PARTIALPASTE_CROP;Obreži +PARTIALPASTE_DARKFRAMEAUTOSELECT;Avtomatska izbira dark-frame +PARTIALPASTE_DARKFRAMEFILE;Datoteke dark-frame +PARTIALPASTE_DEFRINGE;Odstranjevanje barvnih napak robov +PARTIALPASTE_DEHAZE;Odstranjevanje motnosti +PARTIALPASTE_DETAILGROUP;Nastavitve podrobnosti +PARTIALPASTE_DIALOGLABEL;Profil obdelovanja delnega lepljenja +PARTIALPASTE_DIRPYRDENOISE;Zmanjšanje šumov +PARTIALPASTE_DIRPYREQUALIZER;Kontrast po nivojih podrobnosti +PARTIALPASTE_DISTORTION;Popravljanje popačenosti +PARTIALPASTE_EPD;Preslikava odtenkov +PARTIALPASTE_EQUALIZER;Nivoji valovčkov +PARTIALPASTE_EVERYTHING;Vse +PARTIALPASTE_EXIFCHANGES;Exif +PARTIALPASTE_EXPOSURE;Ekspozicija +PARTIALPASTE_FILMNEGATIVE;Filmski negativ +PARTIALPASTE_FILMSIMULATION;Simulacija filma +PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field avtomatski izbor +PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field radij zamegljenosti +PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field vrsta zameglitve +PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field nadzor obrezave +PARTIALPASTE_FLATFIELDFILE;Datoteka flat-field +PARTIALPASTE_GRADIENT;Postopni filter +PARTIALPASTE_HSVEQUALIZER;HSV ekvalizator +PARTIALPASTE_ICMSETTINGS;Nastavitve upravljanja barv +PARTIALPASTE_IMPULSEDENOISE;Impuzno zmanjšanje šuma +PARTIALPASTE_IPTCINFO;IPTC +PARTIALPASTE_LABCURVE;L*a*b* prilagoditve +PARTIALPASTE_LENSGROUP;Nastavitve objektiva +PARTIALPASTE_LENSPROFILE;Popravki objektiva iz njegovega profila +PARTIALPASTE_LOCALCONTRAST;Lokalni kontrast +PARTIALPASTE_METADATA;Način metapodatkov +PARTIALPASTE_METAGROUP;Nastavitve metapodatkov +PARTIALPASTE_PCVIGNETTE;Filter vinjetiranja +PARTIALPASTE_PERSPECTIVE;Perspektiva +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filter mrtvih pikslov +PARTIALPASTE_PREPROCESS_GREENEQUIL;Uravnoteženje zelene +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filter vročih pikslov +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filter šuma na črti +PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;Filter linij PDAF +PARTIALPASTE_PRSHARPENING;Ostrenje po spremembi velikosti +PARTIALPASTE_RAWCACORR_AUTO;CA avtomatski popravek +PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA izogibaj se pomiku barve +PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rdeča & modra +PARTIALPASTE_RAWEXPOS_BLACK;Nivoji črne +PARTIALPASTE_RAWEXPOS_LINEAR;Popravek bele točke +PARTIALPASTE_RAWGROUP;Nastavitve za surove +PARTIALPASTE_RAW_BORDER;Surova meja +PARTIALPASTE_RAW_DCBENHANCE;DCB izboljšava +PARTIALPASTE_RAW_DCBITERATIONS;DCB iteracije +PARTIALPASTE_RAW_DMETHOD;Metoda odstranjevanja mozaičnosti +PARTIALPASTE_RAW_FALSECOLOR;Zatiranje napačne barve +PARTIALPASTE_RAW_IMAGENUM;Sub-image +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE koraki izboljšave +PARTIALPASTE_RAW_PIXELSHIFT;Pomik pikslov +PARTIALPASTE_RESIZE;Sprememba velikosti +PARTIALPASTE_RETINEX;Retinex +PARTIALPASTE_RGBCURVES;Krivulje RGB +PARTIALPASTE_ROTATION;Rotacija +PARTIALPASTE_SHADOWSHIGHLIGHTS;Sence/bleščave +PARTIALPASTE_SHARPENEDGE;Robovi +PARTIALPASTE_SHARPENING;Ostrenje (USM/RL) +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_SOFTLIGHT;Mehka svetloba +PARTIALPASTE_TM_FATTAL;Stiskanje dinamičnega obsega +PARTIALPASTE_VIBRANCE;Vibrance +PARTIALPASTE_VIGNETTING;Popravi vinjetiranja +PARTIALPASTE_WHITEBALANCE;Uravnoteženje beline +PREFERENCES_ADD;Dodaj +PREFERENCES_APPEARANCE;Izgled +PREFERENCES_APPEARANCE_COLORPICKERFONT;Pisava izbire barv +PREFERENCES_APPEARANCE_CROPMASKCOLOR;Barve maske obrezovanja +PREFERENCES_APPEARANCE_MAINFONT;Glavna pisava +PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Glavna barva navigacije +PREFERENCES_APPEARANCE_PSEUDOHIDPI;Psevdo način HiDPI +PREFERENCES_APPEARANCE_THEME;Tema +PREFERENCES_APPLNEXTSTARTUP;potreben ponovni zagon +PREFERENCES_AUTOMONPROFILE;Uporabi profil glavnega monitorja iz operacijskega sistema +PREFERENCES_AUTOSAVE_TP_OPEN;Ob ihodu shrani orodje zloženo/razširjeno +PREFERENCES_BATCH_PROCESSING;Paketna obdelava +PREFERENCES_BEHADDALL;Vse na 'Dodaj' +PREFERENCES_BEHADDALLHINT;Nastavi vse pramaetre na način dodajanja.\nPrilagoditve prametrov v kontrolni plošči paketa bodo spremembe glede na shranjene vrednosti. +PREFERENCES_BEHAVIOR;Obnašanje +PREFERENCES_BEHSETALL;Vse na 'Nastavi' +PREFERENCES_BEHSETALLHINT;Postavi vse parametre v način Nastavi.\nPrilagoditve parametrov v kontrolni plošči paketnega orodja bo absolutno, prikazane bodo dejanske vrednosti. +PREFERENCES_CACHECLEAR;Počisti +PREFERENCES_CACHECLEAR_ALL;Počisti vse datoteke v vmesnem pomnilniku: +PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Očisti vse datoteke iz vmesnega pomnilnika razen profilov obdelav: +PREFERENCES_CACHECLEAR_ONLYPROFILES;Očisti datoteke profilov obdelav iz vmesnega ponilnika: +PREFERENCES_CACHECLEAR_SAFETY;Očiščene samo datoteke v vmesnem pomnilniku. Profili obdelav, ki sodijo k slikam, so nedotaknjeni. +PREFERENCES_CACHEMAXENTRIES;Največje število datotek v vmesnem pomnilniku +PREFERENCES_CACHEOPTS;Nastavitve predpomnilnika +PREFERENCES_CACHETHUMBHEIGHT;Največja višina predogledne slikice +PREFERENCES_CHUNKSIZES;Ploskev na nit +PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE odstranjevanje mozaičnosti +PREFERENCES_CHUNKSIZE_RAW_CA;Surovi CA popravki +PREFERENCES_CHUNKSIZE_RAW_RCD;RCD odstranjevanje mozaičnosti +PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans odstranjevanje mozaičnosti +PREFERENCES_CHUNKSIZE_RGB;RGB obdelava +PREFERENCES_CLIPPINGIND;Indikator obrezave +PREFERENCES_CLUTSCACHE;HaldCLUT predpomnilnik +PREFERENCES_CLUTSCACHE_LABEL;Maksimalno število predpomnjenih CLUTsev +PREFERENCES_CLUTSDIR;HaldCLUT mapa +PREFERENCES_CMMBPC;Prilagoditev črne točke +PREFERENCES_CROP;Obrezovanje +PREFERENCES_CROP_AUTO_FIT;Avtomatically prilagodi obrezavi +PREFERENCES_CROP_GUIDES;Prikaz vodil, kadar ne urejamo obrezave +PREFERENCES_CROP_GUIDES_FRAME;Okvir +PREFERENCES_CROP_GUIDES_FULL;Izvirnik +PREFERENCES_CROP_GUIDES_NONE;Noben +PREFERENCES_CURVEBBOXPOS;Pozicija gumbov za kopiranje in lepljenje krivulj +PREFERENCES_CURVEBBOXPOS_ABOVE;Nad +PREFERENCES_CURVEBBOXPOS_BELOW;Pod +PREFERENCES_CURVEBBOXPOS_LEFT;Levo +PREFERENCES_CURVEBBOXPOS_RIGHT;Desno +PREFERENCES_CUSTPROFBUILD;Orodje za izdelavo profila obdelav po meri +PREFERENCES_CUSTPROFBUILDHINT;Datoteka s programom (ali skriptom), ki se izvede kadar je treba idelati profil obdelave za sliko.\n\nPot za komunikacijsko datoteko (*.ini imenovana kudi "ključna datoteka") je dodana kot parameter ob klicu te datoteke. Vsebuje različne parametre za skripte in dele slik Exif, tako da omogoča generiranje profila obdelave glede na pravila.\n\nWARNING: Če pot vsebuje presledke, je vaša naloga, da jo omejite z dvojnimi apostrofi. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Format ključnih besed +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Ime +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;ID značke +PREFERENCES_CUSTPROFBUILDPATH;Pot izvajanja +PREFERENCES_DARKFRAMEFOUND;Najdeno +PREFERENCES_DARKFRAMESHOTS;posnetkov +PREFERENCES_DARKFRAMETEMPLATES;Šablone +PREFERENCES_DATEFORMAT;Format datuma +PREFERENCES_DATEFORMATHINT;Možna je raba naslednjih formatnih določil:\n%y - leto\n%m - mesec\n%d - dan\n\nNa primer standard ISO 8601 določa datum takole:\n%y-%m-%d +PREFERENCES_DIRDARKFRAMES;Mapa dark-frame +PREFERENCES_DIRECTORIES;Mape +PREFERENCES_DIRHOME;Domača mapa +PREFERENCES_DIRLAST;Zadnje obiskana mapa +PREFERENCES_DIROTHER;Ostalo +PREFERENCES_DIRSELECTDLG;Ob začetki izberi mapo slik... +PREFERENCES_DIRSOFTWARE;Mapa namestitve +PREFERENCES_EDITORCMDLINE;Ukazna vrstica po meri +PREFERENCES_EDITORLAYOUT;Oblika urejevalnika +PREFERENCES_EXTERNALEDITOR;Zunanji urejevalnik +PREFERENCES_FBROWSEROPTS;Pregledovalnik datotek/ Nastavitve predoglednih sličic +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Kompaktne orodne vrstice v pregledovalniku datotek +PREFERENCES_FLATFIELDFOUND;Najdeno +PREFERENCES_FLATFIELDSDIR;Flat-field mapa +PREFERENCES_FLATFIELDSHOTS;posnetki +PREFERENCES_FLATFIELDTEMPLATES;šablone +PREFERENCES_FORIMAGE;Za nesurove slike +PREFERENCES_FORRAW;Za surove slike +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Enaka višina predogledne sličice za pregled filmov in pregledovalnik datotek +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Različni višini zahtevata več časa za obdelavo ob preklopu iz urejevalnika slike v pregledovalnik datotek. +PREFERENCES_GIMPPATH;mapa, kje je nameščen GIMP +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram v levem panoju +PREFERENCES_HISTOGRAM_TOOLTIP;Če je omogočen, za izdelavo histograma slike v navigacijskem panoju uporabim delovni profil, sicer pa popravljen profil game. +PREFERENCES_HLTHRESHOLD;Prag za prilepljene bleščave +PREFERENCES_ICCDIR;Mapa, kjer so barvni profili +PREFERENCES_IMPROCPARAMS;Privzeti profil obdelave +PREFERENCES_INSPECT_LABEL;Preglej +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Največje število shranjenih slik v vmesnem pomnilniku +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Nastavi največje število slik v vmesnem pomnilniku v pregledovalniku datotek; sistemi z malo RAMa (2GB) naj imajo to postavljeno na 1 ali 2. +PREFERENCES_INTENT_ABSOLUTE;Absolutno kolorimetrično +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relativno kolorimetrično +PREFERENCES_INTENT_SATURATION;Nasičenje +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Prikaži predogledno sličico JPEG, če je surova slika še neobdelana +PREFERENCES_LANG;Jezik +PREFERENCES_LANGAUTODETECT;Uporabi jezik sistema +PREFERENCES_MAXRECENTFOLDERS;Največje število zadnje obiskanih map +PREFERENCES_MENUGROUPEXTPROGS;Skupinski "Odpri z" +PREFERENCES_MENUGROUPFILEOPERATIONS;Skupinske "Operacija z datotekami" +PREFERENCES_MENUGROUPLABEL;Skupinska "Oznaka barve" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Skupinske "Operacije profilov obdelav" +PREFERENCES_MENUGROUPRANK;Skupinsko "Rangiranje" +PREFERENCES_MENUOPTIONS;Kontekstne nastavitve menuja +PREFERENCES_MONINTENT;Privzeta namera upodabljanja +PREFERENCES_MONITOR;Monitor +PREFERENCES_MONPROFILE;Privzeti barvni profil +PREFERENCES_MONPROFILE_WARNOSX;Podprt je samo sRGB zaradi omejitev MacOS. +PREFERENCES_MULTITAB;Način večih zavihkov urejevalnika +PREFERENCES_MULTITABDUALMON;Več zavihkov urejevalnika v svojem oknu +PREFERENCES_NAVIGATIONFRAME;Navigacija +PREFERENCES_OVERLAY_FILENAMES;Ime datotek čez predogledne sličice v pregledovalniku datotek +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Ime datotek čez predogledne sličice v urejevalniku slik +PREFERENCES_OVERWRITEOUTPUTFILE;Prepiši obstoječe izhodne datoteke +PREFERENCES_PANFACTORLABEL;Povečanje hitrosti zamikanja +PREFERENCES_PARSEDEXT;Razpoznani podaljški datotek +PREFERENCES_PARSEDEXTADD;Dodaj podaljšek +PREFERENCES_PARSEDEXTADDHINT;Dodaj vnesen podaljšek v seznam. +PREFERENCES_PARSEDEXTDELHINT;Odstrani vnesen podaljšek s seznama. +PREFERENCES_PARSEDEXTDOWNHINT;Premakni vnesen podaljšek po seznamu navzdol. +PREFERENCES_PARSEDEXTUPHINT;Premakni vnesen podaljšek po seznamu navzgor. +PREFERENCES_PERFORMANCE_MEASURE;Mere +PREFERENCES_PERFORMANCE_MEASURE_HINT;Beleži obdelovalne čase na konzoli +PREFERENCES_PERFORMANCE_THREADS;Niti +PREFERENCES_PERFORMANCE_THREADS_LABEL;Največje število niti za odstranjevanje šuma in nivoje valovčkov (0 = Avtomatika) +PREFERENCES_PREVDEMO;Predlogled metode odstranjevamja mozaičnosti +PREFERENCES_PREVDEMO_FAST;Hitro +PREFERENCES_PREVDEMO_LABEL;Metoda odstranjevanja mozaičnosti za predogled <100% zoom: +PREFERENCES_PREVDEMO_SIDECAR;Kot v PP3 +PREFERENCES_PRINTER;Tiskalnik (Poskusni odtis) +PREFERENCES_PROFILEHANDLING;Obdelava profila +PREFERENCES_PROFILELOADPR;Prednost nalaganja profila v obdelavi +PREFERENCES_PROFILEPRCACHE;Profil v predpomnilniku +PREFERENCES_PROFILEPRFILE;Profil poleg vhodne datoteke +PREFERENCES_PROFILESAVEBOTH;Shrani profil obdelave dvojno tako v vmesnem pomnilniku kot zraven vhodne datoteke +PREFERENCES_PROFILESAVECACHE;Shrani profil obdelave v vmesnem pomnilniku +PREFERENCES_PROFILESAVEINPUT;Shrani profil obdelave zraven vhodne datoteke +PREFERENCES_PROFILESAVELOCATION;Lokacija shranjevanja profila obdelave +PREFERENCES_PROFILE_NONE;Noben +PREFERENCES_PROPERTY;Lastnost +PREFERENCES_PRTINTENT;Namera upodabljanja +PREFERENCES_PRTPROFILE;Barvni profil +PREFERENCES_PSPATH;Mapa nameščenega programa Adobe Photoshop +PREFERENCES_REMEMBERZOOMPAN;Zapomni si zoom % in odmik od roba +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Zapomni si zoom % in odmik od trenutne slike ob odpiranju nove slike.\n\nTa nastavitev deluje samo v posamičnem urejevalniku in kadar je metoda odstranjevanja mozaičnosti <100% zoom" in nastavitev "Kot v PP3". +PREFERENCES_SAVE_TP_OPEN_NOW;Shrani stanje orodja v skrčenem ali razširjenem stanju zdaj +PREFERENCES_SELECTLANG;Izbira jezika +PREFERENCES_SERIALIZE_TIFF_READ;Nastavitve branja TIFF +PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Sekvenčno branje datotek TIFF +PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Omogočanje te opcije kadar delamo z mapami, ki vsebujejo nestisnjene datoteke TIFF, lahko izboljšajo generiranje predoglednih sličic. +PREFERENCES_SET;Nastavi +PREFERENCES_SHOWBASICEXIF;Prikaži osnovne Exif informacije +PREFERENCES_SHOWDATETIME;Prikaži datum in čas +PREFERENCES_SHOWEXPOSURECOMPENSATION;Dodaj prilagoditev ekspozicije +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Prikaži orodno vrstico filmskega izseka +PREFERENCES_SHTHRESHOLD;Prag za obrezane sence +PREFERENCES_SINGLETAB;Način enega zavihka urejevalnika +PREFERENCES_SINGLETABVERTAB;Način enega zavihka urejevalnika, Navpični zavihki +PREFERENCES_SND_HELP;Vnesi polno pot za nastavitev zvoka ali pusti prazno za brez zvoka.\nZa sistemske zvoke na sistemu Windows uporabi "SystemDefault", "SystemAsterisk" itd. na Linuxu pa "complete", "window-attention" itd. +PREFERENCES_SND_LNGEDITPROCDONE;Obdelava urejevalnika končana +PREFERENCES_SND_QUEUEDONE;Obdelava v čakalni vrsti končana +PREFERENCES_SND_THRESHOLDSECS;Po sekundah +PREFERENCES_STARTUPIMDIR;Mapa s slikami ob začetku +PREFERENCES_TAB_BROWSER;Brskalnik datotek +PREFERENCES_TAB_COLORMGR;Upravljanje z barvami +PREFERENCES_TAB_DYNAMICPROFILE;Pravila dinamičnih profilov +PREFERENCES_TAB_GENERAL;Splošno +PREFERENCES_TAB_IMPROC;Obdelava slik +PREFERENCES_TAB_PERFORMANCE;Performanse +PREFERENCES_TAB_SOUND;Zvoki +PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Predoglev vdelane JPEG +PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Slika za prikaz +PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Nevtralno surovo upodabljanje +PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Vgrajen JPEG, če je polne velikosti, sicer nevtralno surovo +PREFERENCES_TP_LABEL;Pano z orodji: +PREFERENCES_TP_VSCROLLBAR;Skrij navpični drsnik +PREFERENCES_USEBUNDLEDPROFILES;Uporabi skupne profile +PREFERENCES_WORKFLOW;Razporeditev +PROFILEPANEL_COPYPPASTE;Parametri za kopiranje +PROFILEPANEL_GLOBALPROFILES;Skupni profili +PROFILEPANEL_LABEL;Profili za obdelovanje +PROFILEPANEL_LOADDLGLABEL;Naloži parametre obdelovanja... +PROFILEPANEL_LOADPPASTE;Parametri za nalaganje +PROFILEPANEL_MODE_TIP;Vnosni način profila za obdelovanje.\n\nPritisnjen gumb: delni profili bodo spremenjeni v polne profile; manjkajoče vrednosti bodo zamenjale fiksne privzete vrednosti.\n\nSproščen gumb: profili bodo uporabljeni kakršni so, zamenjajo se samo vnesene vrednosti. +PROFILEPANEL_MYPROFILES;Moji profili +PROFILEPANEL_PASTEPPASTE;Parameteri za lepljenje +PROFILEPANEL_PCUSTOM;Po meri +PROFILEPANEL_PDYNAMIC;Dinamični +PROFILEPANEL_PFILE;Iz datoteke +PROFILEPANEL_PINTERNAL;Nevtralno +PROFILEPANEL_PLASTSAVED;Zadnje shranjene +PROFILEPANEL_SAVEDLGLABEL;Shrani parametre obdelave... +PROFILEPANEL_SAVEPPASTE;Parametri za shranjevanje +PROFILEPANEL_TOOLTIPCOPY;Kopiraj trenutni profil obdelave na odložišče.\nCtrl-klik za izbiro parametrov za kopiranje. +PROFILEPANEL_TOOLTIPLOAD;Naloži profil iz datoteke.\nCtrl-klik za izbiro parametrov za nalaganje. +PROFILEPANEL_TOOLTIPPASTE;Prilepi profil iz odložišča.\nCtrl-klik za izbiro parametrov za leplenje. +PROFILEPANEL_TOOLTIPSAVE;Shrani trenutni profil.\nCtrl-klik za izbiro parametrov za shranjevanje. +PROGRESSBAR_DECODING;Dekodiram... +PROGRESSBAR_GREENEQUIL;Uravnoteženje zelene... +PROGRESSBAR_HLREC;Rekonstrukcija bleščav... +PROGRESSBAR_HOTDEADPIXELFILTER;Filter vročih/mrtvih pikslov... +PROGRESSBAR_LINEDENOISE;Filter linijskega šuma... +PROGRESSBAR_LOADING;Nalagam sliko... +PROGRESSBAR_LOADINGTHUMBS;Nalagam predogledne sličice... +PROGRESSBAR_LOADJPEG;Nalagam datoteko JPEG... +PROGRESSBAR_LOADPNG;Nalagam datoteko PNG... +PROGRESSBAR_LOADTIFF;Nalagam datoteko TIFF... +PROGRESSBAR_NOIMAGES;Ne najdem nobene slike +PROGRESSBAR_PROCESSING;Obdelujem sliko... +PROGRESSBAR_PROCESSING_PROFILESAVED;Profil obdelave shranjen +PROGRESSBAR_RAWCACORR;Popravek surove CA... +PROGRESSBAR_READY;Pripravljen +PROGRESSBAR_SAVEJPEG;Shranjujem datoteko JPEG... +PROGRESSBAR_SAVEPNG;Shranjujem datoteko PNG... +PROGRESSBAR_SAVETIFF;Shranjujem datoteko TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Posnetek dodan +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil obdelave je shranjen v pregledovalniku +QINFO_FRAMECOUNT;%2 okvirov +QINFO_HDR;HDR / %2 okvirov +QINFO_ISO;ISO +QINFO_NOEXIF;Podatki Exif niso na voljo. +QINFO_PIXELSHIFT;Pomik pikslov / %2 okvirjev +QUEUE_AUTOSTART;Avto-start +QUEUE_AUTOSTART_TOOLTIP;Avtomatično začni obdelavo, ko pride nov posel. +QUEUE_DESTFILENAME;Pot in ime datoteke +QUEUE_FORMAT_TITLE;Format datoteke +QUEUE_LOCATION_FOLDER;Shrani v mapo +QUEUE_LOCATION_TEMPLATE;Uporabi šablono +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Določite izhodno lokacijo glede na lokacijo izvirne fotografije, rang, status smeti ali položaj v čakalni vrsti.\n\nZa primer poti uporabite naslednje:\n/home/tom/photos/2010-10-31/photo1.raw\npomen nizov sledi: :\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = photo1\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r bo zamenjana z oceno fotografije. Če slika ni ocenjena, se uporabi '0'. Če je slika v smeteh uporabimo 'x'.\n\n%s1, ..., %s9 bo zamenjano za začetni položaj slike v čakalni vrsti, ko se ta začne. Število opisuje polnilo, npr. %s3 se spremeni v '001'.\n\nČe želite izhodno sliko shraniti poleg izvirne slike, napišite::\n%p1/%f\n\nČe želite izhodno sliko shraniti v mapo z imenom 'converted' ki se nahaja v mapi izvorne fotografije, napišite:\n%p1/converted/%f\n\nČe želite izhodno sliko shraniti v\n'/home/tom/photos/converted/2010-10-31', napišite:\n%p2/converted/%d1/%f +QUEUE_LOCATION_TITLE;Lokacija izhoda +QUEUE_STARTSTOP_TOOLTIP;Začni ali končaj obdelavo slik v čakalni vrsti.\n\nBližnjica: Ctrl+s +SAMPLEFORMAT_0;Neznan format podatkov +SAMPLEFORMAT_1;8-bit brez predznaka +SAMPLEFORMAT_2;16-bit brez predznaka +SAMPLEFORMAT_4;24-bit LogLuv +SAMPLEFORMAT_8;32-bit LogLuv +SAMPLEFORMAT_16;16-bit plavajoča vejica +SAMPLEFORMAT_32;24-bit plavajoča vejica +SAMPLEFORMAT_64;32-bit plavajoča vejica +SAVEDLG_AUTOSUFFIX;Avtomatično dodaj tip, če datoteka že obstaja +SAVEDLG_FILEFORMAT;Format datoteke +SAVEDLG_FILEFORMAT_FLOAT; plavajoča vejica +SAVEDLG_FORCEFORMATOPTS;Zahtevaj opcije shranjevanja +SAVEDLG_JPEGQUAL;JPEG kakovost +SAVEDLG_PUTTOQUEUE;Postavi v čakalno vrsto za obdelavo +SAVEDLG_PUTTOQUEUEHEAD;Postavi na začetek čakalne vrste za obdelavo +SAVEDLG_PUTTOQUEUETAIL;Postavi na konec čakalne vrste za obdelavo +SAVEDLG_SAVEIMMEDIATELY;Takoj shrani +SAVEDLG_SAVESPP;Shrani parametre obdelave skupaj s sliko +SAVEDLG_SUBSAMP;Podvzorčenje +SAVEDLG_SUBSAMP_1;Najboljše stiskanje +SAVEDLG_SUBSAMP_2;Uravnoteženo +SAVEDLG_SUBSAMP_3;Najboljša kakovost +SAVEDLG_SUBSAMP_TOOLTIP;Najbolj stisnjeno:\nJ:a:b 4:2:0\nh/v 2/2\nBarvitost razpolovljena vodoravno in navpično.\n\nUravnoteženo:\nJ:a:b 4:2:2\nh/v 2/1\nBarvitost razpolovljena vodoravno.\n\nNajbolj kakovostno:\nJ:a:b 4:4:4\nh/v 1/1\nBrez podvzorčenja barvitosti. +SAVEDLG_TIFFUNCOMPRESSED;Nestisnjen TIFF +SAVEDLG_WARNFILENAME;Datoteka bo poimenovana +SHCSELECTOR_TOOLTIP;Desni klik za ponastavitev pozicije 3 drsnikov. +SOFTPROOF_GAMUTCHECK_TOOLTIP;Osvetli piksle z barvo izven barvnega prostora glede na:\n- profil tiskalnika, če je nastavljen in je omogočen poskusni odtis,\n- izhodni profil, če tiskalnikov profil ni določen in je poskusni odtis omogočen,\n- profil zaslona, če je poskusni odtis onemogočen. +SOFTPROOF_TOOLTIP;Poskusni odtis simulira izgled slike:\n- ko je natisnjen, če je nastavljen profil tiskalnika v Preference > Upravljanje z barvami,\n- kadar ogledujemo sliko na zaslonu, ki uporablja trenutni profil zaslona, če profil tiskalnika ni določen. +THRESHOLDSELECTOR_B;Spodaj +THRESHOLDSELECTOR_BL;Spodaj-levo +THRESHOLDSELECTOR_BR;Spodaj-desno +THRESHOLDSELECTOR_HINT;Držite tipko Shift za premik posameznih kontrolnih točk. +THRESHOLDSELECTOR_T;Zgoraj +THRESHOLDSELECTOR_TL;Zgoraj-levo +THRESHOLDSELECTOR_TR;Zgoraj-desno +TOOLBAR_TOOLTIP_COLORPICKER;Izbirnik barv, ki ga je moč zakleniti\n\nKadar je orodje aktivno:\n- Dodajte izbiro: levi-klik.\n- Povlecite izbiro: levi-klik in poteg.\n- Briši izbiro: desni-klik.\n- Briši vse izbire: Ctrl+Shift+desni-klik.\n- Povratek na ročno orodje: desni-klik zunaj kateregakoli izbirnika. +TOOLBAR_TOOLTIP_CROP;Crop izbira.\nBližnjica: c\nPremakni obrezavo s Shift+potegom miške. +TOOLBAR_TOOLTIP_HAND;Ročno orodje.\nBližnjica: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Ravnanje / fino vrtenje.\nBližnjica: s\n\nOznačite navpičnico ali vodoravnico z risanjem vodilne črte čez predogled slike. Kot vodilne črte bo prikazan zraven vodilne črte. Središče vrtenja je geometrijsko središče slike. +TOOLBAR_TOOLTIP_WB;Uravnotežena belina točke.\nBližnjica: w +TP_BWMIX_ALGO;Algoritem OYCPM +TP_BWMIX_ALGO_LI;Linearno +TP_BWMIX_ALGO_SP;Posebni učinki +TP_BWMIX_ALGO_TOOLTIP;Linearno: bo povzročil normalni linearni odziv.\nPosebni učinki: bodo povzročili posebne učinke z mešanjem kanalov na ne-linearen način. +TP_BWMIX_AUTOCH;Avto +TP_BWMIX_CC_ENABLED;Prilagodi komplementarno barvo +TP_BWMIX_CC_TOOLTIP;Dovoli avtomatično prilagajanje komplementarnih barv v načinu ROYGCBPM. +TP_BWMIX_CHANNEL;Ekvalizator svetlosti +TP_BWMIX_CURVEEDITOR1;Krivulja 'pred' +TP_BWMIX_CURVEEDITOR2;Krivulja 'po' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Krivulja tonov po predelavi v črno-belo ob koncu postopka. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Krivulja tonov tik prek predelavo v črno-belo.\nLahko je odvisna od barvnih komponent. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Svetlost odvisna od odtenka L=f(H).\nPazite na skrajne vrednosti, ker lahko generirajo artefakte. +TP_BWMIX_FILTER;Barvni Filter +TP_BWMIX_FILTER_BLUE;Modra +TP_BWMIX_FILTER_BLUEGREEN;Modro-Zelena +TP_BWMIX_FILTER_GREEN;Zelena +TP_BWMIX_FILTER_GREENYELLOW;Zeleno-Rumena +TP_BWMIX_FILTER_NONE;Nobena +TP_BWMIX_FILTER_PURPLE;Vijolična +TP_BWMIX_FILTER_RED;Rdeča +TP_BWMIX_FILTER_REDYELLOW;Rdeče-Rumena +TP_BWMIX_FILTER_TOOLTIP;Barvni filter simulira slike posnete z barvnim filtrom pred objektivom. Barvni filtri zmanjšajo prenos določenega dela barv in zato vplivajo na svetlost. Npr. rdeči filtri zatemnijo modro nebo. +TP_BWMIX_FILTER_YELLOW;Rumena +TP_BWMIX_GAMMA;Popravek game +TP_BWMIX_GAM_TOOLTIP;Popravi gamo za vsak RGB kanal. +TP_BWMIX_LABEL;Črno-belo +TP_BWMIX_MET;Metoda +TP_BWMIX_MET_CHANMIX;Mešalnik kanalov +TP_BWMIX_MET_DESAT;Zmanjšanje nasičenosti +TP_BWMIX_MET_LUMEQUAL;Ekvalizator svetlosti +TP_BWMIX_MIXC;Mešalnik kanalov +TP_BWMIX_NEUTRAL;Ponastavi +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Končni faktorji RGB, ki skrbijo za vse možnosti mešalnika.\n"Skupaj" prikaže vsoto RGB vrednosti:\n- vedno 100% v relativnem načinu\n- višje (svetlejše) ali nižje (temnejše) od 100% v absolutnem načinu. +TP_BWMIX_RGB_TOOLTIP;Zmešajte RGB kanale. Uporabite prednastavitve za vodenje.\nBodite pozorni na negativne vrednosti, ki lahko povzročijo artefakte ali napačno delovanje. +TP_BWMIX_SETTING;Prednastavitve +TP_BWMIX_SETTING_TOOLTIP;Različne prednastvitve (film, pokrajina, itd.) ali ročne nastavitve mešalnika kanalov. +TP_BWMIX_SET_HIGHCONTAST;Visok kontrast +TP_BWMIX_SET_HIGHSENSIT;Visoka občutljivost +TP_BWMIX_SET_HYPERPANCHRO;Hiper pankromatsko +TP_BWMIX_SET_INFRARED;Infrardeče +TP_BWMIX_SET_LANDSCAPE;Pokrajina +TP_BWMIX_SET_LOWSENSIT;Nizka občutljivost +TP_BWMIX_SET_LUMINANCE;Svetlost +TP_BWMIX_SET_NORMCONTAST;Normalen kontrast +TP_BWMIX_SET_ORTHOCHRO;Ortokromatsko +TP_BWMIX_SET_PANCHRO;Pankromatsko +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;Absolutno RGB +TP_BWMIX_SET_RGBREL;Relativno RGB +TP_BWMIX_SET_ROYGCBPMABS;Absolutno ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Relativno ROYGCBPM +TP_BWMIX_TCMODE_FILMLIKE;Kot čno-beli film +TP_BWMIX_TCMODE_SATANDVALBLENDING;Črno-belo nasičenje in mešanje vrednosti +TP_BWMIX_TCMODE_STANDARD;Standardno črno-belo +TP_BWMIX_TCMODE_WEIGHTEDSTD;Uteženo standardno črno-belo +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Modro +TP_CACORRECTION_LABEL;Popravek kromatske aberacije +TP_CACORRECTION_RED;Rdeče +TP_CBDL_AFT;Črno-belo 'po' +TP_CBDL_BEF;Črno-belo 'pred' +TP_CBDL_METHOD;Lokacija obdelave +TP_CBDL_METHOD_TOOLTIP;Izberi ali naj bo orodje nivojev kontrasta po transformaciji v črno-belo, ki deluje v prostorum L*a*b* , ali pred transformacijo, ki deluje v prostoru RGB. +TP_CHMIXER_BLUE;Modri kanali +TP_CHMIXER_GREEN;Zeleni kanal +TP_CHMIXER_LABEL;Mešalnik kanalov +TP_CHMIXER_RED;Rdeči kanal +TP_COARSETRAF_TOOLTIP_HFLIP;Vodoravno preobrni. +TP_COARSETRAF_TOOLTIP_ROTLEFT;Zavrti levo.\n\nBližnjica:\n[ - Način večih zavihkov,\nAlt-[ - Način enega zavihka. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Zavrti desno.\n\nBližnjica:\n] - Način večih zavihkov,\nAlt-] - Način enega zavihka. +TP_COARSETRAF_TOOLTIP_VFLIP;Preobrni navpično. +TP_COLORAPP_ABSOLUTELUMINANCE;Absolutna svetlost +TP_COLORAPP_ALGO;Algoritem +TP_COLORAPP_ALGO_ALL;Vse +TP_COLORAPP_ALGO_JC;Svetlost + Barvitost (JC) +TP_COLORAPP_ALGO_JS;Svetlost + Nasičenost (JS) +TP_COLORAPP_ALGO_QM;Bleščina + Polnost barv (QM) +TP_COLORAPP_ALGO_TOOLTIP;Dovoljuje izbiro podmnožice parametrov ali vseh. +TP_COLORAPP_BADPIXSL;Filter vročih/mrtvih pikslov +TP_COLORAPP_BADPIXSL_TOOLTIP;Zatiranje vročih/slabih (živobarvno prikazanih) pikslov.\n0 = Brez učinka\n1 = Mediana\n2 = po Gaussu.\nSicer prilagodi sliko tako da se izogiba zelo temnih senc.\n\nTi artefakti so zaradi omejitev CIECAM02. +TP_COLORAPP_BRIGHT;Svetlost (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Svetlost v CIECAM02 upošteva tudi belino in se razlikuje od svetlosti v L*a*b* . +TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Kadar jo nastavite ročno, priporočam vrednosti nad 65. +TP_COLORAPP_CHROMA;Barvitost (C) +TP_COLORAPP_CHROMA_M;Polnost barv (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Polnost barv v CIECAM02 se razlikuje od polnosti v L*a*b* in RGB. +TP_COLORAPP_CHROMA_S;Nasičenost (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasičenost v CIECAM02 se razlikuje od nasičenosti v L*a*b* in RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Barvitost v CIECAM02 se razlikuje od barvitosti v L*a*b* in RGB. +TP_COLORAPP_CIECAT_DEGREE;CAT02 prilagoditev +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Razlikujte med L*a*b* in RGB kontrastom. +TP_COLORAPP_CONTRAST_TOOLTIP;Razlikujte med L*a*b* in RGB kontrastom. +TP_COLORAPP_CURVEEDITOR1;Krivulja tonov 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Prkaže histogram L* (L*a*b*) pred CIECAM02.\nČe je aktivno "Prikaži CIECAM02 izhodne histograme v krivuljah", prikaže histograme J ali Q po CIECAM02.\n\nJ in Q nista prikazana v glavnem panoju histogramov.\n\nKončni izhod se nanaša na glavni pano histogramov. +TP_COLORAPP_CURVEEDITOR2;Krivulja tonov 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Enaka uporaba kot pri krivulji tonov druge ekspozicije. +TP_COLORAPP_CURVEEDITOR3;Krivulja barv +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Prilagodi barvitost, nasičenje ali polnost barv.\n\nPrikaže histogram barvitosti (L*a*b*) pred CIECAM02.\nČe je aktivirano "Prikaži CIECAM02 izhodne histograme v krivuljah", prikaže histograme C, s ali M po CIECAM02.\n\nC, s in M niso prikazani v glavnem panoju histogramov.\nKončni izhod se nanaša na glavni pano histogramov. +TP_COLORAPP_DATACIE;CIECAM02 izhodni histogrami v krivuljah +TP_COLORAPP_DATACIE_TOOLTIP;Kadar je aktivirano so histogrami, CIECAM02 krivulje prikazujejo približne vrednosti oz. intervale z J ali Q, in C, s ali M po prilagoditvah CIECAM02.\nTa izbira ne vpliva na glavni pano histogramov.\n\nKadar je deaktiviran, histogrami v CIECAM02 krivuljah kažejo vrednosti L*a*b* pred prilagoditvami CIECAM02. +TP_COLORAPP_FREE;Prosta temp+zelena + CAT02 + [output] +TP_COLORAPP_GAMUT;Lontrola barvega obsega (L*a*b*) +TP_COLORAPP_GAMUT_TOOLTIP;Dovoli kontrolo barvnega obsega v L*a*b* načinu. +TP_COLORAPP_HUE;Odtenek (h) +TP_COLORAPP_HUE_TOOLTIP;Odtenek (h) - kot med 0° in 360°. +TP_COLORAPP_LABEL;CIE Prikaz barv Model 2002 +TP_COLORAPP_LABEL_CAM02;Prilagoditve slike +TP_COLORAPP_LABEL_SCENE;Scenski pogoji +TP_COLORAPP_LABEL_VIEWING;Pogoji gledanja +TP_COLORAPP_LIGHT;Svetlost (J) +TP_COLORAPP_LIGHT_TOOLTIP;Svetlost v CIECAM02 se razlikuje od svetlosti v L*a*b* in RGB. +TP_COLORAPP_MEANLUMINANCE;Povprečna svetlost (Yb%) +TP_COLORAPP_MODEL;WP Model +TP_COLORAPP_MODEL_TOOLTIP;Model bele točke.\n\nWB [RT] + [output]: za sceno se uporabi RT-jevo ravnotežje beline, CIECAM02 je nastavljen na D50, nastavitev beline izhodne naprave je nastavljena v Pogojih gledanja.\n\nWB [RT+CAT02] + [output]: RT-jevo ravnotežje beline uporablja CAT02, ravnotežje beline izhodne naprave pa je nastavljeno v Pogojih gledanja.\n\nProsta temp+zelena + CAT02 + [output]: temp in zeleno določi uporabnik, ravnotežje beline izhodne naprave pa je nastavljeno v Pogojih gledanja. +TP_COLORAPP_NEUTRAL;Ponastavi +TP_COLORAPP_NEUTRAL_TIP;Ponastavi vse potrditvena polja in krivulje na njihove privzete vrednosti +TP_COLORAPP_RSTPRO;Varovanje rdečih in kožnih tonov +TP_COLORAPP_RSTPRO_TOOLTIP;Varovanje rdečih in kožnih tonov ima vpliv tako na drsnike kot na krivulje. +TP_COLORAPP_SURROUND;Obkroži +TP_COLORAPP_SURROUND_AVER;Povprečno +TP_COLORAPP_SURROUND_DARK;Temno +TP_COLORAPP_SURROUND_DIM;Zatemnjeno +TP_COLORAPP_SURROUND_EXDARK;Izjemno črno (Cutsheet) +TP_COLORAPP_SURROUND_TOOLTIP;Spremembe tonov in barv so odvisne od pogojev gledanja na izhodno enoto.\n\nPovprečje: Povprečno svetlobno okolje (standard). Slika se ne bo spremenila.\n\nZatemnjeno: Zatemnjeno okolje (TV). Slika bo postala malo temnejša.\n\nTemno: temno okolje (projektor). Slika bo postala bolj temna.\n\nIzredno temno: Izredno temno okolje (Cutsheet). Slika bo postala zelo temna. +TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +TP_COLORAPP_TCMODE_CHROMA;Barvitost +TP_COLORAPP_TCMODE_COLORF;Polnost barv +TP_COLORAPP_TCMODE_LABEL1;Krivulja način 1 +TP_COLORAPP_TCMODE_LABEL2;Krivulja način 2 +TP_COLORAPP_TCMODE_LABEL3;Krivulja barvitosti +TP_COLORAPP_TCMODE_LIGHTNESS;Svetlost +TP_COLORAPP_TCMODE_SATUR;Nasičenost +TP_COLORAPP_TEMP_TOOLTIP;Za izbrano svetilo vedno postavi Tint=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TONECIE;Preslikava barvnih tonov s CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Če je ta opcija neaktivna, je preslikava barvnih tonov v prostoru L*a*b* .\nČe je aktivirana, je prenos barvnih tonov z uporabo CIECAM02.\nOrodje za prenos barvnih tonov mora biti aktivno, da ima učinek. +TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolutna svetlost okolice gledanja\n(običajno 16 cd/m²). +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] +TP_COLORAPP_WBRT;WB [RT] + [output] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Avtomatično +TP_COLORTONING_BALANCE;Uravnoteženo +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Neprosojnost +TP_COLORTONING_COLOR;Barva +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Neprosojnost barvitosti kot funkcija svetlosti oC=f(L) +TP_COLORTONING_HIGHLIGHT;Bleščave +TP_COLORTONING_HUE;Odtenki +TP_COLORTONING_LAB;L*a*b* mešanje +TP_COLORTONING_LABEL;Toniranje barv +TP_COLORTONING_LABGRID;L*a*b* mreža popravkov barv +TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 +TP_COLORTONING_LABREGIONS;Regije popravkov barv +TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 +TP_COLORTONING_LABREGION_CHANNEL;Kanal +TP_COLORTONING_LABREGION_CHANNEL_ALL;Vse +TP_COLORTONING_LABREGION_CHANNEL_B;Modra +TP_COLORTONING_LABREGION_CHANNEL_G;Zelena +TP_COLORTONING_LABREGION_CHANNEL_R;Rdeča +TP_COLORTONING_LABREGION_CHROMATICITYMASK;C +TP_COLORTONING_LABREGION_HUEMASK;H +TP_COLORTONING_LABREGION_LIGHTNESS;Svetlost +TP_COLORTONING_LABREGION_LIGHTNESSMASK;L +TP_COLORTONING_LABREGION_LIST_TITLE;Popravek +TP_COLORTONING_LABREGION_MASK;Maska +TP_COLORTONING_LABREGION_MASKBLUR;Maska zamegljenosti +TP_COLORTONING_LABREGION_OFFSET;Odmik +TP_COLORTONING_LABREGION_POWER;Moč +TP_COLORTONING_LABREGION_SATURATION;Nasičenje +TP_COLORTONING_LABREGION_SHOWMASK;Prikaži masko +TP_COLORTONING_LABREGION_SLOPE;Strmina +TP_COLORTONING_LUMA;Svetlost +TP_COLORTONING_LUMAMODE;Ohrani svetlost +TP_COLORTONING_LUMAMODE_TOOLTIP;Če je aktivno, se ob spremembi barve (rdeča, zelena, cian, modra, itd.) ohrani tudi svetlost vsakega piksla. +TP_COLORTONING_METHOD;Metoda +TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* mešanje", "RGB drsniki" in "RGB krivulje" uporabljajo interpolirno mešanje barv.\n"Uravnoteženje barv (Sence/Srednji toni/Bleščave)" and "Nasičenje 2 barv" uporabljajo neposredne barve.\n\nČrno-belo orodje lahko uporabimo pri katerikoli metodi barvega toniranja. +TP_COLORTONING_MIDTONES;Srednji toni +TP_COLORTONING_NEUTRAL;Ponastavi drsnike +TP_COLORTONING_NEUTRAL_TIP;Ponastavi vse vrednosti (Sence, Srednji toni, Bleščave) na prizeto vrednost. +TP_COLORTONING_OPACITY;Neprosojnost +TP_COLORTONING_RGBCURVES;RGB - Krivulje +TP_COLORTONING_RGBSLIDERS;RGB - Drsniki +TP_COLORTONING_SA;Zavarovanje nasičenosti +TP_COLORTONING_SATURATEDOPACITY;Moč +TP_COLORTONING_SATURATIONTHRESHOLD;Prag +TP_COLORTONING_SHADOWS;Sence +TP_COLORTONING_SPLITCO;Sence/Srednje vrednosti/Bleščave +TP_COLORTONING_SPLITCOCO;Uravnoteženje barv Sence/Srednje vrednosti/Bleščave +TP_COLORTONING_SPLITLR;Nasičenje 2 barv +TP_COLORTONING_STR;Moč +TP_COLORTONING_STRENGTH;Moč +TP_COLORTONING_TWO2;Posebna barvitost '2 colors' +TP_COLORTONING_TWOALL;Posebna barvitost +TP_COLORTONING_TWOBY;Posebna a* in b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardna barvitost:\nLinearni odziv, a* = b*.\n\nPosebna barvitost:\nLinearni odziv, a* = b*, toda neomejen - poskusi pod diagonalo.\n\nPosebna a* in b*:\nLinearni neomejeni odziv s posebnima krivuljama za a* in b*. Namenjeno posebnim učinkom.\n\nPosebna barvitost 2 barv:\nBolj predvidljivo. +TP_COLORTONING_TWOSTD;Standardna barvitost +TP_CROP_FIXRATIO;Zakleni razmerje +TP_CROP_GTDIAGONALS;Pravilo diagonal +TP_CROP_GTEPASSPORT;Biometrični potni list +TP_CROP_GTFRAME;Okvir +TP_CROP_GTGRID;Mreža +TP_CROP_GTHARMMEANS;Harmonična povprečja +TP_CROP_GTNONE;Noben +TP_CROP_GTRULETHIRDS;Pravilo tretjin +TP_CROP_GTTRIANGLE1;Zlati trikotniki 1 +TP_CROP_GTTRIANGLE2;Zlati trikotniki 2 +TP_CROP_GUIDETYPE;Vodilo tipa: +TP_CROP_H;Višina +TP_CROP_LABEL;Obreži +TP_CROP_PPI;PPI +TP_CROP_RESETCROP;Ponastavi +TP_CROP_SELECTCROP;Izberi +TP_CROP_W;Širina +TP_CROP_X;Levo +TP_CROP_Y;Vrh +TP_DARKFRAME_AUTOSELECT;Avtomatičen izbor +TP_DARKFRAME_LABEL;Dark-frame +TP_DEFRINGE_LABEL;Odstrani artefakte +TP_DEFRINGE_RADIUS;Radij +TP_DEFRINGE_THRESHOLD;Prag +TP_DEHAZE_DEPTH;Globina +TP_DEHAZE_LABEL;Odstranjevanje zamegljenosti +TP_DEHAZE_LUMINANCE;Samo svetlost +TP_DEHAZE_SHOW_DEPTH_MAP;Prikaži karto globin +TP_DEHAZE_STRENGTH;Moč +TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Avto multi-cone +TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Avtomatično globalno +TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Krominanca - modro-rumeno +TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Krivulja krominance +TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Povečaj (pomnoži) vrednosti vseh krominanc drsnikov.\nTa krivulja omogoča prilagajanje moči zmanjševanje barvnega šuma kot funkcijo kromatičnosti, na primer za povečanje aktivnosti v področjih z nizko nasičenostjo in zmanjšanje na področjih visoke nasičenosti. +TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Krominanca +TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Ročno +TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Krominanca - Matična +TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Metoda +TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Ročno\nDeluje na vsej sliki.\nNastavitve odstranjevanja šuma upravljate ročno.\n\nAvtomatično globalno\nDeluje na vsej sliki.\nUporabljeno je 9 con za izračun parametrov globalnega zmanjšanja barvnega šuma.\n\nPreogled\nDeluje na celotni sliki.\nDel slike, ki je viden v predlogledu je uporabljen za izračun parametrov za odstranjevanje šuma. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manual\nDeluje na vsej sliki.\nastavitve odstranjevanja šuma upravljate ročno.\n\nAvtomatično globalno\nDeluje na vsej sliki.\nUporabljeno je 9 con za izračun parametrov globalnega zmanjšanja barvnega šuma.\n\nAvtomatično več-consko\nNi predogleda - deluje samo ob shranjevanju, toda z uporabo "Predogledne" metode tako, da je center slike center predogleda, velikost slike pa velikost predogleda tako, da dobite vtis o predvidenih učinkih.\nSlika je razdeljena na krpe (od 10 do 70 odvisno od velikosti slike) in vsaka krpa ima svoje nastavitve odpravljanja barvnega šuma.\n\nPredogled\nDeluje na celotni sliki.\nDel slike, ki je viden v predlogledu je uporabljen za izračun parametrov za odstranjevanje šuma. +TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Multi-cone predogleda +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Predogled +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Prikaže preostale nivoje šuma na delu slike v predogledu po valovčku.\n\n>300 Z veliko šuma\n100-300 Šum\n50-100 Malo šuma\n<50 Zelo malo šuma\n\nVedite, da se vrednosti razlikujejo med RGB in L*a*b* . Vrednosti v RGB so manj natančne, ker RGB način v celoti ne loči svetlosti in barvitosti. +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Velikost predogleda=%1, Center: Px=%2 Py=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Šum predogleda: Povprečje=%1 Visoko=%2 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Šum predogleda: Povprečje= - Visoko= - +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Velikost krpe=%1, Center: Tx=%2 Ty=%3 +TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Krominanca - Rdeča-Zelena +TP_DIRPYRDENOISE_LABEL;Odpravljanje šuma +TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Upravljanje svetlosti +TP_DIRPYRDENOISE_LUMINANCE_CURVE;Krivulja svetlosti +TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Podrobnost obnove +TP_DIRPYRDENOISE_LUMINANCE_FRAME;Svetlost +TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Svetlost +TP_DIRPYRDENOISE_MAIN_COLORSPACE;Barvni prostor +TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* +TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB +TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Za surove slike je moč uporabiti ali RGB ali L*a*b* .\n\nZa ne-surove slike bo ne glede na izbiro uporabljena metoda L*a*b* . +TP_DIRPYRDENOISE_MAIN_GAMMA;Gama +TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Gama ima vpliv na moč zmanjšanja šuma glede nabora tonov. Manjše vrednosti ciljajo na sence, večje vrednosti pa bodo raztegnile vpliv na svetlejše tone. +TP_DIRPYRDENOISE_MAIN_MODE;Način +TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Agresivno +TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Konservativno +TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;"Konservativno" ohranja nizke frekvence vzorcev barvitosti, medtem ko jih "agresivne" izbrišejo. +TP_DIRPYRDENOISE_MEDIAN_METHOD;Metode mediane +TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Samo barvitost +TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* +TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Filter mediane +TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Samo svetlost +TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB +TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;Pri uporabi "Samo svetlost" in metodi "L*a*b*", se bo filtriranje po mediani izvedlo čisto po koraku valovčkov v zaporedju zmanjšanja šuma.\nOb uporabi načina "RGB" se bo izvedlo na samem koncu zaporedja postopkov za zmanjšanje šuma. +TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Weighted L* (malo) + a*b* (normalno) +TP_DIRPYRDENOISE_MEDIAN_PASSES;Iteracij mediane +TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Uporaba trikratnega filtra mediane v oknu 3×3 pogosto naredi boljši rezultat od ene iteracije filtra mediane na oknu velikosti 7×7. +TP_DIRPYRDENOISE_MEDIAN_TYPE;Tip mediane +TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Uporabi filter mediane na željeni velikosti okna. Večje okno zahteva več časa obdelave.\n\n3×3 mehko: obdela 5 pikslov v oknu 3×3.\n3×3: obdela 9 pikslov v oknu 3×3.\n5×5 mehko: obdela 13 pikslov v oknu 5×5.\n5×5: obdela 25 pikslov v oknu 5×5.\n7×7: obdela 49 pikslov v oknu 7×7.\n9×9: obdela 81 pikslov v oknu 9×9.\n\nVčasih je moč dobiti boljšo kakovost z uporabo večkratnih filtrov na manjšem oknu kot enkratnemu filtru na večjem oknu. +TP_DIRPYRDENOISE_TYPE_3X3;3×3 +TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 mehko +TP_DIRPYRDENOISE_TYPE_5X5;5×5 +TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 mehko +TP_DIRPYRDENOISE_TYPE_7X7;7×7 +TP_DIRPYRDENOISE_TYPE_9X9;9×9 +TP_DIRPYREQUALIZER_ALGO;Barvni Obseg Kože +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fino: bližje barvi kože, minimiziranje učinka na drugih barvah\nVeliko: izogibanje artefaktom. +TP_DIRPYREQUALIZER_ARTIF;Zmanjšanje artefaktov +TP_DIRPYREQUALIZER_HUESKIN;Odtenek kože +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Ta piramida je za gornji del, kjer algoritem deluje maksimalno učinkovito.\nNa spodnjem delu so cone pretvorbe.\nČe želite premakniti področje bistveno na levo ali na desno oz. če se pojavljajo arifakti: je ravnotežje beline napačno. Lahko rahlo zmanjšate cono, da preprečite vplive na ostali del slike. +TP_DIRPYREQUALIZER_LABEL;Kontrast glede nivojev podrobnosti +TP_DIRPYREQUALIZER_LUMACOARSEST;Najbolj grobo +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast - +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast + +TP_DIRPYREQUALIZER_LUMAFINEST;Najbolj fino +TP_DIRPYREQUALIZER_LUMANEUTRAL;Nevtralno +TP_DIRPYREQUALIZER_SKIN;Ciljna zaščita kože +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Pri -100 so ciljani toni kože.\nPri 0 so vsi toni obravnavani enako.\nPri +100 so zaščiteni toni kože, vsi ostali pa so spremenjeni. +TP_DIRPYREQUALIZER_THRESHOLD;Prag +TP_DIRPYREQUALIZER_TOOLTIP;Poskusi zmanjšati artefakte pri spremembi barve kože (odtenek, barvitost, luma) in preostankom slike. +TP_DISTORTION_AMOUNT;Količina +TP_DISTORTION_AUTO_TIP;Avtomatsko popravi popačitve objektiva pri surovih slikah s primerjavo z vgrajeno sliko JPEG, če obstaja in so popravki objektiva izvedeni v fotoaparatu. +TP_DISTORTION_LABEL;Popravek popačenja +TP_EPD_EDGESTOPPING;Zaustavljanje roba +TP_EPD_GAMMA;Gama +TP_EPD_LABEL;Preslikava tonov +TP_EPD_REWEIGHTINGITERATES;Ponovno tehtanje ponovitev +TP_EPD_SCALE;Merilo +TP_EPD_STRENGTH;Moč +TP_EXPOSURE_AUTOLEVELS;Avto nivoji +TP_EXPOSURE_AUTOLEVELS_TIP;Preklaplja izvajanje avto nivojev z vrednostmi izračunani iz analize slike.\nOmogoča rekonstrukcijo bleščav, če je potrebna. +TP_EXPOSURE_BLACKLEVEL;Črna +TP_EXPOSURE_BRIGHTNESS;Svetlost +TP_EXPOSURE_CLAMPOOG;Posnetek barv izven obsega +TP_EXPOSURE_CLIP;Posnetek % +TP_EXPOSURE_CLIP_TIP;Delež pikslov, ki naj bodo posneti v operaciji avto nivoji. +TP_EXPOSURE_COMPRHIGHLIGHTS;Stiskanje bleščav +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Prag stiskanja bleščav +TP_EXPOSURE_COMPRSHADOWS;Stiskanje senc +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Krivulja tonov 1 +TP_EXPOSURE_CURVEEDITOR2;Krivulja tonov 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Prosim preberite članek v Rawpediji "Exposure > Tone Curves" kako dosežete najboljše rezultate z uporabo krivulj dveh tonov. +TP_EXPOSURE_EXPCOMP;Prilagoditev ekspozicije +TP_EXPOSURE_HISTMATCHING;Avtomatsko pridobljena krivulja tonov +TP_EXPOSURE_HISTMATCHING_TOOLTIP;Avtomatsko prilagodi drsnike in krivulje (razen prilagoditve ekspozicije) da ustreza videzu vgrajene slike JPEG. +TP_EXPOSURE_LABEL;Ekspozicija +TP_EXPOSURE_SATURATION;Nasičenje +TP_EXPOSURE_TCMODE_FILMLIKE;Kot na filmu +TP_EXPOSURE_TCMODE_LABEL1;Krivulja način 1 +TP_EXPOSURE_TCMODE_LABEL2;Krivulja način 2 +TP_EXPOSURE_TCMODE_LUMINANCE;Svetlost +TP_EXPOSURE_TCMODE_PERCEPTUAL;Glede na zaznavo +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Nasičenje im mešanje vrednosti +TP_EXPOSURE_TCMODE_STANDARD;Standardno +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Uteženo standardno +TP_EXPOS_BLACKPOINT_LABEL;Surove črne točke +TP_EXPOS_WHITEPOINT_LABEL;Surove bele točke +TP_FILMNEGATIVE_BLUE;Kvocient modre +TP_FILMNEGATIVE_GREEN;Referenčni eksponent (kontrast) +TP_FILMNEGATIVE_GUESS_TOOLTIP;Izračunajte eksponente tako, da na sliki izberete dve nevtralni referenčni točki; ena bela (svetlo siva) in ena črna (temno siva). Vrstni red ni pomemben. Eksponenti bodo izračunani takoj po izbiri drugega mesta. +TP_FILMNEGATIVE_LABEL;Filmski negativ +TP_FILMNEGATIVE_PICK;Poberite črne in bele točke +TP_FILMNEGATIVE_RED;Kvocient rdeče +TP_FILMSIMULATION_LABEL;Simulacija filma +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee je nastavljen, da išče slike Hald CLUT, ki so uporabljene za orodje simulacije filma, v mapi, kje potrebujejo preveč časa za nalaganje.\nPojdite v Preference > Obdelava slik > Simulacija filma\n da si ogledate katera mapa je v uporabi. Nastaviti morate RawTherapee tako, da bodisi kaže v mapo, ki vsebuje samo slike Hald CLUT in nič drugega, ali v prazno mapo, če ne želite uporabiti orodja za simulacijo filma.\n\nZa več informacij preberite članek Film Simulation v Rawpediji.\n\nAli želite prekiniti skeniranje? +TP_FILMSIMULATION_STRENGTH;Moč +TP_FILMSIMULATION_ZEROCLUTSFOUND;Nastavi mapo za HaldCLUT v preferencah +TP_FLATFIELD_AUTOSELECT;Avtomatska selekcija +TP_FLATFIELD_BLURRADIUS;Radij zameglevanja +TP_FLATFIELD_BLURTYPE;Tip zameglevanja +TP_FLATFIELD_BT_AREA;Površina +TP_FLATFIELD_BT_HORIZONTAL;Vodoravno +TP_FLATFIELD_BT_VERTHORIZ;Navpično + Vodoravno +TP_FLATFIELD_BT_VERTICAL;Navpično +TP_FLATFIELD_CLIPCONTROL;Kontrola posnetka +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Kontrola posnetka se izogiba bleščav z uporabo poravnilnika. Če obstaja že nekaj posnetih poravnanih bleščav, lahko ta kontrola vodi k barvemu pridihu. +TP_FLATFIELD_LABEL;Flat-field +TP_GENERAL_11SCALE_TOOLTIP;Učinki tega so vidni in natančno prikazani samo v predogledu merila 1:1. +TP_GRADIENT_CENTER;Center +TP_GRADIENT_CENTER_X;Center X +TP_GRADIENT_CENTER_X_TOOLTIP;Pomakni gradient na levo (negativne vrednosti) ali desno (pozitivne vrednosti). +TP_GRADIENT_CENTER_Y;Center Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Pomakni gradient navzgor (negativne vrednosti) ali dol (pozitivne vrednosti). +TP_GRADIENT_DEGREE;Kot +TP_GRADIENT_DEGREE_TOOLTIP;Kot vrtenja v stopinjah. +TP_GRADIENT_FEATHER;Pero +TP_GRADIENT_FEATHER_TOOLTIP;Širina gradienta v odstotkih diagonale slike. +TP_GRADIENT_LABEL;Postopni filter +TP_GRADIENT_STRENGTH;Moč +TP_GRADIENT_STRENGTH_TOOLTIP;Moč filtra v stopnjah. +TP_HLREC_BLEND;Zmešaj +TP_HLREC_CIELAB;Mešaj v CIELab +TP_HLREC_COLOR;Razmnoževanje barve +TP_HLREC_ENA_TOOLTIP;Je lahko aktivirano z avto nivoji. +TP_HLREC_LABEL;Restavriranje bleščav +TP_HLREC_LUMINANCE;Restavriranje svetlosti +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER_CHANNEL;Kanal +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Ekvalizator HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Osnovna ekspozicija +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Uporabi vgrajeno osnovno tabelo odmikov DCP. Nastavitev je na voljo samo, če obstaja DCP. +TP_ICM_APPLYHUESATMAP;Osnovna tabela +TP_ICM_APPLYHUESATMAP_TOOLTIP;Uporabi vgrajeno osnovno tabelo DCP (HueSatMap). Nastavitev je na voljo samo če obstaja DCP. +TP_ICM_APPLYLOOKTABLE;Look table +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Uporabi vgrajeno osnovno tabelo vpogledov DCP. Nastavitev je na voljo samo če obstaja DCP. +TP_ICM_BPC;Prilagoditev črne točke +TP_ICM_DCPILLUMINANT;Osvetljevalnik +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolirano +TP_ICM_DCPILLUMINANT_TOOLTIP;Izberi katero vgrajeno DCP svetilo uporabiti. Privzeto je "interpolirano", ki je mešanica dveh glede na belino. Nastavitev je na voljo, samo če izbran dvojno osvetlitveni CDP s podporo za interpolacijo. +TP_ICM_INPUTCAMERA;Standardni fotoaparat +TP_ICM_INPUTCAMERAICC;Avtomatično usklajen profil s fotoaparatom +TP_ICM_INPUTCAMERAICC_TOOLTIP;Uporabi RawTherapee-jev specifičen DCP za ta fotoaparat ali vhodni ICC profil. Ti profili so bolj natančni kot enostavni matrični profili, a niso na voljo za vse fotoaparate. Ti profili so shranjeni v mapah /iccprofiles/input in /dcpprofiles in jih razpoznamo iz natančnega imena modela fotoaparata. +TP_ICM_INPUTCAMERA_TOOLTIP;Uporabi enostavno matriko iz dcraw, izboljšano verzijo RawTherapee (katerikoli je na voljo za ta model fotoaparata) ali profil vgrajen v DNG. +TP_ICM_INPUTCUSTOM;Po meri +TP_ICM_INPUTCUSTOM_TOOLTIP;Izberi vaš lastni barvni profil DCP/ICC za fotoaparat. +TP_ICM_INPUTDLGLABEL;Izberi vhodni DCP/ICC Profil... +TP_ICM_INPUTEMBEDDED;Uporabi vgrajenega, če je možno +TP_ICM_INPUTEMBEDDED_TOOLTIP;Uporabi profil vgrajen v ne-surove slike. +TP_ICM_INPUTNONE;Ni profila +TP_ICM_INPUTNONE_TOOLTIP;Ne uporabi nobenega profila.\nUporabi samo v posebnih primerih. +TP_ICM_INPUTPROFILE;Vhodni profil +TP_ICM_LABEL;Upravljanje barv +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTPROFILE;Izhodni profil +TP_ICM_PROFILEINTENT;Namera upodabljanja +TP_ICM_SAVEREFERENCE;Shrani referenčno sliko +TP_ICM_SAVEREFERENCE_APPLYWB;Uporabi uravnoteženje beline +TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Na splošno uporabi uravnoteženje beline kadar shranjujete slike za tvorbo ICC profilov, ne porabljajte pa uravnoteženje beline za tvorbo DCP profilov. +TP_ICM_SAVEREFERENCE_TOOLTIP;Shrani linearno sliko TIFF pred uporabo vhodnega profila. Rezultat lahko uporabiš za kalibracijo in tvorbo profila fotoaparata. +TP_ICM_TONECURVE;Krivulja tonov +TP_ICM_TONECURVE_TOOLTIP;Uporabi vgrajeno krivuljo tonov DCP. Nastavitev je na voljo samo, če ima izbran DCP tudi krivuljo tonov. +TP_ICM_WORKINGPROFILE;Delovni profil +TP_ICM_WORKING_TRC;Krivulja tonskih odzivov: +TP_ICM_WORKING_TRC_CUSTOM;Po meri +TP_ICM_WORKING_TRC_GAMMA;Gama +TP_ICM_WORKING_TRC_NONE;Nič +TP_ICM_WORKING_TRC_SLOPE;Strmina +TP_ICM_WORKING_TRC_TOOLTIP;Samo za vgrajene profile. +TP_IMPULSEDENOISE_LABEL;Impulzno zmanjšanje šuma +TP_IMPULSEDENOISE_THRESH;Prag +TP_LABCURVE_AVOIDCOLORSHIFT;Izogibaj se barvnega pomika +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Prilagodi barve barvnemu prostoru delovnega barvnega prostora in uporabi Munsellov popravek. +TP_LABCURVE_BRIGHTNESS;Svetlost +TP_LABCURVE_CHROMATICITY;Kromatičnost +TP_LABCURVE_CHROMA_TOOLTIP;Za uporabo črno-belega toniranja nastavi kromatičnost na -100. +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krivulja osvetljenosti +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Nasičena zelena +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Pastelno zelena +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Pastelno rdeča +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Nasičeno rdeča +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Nasičeno modra +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Pastelno modra +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Pastelno rumena +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Nasičeno rumena +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Nevtralna +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dolgočasna +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastelna +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Nasičena +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Kromatičnost glede na kromatičnost C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Kromatičnost glede na odtenek C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Kromatičnost glede na svetlost C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Odtenek glede na odtenek H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Svetlost glede na kromatičnost L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Svetlost glede na odtenek L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Svetlost glede na svetlost L=f(L) +TP_LABCURVE_LABEL;Prilagoditve L*a*b* +TP_LABCURVE_LCREDSK;Omeji LC na rdečo in kožne barve +TP_LABCURVE_LCREDSK_TIP;Če je aktivna, krivulja LC vpliva samo na rdečo in kožne barve.\nČe je onemogočen, se nanaša na vse tone. +TP_LABCURVE_RSTPROTECTION;Zaščita rdeče in kožnih barv +TP_LABCURVE_RSTPRO_TOOLTIP;Deluje na drsniku kromatičnost in krivulji CC. +TP_LENSGEOM_AUTOCROP;Avtomatska obrezava +TP_LENSGEOM_FILL;Avtomatsko popolnitev +TP_LENSGEOM_LABEL;Objektiv / geometrija +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Avtomatično izbrano +TP_LENSPROFILE_CORRECTION_LCPFILE;datoteka LCP +TP_LENSPROFILE_CORRECTION_MANUAL;Ročno izbrano +TP_LENSPROFILE_LABEL;Popravek objektiva s profilom +TP_LENSPROFILE_LENS_WARNING;Opozorilo: faktor obrezave za objektiv je večje od faktorja obrezave za fotoaparat, rezultat utegne biti napačen. +TP_LENSPROFILE_MODE_HEADER;Profil objektiva +TP_LENSPROFILE_USE_CA;Kromatska aberacija +TP_LENSPROFILE_USE_GEOMETRIC;Geometrično popačenje +TP_LENSPROFILE_USE_HEADER;Popravi +TP_LENSPROFILE_USE_VIGNETTING;Vinjetiranje +TP_LOCALCONTRAST_AMOUNT;Količina +TP_LOCALCONTRAST_DARKNESS;Nivo temine +TP_LOCALCONTRAST_LABEL;Lokalni kontrast +TP_LOCALCONTRAST_LIGHTNESS;Nivo svetlosti +TP_LOCALCONTRAST_RADIUS;Radij +TP_METADATA_EDIT;Izvedi spremembe +TP_METADATA_MODE;Način kopiranja metapodatkov +TP_METADATA_STRIP;Odstrani vse metapodatke +TP_METADATA_TUNNEL;Kopiraj nespremenjeno +TP_NEUTRAL;Ponastavi +TP_NEUTRAL_TIP;Ponastavi drsnike ekspozicije v nevtralno stanje.\nUporablja enake parametre kot pri Avtomatskih nivojih, ne glede na to ali so uporabljeni ali ne.. +TP_PCVIGNETTE_FEATHER;Pero +TP_PCVIGNETTE_FEATHER_TOOLTIP;Perje:\n0 = samo vogali,\n50 = na polovici do centra,\n100 = v centru. +TP_PCVIGNETTE_LABEL;Filter vinjetiranja +TP_PCVIGNETTE_ROUNDNESS;Okroglina +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Okroglina:\n0 = pravokotnik,\n50 = včrtana elipsa,\n100 = krog. +TP_PCVIGNETTE_STRENGTH;Moč +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Moč filtra v stopnjah (uporabljeno v vogalih). +TP_PDSHARPENING_LABEL;Ujemite ostrenje +TP_PERSPECTIVE_HORIZONTAL;Vodoravno +TP_PERSPECTIVE_LABEL;Perspektiva +TP_PERSPECTIVE_VERTICAL;Navpično +TP_PFCURVE_CURVEEDITOR_CH;Ostanek +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Kontrolira moč ostranjevanja artefaktov.\nVisoko = več,\nNizko = manj. +TP_PREPROCESS_DEADPIXFILT;Filter mrtvih pikslov +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Poskuša odstraniti mrtve piksle. +TP_PREPROCESS_GREENEQUIL;Uravnoteženje zelene +TP_PREPROCESS_HOTPIXFILT;Filter vročih pikslov +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Poskuša odstraniti vroče piksle. +TP_PREPROCESS_LABEL;Predobdelava +TP_PREPROCESS_LINEDENOISE;Filter linijskega šuma +TP_PREPROCESS_LINEDENOISE_DIRECTION;Smer +TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Obe +TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Vodoravno +TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Voporavno samo na vrsticah PDAF +TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Navpično +TP_PREPROCESS_NO_FOUND;Noben ni najden +TP_PREPROCESS_PDAFLINESFILTER;Linijski filter PDAF +TP_PRSHARPENING_LABEL;Ostrenje po spremembi velikosti +TP_PRSHARPENING_TOOLTIP;Naostri sliko po spremembi velikosti. Deluje samo z metodo "Lanczos". Nemogoče je izvesti predogled tega postopka. Glej Rawpedijo za navodila za uporabo. +TP_RAWCACORR_AUTO;Avtomatski popravki +TP_RAWCACORR_AUTOIT;Iteracije +TP_RAWCACORR_AUTOIT_TOOLTIP;Ta nastavitev je na voljo, če je omogočen "Avto-popravek"\nAvto-popravek je konzervativen, kar pomeni, da pogosto ne popravi vse kromatske aberacije.\nZa popravek preostale kromatske aberacije lahko uporabiš do pet iteracij avtomatske kromatske aberacije.\nVsaka iteracija bo zmanjšala preostalo kromatsko aberacijo glede na prejšnjo na račun dodatnega časa za obdelavo. +TP_RAWCACORR_AVOIDCOLORSHIFT;Izogibaj se pomiku barve +TP_RAWCACORR_CABLUE;Modra +TP_RAWCACORR_CARED;Rdeča +TP_RAWCACORR_LABEL;Popravek kromatske aberacije +TP_RAWEXPOS_BLACK_0;Zelena 1 (vodilna) +TP_RAWEXPOS_BLACK_1;Rdeča +TP_RAWEXPOS_BLACK_2;Modra +TP_RAWEXPOS_BLACK_3;Zelena 2 +TP_RAWEXPOS_BLACK_BLUE;Modra +TP_RAWEXPOS_BLACK_GREEN;Zelena +TP_RAWEXPOS_BLACK_RED;Rdeča +TP_RAWEXPOS_LINEAR;Popravek bele točke +TP_RAWEXPOS_RGB;Rdeča, Zelena, Modra +TP_RAWEXPOS_TWOGREEN;Poveži zelene +TP_RAW_1PASSMEDIUM;1-pass (Markesteijn) +TP_RAW_2PASS;1-pass+fast +TP_RAW_3PASSBEST;3-pass (Markesteijn) +TP_RAW_4PASS;3-prehodi+hitri +TP_RAW_AHD;AHD +TP_RAW_AMAZE;AMaZE +TP_RAW_AMAZEVNG4;AMaZE+VNG4 +TP_RAW_BORDER;Meja +TP_RAW_DCB;DCB +TP_RAW_DCBENHANCE;DCB izboljšava +TP_RAW_DCBITERATIONS;Število iteracij DCB +TP_RAW_DCBVNG4;DCB+VNG4 +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;%1 odstranjevanje mozaičnosti... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Izboljšava odstranejvanja mozaičnosti... +TP_RAW_DMETHOD_TOOLTIP;Opomba: IGV in LMMSE sta namenjeni slikam z visokim ISO za pomoč pri odstranjevanju šuma ne da bi povzročali vzorce v obliki labirintov posterizacije ali izpranega videza.\nPomik pikslov je samo za datoteke Pentax/Sony Pixel Shift. Pri drugih datotekah je namesto tega uporabljen AMaZE. +TP_RAW_DUALDEMOSAICAUTOCONTRAST;Avtomatični prag +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Če je ta opcija vključena (priporočljivo), RawTherapee izračuna optimalno vrednost glede na gladke dele slike.\nČe ni gladkega dela slike ali pa če je slika preveč šumna, bo vrednost postavljena na 0.\nČe želiš postaviti vrednost ročno, najprej izključi opcijo (primerna vrednost je odvisna od slike). +TP_RAW_DUALDEMOSAICCONTRAST;Prag kontrasta +TP_RAW_EAHD;EAHD +TP_RAW_FALSECOLOR;Število korakov zatiranja napačnih barv +TP_RAW_FAST;Hitro +TP_RAW_HD;Prag +TP_RAW_HD_TOOLTIP;Nizke vrednosti bodo bolj agresivno določale vroče/mrtve piksle in lažne točke bodo pridelale artefakte. Če opazite pojav artefaktov, ko ste omogočili filter vročih/mrtvih pikslov, postopno povečajte vrednost praga, dokler artefakti ne izginejo. +TP_RAW_HPHD;HPHD +TP_RAW_IGV;IGV +TP_RAW_IMAGENUM;Po-slika +TP_RAW_IMAGENUM_SN;SN način +TP_RAW_IMAGENUM_TOOLTIP;Nekatere surove slike vsebujejo več podslik (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nKadar uporabljate katerokoli metodo razen pomika pikslov, to določa katera podslika bo uporabljena.\n\nKadar uporabiš pomik pikslov na surovi sliki, so uporabljene vse podslike in to določa, katera podslika naj bo uporabljena za gibajoče dele. +TP_RAW_LABEL;Odstranjevanje mozaičnosti +TP_RAW_LMMSE;LMMSE +TP_RAW_LMMSEITERATIONS;LMMSE koraki izboljševanja +TP_RAW_LMMSE_TOOLTIP;Dodaj gamo (korak 1), mediano (koraki 2-4) in izboljševanje (koraka 5-6) za zmanjševanje artefaktov in izboljšanje razmerja signal šum. +TP_RAW_MONO;Mono +TP_RAW_NONE;None (Prikaži vzorec senzorja) +TP_RAW_PIXELSHIFT;Pomik pikslov +TP_RAW_PIXELSHIFTBLUR;Zamegli maska gibanja +TP_RAW_PIXELSHIFTDMETHOD;Metoda Odstranjevanja mozaičnosti +TP_RAW_PIXELSHIFTEPERISO;Občutljivost +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;Privzeta vrednost 0 bi morala delovati za osnovni ISO.\nVišje vrednosti povečajo občutljivost za detekcijo gibanja.\nSpreminjajte počasi in opazujte masko gibanja.\nPovečajte občutljivost za podosvetljene slike ali slike z visokim ISO. +TP_RAW_PIXELSHIFTEQUALBRIGHT;Izenači svetlost okvirjev +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Izenači po kanalih +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Omogočeno: Izenači kanale RGB neodvisno.\nOnemogočeno: Uporabi enak faktor izenačevanja za vse kanale. +TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Izenači svetlost okvirjev svetlosti izbranega okvirja.\nČe obstajajo preosvetljeni deli okvirjev, izberite najsvetlejšega, da se izognete barvnemu tonu magente pri preosvetljenih delih ali da omogočite popravke gibanja. +TP_RAW_PIXELSHIFTGREEN;Preveri zeleni kanal za gibanje +TP_RAW_PIXELSHIFTHOLEFILL;Zapolni luknje v maski gibanja +TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Zapolni luknje v maski gibanja +TP_RAW_PIXELSHIFTMEDIAN;Uporabi mediano za gibajoče se dele +TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Uporabi mediano za vse okvirje namesto izbranega okvirja za dele z gibanjem.\nDaje efekt gibanja na počasi gibajočin (prekrivajočih se) predmetih. +TP_RAW_PIXELSHIFTMM_AUTO;Avtomatično +TP_RAW_PIXELSHIFTMM_CUSTOM;Po meri +TP_RAW_PIXELSHIFTMM_OFF;Izklopljeno +TP_RAW_PIXELSHIFTMOTIONMETHOD;Popravek gibanja +TP_RAW_PIXELSHIFTNONGREENCROSS;Preveri rdeč/moder kanal za gibanje +TP_RAW_PIXELSHIFTSHOWMOTION;Prikaži masko gibanja +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Prikaži samo masko gibanja +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Prikaže masko gibanja brez slike. +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Prekrij sliko z zeleno masko, ki prikazuje področja z gibanjem. +TP_RAW_PIXELSHIFTSIGMA;Radij zameglevanja +TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Privzet radij 1.0 običajno ustreza osnovnem ISO.\nVrednost povečajte za visok ISO, 5.0 je dobra začetna vrednost.\nOpazujte masko gibanja, ko spreminjate vrednost. +TP_RAW_PIXELSHIFTSMOOTH;Gladki prehodi +TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Gladki prehodi med področji z gibanjem in področji brez.\nPostavite na 1, da dobite rezultat AMaZE/LMMSE za izbran okvir (odvisno ali je izbran "Uporabi LMMSE") ali mediana za vse štiri okvire, če je izbran "Uporabi mediano". +TP_RAW_RCD;RCD +TP_RAW_RCDVNG4;RCD+VNG4 +TP_RAW_SENSOR_BAYER_LABEL;Senzor z matriko Bayer +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-prehodi daje boljše rezultate (priporočljivo za nizek ISO).\n1-prehod je komaj različen od 3-prehodov za visoke ISO slike in je hitrejši.\n+fast daje manj artefaktov v gladkih predelih +TP_RAW_SENSOR_XTRANS_LABEL;Senzor z matriko X-Trans +TP_RAW_VNG4;VNG4 +TP_RAW_XTRANS;X-Trans +TP_RAW_XTRANSFAST;Fast X-Trans +TP_RESIZE_ALLOW_UPSCALING;Dovoli povečavo +TP_RESIZE_APPLIESTO;Se nanaša na: +TP_RESIZE_CROPPEDAREA;Izrezano področje +TP_RESIZE_FITBOX;Bounding Box +TP_RESIZE_FULLIMAGE;Celotna slika +TP_RESIZE_H;Višina: +TP_RESIZE_HEIGHT;Višina +TP_RESIZE_LABEL;Spremeni velikost +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Najbližji +TP_RESIZE_SCALE;Merilo +TP_RESIZE_SPECIFY;Opiši: +TP_RESIZE_W;Širina: +TP_RESIZE_WIDTH;Širina +TP_RETINEX_CONTEDIT_HSL;HSL histogram +TP_RETINEX_CONTEDIT_LAB;L*a*b* histogram +TP_RETINEX_CONTEDIT_LH;Odtenek +TP_RETINEX_CONTEDIT_MAP;Izenačevalnik +TP_RETINEX_CURVEEDITOR_CD;L=f(L) +TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Svetlost glede na svetlost L=f(L)\nPopravi surove podatke, da zmanjšaš odboje in artefakte. +TP_RETINEX_CURVEEDITOR_LH;Moč=f(H) +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Moč glede na odtenek Moč=f(H)\nTa krivulja deluje tudi na barvitosti kadar uporabljamo metodo Retinex na bleščavah. +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;To krivuljo lahko uporabimo samo ali pa z Gaussovo masko ali masko valovčkov.\nPazite na artefakte! +TP_RETINEX_EQUAL;Izenačevalnik +TP_RETINEX_FREEGAMMA;Prosta gama +TP_RETINEX_GAIN;Ojačenje +TP_RETINEX_GAINOFFS;Ojačenje in odmik (svetlost) +TP_RETINEX_GAINTRANSMISSION;Prenos ojačenja +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Ojačaj ali oslabi prenosno funkcijo da dosežete željeno svetlost.\nOs x je prenos.\nOs y je ojačenje. +TP_RETINEX_GAMMA;Gama +TP_RETINEX_GAMMA_FREE;Prost +TP_RETINEX_GAMMA_HIGH;Visok +TP_RETINEX_GAMMA_LOW;Nizek +TP_RETINEX_GAMMA_MID;Srednji +TP_RETINEX_GAMMA_NONE;Nič +TP_RETINEX_GAMMA_TOOLTIP;Obnovi tone z uporabo game pred ali po Retinexu. Krivulje so drugačne od Retinexovih ali drugih (Lab, Ekspozicija, itd.). +TP_RETINEX_GRAD;Gradient prenosa +TP_RETINEX_GRADS;Moč gradienta +TP_RETINEX_GRADS_TOOLTIP;Če je drsnik na 0, so vse iteracije identične.\nČe je > 0 moč pojema pri vsaki iteraciji in obratno. +TP_RETINEX_GRAD_TOOLTIP;Če je drsnik na 0, so vse iteracije identične.\nČe je > 0 Varianca in Prag pojemata pri vsaki iteraciji in obratno. +TP_RETINEX_HIGH;Visoko +TP_RETINEX_HIGHLIG;Bleščava +TP_RETINEX_HIGHLIGHT;Prag bleščave +TP_RETINEX_HIGHLIGHT_TOOLTIP;Poveča aktivnosti visokega algoritma.\nMorda bo zahtevala prilagoditev "Sosednjih pikslov" in povečanje "Popravka bele točke" v orodju v zavihku Surove -> Orodju Surova Bela Točka. +TP_RETINEX_HSLSPACE_LIN;HSL-Linearno +TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmično +TP_RETINEX_ITER;Iteracije (Preslikava tonov) +TP_RETINEX_ITERF;Preslikava tonov +TP_RETINEX_ITER_TOOLTIP;Simuliraj operacijo preslikave tonov.\nVisoke vrednosti povečujejo čas obdelave. +TP_RETINEX_LABEL;Retinex +TP_RETINEX_LABEL_MASK;Maska +TP_RETINEX_LABSPACE;L*a*b* +TP_RETINEX_LOW;Nizko +TP_RETINEX_MAP;Metoda +TP_RETINEX_MAP_GAUS;Gaussova maska +TP_RETINEX_MAP_MAPP;Maska ostrenja (delni valovčki) +TP_RETINEX_MAP_MAPT;Maska ostrenja (popolni valovčki) +TP_RETINEX_MAP_METHOD_TOOLTIP;Uporabi masko, ki ga je generirala gornja Gaussova funkcija (Radin, Metoda) za zmanjševanja odbojev in artefaktov.\n\nSamo krivulja: uporabi diagonalni kontrast na maski.\nPazite na artefakte!\n\nGaussova maska: tvori in uporabi Gaussovo zameglitev izvorne maske.\nHitro.\n\nMaska ostrenja: tvori in uporabi valovčke na izvorni maski.\nPočasno. +TP_RETINEX_MAP_NONE;Nič +TP_RETINEX_MEDIAN;Fiter mediane prenosa +TP_RETINEX_METHOD;Metoda +TP_RETINEX_METHOD_TOOLTIP;Low = Ojačaj šibko svetlobo.\nEnakomerno = Izenači.\nVisoko = Ojačaj močno svetlobo.\nBleščave = Odstrani magento iz bleščav. +TP_RETINEX_MLABEL;Obnovi brez meglic Min=%1 Max=%2 +TP_RETINEX_MLABEL_TOOLTIP;Mora biti blizu min=0 max=32768\nObnovljena slika brez mešanja. +TP_RETINEX_NEIGHBOR;Radij +TP_RETINEX_NEUTRAL;Ponastavi +TP_RETINEX_NEUTRAL_TIP;Ponastavi vse drsnike in klrivulje na njihove privzete vrednosti. +TP_RETINEX_OFFSET;Odmik (svetlost) +TP_RETINEX_SCALES;Gaussov gradient +TP_RETINEX_SCALES_TOOLTIP;Če je drsnik na 0, so vse iteracije identične.\nČe je > 0 merilo in radij pojemata pri vsaki iteraciji in obratno. +TP_RETINEX_SETTINGS;Nastavitve +TP_RETINEX_SKAL;Merilo +TP_RETINEX_SLOPE;Prosta strmina game +TP_RETINEX_STRENGTH;Moč +TP_RETINEX_THRESHOLD;Prag +TP_RETINEX_THRESHOLD_TOOLTIP;Omejuje vhod/izhod.\nVhod = izvorna slika,\nIzhod = slika po Gaussu. +TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Povprečje=%3 Sigma=%4 +TP_RETINEX_TLABEL2;TM Tm=%1 TM=%2 +TP_RETINEX_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nMean and Sigma.\nTm=Min TM=Max of transmission map. +TP_RETINEX_TRANF;Prenos +TP_RETINEX_TRANSMISSION;Prenosna funkcija +TP_RETINEX_TRANSMISSION_TOOLTIP;Prenos glede na prenos.\nAbscisa: prenos negativnih vrednosti (min), povprečja, in pozitivnih vrednosti (max).\nOrdinata: ojačenje ali slabljenje. +TP_RETINEX_UNIFORM;Enakomerno +TP_RETINEX_VARIANCE;Kontrast +TP_RETINEX_VARIANCE_TOOLTIP;Nizka varianca povečuje lokalni kontrast in nasičenje, toda lahko tvori artefakte. +TP_RETINEX_VIEW;Obdelava +TP_RETINEX_VIEW_MASK;Maska +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standardno - Normalen prikaz.\nMaska - Prikazuje masko.\nNeostra maska - Prikaže sliko z neostro masko z velikim radijem.\nPrenos - Avto/Fiksno - Prikaže prenosno funkcijo pred kakršnimkoli posegom na kontrastu ali svetlosti.\n\nPozor: maska ni realistična, ampak je ojačana, da se bolje vidi. +TP_RETINEX_VIEW_NONE;Standardno +TP_RETINEX_VIEW_TRAN;Prenos - Avto +TP_RETINEX_VIEW_TRAN2;Prenos - Fiksno +TP_RETINEX_VIEW_UNSHARP;Neostra maska +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB krivulje +TP_RGBCURVES_LUMAMODE;Način svetilnosti +TP_RGBCURVES_LUMAMODE_TOOLTIP;Način svetilnosti dovoljuje spreminjanje prispevka kanalov R, G in B na svetlost slike, ne da bi spreminjali barve slike. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Stopnja +TP_ROTATE_LABEL;Zavrti +TP_ROTATE_SELECTLINE;Izberi ravno črto +TP_SAVEDIALOG_OK_TIP;Bližnjica: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Bleščave +TP_SHADOWSHLIGHTS_HLTONALW;Tonska širina bleščav +TP_SHADOWSHLIGHTS_LABEL;Sence/bleščave +TP_SHADOWSHLIGHTS_RADIUS;Radij +TP_SHADOWSHLIGHTS_SHADOWS;Sence +TP_SHADOWSHLIGHTS_SHTONALW;Tonska širina senc +TP_SHARPENEDGE_AMOUNT;Količina +TP_SHARPENEDGE_LABEL;Robovi +TP_SHARPENEDGE_PASSES;Iteracij +TP_SHARPENEDGE_THREE;Samo svetlost +TP_SHARPENING_AMOUNT;Količina +TP_SHARPENING_BLUR;Radij zamegljevanja +TP_SHARPENING_CONTRAST;Prag kontrasta +TP_SHARPENING_EDRADIUS;Radij +TP_SHARPENING_EDTOLERANCE;Toleranca robov +TP_SHARPENING_GAMMA;Gama +TP_SHARPENING_HALOCONTROL;Kontrola odbojev +TP_SHARPENING_HCAMOUNT;Količina +TP_SHARPENING_LABEL;Ostrenje +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Naostri samo robove +TP_SHARPENING_RADIUS;Radij +TP_SHARPENING_RADIUS_BOOST;Povečanje polmera vogala +TP_SHARPENING_RLD;RL Dekonvolucija +TP_SHARPENING_RLD_AMOUNT;Količina +TP_SHARPENING_RLD_DAMPING;Blaženje +TP_SHARPENING_RLD_ITERATIONS;Iteracij +TP_SHARPENING_THRESHOLD;Prag +TP_SHARPENING_USM;Neostra maska +TP_SHARPENMICRO_AMOUNT;Količina +TP_SHARPENMICRO_CONTRAST;Prag kontrasta +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;3×3 matrika namesto 5×5 +TP_SHARPENMICRO_UNIFORMITY;Enakomernost +TP_SOFTLIGHT_LABEL;Mehka svetloba +TP_SOFTLIGHT_STRENGTH;Moč +TP_TM_FATTAL_AMOUNT;Količina +TP_TM_FATTAL_ANCHOR;Sidro +TP_TM_FATTAL_LABEL;Kompresija dinamičnega obsega +TP_TM_FATTAL_THRESHOLD;Podrobnost +TP_VIBRANCE_AVOIDCOLORSHIFT;Izogibaj se pomiku barve +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Kožni toni +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;rdeča/rožnata +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;rdeča +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;rdeča/rumena +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;rumena +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Odtenek glede na odtenek H=f(H) +TP_VIBRANCE_LABEL;Živost +TP_VIBRANCE_PASTELS;Pastelni toni +TP_VIBRANCE_PASTSATTOG;Poveži pastelne in nasičene tone +TP_VIBRANCE_PROTECTSKINS;Zaščiti kožne tone +TP_VIBRANCE_PSTHRESHOLD;Prag pastelnih/nasičenih tonov +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Prag nasičenja +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Navpična os predstavlja pestelne tone spodaj in nasičene tone na vrhu.\nVodoravna os predstavlja obseg nasičenja. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Utež prenosa pastelno/nasičeno +TP_VIBRANCE_SATURATED;Nasičeni toni +TP_VIGNETTING_AMOUNT;Količina +TP_VIGNETTING_CENTER;Center +TP_VIGNETTING_CENTER_X;Center X +TP_VIGNETTING_CENTER_Y;Center Y +TP_VIGNETTING_LABEL;Popravek vinjetiranja +TP_VIGNETTING_RADIUS;Radij +TP_VIGNETTING_STRENGTH;Moč +TP_WAVELET_1;Nivo 1 +TP_WAVELET_2;Nivo 2 +TP_WAVELET_3;Nivo 3 +TP_WAVELET_4;Nivo 4 +TP_WAVELET_5;Nivo 5 +TP_WAVELET_6;Nivo 6 +TP_WAVELET_7;Nivo 7 +TP_WAVELET_8;Nivo 8 +TP_WAVELET_9;Nivo 9 +TP_WAVELET_APPLYTO;Uporabi na +TP_WAVELET_AVOID;Izogibaj se pomiku barv +TP_WAVELET_B0;Črna +TP_WAVELET_B1;Siva +TP_WAVELET_B2;Preostanek +TP_WAVELET_BACKGROUND;Ozadje +TP_WAVELET_BACUR;Krivulja +TP_WAVELET_BALANCE;Ravnotežje kontrasta d/v-h +TP_WAVELET_BALANCE_TOOLTIP;Spremeni ravnotežje med smermi valovčkov: navpično-vodoravno in diagonalno.\nČe so omogočeni kontrast, barvitost ali preostali prenos tonov, je učinek ojačan. +TP_WAVELET_BALCHRO;Ravnotežje barvitosti +TP_WAVELET_BALCHRO_TOOLTIP;Če je omogočen potem krivulja ravnotežja kontrasta ali drsnik tudi spreminja ravnotežje barvitosti. +TP_WAVELET_BANONE;Nič +TP_WAVELET_BASLI;Drsnik +TP_WAVELET_BATYPE;Metoda ravnotežja kontrasta +TP_WAVELET_CBENAB;Ravnotežje tonov in barve +TP_WAVELET_CB_TOOLTIP;Za močne vrednosti barvno toniranje izdelka, če ga kombinirate ali ne s stopnjami razkroja 'toniranje'\nZa nizke vrednosti lahko spremenite ravnovesje beline v ozadju (nebo, ...), ne da bi spremenili stanje sprednje ravnine, na splošno bolj kontrastno +TP_WAVELET_CCURVE;Lokalni kontrast +TP_WAVELET_CH1;Obseg vse barvitosti +TP_WAVELET_CH2;Nasičena/pastelna +TP_WAVELET_CH3;Nivoji povezav kontrastov +TP_WAVELET_CHCU;Krivulja +TP_WAVELET_CHR;Moč povezave barvitosti in kontrasta +TP_WAVELET_CHRO;Prag nasičenja/pastelnosti +TP_WAVELET_CHRO_TOOLTIP;Nastavi nivo valovčkov, ki določa prag med nasičenimi in pastelnimi barvami.\n1-x: nasičene\nx-9: pastelne\n\nČe vrednost presega štvilo nivojev valovčkov, ki jih uporabljate, vrednost zanemarimo. +TP_WAVELET_CHR_TOOLTIP;Prilagodi barvitost kot funkcijo "nivojev kontrasta" in "moč povezave barvitost-kontrast" +TP_WAVELET_CHSL;Drsniki +TP_WAVELET_CHTYPE;Metoda krominance +TP_WAVELET_COLORT;Neprosojnost rdeče-zelene +TP_WAVELET_COMPCONT;Kontrast +TP_WAVELET_COMPGAMMA;Stiskanje game +TP_WAVELET_COMPGAMMA_TOOLTIP;Prilagoditev game preostanka slike dovoljuje uravnoteženje podatkov in histograma. +TP_WAVELET_COMPTM;Prenosna funkcija tonov +TP_WAVELET_CONTEDIT;Krivulja kontrasta "Po" +TP_WAVELET_CONTR;Barvni obseg +TP_WAVELET_CONTRA;Kontrast +TP_WAVELET_CONTRAST_MINUS;Kontrast - +TP_WAVELET_CONTRAST_PLUS;Kontrast + +TP_WAVELET_CONTRA_TOOLTIP;Spremeni kontrast preostanka slike. +TP_WAVELET_CTYPE;Kontrola krominance +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Spremeni lokalni kontrast kot funkcijo izvirnega lokalnega kontrasta (abscisa).\nSpodnje vrednosti na abscisi predstavljajo majhne izvirne lokalne kontraste (vrednosti med 100 in 300).\n66% na abscisi predstavlja standardno deviacijo lokalnih kontrastov (vrednosti med 300 in 800)\n100% na abscisi pa predstavlja maksimalne lokalne kontraste (vrednosti med 3000 in 8000). +TP_WAVELET_CURVEEDITOR_CH;Kontrast nivoji=f(Odtenek) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Spremeni kontrast vsake stopnje kot funkcijo odtenka.\nPazite, da ne boste prepisali sprememb, izvedenih s krmilnimi odtenki podorodja Gamut.\nKrivulja bo imela učinek le, če so drsniki na ravni valovnih kontrastov brez ničle. +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Uporabi končno krivuljo svetilnosti kontrasta na koncu obdelave z valovčki. +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Spremeni odtenek preostale slike kot funkcijo odtenka. +TP_WAVELET_DALL;Vse smeri +TP_WAVELET_DAUB;Performance robov +TP_WAVELET_DAUB2;D2 - nizko +TP_WAVELET_DAUB4;D4 - standard +TP_WAVELET_DAUB6;D6 - standard plus +TP_WAVELET_DAUB10;D10 - srednje +TP_WAVELET_DAUB14;D14 - visoko +TP_WAVELET_DAUB_TOOLTIP;Spremeni Daubechiesove koeficiente:\nD4 = Standardno,\nD14 = Pogosto najboljše, 10% bolj časovno zahetvno.\n\nVpliva na razpoznavanje robov kot tudi splošno kakovost prvih nivojev. Kljub temu splošna kakovost ni strogo odvisna od tega koeficienta in se lahko spremeni v odvisnosti od slik in uporabe. +TP_WAVELET_DONE;Navpično +TP_WAVELET_DTHR;Diagonalno +TP_WAVELET_DTWO;Vodoravno +TP_WAVELET_EDCU;Krivulja +TP_WAVELET_EDGCONT;Lokalni kontrast +TP_WAVELET_EDGCONT_TOOLTIP;Prilagoditev točk na levi zmanjšuje kontrast in na desni ga povečuje.\nSpodaj-levo, zgoraj-levo, zgoraj-desno in spodaj-desno predstavljajo lokalni kontrast za nizke vrednosti, povprečje, povprečje+stdev in maximum. +TP_WAVELET_EDGE;Ostrina roba +TP_WAVELET_EDGEAMPLI;Osnovno ojačenje +TP_WAVELET_EDGEDETECT;Gradient občutljivosti +TP_WAVELET_EDGEDETECTTHR;Spodnji prag (šum) +TP_WAVELET_EDGEDETECTTHR2;Zgornji prag (občutljivost) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Ta prilagojevalnik omogoča ciljno detekcijo robov za izogibanje ostrine robov na finih podrobnostih kot npr. šum na nebu. +TP_WAVELET_EDGEDETECT_TOOLTIP;Pomik drsnika na desno poveča občutljivost za robove. To vpliva na lokalni kontrast, nastavitve robov in šum. +TP_WAVELET_EDGESENSI;Rob občutljivosti +TP_WAVELET_EDGREINF_TOOLTIP;Ojači ali zmanjšaj vpliv prvega nivoja, nasprotni vpliv drugega nivoja, preostalo pusti nespremenjeno. +TP_WAVELET_EDGTHRESH;Podrobnost +TP_WAVELET_EDGTHRESH_TOOLTIP;Spremeni ponovne delitve med prvim nivojem in ostalimi. Višji kot je prag, več aktivnosti je osredotočeno na prve nivoje.Bodite previdni z negativnimi vrednostmi, ki povečaujejo aktivnosti visokih nivojev in lahko povzročajo artefakte. +TP_WAVELET_EDRAD;Radij +TP_WAVELET_EDRAD_TOOLTIP;Ta prilagoditev radija je bistveno drugačna kot pri drugih orodij ostrenja. Vrednost radija se primerja prek kompleksne funkcije z drugimi nivoji. Tako ima tudi vrednost 0 vpliv. +TP_WAVELET_EDSL;Prag drsnikov +TP_WAVELET_EDTYPE;Metoda Lokalnega kontrasta +TP_WAVELET_EDVAL;Moč +TP_WAVELET_FINAL;Končni poseg +TP_WAVELET_FINEST;Najbolj fino +TP_WAVELET_HIGHLIGHT;Obseg svetlosti bleščav +TP_WAVELET_HS1;Celotni obseg svetlosti +TP_WAVELET_HS2;Sence/bleščave +TP_WAVELET_HUESKIN;Kožni odtenek +TP_WAVELET_HUESKIN_TOOLTIP;Spodnje točke določajo začetek cone sprememb, zgornje točke pa konec, kjer so spremembe najmočnejše.\n\nČe morate področje bistveno premakniti ali pa se pojavljajo artefakti, potem je ravnotežje beline napačno. +TP_WAVELET_HUESKY;Odtenek neba +TP_WAVELET_HUESKY_TOOLTIP;Spodnje točke določajo začetek cone sprememb, zgornje točke pa konec, kjer so spremembe najmočnejše.\n\nČe morate področje bistveno premakniti ali pa se pojavljajo artefakti, potem je ravnotežje beline napačno. +TP_WAVELET_ITER;Nivoji ravnotežja Delta +TP_WAVELET_ITER_TOOLTIP;Levo: povečajne spodnje nivoje in zmanjšajte visoke nivoje,\nDesno: zmanjšajte nizke nivoje in povečajte visoke nivoje. +TP_WAVELET_LABEL;Nivoji valovčkov +TP_WAVELET_LARGEST;Najbolj grobo +TP_WAVELET_LEVCH;Barvitost +TP_WAVELET_LEVDIR_ALL;Vsi nivoji v vseh smereh +TP_WAVELET_LEVDIR_INF;Pod ali enako nivoju +TP_WAVELET_LEVDIR_ONE;En nivo +TP_WAVELET_LEVDIR_SUP;Nad nivojem +TP_WAVELET_LEVELS;Nivoji valovčkov +TP_WAVELET_LEVELS_TOOLTIP;Izberi število nivojev podrobnosti slike, ki naj se razdeli. Več nivojev zahteva več RAMa in več časa obdelovanja. +TP_WAVELET_LEVF;Kontrast +TP_WAVELET_LEVLABEL;Predogled največ možnih nivojev = %1 +TP_WAVELET_LEVONE;Nivo 2 +TP_WAVELET_LEVTHRE;Nivo 4 +TP_WAVELET_LEVTWO;Nivo 3 +TP_WAVELET_LEVZERO;Nivo 1 +TP_WAVELET_LINKEDG;Povežo z močjo ostrine robov +TP_WAVELET_LIPST;Izboljšan algoritem +TP_WAVELET_LOWLIGHT;Obseg svetlosti senc +TP_WAVELET_MEDGREINF;Prvi nivo +TP_WAVELET_MEDI;Odstrani artefakte na modrem nebu +TP_WAVELET_MEDILEV;Detekcija roba +TP_WAVELET_MEDILEV_TOOLTIP;Kadar omogočite detekcijo robov, priporočamo:\n- onemogočanje nizkih nivojev kontrasta za izogibanje artefaktom,\n- uporabo visokih vrednosti gradienta občutljivosti.\n\nMoč lahko nastavljate z izboljšavo od 'Odstranjevanja šuma' do 'Olepševanja'. +TP_WAVELET_NEUTRAL;Nevtralno +TP_WAVELET_NOIS;Odstrani šum +TP_WAVELET_NOISE;Odstrani šum in izpopolni +TP_WAVELET_NPHIGH;Visoko +TP_WAVELET_NPLOW;Nizko +TP_WAVELET_NPNONE;Nič +TP_WAVELET_NPTYPE;Sosednji piksli +TP_WAVELET_NPTYPE_TOOLTIP;Ta algoritem uporablja bližino piksla in osem njegovih sosedov. Če je majhna razlika, so robovi ojačeni. +TP_WAVELET_OPACITY;Neprosojnost modra-rumena +TP_WAVELET_OPACITYW;Krivulja ravnotežja kontrasta d/v-h +TP_WAVELET_OPACITYWL;Končni lokalni kontrast +TP_WAVELET_OPACITYWL_TOOLTIP;Spremeni končni lokalni kontrast ob koncu obdelave z valovčki\n\nLeva stran predstavlja najmanjši lokalni kontrast, ki se povečuje in doseže največji kontrast na desni strani. +TP_WAVELET_PASTEL;Pastelna barvitost +TP_WAVELET_PROC;Obdelaj +TP_WAVELET_RE1;Ojačeno +TP_WAVELET_RE2;Nespremenjeno +TP_WAVELET_RE3;Oslabljeno +TP_WAVELET_RESCHRO;Barvitost +TP_WAVELET_RESCON;Sence +TP_WAVELET_RESCONH;Bleščave +TP_WAVELET_RESID;Preostanek slike +TP_WAVELET_SAT;Nasičena barvitost +TP_WAVELET_SETTINGS;Nastavitev valovčkov +TP_WAVELET_SKIN;Ciljna zaščita kože +TP_WAVELET_SKIN_TOOLTIP;Pri -100 so odtenki kože ciljani.\nPri 0 so vsi toni obravnavani enako.\nPri +100 so kožni toni zaščiteni, vsi ostali pa spremenjeni. +TP_WAVELET_SKY;Ciljna zaščita neba +TP_WAVELET_SKY_TOOLTIP;Pri -100 so odtenki neba ciljani.\nPri 0 so vsi toni obravnavani enako.\nPri +100 so toni neba zaščiteni, vsi ostali pa spremenjeni. +TP_WAVELET_STREN;Moč +TP_WAVELET_STRENGTH;Moč +TP_WAVELET_SUPE;Ekstra +TP_WAVELET_THR;Prag senc +TP_WAVELET_THRESHOLD;Nivoji bleščav +TP_WAVELET_THRESHOLD2;Nivoji bleščav +TP_WAVELET_THRESHOLD2_TOOLTIP;Sprememba svetlosti v sencah bo samo na nivojih od 9 do 9 minus vrednost. Ostali nivoji bodo obdelani. Najvišji možni nivo je omejen z nivojem bleščav (9 minus nivo bleščav). +TP_WAVELET_THRESHOLD_TOOLTIP;Vpliv obsega lumninance bo samo na nivojih nad izbrano vrednostjo. Vsi ostali nivoji bodo obdelani. Izbrana vrednost omejuje najvišji možni nivo v sencah. +TP_WAVELET_THRH;Prag bleščav +TP_WAVELET_TILESBIG;Velike krpe +TP_WAVELET_TILESFULL;Celotna slika +TP_WAVELET_TILESIZE;Metoda pokrivanja +TP_WAVELET_TILESLIT;Majhne krpe +TP_WAVELET_TILES_TOOLTIP;Obdelava celotne slike zagotavlja boljšo kakovost in jo priporočamo, medtem ko je uporaba krp rezervna možnost za uporabnike z malo RAMa. Poglejte v RawPedio za potrebe po pomnilniku. +TP_WAVELET_TMSTRENGTH;Compression strength +TP_WAVELET_TMSTRENGTH_TOOLTIP;Upravlja z močjo tonske preslikave ali stiskanja kontrasta preostanka slike. Kadar je vrednost različna od 0, potem sta drsnika za moč in gamo posivela in onemogočena. +TP_WAVELET_TMTYPE;Metode stiskanja +TP_WAVELET_TON;Toniranje +TP_WBALANCE_AUTO;Avto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Oblačno +TP_WBALANCE_CUSTOM;Po meri +TP_WBALANCE_DAYLIGHT;Dnevna svetloba (sončno) +TP_WBALANCE_EQBLUERED;Izenačevalnik modro/rdeče +TP_WBALANCE_EQBLUERED_TOOLTIP;Dovoljuje drugačno obnašanje od običajnega "uravnoteževanja beline" z urejanjem ravnotežja med rdečo in modro.\nTo je uporabno, kadar so pogoji snemanja:\na) daleč od običajnih pogojev osvetlitve (npr. pod vodo)\nb) so daleč od pogojev, kjer so bile izvedene nastavitve,\nc) ali, kjer so matrike ali ICC profili neprimerni. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Bliskavica +TP_WBALANCE_FLUO1;F1 - Dnevna svetloba +TP_WBALANCE_FLUO2;F2 - Hladna bela +TP_WBALANCE_FLUO3;F3 - Bela +TP_WBALANCE_FLUO4;F4 - Topla bela +TP_WBALANCE_FLUO5;F5 - Dnevna svetloba +TP_WBALANCE_FLUO6;F6 - Svetla bela +TP_WBALANCE_FLUO7;F7 - D65 Simulator dnevne svetlobe +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - De luxe hladna bela +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent +TP_WBALANCE_GREEN;Odtenek +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Uravnoteženje beline +TP_WBALANCE_LAMP_HEADER;Žarnica +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_PICKER;Poberi +TP_WBALANCE_SHADE;Senca +TP_WBALANCE_SIZE;Velikost: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Uporabi pipeto za pridobivanje ravnotežne beline iz nevtralnega dela slike v predogledu. +TP_WBALANCE_TEMPBIAS;AWB pristranost temperature +TP_WBALANCE_TEMPBIAS_TOOLTIP;Dovoljuje spremenjen izračun "avtomatičnega ravnotežja beline"\nz spremembo proti toplejšemu ali hladnejšemu spektru. \nPristranost je izražena z odstotkom od izračunane temperature\ntako da je rezultat izražen z "izračunanaTemp + izračunanaTemp * pristranost". +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungsten +TP_WBALANCE_WATER1;Podvodna 1 +TP_WBALANCE_WATER2;Podvodna 2 +TP_WBALANCE_WATER_HEADER;Pod vodo +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Odpri (novo) okno s podrobnostmi +ZOOMPANEL_ZOOM100;Zoom do 100%\nBližnjica: z +ZOOMPANEL_ZOOMFITCROPSCREEN;Prilagodi izrez zaslonu\nBližnjica: f +ZOOMPANEL_ZOOMFITSCREEN;Prilagodi celotno sliko zaslonu\nBližnjica: Alt-f +ZOOMPANEL_ZOOMIN;Zoom In\nBližnjica: + +ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations +!TP_SHARPENING_ITERCHECK;Auto limit iterations diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 220339a45..7861f2276 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -698,8 +698,8 @@ MAIN_TOOLTIP_BACKCOLOR1;Bakgrundsfärg: Svart\nKortkommando: 9 MAIN_TOOLTIP_BACKCOLOR2;Bakgrundsfärg: Vit\nKortkommando: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Lås / Lås upp före-vyn\n\nLås: behåll före-vyn oförändrad.\nAnvändbart för att utvärdera den sammanlagda effekten av flera stegs redigering. Dessutom kan jämförelser göras gentemot varje annat steg i historiken.\n\nLås upp: Före-vyn kommer hela tiden visa ett tidigare steg jämfört med efter-vyn, och visar därmed effekten av det verktyg som användes senast. MAIN_TOOLTIP_HIDEHP;Visa/göm den vänstra panelen. Kortkommando: l -MAIN_TOOLTIP_INDCLIPPEDH;Markera högdagerindikation.\nKortkommando: < -MAIN_TOOLTIP_INDCLIPPEDS;Markera skuggindikation.\nKortkommando: > +MAIN_TOOLTIP_INDCLIPPEDH;Markera högdagerindikation.\nKortkommando: > +MAIN_TOOLTIP_INDCLIPPEDS;Markera skuggindikation.\nKortkommando: < MAIN_TOOLTIP_PREVIEWB;Förhandsgranska den blå kanalen.\nGenväg: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Förhandsgranska fokusmasken.\nKortkommando: Shift-f\n\nNoggrannare på bilder med kort skärpedjup, lågt brus och där en hög zoom-grad är vald.\n\nFör att förbättra detekteringen för brusiga bilder, utvärdera vid en zoom-grad om 10-30%\n\nFörhandsvisningen görs långsammare med fokusmasken påslagen. MAIN_TOOLTIP_PREVIEWG;Förhandsgranska den gröna kanalen.\nGenväg: g @@ -1842,6 +1842,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_491;White Balance !HISTORY_MSG_492;RGB Curves !HISTORY_MSG_493;L*a*b* Adjustments +!HISTORY_MSG_494;Capture Sharpening !HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors !HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction !HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1859,6 +1860,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth !HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +!HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only !HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1879,6 +1881,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +!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 !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2100,6 +2109,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_CROP_SELECTCROP;Select !TP_DEHAZE_DEPTH;Depth !TP_DEHAZE_LABEL;Haze Removal +!TP_DEHAZE_LUMINANCE;Luminance only !TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map !TP_DEHAZE_STRENGTH;Strength !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -2122,12 +2132,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!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_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_PICK;Pick neutral spots !TP_FILMNEGATIVE_RED;Red ratio !TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only available if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table @@ -2157,6 +2167,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_METADATA_MODE;Metadata copy mode !TP_METADATA_STRIP;Strip all metadata !TP_METADATA_TUNNEL;Copy unchanged +!TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PREPROCESS_LINEDENOISE_DIRECTION;Direction !TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both !TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontal @@ -2246,6 +2257,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Normal display.\nMask - Displays the mask.\nUnsharp mask - Displays the image with a high radius unsharp mask.\nTransmission - Auto/Fixed - Displays the file transmission-map, before any action on contrast and brightness.\n\nAttention: the mask does not correspond to reality, but is amplified to make it more visible. !TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_CONTRAST;Contrast threshold +!TP_SHARPENING_ITERCHECK;Auto limit iterations +!TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SHARPENMICRO_CONTRAST;Contrast threshold !TP_SOFTLIGHT_LABEL;Soft Light !TP_SOFTLIGHT_STRENGTH;Strength diff --git a/rtdata/languages/default b/rtdata/languages/default index 912abca3b..e0e65ea0c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -744,6 +744,7 @@ HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -764,12 +765,13 @@ HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold -HISTORY_MSG_PDSHARPEN_CONTRAST;CAS - Contrast threshold -HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CAS - Auto threshold -HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CAS - Auto radius -HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma -HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations -HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius +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 HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -780,7 +782,6 @@ HISTORY_MSG_RAW_BORDER;Raw border HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold -HISTORY_MSG_SHARPENING_GAMMA;Sharpening - Gamma HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength @@ -938,8 +939,8 @@ MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: white\nShortcut: MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l -MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: < -MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: > +MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: < MAIN_TOOLTIP_PREVIEWB;Preview the blue channel.\nShortcut: b MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the focus mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\nZoom out to 10-30% to improve detection accuracy on noisy images. MAIN_TOOLTIP_PREVIEWG;Preview the green channel.\nShortcut: g @@ -1540,6 +1541,7 @@ TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Threshold TP_DEHAZE_DEPTH;Depth TP_DEHAZE_LABEL;Haze Removal +TP_DEHAZE_LUMINANCE;Luminance only TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map TP_DEHAZE_STRENGTH;Strength TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones @@ -1650,9 +1652,9 @@ TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points TP_EXPOS_WHITEPOINT_LABEL;Raw White Points TP_FILMNEGATIVE_BLUE;Blue ratio TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +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_LABEL;Film Negative -TP_FILMNEGATIVE_PICK;Pick white and black spots +TP_FILMNEGATIVE_PICK;Pick neutral spots TP_FILMNEGATIVE_RED;Red ratio TP_FILMSIMULATION_LABEL;Film Simulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? @@ -1666,7 +1668,7 @@ TP_FLATFIELD_BT_HORIZONTAL;Horizontal TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal TP_FLATFIELD_BT_VERTICAL;Vertical TP_FLATFIELD_CLIPCONTROL;Clip control -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. TP_FLATFIELD_LABEL;Flat-Field TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. TP_GRADIENT_CENTER;Center @@ -1803,7 +1805,6 @@ TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse, TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). TP_PDSHARPENING_LABEL;Capture Sharpening -TP_PDSHARPENING_AUTORADIUS_TOOLTIP;If the checkbox is checked, RawTherapee calculates a value based on the raw data of the image. TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_VERTICAL;Vertical @@ -2032,13 +2033,14 @@ TP_SHARPENING_BLUR;Blur radius TP_SHARPENING_CONTRAST;Contrast threshold TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance -TP_SHARPENING_GAMMA;Gamma TP_SHARPENING_HALOCONTROL;Halo control TP_SHARPENING_HCAMOUNT;Amount +TP_SHARPENING_ITERCHECK;Auto limit iterations TP_SHARPENING_LABEL;Sharpening TP_SHARPENING_METHOD;Method TP_SHARPENING_ONLYEDGES;Sharpen only edges TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RADIUS_BOOST;Corner radius boost TP_SHARPENING_RLD;RL Deconvolution TP_SHARPENING_RLD_AMOUNT;Amount TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index 1d2f9faac..580390b28 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index 11c5da4c8..58e0a5604 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index a4a767bf4..a54e021b1 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 index 882c0130f..c94077b21 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 @@ -21,3 +21,6 @@ DCPIlluminant=0 [RAW] CA=true + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 index 5587b19e0..286b5a289 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 @@ -1,18 +1,8 @@ [Sharpening] -Enabled=true -Contrast=5 -Method=rld -DeconvRadius=0.75 -DeconvAmount=100 -DeconvDamping=0 -DeconvIterations=30 +Enabled=false [SharpenMicro] -Enabled=true -Contrast=15 -Matrix=false -Strength=20 -Uniformity=5 +Enabled=false [RAW] CA=true @@ -38,3 +28,6 @@ pixelShiftBlur=true pixelShiftSmoothFactor=0.69999999999999996 pixelShiftLmmse=false pixelShiftNonGreenCross=true + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 index f1d889f97..0975251e2 100644 --- a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 +++ b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 @@ -1,18 +1,8 @@ [Sharpening] -Enabled=true -Contrast=5 -Method=rld -DeconvRadius=0.75 -DeconvAmount=100 -DeconvDamping=0 -DeconvIterations=30 +Enabled=false [SharpenMicro] -Enabled=true -Contrast=15 -Matrix=false -Strength=20 -Uniformity=5 +Enabled=false [RAW] CA=true @@ -22,3 +12,6 @@ Method=pixelshift PixelShiftMotion=0 PixelShiftMotionCorrection=5 PixelShiftMotionCorrectionMethod=0 + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 index c23b5b8a4..45fcca730 100644 --- a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 @@ -23,3 +23,6 @@ DCPIlluminant=0 [RAW] CA=true + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/rawtherapee.desktop.in b/rtdata/rawtherapee.desktop.in index 233a737b6..f6bc3afeb 100644 --- a/rtdata/rawtherapee.desktop.in +++ b/rtdata/rawtherapee.desktop.in @@ -2,7 +2,7 @@ Type=Application Version=1.0 Name=RawTherapee -GenericName=Raw photo editor +GenericName=Raw Photo Editor GenericName[cs]=Editor raw obrázků GenericName[fr]=Éditeur d'images raw GenericName[pl]=Edytor zdjęć raw @@ -11,9 +11,11 @@ Comment[cs]=Program pro konverzi a zpracování digitálních raw fotografií Comment[fr]=Logiciel de conversion et de traitement de photos numériques de format raw (but de capteur) Comment[pl]=Zaawansowany program do wywoływania zdjęć typu raw Icon=rawtherapee +TryExec=rawtherapee Exec=rawtherapee %f Terminal=false MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-hasselblad-3fr;image/x-hasselblad-fff;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-leaf-mos;image/x-leica-rwl;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-phaseone-iiq;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sigma-x3f;image/x-sony-arq;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-tif; -Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK; -Keywords=raw;photography;develop;pp3;graphics; +Categories=Graphics;Photography;2DGraphics;RasterGraphics;GTK; +Keywords=raw;photo;photography;develop;pp3;graphics; +StartupNotify=true StartupWMClass=rawtherapee diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index 3f5072f48..a5f52a769 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -640,11 +640,11 @@ spinbutton entry { } spinbutton button { margin: 0; - padding: 0; - border-radius: 0; + padding: 0; + border-radius: 0; } spinbutton button.up { - border-radius: 0 0.16666666666666666666em 0.16666666666666666666em 0; + border-radius: 0 0.16666666666666666666em 0.16666666666666666666em 0; } entry:disabled, spinbutton:disabled { @@ -841,7 +841,7 @@ flowboxchild:selected { color: #CCCCCC; padding: 0; margin: 0 0.25em 0 0.25em; - font-size: 1.1em; + font-size: 1.1em; } #MyExpanderTitle:hover { background-color: #202020; @@ -955,7 +955,7 @@ fontchooser scrolledwindow, } #PlacesPaned { - margin: 0; + margin: 0; padding: 0 0.4166666666666666em 0 0; } #PlacesPaned > box:nth-child(1) scrolledwindow + grid { @@ -1050,7 +1050,7 @@ dialog frame > label:not(.dummy) { #LabelRightNotebook { padding: 0.4166666666666666em; margin: 0.1666666666666666em; - font-size: 1.25em; + font-size: 1.25em; } #ToolPanelNotebook { diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css index 58742e8ca..f4bec23b1 100644 --- a/rtdata/themes/RawTherapee-GTK3-_19.css +++ b/rtdata/themes/RawTherapee-GTK3-_19.css @@ -46,7 +46,7 @@ GtkBox { border-style: none; border-radius: 0; margin: 0; - padding: 0; + padding: 0; } GtkGrid { diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index a2d68402f..4dc2019c1 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -28,6 +28,14 @@ #include "gauss.h" #include "median.h" #include "StopWatch.h" + +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} +} + namespace { bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) @@ -106,10 +114,6 @@ bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) //end of linear equation solver } -namespace rtengine { - extern const Settings* settings; -} - using namespace std; using namespace rtengine; @@ -138,6 +142,7 @@ float* RawImageSource::CA_correct_RT( } // multithreaded and vectorized by Ingo Weyrich + const unsigned int cfa[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; constexpr int ts = 128; constexpr int tsh = ts / 2; constexpr int cb = 2; // 2 pixels border will be excluded from correction @@ -148,7 +153,7 @@ float* RawImageSource::CA_correct_RT( // Test for RGB cfa for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { - if (FC(i, j) == 3) { + if (fc(cfa, i, j) == 3) { std::cout << "CA correction supports only RGB Colour filter arrays" << std::endl; return buffer; } @@ -167,7 +172,7 @@ float* RawImageSource::CA_correct_RT( #pragma omp parallel for #endif for (int i = cb; i < H - cb; ++i) { - for (int j = cb + (FC(i, 0) & 1); j < W - cb; j += 2) { + for (int j = cb + (fc(cfa, i, 0) & 1); j < W - cb; j += 2) { (*oldraw)[i - cb][(j - cb) / 2] = rawData[i][j]; } } @@ -198,7 +203,7 @@ float* RawImageSource::CA_correct_RT( //block CA shift values and weight assigned to block float* const blockwt = buffer + (height * width); - memset(blockwt, 0, vblsz * hblsz * (2 * 2 + 1) * sizeof(float)); + memset(blockwt, 0, static_cast(vblsz) * hblsz * (2 * 2 + 1) * sizeof(float)); float (*blockshifts)[2][2] = (float (*)[2][2])(blockwt + vblsz * hblsz); // Because we can't break parallel processing, we need a switch do handle the errors @@ -320,12 +325,12 @@ float* RawImageSource::CA_correct_RT( int cc = ccmin; int col = cc + left; #ifdef __SSE2__ - int c0 = FC(rr, cc); + int c0 = fc(cfa, rr, cc); if (c0 == 1) { rgb[c0][rr * ts + cc] = rawData[row][col] / 65535.f; cc++; col++; - c0 = FC(rr, cc); + c0 = fc(cfa, rr, cc); } int indx1 = rr * ts + cc; for (; cc < ccmax - 7; cc+=8, col+=8, indx1 += 8) { @@ -338,7 +343,7 @@ float* RawImageSource::CA_correct_RT( } #endif for (; cc < ccmax; cc++, col++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); int indx1 = rr * ts + cc; rgb[c][indx1 >> ((c & 1) ^ 1)] = rawData[row][col] / 65535.f; } @@ -348,7 +353,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0) { for (int rr = 0; rr < border; rr++) { for (int cc = ccmin; cc < ccmax; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][((border2 - rr) * ts + cc) >> ((c & 1) ^ 1)]; } } @@ -357,7 +362,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1) { for (int rr = 0; rr < border; rr++) { for (int cc = ccmin; cc < ccmax; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][left + cc] / 65535.f; } } @@ -366,7 +371,7 @@ float* RawImageSource::CA_correct_RT( if (ccmin > 0) { for (int rr = rrmin; rr < rrmax; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][(rr * ts + border2 - cc) >> ((c & 1) ^ 1)]; } } @@ -375,7 +380,7 @@ float* RawImageSource::CA_correct_RT( if (ccmax < cc1) { for (int rr = rrmin; rr < rrmax; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(top + rr)][(width - cc - 2)] / 65535.f; } } @@ -385,7 +390,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0 && ccmin > 0) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rawData[border2 - rr][border2 - cc] / 65535.f; } } @@ -394,7 +399,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1 && ccmax < cc1) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][(width - cc - 2)] / 65535.f; } } @@ -403,7 +408,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0 && ccmax < cc1) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(border2 - rr)][(width - cc - 2)] / 65535.f; } } @@ -412,7 +417,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1 && ccmin > 0) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][(border2 - cc)] / 65535.f; } } @@ -427,9 +432,9 @@ float* RawImageSource::CA_correct_RT( #endif for (int rr = 3; rr < rr1 - 3; rr++) { int row = rr + top; - int cc = 3 + (FC(rr,3) & 1); + int cc = 3 + (fc(cfa, rr,3) & 1); int indx = rr * ts + cc; - int c = FC(rr,cc); + int c = fc(cfa, rr,cc); #ifdef __SSE2__ for (; cc < cc1 - 9; cc+=8, indx+=8) { //compute directional weights using image gradients @@ -463,7 +468,7 @@ float* RawImageSource::CA_correct_RT( } if (row > -1 && row < height) { - int offset = (FC(row,max(left + 3, 0)) & 1); + int offset = (fc(cfa, row,max(left + 3, 0)) & 1); int col = max(left + 3, 0) + offset; int indx = rr * ts + 3 - (left < 0 ? (left+3) : 0) + offset; #ifdef __SSE2__ @@ -481,9 +486,9 @@ float* RawImageSource::CA_correct_RT( vfloat zd25v = F2V(0.25f); #endif for (int rr = 4; rr < rr1 - 4; rr++) { - int cc = 4 + (FC(rr, 2) & 1); + int cc = 4 + (fc(cfa, rr, 2) & 1); int indx = rr * ts + cc; - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); #ifdef __SSE2__ for (; cc < cc1 - 10; cc += 8, indx += 8) { vfloat rgb1v = LC2VFU(rgb[1][indx]); @@ -547,9 +552,9 @@ float* RawImageSource::CA_correct_RT( // along line segments, find the point along each segment that minimizes the colour variance // averaged over the tile; evaluate for up/down and left/right away from R/B grid point for (int rr = 8; rr < rr1 - 8; rr++) { - int cc = 8 + (FC(rr, 2) & 1); + int cc = 8 + (fc(cfa, rr, 2) & 1); int indx = rr * ts + cc; - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); #ifdef __SSE2__ vfloat coeff00v = ZEROV; vfloat coeff01v = ZEROV; @@ -871,14 +876,14 @@ float* RawImageSource::CA_correct_RT( int indx = row * width + col; int indx1 = rr * ts + cc; #ifdef __SSE2__ - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); if (c & 1) { rgb[1][indx1] = rawData[row][col] / 65535.f; indx++; indx1++; cc++; col++; - c = FC(rr, cc); + c = fc(cfa, rr, cc); } for (; cc < ccmax - 7; cc += 8, col += 8, indx += 8, indx1 += 8) { vfloat val1v = LVFU(rawData[row][col]) / c65535v; @@ -890,7 +895,7 @@ float* RawImageSource::CA_correct_RT( } #endif for (; cc < ccmax; cc++, col++, indx++, indx1++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][indx1 >> ((c & 1) ^ 1)] = rawData[row][col] / 65535.f; if ((c & 1) == 0) { @@ -903,7 +908,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0) { for (int rr = 0; rr < border; rr++) { for (int cc = ccmin; cc < ccmax; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][((border2 - rr) * ts + cc) >> ((c & 1) ^ 1)]; rgb[1][rr * ts + cc] = rgb[1][(border2 - rr) * ts + cc]; } @@ -913,7 +918,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1) { for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) { for (int cc = ccmin; cc < ccmax; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][left + cc]) / 65535.f; if ((c & 1) == 0) { rgb[1][(rrmax + rr)*ts + cc] = Gtmp[((height - rr - 2) * width + left + cc) >> 1]; @@ -925,7 +930,7 @@ float* RawImageSource::CA_correct_RT( if (ccmin > 0) { for (int rr = rrmin; rr < rrmax; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][(rr * ts + border2 - cc) >> ((c & 1) ^ 1)]; rgb[1][rr * ts + cc] = rgb[1][rr * ts + border2 - cc]; } @@ -935,7 +940,7 @@ float* RawImageSource::CA_correct_RT( if (ccmax < cc1) { for (int rr = rrmin; rr < rrmax; rr++) { for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(top + rr)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { rgb[1][rr * ts + ccmax + cc] = Gtmp[((top + rr) * width + (width - cc - 2)) >> 1]; @@ -948,7 +953,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0 && ccmin > 0) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = (rawData[border2 - rr][border2 - cc]) / 65535.f; if ((c & 1) == 0) { rgb[1][rr * ts + cc] = Gtmp[((border2 - rr) * width + border2 - cc) >> 1]; @@ -960,7 +965,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1 && ccmax < cc1) { for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) { for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { rgb[1][(rrmax + rr)*ts + ccmax + cc] = Gtmp[((height - rr - 2) * width + (width - cc - 2)) >> 1]; @@ -972,7 +977,7 @@ float* RawImageSource::CA_correct_RT( if (rrmin > 0 && ccmax < cc1) { for (int rr = 0; rr < border; rr++) { for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(border2 - rr)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { rgb[1][rr * ts + ccmax + cc] = Gtmp[((border2 - rr) * width + (width - cc - 2)) >> 1]; @@ -984,7 +989,7 @@ float* RawImageSource::CA_correct_RT( if (rrmax < rr1 && ccmin > 0) { for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) { for (int cc = 0; cc < border; cc++) { - int c = FC(rr, cc); + int c = fc(cfa, rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(border2 - cc)]) / 65535.f; if ((c & 1) == 0) { rgb[1][(rrmax + rr)*ts + cc] = Gtmp[((height - rr - 2) * width + (border2 - cc)) >> 1]; @@ -1001,7 +1006,7 @@ float* RawImageSource::CA_correct_RT( #endif //manual CA correction; use red/blue slider values to set CA shift parameters for (int rr = 3; rr < rr1 - 3; rr++) { - int cc = 3 + FC(rr, 1), c = FC(rr,cc), indx = rr * ts + cc; + int cc = 3 + fc(cfa, rr, 1), c = fc(cfa, rr,cc), indx = rr * ts + cc; #ifdef __SSE2__ for (; cc < cc1 - 10; cc += 8, indx += 8) { //compute directional weights using image gradients @@ -1082,8 +1087,8 @@ float* RawImageSource::CA_correct_RT( } for (int rr = 4; rr < rr1 - 4; rr++) { - int cc = 4 + (FC(rr, 2) & 1); - int c = FC(rr, cc); + int cc = 4 + (fc(cfa, rr, 2) & 1); + int c = fc(cfa, rr, cc); int indx = (rr * ts + cc) >> 1; int indxfc = (rr + shiftvfloor[c]) * ts + cc + shifthceil[c]; int indxff = (rr + shiftvfloor[c]) * ts + cc + shifthfloor[c]; @@ -1132,8 +1137,8 @@ float* RawImageSource::CA_correct_RT( vfloat epsv = F2V(eps); #endif for (int rr = 8; rr < rr1 - 8; rr++) { - int cc = 8 + (FC(rr, 2) & 1); - int c = FC(rr, cc); + int cc = 8 + (fc(cfa, rr, 2) & 1); + int c = fc(cfa, rr, cc); int GRBdir0 = GRBdir[0][c]; int GRBdir1 = GRBdir[1][c]; #ifdef __SSE2__ @@ -1170,7 +1175,7 @@ float* RawImageSource::CA_correct_RT( STVFU(rgb[c][indx >> 1], RBint); } #endif - for (int c = FC(rr, cc), indx = rr * ts + cc; cc < cc1 - 8; cc += 2, indx += 2) { + for (int c = fc(cfa, rr, cc), indx = rr * ts + cc; cc < cc1 - 8; cc += 2, indx += 2) { float grbdiffold = rgb[1][indx] - rgb[c][indx >> 1]; //interpolate colour difference from optical R/B locations to grid locations @@ -1212,9 +1217,9 @@ float* RawImageSource::CA_correct_RT( // copy CA corrected results to temporary image matrix for (int rr = border; rr < rr1 - border; rr++) { - int c = FC(rr + top, left + border + (FC(rr + top, 2) & 1)); + int c = fc(cfa, rr + top, left + border + (fc(cfa, rr + top, 2) & 1)); int row = rr + top; - int cc = border + (FC(rr, 2) & 1); + int cc = border + (fc(cfa, rr, 2) & 1); int indx = (row * width + cc + left) >> 1; int indx1 = (rr * ts + cc) >> 1; #ifdef __SSE2__ @@ -1249,7 +1254,7 @@ float* RawImageSource::CA_correct_RT( #endif for (int row = cb; row < height - cb; row++) { - int col = cb + (FC(row, 0) & 1); + int col = cb + (fc(cfa, row, 0) & 1); int indx = (row * width + col) >> 1; #ifdef __SSE2__ for (; col < width - 7 - cb; col += 8, indx += 4) { @@ -1284,8 +1289,8 @@ float* RawImageSource::CA_correct_RT( #pragma omp for #endif for (int i = 0; i < H - 2 * cb; ++i) { - const int firstCol = FC(i, 0) & 1; - const int colour = FC(i, firstCol); + const int firstCol = fc(cfa, i, 0) & 1; + const int colour = fc(cfa, i, firstCol); const array2D* nonGreen = colour == 0 ? redFactor : blueFactor; int j = firstCol; #ifdef __SSE2__ @@ -1317,9 +1322,9 @@ float* RawImageSource::CA_correct_RT( if (W % 2) { // odd width => factors for one channel are not set in last column => use value of preceding column - const int ngRow = 1 - (FC(0, 0) & 1); - const int ngCol = FC(ngRow, 0) & 1; - const int colour = FC(ngRow, ngCol); + const int ngRow = 1 - (fc(cfa, 0, 0) & 1); + const int ngCol = fc(cfa, ngRow, 0) & 1; + const int colour = fc(cfa, ngRow, ngCol); const array2D* nonGreen = colour == 0 ? redFactor : blueFactor; for (int i = 0; i < (H + 1 - 2 * cb) / 2; ++i) { (*nonGreen)[i][(W - 2 * cb + 1) / 2 - 1] = (*nonGreen)[i][(W - 2* cb + 1) / 2 - 2]; @@ -1336,8 +1341,8 @@ float* RawImageSource::CA_correct_RT( #pragma omp for #endif for (int i = 0; i < H - 2 * cb; ++i) { - const int firstCol = FC(i, 0) & 1; - const int colour = FC(i, firstCol); + const int firstCol = fc(cfa, i, 0) & 1; + const int colour = fc(cfa, i, firstCol); const array2D* nonGreen = colour == 0 ? redFactor : blueFactor; for (int j = firstCol; j < W - 2 * cb; j += 2) { rawData[i + cb][j + cb] *= (*nonGreen)[i / 2][j / 2]; diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 89d7208f0..844cb8e75 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -11,7 +11,7 @@ include_directories(${EXTRA_INCDIR} ${LCMS_INCLUDE_DIRS} ${LENSFUN_INCLUDE_DIRS} ${RSVG_INCLUDE_DIRS} - ) +) link_directories("${PROJECT_SOURCE_DIR}/rtexif" ${EXPAT_LIBRARY_DIRS} @@ -25,26 +25,25 @@ link_directories("${PROJECT_SOURCE_DIR}/rtexif" ${LCMS_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS} ${RSVG_LIBRARY_DIRS} - ) +) set(CAMCONSTSFILE "camconst.json") set(RTENGINESOURCEFILES - badpixels.cc - CA_correct_RT.cc - capturesharpening.cc - EdgePreservingDecomposition.cc - FTblockDN.cc - PF_correct_RT.cc - ahd_demosaic_RT.cc alpha.cc + ahd_demosaic_RT.cc amaze_demosaic_RT.cc - cJSON.c + badpixels.cc + boxblur.cc + canon_cr3_decoder.cc + CA_correct_RT.cc calc_distort.cc camconst.cc + capturesharpening.cc cfa_linedn_RT.cc ciecam02.cc cieimage.cc + cJSON.c clutstore.cc color.cc colortemp.cc @@ -61,14 +60,19 @@ set(RTENGINESOURCEFILES dual_demosaic_RT.cc dynamicprofile.cc eahd_demosaic.cc + EdgePreservingDecomposition.cc fast_demo.cc ffmanager.cc filmnegativeproc.cc filmnegativethumb.cc flatcurves.cc + FTblockDN.cc + gamutwarning.cc gauss.cc green_equil_RT.cc + guidedfilter.cc hilite_recon.cc + histmatching.cc hphd_demosaic_RT.cc iccjpeg.cc iccstore.cc @@ -83,62 +87,52 @@ set(RTENGINESOURCEFILES improcfun.cc impulse_denoise.cc init.cc + ipdehaze.cc iplab2rgb.cc + iplabregions.cc + iplocalcontrast.cc ipresize.cc ipretinex.cc + ipshadowshighlights.cc ipsharpen.cc + ipsoftlight.cc iptransform.cc ipvibrance.cc ipwavelet.cc jdatasrc.cc jpeg_ijg/jpeg_memsrc.cc - klt/convolve.cc - klt/error.cc - klt/klt.cc - klt/klt_util.cc - klt/pnmio.cc - klt/pyramid.cc - klt/selectGoodFeatures.cc - klt/storeFeatures.cc - klt/trackFeatures.cc - klt/writeFeatures.cc labimage.cc lcp.cc + lj92.c + lmmse_demosaic.cc loadinitial.cc myfile.cc + panasonic_decoders.cc + pdaflinesfilter.cc + PF_correct_RT.cc pipettebuffer.cc pixelshift.cc previewimage.cc processingjob.cc procparams.cc profilestore.cc + rawflatfield.cc rawimage.cc rawimagesource.cc rcd_demosaic.cc refreshmap.cc rt_algo.cc + rtlensfun.cc rtthumbnail.cc shmap.cc simpleprocess.cc - slicer.cc spot.cc stdimagesource.cc - utils.cc - rtlensfun.cc tmo_fattal02.cc - iplocalcontrast.cc - histmatching.cc - pdaflinesfilter.cc - gamutwarning.cc - ipshadowshighlights.cc - xtrans_demosaic.cc + utils.cc vng4_demosaic_RT.cc - ipsoftlight.cc - guidedfilter.cc - ipdehaze.cc - iplabregions.cc - lj92.c - ) + xtrans_demosaic.cc +) if(LENSFUN_HAS_LOAD_DIRECTORY) set_source_files_properties(rtlensfun.cc PROPERTIES COMPILE_DEFINITIONS RT_LENSFUN_HAS_LOAD_DIRECTORY) @@ -152,21 +146,22 @@ if(NOT WITH_SYSTEM_KLT) set(RTENGINESOURCEFILES ${RTENGINESOURCEFILES} klt/convolve.cc klt/error.cc - klt/klt.cc klt/klt_util.cc + klt/klt.cc klt/pnmio.cc klt/pyramid.cc klt/selectGoodFeatures.cc klt/storeFeatures.cc klt/trackFeatures.cc klt/writeFeatures.cc - ) + ) set(KLT_LIBRARIES) endif() include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") -add_library(rtengine ${RTENGINESOURCEFILES}) +add_library(rtengine STATIC ${RTENGINESOURCEFILES}) + add_dependencies(rtengine UpdateInfo) # It may be nice to store library version too @@ -192,6 +187,6 @@ target_link_libraries(rtengine rtexif ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} - ) +) install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 85b7ce243..700181e1d 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -4,8 +4,7 @@ #ifdef _OPENMP #include #endif -#include "sleef.c" -#include "opthelper.h" +#include "sleef.h" #define DIAGONALS 5 #define DIAGONALSP1 6 diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index d1e659114..121c8189d 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -23,25 +23,34 @@ //////////////////////////////////////////////////////////////// #include + #include -#include "../rtgui/threadutils.h" -#include "rtengine.h" -#include "improcfun.h" -#include "LUT.h" + #include "array2D.h" -#include "iccmatrices.h" #include "boxblur.h" -#include "rt_math.h" -#include "mytime.h" -#include "sleef.c" -#include "opthelper.h" #include "cplx_wavelet_dec.h" -#include "median.h" +#include "color.h" +#include "curves.h" +#include "iccmatrices.h" #include "iccstore.h" +#include "imagefloat.h" +#include "improcfun.h" +#include "labimage.h" +#include "LUT.h" +#include "median.h" +#include "mytime.h" +#include "opthelper.h" #include "procparams.h" +#include "rt_math.h" +#include "sleef.h" + +#include "../rtgui/threadutils.h" +#include "../rtgui/options.h" + #ifdef _OPENMP #include #endif + //#define BENCHMARK #include "StopWatch.h" @@ -69,11 +78,7 @@ namespace rtengine */ -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -extern const Settings* settings; extern MyMutex *fftwMutex; @@ -479,6 +484,7 @@ enum nrquality {QUALITY_STANDARD, QUALITY_HIGH}; void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi) { BENCHFUN + //#ifdef _DEBUG MyTime t1e, t2e; t1e.set(); @@ -687,8 +693,8 @@ BENCHFUN } } - int tilesize; - int overlap; + int tilesize = 0; + int overlap = 0; if (settings->leveldnti == 0) { tilesize = 1024; @@ -1341,8 +1347,6 @@ BENCHFUN #ifdef _OPENMP int masterThread = omp_get_thread_num(); -#endif -#ifdef _OPENMP #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { @@ -1351,11 +1355,9 @@ BENCHFUN #else int subThread = 0; #endif - float blurbuffer[TS * TS] ALIGNED64; float *Lblox = LbloxArray[subThread]; float *fLblox = fLbloxArray[subThread]; float pBuf[width + TS + 2 * blkrad * offset] ALIGNED16; - float nbrwt[TS * TS] ALIGNED64; #ifdef _OPENMP #pragma omp for #endif @@ -1430,7 +1432,7 @@ BENCHFUN for (int hblk = 0; hblk < numblox_W; ++hblk) { - RGBtile_denoise(fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer); + RGBtile_denoise(fLblox, hblk, noisevar_Ldetail); }//end of horizontal block loop //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1447,14 +1449,8 @@ BENCHFUN //add row of blocks to output image tile RGBoutput_tile_row(Lblox, Ldetail, tilemask_out, height, width, topproc); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - }//end of vertical block loop - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef _OPENMP #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) @@ -1603,9 +1599,9 @@ BENCHFUN Color::Lab2RGBLimit(labdn->L[i1], labdn->a[i1], labdn->b[i1], labdn->L[i1], labdn->a[i1], labdn->b[i1], wip, 9000000.f, 1.f + qhighFactor * realred, 1.f + qhighFactor * realblue, width); for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; - float r_ = labdn->L[i1][j1]; - float g_ = labdn->a[i1][j1]; - float b_ = labdn->b[i1][j1]; + float r_ = std::max(0.f, labdn->L[i1][j1]); + float g_ = std::max(0.f, labdn->a[i1][j1]); + float b_ = std::max(0.f, labdn->b[i1][j1]); //inverse gamma standard (slider) r_ = r_ < 32768.f ? igamcurve[r_] : (Color::gammanf(r_ / 32768.f, igam) * 65535.f); g_ = g_ < 32768.f ? igamcurve[g_] : (Color::gammanf(g_ / 32768.f, igam) * 65535.f); @@ -2041,26 +2037,20 @@ BENCHFUN }//end of main RGB_denoise - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -void ImProcFunctions::RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer) //for DCT +void ImProcFunctions::RGBtile_denoise(float* fLblox, int hblproc, float noisevar_Ldetail) //for DCT { - int blkstart = hblproc * TS * TS; + float nbrwt[TS * TS] ALIGNED64; + const int blkstart = hblproc * TS * TS; - boxabsblur(fLblox + blkstart, nbrwt, 3, 3, TS, TS, blurbuffer); //blur neighbor weights for more robust estimation //for DCT + boxabsblur(fLblox + blkstart, nbrwt, 3, TS, TS, false); //blur neighbor weights for more robust estimation //for DCT #ifdef __SSE2__ - __m128 tempv; - __m128 noisevar_Ldetailv = _mm_set1_ps(noisevar_Ldetail); - __m128 onev = _mm_set1_ps(1.0f); + const vfloat noisevar_Ldetailv = F2V(-1.f / noisevar_Ldetail); + const vfloat onev = F2V(1.f); for (int n = 0; n < TS * TS; n += 4) { //for DCT - tempv = onev - xexpf(-SQRV(LVF(nbrwt[n])) / noisevar_Ldetailv); - _mm_storeu_ps(&fLblox[blkstart + n], LVFU(fLblox[blkstart + n]) * tempv); + const vfloat tempv = onev - xexpf(SQRV(LVF(nbrwt[n])) * noisevar_Ldetailv); + STVF(fLblox[blkstart + n], LVF(fLblox[blkstart + n]) * tempv); }//output neighbor averaged result #else @@ -2071,14 +2061,7 @@ void ImProcFunctions::RGBtile_denoise(float * fLblox, int hblproc, float noiseva #endif - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //printf("vblk=%d hlk=%d wsqave=%f || ",vblproc,hblproc,wsqave); - -}//end of function tile_denoise - - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +} void ImProcFunctions::RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top) { @@ -2207,7 +2190,7 @@ void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeff chmaxresid = maxresid; } -bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) +bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) { int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; @@ -2258,23 +2241,22 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &Wavelet //simple wavelet shrinkage float * sfave = buffer[0] + 32; float * sfaved = buffer[2] + 96; - float * blurBuffer = buffer[1] + 64; float mad_Lr = madL[lvl][dir - 1]; float levelFactor = mad_Lr * 5.f / (lvl + 1); #ifdef __SSE2__ - __m128 mad_Lv; - __m128 ninev = _mm_set1_ps(9.0f); - __m128 epsv = _mm_set1_ps(eps); - __m128 mag_Lv; - __m128 levelFactorv = _mm_set1_ps(levelFactor); + vfloat mad_Lv; + vfloat ninev = F2V(9.0f); + vfloat epsv = F2V(eps); + vfloat mag_Lv; + vfloat levelFactorv = F2V(levelFactor); int coeffloc_L; for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) { mad_Lv = LVFU(noisevarlum[coeffloc_L]) * levelFactorv; mag_Lv = SQRV(LVFU(WavCoeffs_L[dir][coeffloc_L])); - _mm_storeu_ps(&sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv)); + STVFU(sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv)); } for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { @@ -2294,15 +2276,15 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &Wavelet } #endif - boxblur(sfave, sfaved, blurBuffer, lvl + 2, lvl + 2, Wlvl_L, Hlvl_L); //increase smoothness by locally averaging shrinkage + boxblur(sfave, sfaved, lvl + 2, Wlvl_L, Hlvl_L, false); //increase smoothness by locally averaging shrinkage #ifdef __SSE2__ - __m128 sfavev; - __m128 sf_Lv; + vfloat sfavev; + vfloat sf_Lv; for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) { sfavev = LVFU(sfaved[coeffloc_L]); sf_Lv = LVFU(sfave[coeffloc_L]); - _mm_storeu_ps(&WavCoeffs_L[dir][coeffloc_L], LVFU(WavCoeffs_L[dir][coeffloc_L]) * (SQRV(sfavev) + SQRV(sf_Lv)) / (sfavev + sf_Lv + epsv)); + STVFU(WavCoeffs_L[dir][coeffloc_L], LVFU(WavCoeffs_L[dir][coeffloc_L]) * (SQRV(sfavev) + SQRV(sf_Lv)) / (sfavev + sf_Lv + epsv)); //use smoothed shrinkage unless local shrinkage is much less } @@ -2340,7 +2322,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &Wavelet return (!memoryAllocationFailed); } -bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, +bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) { int maxlvl = WaveletCoeffs_L.maxlevel(); @@ -2422,12 +2404,12 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &Wavele if (noisevar_ab > 0.001f) { #ifdef __SSE2__ - __m128 onev = _mm_set1_ps(1.f); - __m128 mad_abrv = _mm_set1_ps(mad_abr); - __m128 rmad_Lm9v = onev / _mm_set1_ps(mad_Lr * 9.f); - __m128 mad_abv; - __m128 mag_Lv, mag_abv; - __m128 tempabv; + vfloat onev = F2V(1.f); + vfloat mad_abrv = F2V(mad_abr); + vfloat rmad_Lm9v = onev / F2V(mad_Lr * 9.f); + vfloat mad_abv; + vfloat mag_Lv, mag_abv; + vfloat tempabv; int coeffloc_ab; for (coeffloc_ab = 0; coeffloc_ab < Hlvl_ab * Wlvl_ab - 3; coeffloc_ab += 4) { @@ -2437,7 +2419,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &Wavele mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); mag_abv = SQRV(tempabv); mag_Lv = SQRV(mag_Lv) * rmad_Lm9v; - _mm_storeu_ps(&WavCoeffs_ab[dir][coeffloc_ab], tempabv * SQRV((onev - xexpf(-(mag_abv / mad_abv) - (mag_Lv))))); + STVFU(WavCoeffs_ab[dir][coeffloc_ab], tempabv * SQRV((onev - xexpf(-(mag_abv / mad_abv) - (mag_Lv))))); } // few remaining pixels @@ -2470,9 +2452,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &Wavele } for (int i = 2; i >= 0; i--) { - if (buffer[i] != nullptr) { - delete[] buffer[i]; - } + delete[] buffer[i]; } } @@ -2480,7 +2460,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &Wavele } -bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge)//mod JD +bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge)//mod JD { @@ -2530,16 +2510,14 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, } for (int i = 3; i >= 0; i--) { - if (buffer[i] != nullptr) { - delete[] buffer[i]; - } + delete[] buffer[i]; } } return (!memoryAllocationFailed); } -bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, +bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb)//mod JD { @@ -2596,7 +2574,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, +void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge) { @@ -2607,12 +2585,12 @@ void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float * float * sfaved = buffer[1] + 64; float * blurBuffer = buffer[2] + 96; - int W_L = WaveletCoeffs_L.level_W(level); - int H_L = WaveletCoeffs_L.level_H(level); + const int W_L = WaveletCoeffs_L.level_W(level); + const int H_L = WaveletCoeffs_L.level_H(level); float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); -// printf("OK lev=%d\n",level); - float mad_L = madL[dir - 1] ; + const float mad_L = madL[dir - 1] ; + const float levelFactor = mad_L * 5.f / static_cast(level + 1); if (edge == 1 && vari) { noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer @@ -2622,71 +2600,45 @@ void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float * } } - float levelFactor = mad_L * 5.f / static_cast(level + 1); + int i = 0; #ifdef __SSE2__ - __m128 magv; - __m128 levelFactorv = _mm_set1_ps(levelFactor); - __m128 mad_Lv; - __m128 ninev = _mm_set1_ps(9.0f); - __m128 epsv = _mm_set1_ps(eps); - int i; + const vfloat levelFactorv = F2V(levelFactor); + const vfloat ninev = F2V(9.f); + const vfloat epsv = F2V(eps); - for (i = 0; i < W_L * H_L - 3; i += 4) { - mad_Lv = LVFU(noisevarlum[i]) * levelFactorv; - magv = SQRV(LVFU(WavCoeffs_L[dir][i])); - _mm_storeu_ps(&sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); + for (; i < W_L * H_L - 3; i += 4) { + const vfloat mad_Lv = LVFU(noisevarlum[i]) * levelFactorv; + const vfloat magv = SQRV(LVFU(WavCoeffs_L[dir][i])); + STVFU(sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); } - +#endif // few remaining pixels for (; i < W_L * H_L; ++i) { - float mag = SQR(WavCoeffs_L[dir][i]); + const float mag = SQR(WavCoeffs_L[dir][i]); sfave[i] = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); } -#else - - for (int i = 0; i < W_L * H_L; ++i) { - - float mag = SQR(WavCoeffs_L[dir][i]); - float shrinkfactor = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); - sfave[i] = shrinkfactor; - } - -#endif - boxblur(sfave, sfaved, blurBuffer, level + 2, level + 2, W_L, H_L); //increase smoothness by locally averaging shrinkage + boxblur(sfave, sfaved, level + 2, W_L, H_L, false); //increase smoothness by locally averaging shrinkage + i = 0; #ifdef __SSE2__ - __m128 sfv; - for (i = 0; i < W_L * H_L - 3; i += 4) { - sfv = LVFU(sfave[i]); + for (; i < W_L * H_L - 3; i += 4) { + const vfloat sfv = LVFU(sfave[i]); //use smoothed shrinkage unless local shrinkage is much less - _mm_storeu_ps(&WavCoeffs_L[dir][i], _mm_loadu_ps(&WavCoeffs_L[dir][i]) * (SQRV(LVFU(sfaved[i])) + SQRV(sfv)) / (LVFU(sfaved[i]) + sfv + epsv)); + STVFU(WavCoeffs_L[dir][i], LVFU(WavCoeffs_L[dir][i]) * (SQRV(LVFU(sfaved[i])) + SQRV(sfv)) / (LVFU(sfaved[i]) + sfv + epsv)); } - +#endif // few remaining pixels for (; i < W_L * H_L; ++i) { - float sf = sfave[i]; - + const float sf = sfave[i]; //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][i] *= (SQR(sfaved[i]) + SQR(sf)) / (sfaved[i] + sf + eps); }//now luminance coefficients are denoised - -#else - - for (int i = 0; i < W_L * H_L; ++i) { - float sf = sfave[i]; - - //use smoothed shrinkage unless local shrinkage is much less - WavCoeffs_L[dir][i] *= (SQR(sfaved[i]) + SQR(sf)) / (sfaved[i] + sf + eps); - - }//now luminance coefficients are denoised - -#endif } -void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, +void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab, bool madCalculated) @@ -2700,7 +2652,6 @@ void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavele float * sfaveab = buffer[0] + 32; float * sfaveabd = buffer[1] + 64; - float * blurBuffer = buffer[2] + 96; int W_ab = WaveletCoeffs_ab.level_W(level); int H_ab = WaveletCoeffs_ab.level_H(level); @@ -2724,12 +2675,12 @@ void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavele if (noisevar_ab > 0.001f) { madab = useNoiseCCurve ? madab : madab * noisevar_ab; #ifdef __SSE2__ - __m128 onev = _mm_set1_ps(1.f); - __m128 mad_abrv = _mm_set1_ps(madab); + vfloat onev = F2V(1.f); + vfloat mad_abrv = F2V(madab); - __m128 rmadLm9v = onev / _mm_set1_ps(mad_L * 9.f); - __m128 mad_abv ; - __m128 mag_Lv, mag_abv; + vfloat rmadLm9v = onev / F2V(mad_L * 9.f); + vfloat mad_abv ; + vfloat mag_Lv, mag_abv; int coeffloc_ab; for (coeffloc_ab = 0; coeffloc_ab < H_ab * W_ab - 3; coeffloc_ab += 4) { @@ -2738,7 +2689,7 @@ void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavele mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); mag_abv = SQRV(LVFU(WavCoeffs_ab[dir][coeffloc_ab])); mag_Lv = (SQRV(mag_Lv)) * rmadLm9v; - _mm_storeu_ps(&sfaveab[coeffloc_ab], (onev - xexpf(-(mag_abv / mad_abv) - (mag_Lv)))); + STVFU(sfaveab[coeffloc_ab], (onev - xexpf(-(mag_abv / mad_abv) - (mag_Lv)))); } // few remaining pixels @@ -2761,18 +2712,18 @@ void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavele #endif - boxblur(sfaveab, sfaveabd, blurBuffer, level + 2, level + 2, W_ab, H_ab); //increase smoothness by locally averaging shrinkage + boxblur(sfaveab, sfaveabd, level + 2, W_ab, H_ab, false); //increase smoothness by locally averaging shrinkage #ifdef __SSE2__ - __m128 epsv = _mm_set1_ps(eps); - __m128 sfabv; - __m128 sfaveabv; + vfloat epsv = F2V(eps); + vfloat sfabv; + vfloat sfaveabv; for (coeffloc_ab = 0; coeffloc_ab < H_ab * W_ab - 3; coeffloc_ab += 4) { sfabv = LVFU(sfaveab[coeffloc_ab]); sfaveabv = LVFU(sfaveabd[coeffloc_ab]); //use smoothed shrinkage unless local shrinkage is much less - _mm_storeu_ps(&WavCoeffs_ab[dir][coeffloc_ab], LVFU(WavCoeffs_ab[dir][coeffloc_ab]) * (SQRV(sfaveabv) + SQRV(sfabv)) / (sfaveabv + sfabv + epsv)); + STVFU(WavCoeffs_ab[dir][coeffloc_ab], LVFU(WavCoeffs_ab[dir][coeffloc_ab]) * (SQRV(sfaveabv) + SQRV(sfabv)) / (sfaveabv + sfabv + epsv)); } // few remaining pixels @@ -2919,8 +2870,8 @@ void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, } -void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, +void ImProcFunctions::WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, + const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb) { @@ -3106,7 +3057,7 @@ void ImProcFunctions::calcautodn_info(float &chaut, float &delta, int Nb, int le } -void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread) +void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread) { if ((settings->leveldnautsimpl == 1 && dnparams.Cmethod == "MAN") || (settings->leveldnautsimpl == 0 && dnparams.C2method == "MANU")) { //nothing to do @@ -3173,8 +3124,8 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const float gain = pow(2.0f, float(expcomp)); - int tilesize; - int overlap; + int tilesize = 0; + int overlap = 0; if (settings->leveldnti == 0) { tilesize = 1024; @@ -3275,16 +3226,16 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, for (int i = tiletop; i < tilebottom; i += 2) { int i1 = i - tiletop; #ifdef __SSE2__ - __m128 aNv, bNv; - __m128 c100v = _mm_set1_ps(100.f); + vfloat aNv, bNv; + vfloat c100v = F2V(100.f); int j; for (j = tileleft; j < tileright - 7; j += 8) { int j1 = j - tileleft; aNv = LVFU(acalc[i >> 1][j >> 1]); bNv = LVFU(bcalc[i >> 1][j >> 1]); - _mm_storeu_ps(&noisevarhue[i1 >> 1][j1 >> 1], xatan2f(bNv, aNv)); - _mm_storeu_ps(&noisevarchrom[i1 >> 1][j1 >> 1], vmaxf(vsqrtf(SQRV(aNv) + SQRV(bNv)),c100v)); + STVFU(noisevarhue[i1 >> 1][j1 >> 1], xatan2f(bNv, aNv)); + STVFU(noisevarchrom[i1 >> 1][j1 >> 1], vmaxf(vsqrtf(SQRV(aNv) + SQRV(bNv)),c100v)); } for (; j < tileright; j += 2) { diff --git a/rtengine/LUT.h b/rtengine/LUT.h index 34f572f58..a80e5996d 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -56,21 +56,18 @@ * LUTuc stands for LUT */ -#ifndef LUT_H_ -#define LUT_H_ +#pragma once #include #include #include #ifndef NDEBUG -#include #include #endif #include "opthelper.h" #include "rt_math.h" -#include "noncopyable.h" // Bit representations of flags enum { @@ -485,26 +482,6 @@ public: return (p1 + p2 * diff); } -#ifndef NDEBUG - // Debug facility ; dump the content of the LUT in a file. No control of the filename is done - void dump(Glib::ustring fname) - { - if (size) { - Glib::ustring fname_ = fname + ".xyz"; // TopSolid'Design "plot" file format - std::ofstream f (fname_.c_str()); - f << "$" << std::endl; - - for (unsigned int iter = 0; iter < size; iter++) { - f << iter << ", " << data[iter] << ", 0." << std::endl; - } - - f << "$" << std::endl; - f.close (); - } - } -#endif - - operator bool (void) const { return size > 0; @@ -649,5 +626,3 @@ public: }; - -#endif /* LUT_H_ */ diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index 7df042663..9a95b8e2f 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -29,8 +29,12 @@ #include "gauss.h" #include "improcfun.h" -#include "sleef.c" -#include "../rtgui/myflatcurve.h" +#include "cieimage.h" +#include "color.h" +#include "curves.h" +#include "labimage.h" +#include "sleef.h" +#include "curves.h" #include "rt_math.h" #include "opthelper.h" #include "median.h" diff --git a/rtengine/ahd_demosaic_RT.cc b/rtengine/ahd_demosaic_RT.cc index b3a34295c..064dfd6e1 100644 --- a/rtengine/ahd_demosaic_RT.cc +++ b/rtengine/ahd_demosaic_RT.cc @@ -27,12 +27,17 @@ #include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" -#include "procparams.h" #include "../rtgui/multilangmgr.h" #include "median.h" //#define BENCHMARK #include "StopWatch.h" +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} +} namespace rtengine { #define TS 144 @@ -40,6 +45,7 @@ void RawImageSource::ahd_demosaic() { BENCHFUN + const unsigned int cfa[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; constexpr int dirs[4] = { -1, 1, -TS, TS }; float xyz_cam[3][3]; LUTf cbrt(65536); @@ -74,7 +80,7 @@ void RawImageSource::ahd_demosaic() } } } - border_interpolate2(W, H, 5, rawData, red, green, blue); + border_interpolate(W, H, 5, rawData, red, green, blue); #ifdef _OPENMP @@ -94,7 +100,7 @@ void RawImageSource::ahd_demosaic() for (int left = 2; left < width - 5; left += TS - 6) { // Interpolate green horizontally and vertically: for (int row = top; row < top + TS && row < height - 2; row++) { - for (int col = left + (FC(row, left) & 1); col < std::min(left + TS, width - 2); col += 2) { + for (int col = left + (fc(cfa, row, left) & 1); col < std::min(left + TS, width - 2); col += 2) { auto pix = &rawData[row][col]; float val0 = 0.25f * ((pix[-1] + pix[0] + pix[1]) * 2 - pix[-2] - pix[2]) ; @@ -108,12 +114,12 @@ void RawImageSource::ahd_demosaic() // Interpolate red and blue, and convert to CIELab: for (int d = 0; d < 2; d++) for (int row = top + 1; row < top + TS - 1 && row < height - 3; row++) { - int cng = FC(row + 1, FC(row + 1, 0) & 1); + int cng = fc(cfa, row + 1, fc(cfa, row + 1, 0) & 1); for (int col = left + 1; col < std::min(left + TS - 1, width - 3); col++) { auto pix = &rawData[row][col]; auto rix = &rgb[d][row - top][col - left]; auto lix = lab[d][row - top][col - left]; - if (FC(row, col) == 1) { + if (fc(cfa, row, col) == 1) { rix[0][2 - cng] = CLIP(pix[0] + (0.5f * (pix[-1] + pix[1] - rix[-1][1] - rix[1][1] ) )); rix[0][cng] = CLIP(pix[0] + (0.5f * (pix[-width] + pix[width] diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h index b2c720bd8..05a965766 100644 --- a/rtengine/alignedbuffer.h +++ b/rtengine/alignedbuffer.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ALIGNEDBUFFER_ -#define _ALIGNEDBUFFER_ +#pragma once #include #include @@ -142,5 +141,3 @@ public: return unitSize ? allocatedSize / unitSize : 0; } }; - -#endif diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 43aef0f71..24c463458 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -30,12 +30,18 @@ #include "rawimagesource.h" #include "rt_math.h" #include "../rtgui/multilangmgr.h" -#include "sleef.c" +#include "sleef.h" #include "opthelper.h" #include "median.h" -#include "procparams.h" #include "StopWatch.h" +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} +} + namespace rtengine { @@ -56,6 +62,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c plistener->setProgress(progress); } + const unsigned int cfarray[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; const int width = winw, height = winh; const float clip_pt = 1.0 / initialGain; const float clip_pt8 = 0.8 / initialGain; @@ -74,8 +81,8 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c int ex, ey; //determine GRBG coset; (ey,ex) is the offset of the R subarray - if (FC(0, 0) == 1) { //first pixel is G - if (FC(0, 1) == 0) { + if (fc(cfarray, 0, 0) == 1) { //first pixel is G + if (fc(cfarray, 0, 1) == 0) { ey = 0; ex = 1; } else { @@ -83,7 +90,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c ex = 0; } } else {//first pixel is R or B - if (FC(0, 0) == 0) { + if (fc(cfarray, 0, 0) == 0) { ey = 0; ex = 0; } else { @@ -373,7 +380,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #ifdef __SSE2__ vfloat sgnv; - if( !(FC(4, 4) & 1) ) { + if( !(fc(cfarray, 4, 4) & 1) ) { sgnv = _mm_set_ps( 1.f, -1.f, 1.f, -1.f ); } else { sgnv = _mm_set_ps( -1.f, 1.f, -1.f, 1.f ); @@ -440,7 +447,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else for (int rr = 4; rr < rr1 - 4; rr++) { - bool fcswitch = FC(rr, 4) & 1; + bool fcswitch = fc(cfarray, rr, 4) & 1; for (int cc = 4, indx = rr * ts + cc; cc < cc1 - 4; cc++, indx++) { @@ -532,7 +539,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c vfloat clip_ptv = F2V( clip_pt ); vfloat sgn3v; - if( !(FC(4, 4) & 1) ) { + if( !(fc(cfarray, 4, 4) & 1) ) { sgnv = _mm_set_ps( 1.f, -1.f, 1.f, -1.f ); } else { sgnv = _mm_set_ps( -1.f, 1.f, -1.f, 1.f ); @@ -590,7 +597,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else for (int rr = 4; rr < rr1 - 4; rr++) { - for (int cc = 4, indx = rr * ts + cc, c = FC(rr, cc) & 1; cc < cc1 - 4; cc++, indx++) { + for (int cc = 4, indx = rr * ts + cc, c = fc(cfarray, rr, cc) & 1; cc < cc1 - 4; cc++, indx++) { float hcdvar = 3.f * (SQR(hcd[indx - 2]) + SQR(hcd[indx]) + SQR(hcd[indx + 2])) - SQR(hcd[indx - 2] + hcd[indx] + hcd[indx + 2]); float hcdaltvar = 3.f * (SQR(hcdalt[indx - 2]) + SQR(hcdalt[indx]) + SQR(hcdalt[indx + 2])) - SQR(hcdalt[indx - 2] + hcdalt[indx] + hcdalt[indx + 2]); float vcdvar = 3.f * (SQR(vcd[indx - v2]) + SQR(vcd[indx]) + SQR(vcd[indx + v2])) - SQR(vcd[indx - v2] + vcd[indx] + vcd[indx + v2]); @@ -686,7 +693,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c vfloat epssqv = F2V( epssq ); for (int rr = 6; rr < rr1 - 6; rr++) { - for (int indx = rr * ts + 6 + (FC(rr, 2) & 1); indx < rr * ts + cc1 - 6; indx += 8) { + for (int indx = rr * ts + 6 + (fc(cfarray, rr, 2) & 1); indx < rr * ts + cc1 - 6; indx += 8) { //compute colour difference variances in cardinal directions vfloat tempv = LC2VFU(vcd[indx]); vfloat uavev = tempv + LC2VFU(vcd[indx - v1]) + LC2VFU(vcd[indx - v2]) + LC2VFU(vcd[indx - v3]); @@ -732,7 +739,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else for (int rr = 6; rr < rr1 - 6; rr++) { - for (int cc = 6 + (FC(rr, 2) & 1), indx = rr * ts + cc; cc < cc1 - 6; cc += 2, indx += 2) { + for (int cc = 6 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc; cc < cc1 - 6; cc += 2, indx += 2) { //compute colour difference variances in cardinal directions @@ -794,7 +801,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c // precompute nyquist for (int rr = 6; rr < rr1 - 6; rr++) { - int cc = 6 + (FC(rr, 2) & 1); + int cc = 6 + (fc(cfarray, rr, 2) & 1); int indx = rr * ts + cc; #ifdef __SSE2__ @@ -857,7 +864,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c int nyendcol = 0; for (int rr = 6; rr < rr1 - 6; rr++) { - for (int cc = 6 + (FC(rr, 2) & 1), indx = rr * ts + cc; cc < cc1 - 6; cc += 2, indx += 2) { + for (int cc = 6 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc; cc < cc1 - 6; cc += 2, indx += 2) { //nyquist texture test: ask if difference of vcd compared to hcd is larger or smaller than RGGB gradients if(nyqutest[indx >> 1] > 0.f) { @@ -908,7 +915,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - for (int indx = rr * ts + nystartcol + (FC(rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { + for (int indx = rr * ts + nystartcol + (fc(cfarray, rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { unsigned int nyquisttemp = (nyquist[(indx - v2) >> 1] + nyquist[(indx - m1) >> 1] + nyquist[(indx + p1) >> 1] + nyquist[(indx - 2) >> 1] + nyquist[(indx + 2) >> 1] + nyquist[(indx - p1) >> 1] + nyquist[(indx + m1) >> 1] + nyquist[(indx + v2) >> 1]); @@ -923,7 +930,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c // in areas of Nyquist texture, do area interpolation for (int rr = nystartrow; rr < nyendrow; rr++) - for (int indx = rr * ts + nystartcol + (FC(rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { + for (int indx = rr * ts + nystartcol + (fc(cfarray, rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { if (nyquist2[indx >> 1]) { // area interpolation @@ -963,7 +970,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c //populate G at R/B sites for (int rr = 8; rr < rr1 - 8; rr++) - for (int indx = rr * ts + 8 + (FC(rr, 2) & 1); indx < rr * ts + cc1 - 8; indx += 2) { + for (int indx = rr * ts + 8 + (fc(cfarray, rr, 2) & 1); indx < rr * ts + cc1 - 8; indx += 2) { //first ask if one gets more directional discrimination from nearby B/R sites float hvwtalt = xdivf(hvwt[(indx - m1) >> 1] + hvwt[(indx + p1) >> 1] + hvwt[(indx - p1) >> 1] + hvwt[(indx + m1) >> 1], 2); @@ -986,7 +993,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c // refine Nyquist areas using G curvatures if(doNyquist) { for (int rr = nystartrow; rr < nyendrow; rr++) - for (int indx = rr * ts + nystartcol + (FC(rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { + for (int indx = rr * ts + nystartcol + (fc(cfarray, rr, 2) & 1); indx < rr * ts + nyendcol; indx += 2) { if (nyquist2[indx >> 1]) { //local averages (over Nyquist pixels only) of G curvature squared @@ -1009,7 +1016,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #ifdef __SSE2__ for (int rr = 6; rr < rr1 - 6; rr++) { - if((FC(rr, 2) & 1) == 0) { + if((fc(cfarray, rr, 2) & 1) == 0) { for (int cc = 6, indx = rr * ts + cc; cc < cc1 - 6; cc += 8, indx += 8) { vfloat tempv = LC2VFU(cfa[indx + 1]); vfloat Dgrbsq1pv = (SQRV(tempv - LC2VFU(cfa[indx + 1 - p1])) + SQRV(tempv - LC2VFU(cfa[indx + 1 + p1]))); @@ -1035,7 +1042,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else for (int rr = 6; rr < rr1 - 6; rr++) { - if((FC(rr, 2) & 1) == 0) { + if((fc(cfarray, rr, 2) & 1) == 0) { for (int cc = 6, indx = rr * ts + cc; cc < cc1 - 6; cc += 2, indx += 2) { delp[indx >> 1] = fabsf(cfa[indx + p1] - cfa[indx - p1]); delm[indx >> 1] = fabsf(cfa[indx + m1] - cfa[indx - m1]); @@ -1064,7 +1071,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int rr = 8; rr < rr1 - 8; rr++) { #ifdef __SSE2__ - for (int indx = rr * ts + 8 + (FC(rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 8; indx += 8, indx1 += 4) { + for (int indx = rr * ts + 8 + (fc(cfarray, rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 8; indx += 8, indx1 += 4) { //diagonal colour ratios vfloat cfav = LC2VFU(cfa[indx]); @@ -1129,7 +1136,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - for (int cc = 8 + (FC(rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 8; cc += 2, indx += 2, indx1++) { + for (int cc = 8 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 8; cc += 2, indx += 2, indx1++) { //diagonal colour ratios float crse = xmul2f(cfa[indx + m1]) / (eps + cfa[indx] + (cfa[indx + m2])); @@ -1219,7 +1226,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int rr = 10; rr < rr1 - 10; rr++) #ifdef __SSE2__ - for (int indx = rr * ts + 10 + (FC(rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 10; indx += 8, indx1 += 4) { + for (int indx = rr * ts + 10 + (fc(cfarray, rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 10; indx += 8, indx1 += 4) { //first ask if one gets more directional discrimination from nearby B/R sites vfloat pmwtaltv = zd25v * (LVFU(pmwt[(indx - m1) >> 1]) + LVFU(pmwt[(indx + p1) >> 1]) + LVFU(pmwt[(indx - p1) >> 1]) + LVFU(pmwt[(indx + m1) >> 1])); @@ -1231,7 +1238,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - for (int cc = 10 + (FC(rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 10; cc += 2, indx += 2, indx1++) { + for (int cc = 10 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 10; cc += 2, indx += 2, indx1++) { //first ask if one gets more directional discrimination from nearby B/R sites float pmwtalt = xdivf(pmwt[(indx - m1) >> 1] + pmwt[(indx + p1) >> 1] + pmwt[(indx - p1) >> 1] + pmwt[(indx + m1) >> 1], 2); @@ -1247,7 +1254,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int rr = 12; rr < rr1 - 12; rr++) #ifdef __SSE2__ - for (int indx = rr * ts + 12 + (FC(rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 12; indx += 8, indx1 += 4) { + for (int indx = rr * ts + 12 + (fc(cfarray, rr, 2) & 1), indx1 = indx >> 1; indx < rr * ts + cc1 - 12; indx += 8, indx1 += 4) { vmask copymask = vmaskf_ge(vabsf(zd5v - LVFU(pmwt[indx1])), vabsf(zd5v - LVFU(hvwt[indx1]))); if(_mm_movemask_ps((vfloat)copymask)) { // if for any of the 4 pixels the condition is true, do the maths for all 4 pixels and mask the unused out at the end @@ -1302,7 +1309,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - for (int cc = 12 + (FC(rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 12; cc += 2, indx += 2, indx1++) { + for (int cc = 12 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 12; cc += 2, indx += 2, indx1++) { if (fabsf(0.5f - pmwt[indx >> 1]) < fabsf(0.5f - hvwt[indx >> 1]) ) { continue; @@ -1400,7 +1407,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int rr = 14; rr < rr1 - 14; rr++) #ifdef __SSE2__ - for (int cc = 14 + (FC(rr, 2) & 1), indx = rr * ts + cc, c = 1 - FC(rr, cc) / 2; cc < cc1 - 14; cc += 8, indx += 8) { + for (int cc = 14 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc, c = 1 - fc(cfarray, rr, cc) / 2; cc < cc1 - 14; cc += 8, indx += 8) { vfloat tempv = epsv + vabsf(LVFU(Dgrb[c][(indx - m1) >> 1]) - LVFU(Dgrb[c][(indx + m1) >> 1])); vfloat temp2v = epsv + vabsf(LVFU(Dgrb[c][(indx + p1) >> 1]) - LVFU(Dgrb[c][(indx - p1) >> 1])); vfloat wtnwv = onev / (tempv + vabsf(LVFU(Dgrb[c][(indx - m1) >> 1]) - LVFU(Dgrb[c][(indx - m3) >> 1])) + vabsf(LVFU(Dgrb[c][(indx + m1) >> 1]) - LVFU(Dgrb[c][(indx - m3) >> 1]))); @@ -1416,7 +1423,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - for (int cc = 14 + (FC(rr, 2) & 1), indx = rr * ts + cc, c = 1 - FC(rr, cc) / 2; cc < cc1 - 14; cc += 2, indx += 2) { + for (int cc = 14 + (fc(cfarray, rr, 2) & 1), indx = rr * ts + cc, c = 1 - fc(cfarray, rr, cc) / 2; cc < cc1 - 14; cc += 2, indx += 2) { float wtnw = 1.f / (eps + fabsf(Dgrb[c][(indx - m1) >> 1] - Dgrb[c][(indx + m1) >> 1]) + fabsf(Dgrb[c][(indx - m1) >> 1] - Dgrb[c][(indx - m3) >> 1]) + fabsf(Dgrb[c][(indx + m1) >> 1] - Dgrb[c][(indx - m3) >> 1])); float wtne = 1.f / (eps + fabsf(Dgrb[c][(indx + p1) >> 1] - Dgrb[c][(indx - p1) >> 1]) + fabsf(Dgrb[c][(indx + p1) >> 1] - Dgrb[c][(indx + p3) >> 1]) + fabsf(Dgrb[c][(indx - p1) >> 1] - Dgrb[c][(indx + p3) >> 1])); float wtsw = 1.f / (eps + fabsf(Dgrb[c][(indx - p1) >> 1] - Dgrb[c][(indx + p1) >> 1]) + fabsf(Dgrb[c][(indx - p1) >> 1] - Dgrb[c][(indx + m3) >> 1]) + fabsf(Dgrb[c][(indx + p1) >> 1] - Dgrb[c][(indx - p3) >> 1])); @@ -1435,7 +1442,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c vfloat twov = F2V(2.f); vmask selmask; - if((FC(16, 2) & 1) == 1) { + if((fc(cfarray, 16, 2) & 1) == 1) { selmask = _mm_set_epi32(0xffffffff, 0, 0xffffffff, 0); offset = 1; } else { @@ -1510,7 +1517,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c #else - if((FC(rr, 2) & 1) == 1) { + if((fc(cfarray, rr, 2) & 1) == 1) { for (; indx < rr * ts + cc1 - 16 - (cc1 & 1); indx++, col++) { float temp = 1.f / (hvwt[(indx - v1) >> 1] + 2.f - hvwt[(indx + 1) >> 1] - hvwt[(indx - 1) >> 1] + hvwt[(indx + v1) >> 1]); red[row][col] = 65535.f * (rgbgreen[indx] - ((hvwt[(indx - v1) >> 1]) * Dgrb[0][(indx - v1) >> 1] + (1.f - hvwt[(indx + 1) >> 1]) * Dgrb[0][(indx + 1) >> 1] + (1.f - hvwt[(indx - 1) >> 1]) * Dgrb[0][(indx - 1) >> 1] + (hvwt[(indx + v1) >> 1]) * Dgrb[0][(indx + v1) >> 1]) * @@ -1592,7 +1599,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c free(buffer); } if(border < 4) { - border_interpolate2(W, H, 3, rawData, red, green, blue); + border_interpolate(W, H, 3, rawData, red, green, blue); } if(plistener) { diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 7713cd55c..208dab1aa 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -52,8 +52,8 @@ * * !! locked arrays cannot be resized and cannot be unlocked again !! */ -#ifndef ARRAY2D_H_ -#define ARRAY2D_H_ +#pragma once + #include // for raise() #include @@ -249,7 +249,7 @@ public: ar_realloc(w, h, offset); if (flags & ARRAY2D_CLEAR_DATA) { - memset(data + offset, 0, w * h * sizeof(T)); + memset(data + offset, 0, static_cast(w) * h * sizeof(T)); } } @@ -313,4 +313,3 @@ public: return list[index]; } }; -#endif /* array2D_H_ */ diff --git a/rtengine/badpixels.cc b/rtengine/badpixels.cc index 79b8187f7..0ae63a618 100644 --- a/rtengine/badpixels.cc +++ b/rtengine/badpixels.cc @@ -20,7 +20,42 @@ #include "array2D.h" #include "median.h" #include "pixelsmap.h" +#include "rawimage.h" #include "rawimagesource.h" +//#define BENCHMARK +#include "StopWatch.h" + +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} + +inline void sum5x5(const array2D& in, int col, float &sum) { +#ifdef __SSE2__ + // sum up 5*4 = 20 values using SSE + // 10 fabs function calls and 10 float additions with SSE + const vfloat sumv = (vabsf(LVFU(in[0][col])) + vabsf(LVFU(in[1][col]))) + + (vabsf(LVFU(in[2][col])) + vabsf(LVFU(in[3][col]))) + + vabsf(LVFU(in[4][col])); + // horizontally add the values and add the result to hfnbrave + sum += vhadd(sumv); + + // add remaining 5 values of last column + sum += (fabsf(in[0][col + 4]) + fabsf(in[1][col + 4])) + + (fabsf(in[2][col + 4]) + fabsf(in[3][col + 4])) + + fabsf(in[4][col + 4]); +#else + // 25 fabs function calls and 25 float additions without SSE + for (int nn = col; nn < col + 5; ++nn) { + sum += (fabsf(in[0][nn]) + fabsf(in[1][nn])) + + (fabsf(in[2][nn]) + fabsf(in[3][nn])) + + fabsf(in[4][nn]); + } +#endif + +} +} namespace rtengine { @@ -30,6 +65,7 @@ namespace rtengine */ int RawImageSource::interpolateBadPixelsBayer(const PixelsMap &bitmapBads, array2D &rawData) { + const unsigned int cfarray[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; constexpr float eps = 1.f; int counter = 0; @@ -53,7 +89,7 @@ int RawImageSource::interpolateBadPixelsBayer(const PixelsMap &bitmapBads, array float wtdsum = 0.f, norm = 0.f; // diagonal interpolation - if (FC(row, col) == 1) { + if (fc(cfarray, row, col) == 1) { // green channel. We can use closer pixels than for red or blue channel. Distance to center pixel is sqrt(2) => weighting is 0.70710678 // For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center. // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad @@ -436,126 +472,124 @@ int RawImageSource::interpolateBadPixelsXtrans(const PixelsMap &bitmapBads) /* Search for hot or dead pixels in the image and update the map * For each pixel compare its value to the average of similar color surrounding * (Taken from Emil Martinec idea) - * (Optimized by Ingo Weyrich 2013 and 2015) - */ + * (Optimized by Ingo Weyrich 2013, 2015, and 2019) +*/ int RawImageSource::findHotDeadPixels(PixelsMap &bpMap, const float thresh, const bool findHotPixels, const bool findDeadPixels) const { + BENCHFUN const float varthresh = (20.0 * (thresh / 100.0) + 1.0) / 24.f; - // allocate temporary buffer - float* cfablur = new float[H * W]; - // counter for dead or hot pixels int counter = 0; #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel reduction(+:counter) #endif { + array2D cfablur(W, 5, ARRAY2D_CLEAR_DATA); + int firstRow = -1; + int lastRow = -1; + #ifdef _OPENMP - #pragma omp for schedule(dynamic,16) nowait + // note, static scheduling is important in this implementation + #pragma omp for schedule(static) nowait #endif - for (int i = 2; i < H - 2; i++) { - for (int j = 2; j < W - 2; j++) { + for (int i = 2; i < H - 2; ++i) { + if (firstRow == -1) { + firstRow = i; + if (firstRow > 2) { + for (int row = firstRow - 2; row < firstRow; ++row) { + const int destRow = row % 5; + for (int j = 2; j < W - 2; ++j) { + const float temp = median(rawData[row - 2][j - 2], rawData[row - 2][j], rawData[row - 2][j + 2], + rawData[row][j - 2], rawData[row][j], rawData[row][j + 2], + rawData[row + 2][j - 2], rawData[row + 2][j], rawData[row + 2][j + 2]); + cfablur[destRow][j] = rawData[row][j] - temp; + } + } + } + } + lastRow = i; + const int destRow = i % 5; + for (int j = 2; j < W - 2; ++j) { const float temp = median(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2]); - cfablur[i * W + j] = rawData[i][j] - temp; + cfablur[destRow][j] = rawData[i][j] - temp; + } + + if (i - 1 > firstRow) { + const int rr = i - 2; + const int rr0 = rr % 5; + for (int cc = 2; cc < W - 2; ++cc) { + //evaluate pixel for heat/death + float pixdev = cfablur[rr0][cc]; + + if (!findDeadPixels && pixdev <= 0.f) { + continue; + } + + if (!findHotPixels && pixdev >= 0.f) { + continue; + } + + pixdev = fabsf(pixdev); + float hfnbrave = -pixdev; + sum5x5(cfablur, cc - 2, hfnbrave); + if (pixdev > varthresh * hfnbrave) { + // mark the pixel as "bad" + bpMap.set(cc, rr); + ++counter; + } + } //end of pixel evaluation } } - // process borders. Former version calculated the median using mirrored border which does not make sense because the original pixel loses weight - // Setting the difference between pixel and median for border pixels to zero should do the job not worse then former version -#ifdef _OPENMP - #pragma omp single -#endif - { - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < W; ++j) { - cfablur[i * W + j] = 0.f; - } - } - - for (int i = 2; i < H - 2; ++i) { - for (int j = 0; j < 2; ++j) { - cfablur[i * W + j] = 0.f; - } - - for (int j = W - 2; j < W; ++j) { - cfablur[i * W + j] = 0.f; - } - } - - for (int i = H - 2; i < H; ++i) { - for (int j = 0; j < W; ++j) { - cfablur[i * W + j] = 0.f; - } - } - } - -#ifdef _OPENMP - #pragma omp barrier // barrier because of nowait clause above - - #pragma omp for reduction(+:counter) schedule(dynamic,16) -#endif - - //cfa pixel heat/death evaluation - for (int rr = 2; rr < H - 2; ++rr) { - for (int cc = 2, rrmWpcc = rr * W + 2; cc < W - 2; ++cc, ++rrmWpcc) { - //evaluate pixel for heat/death - float pixdev = cfablur[rrmWpcc]; - - if (pixdev == 0.f) { - continue; - } - - if ((!findDeadPixels) && pixdev < 0) { - continue; - } - - if ((!findHotPixels) && pixdev > 0) { - continue; - } - - pixdev = fabsf(pixdev); - float hfnbrave = -pixdev; - -#ifdef __SSE2__ - // sum up 5*4 = 20 values using SSE - // 10 fabs function calls and 10 float additions with SSE - vfloat sum = vabsf(LVFU(cfablur[(rr - 2) * W + cc - 2])) + vabsf(LVFU(cfablur[(rr - 1) * W + cc - 2])); - sum += vabsf(LVFU(cfablur[(rr) * W + cc - 2])); - sum += vabsf(LVFU(cfablur[(rr + 1) * W + cc - 2])); - sum += vabsf(LVFU(cfablur[(rr + 2) * W + cc - 2])); - // horizontally add the values and add the result to hfnbrave - hfnbrave += vhadd(sum); - - // add remaining 5 values of last column - for (int mm = rr - 2; mm <= rr + 2; ++mm) { - hfnbrave += fabsf(cfablur[mm * W + cc + 2]); - } - -#else - - // 25 fabs function calls and 25 float additions without SSE - for (int mm = rr - 2; mm <= rr + 2; ++mm) { - for (int nn = cc - 2; nn <= cc + 2; ++nn) { - hfnbrave += fabsf(cfablur[mm * W + nn]); + if (lastRow > 0 && lastRow < H - 2) { + //cfa pixel heat/death evaluation + for (int rr = lastRow - 1; rr < lastRow + 1; ++rr) { + const int i = rr + 2; + const int destRow = i % 5; + if (i >= H - 2) { + for (int j = 2; j < W - 2; j++) { + cfablur[destRow][j] = 0.f; + } + } else { + for (int j = 2; j < W - 2; ++j) { + const float temp = median(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], + rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], + rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2]); + cfablur[destRow][j] = rawData[i][j] - temp; } } -#endif + const int rr0 = rr % 5; + for (int cc = 2; cc < W - 2; ++cc) { + //evaluate pixel for heat/death + float pixdev = cfablur[rr0][cc]; - if (pixdev > varthresh * hfnbrave) { - // mark the pixel as "bad" - bpMap.set(cc, rr); - counter++; - } - }//end of pixel evaluation + if (!findDeadPixels && pixdev <= 0.f) { + continue; + } + + if (!findHotPixels && pixdev >= 0.f) { + continue; + } + + pixdev = fabsf(pixdev); + float hfnbrave = -pixdev; + sum5x5(cfablur, cc - 2, hfnbrave); + if (pixdev > varthresh * hfnbrave) { + // mark the pixel as "bad" + bpMap.set(cc, rr); + ++counter; + } + }//end of pixel evaluation + } } }//end of parallel processing - delete [] cfablur; + return counter; } diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h index d0496810d..53e18fb20 100644 --- a/rtengine/bilateral2.h +++ b/rtengine/bilateral2.h @@ -16,22 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BILATERAL2_ -#define _BILATERAL2_ +#pragma once +#include #include -#include #include -#include - -#include "rtengine.h" -#include "rt_math.h" -#include "mytime.h" +#include #include "array2D.h" -#ifdef _OPENMP -#include -#endif +#include "LUT.h" +#include "rt_math.h" using namespace rtengine; @@ -573,7 +567,7 @@ template void bilateral (T** src, T** dst, int W, int H, int sigmar, do // calculate histogram at the beginning of the row rhist.clear(); - for (int x = MAX(0, row_from - r); x <= MIN(H, row_from + r); x++) + for (int x = std::max(0, row_from - r); x <= std::min(H, row_from + r); x++) for (int y = 0; y < r + 1; y++) { rhist[((int)src[x][y]) >> TRANSBIT]++; } @@ -584,12 +578,12 @@ template void bilateral (T** src, T** dst, int W, int H, int sigmar, do // calculate histogram at the beginning of the row if (i > r) - for (int x = 0; x <= MIN(H, r); x++) { + for (int x = 0; x <= std::min(H, r); x++) { rhist[((int)src[i - r - 1][x]) >> TRANSBIT]--; } if (i < H - r) - for (int x = 0; x <= MIN(H, r); x++) { + for (int x = 0; x <= std::min(H, r); x++) { rhist[((int)src[i + r][x]) >> TRANSBIT]++; } @@ -599,12 +593,12 @@ template void bilateral (T** src, T** dst, int W, int H, int sigmar, do // subtract pixels at the left and add pixels at the right if (j > r) - for (int x = MAX(0, i - r); x <= MIN(i + r, H - 1); x++) { + for (int x = std::max(0, i - r); x <= std::min(i + r, H - 1); x++) { hist[(int)(src[x][j - r - 1]) >> TRANSBIT]--; } if (j < W - r) - for (int x = MAX(0, i - r); x <= MIN(i + r, H - 1); x++) { + for (int x = std::max(0, i - r); x <= std::min(i + r, H - 1); x++) { hist[((int)src[x][j + r]) >> TRANSBIT]++; } @@ -643,5 +637,3 @@ template void bilateral (T** src, T** dst, int W, int H, int sigmar, do } #undef BINBIT #undef TRANSBIT - -#endif diff --git a/rtengine/boxblur.cc b/rtengine/boxblur.cc new file mode 100644 index 000000000..045c7ac3f --- /dev/null +++ b/rtengine/boxblur.cc @@ -0,0 +1,421 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (C) 2010 Emil Martinec + * Copyright (C) 2019 Ingo Weyrich + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ + +#include +#include + +#include "boxblur.h" + +#include "rt_math.h" +#include "opthelper.h" + +namespace rtengine +{ + +void boxblur(float** src, float** dst, int radius, int W, int H, bool multiThread) +{ + //box blur using rowbuffers and linebuffers instead of a full size buffer + + radius = rtengine::min(radius, W - 1, H - 1); + if (radius == 0) { + if (src != dst) { +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W; ++col) { + dst[row][col] = src[row][col]; + } + } + } + return; + } + + constexpr int numCols = 8; // process numCols columns at once for better usage of L1 cpu cache +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + std::unique_ptr buffer(new float[numCols * (radius + 1)]); + + //horizontal blur + float* const lineBuffer = buffer.get(); +#ifdef _OPENMP + #pragma omp for +#endif + for (int row = 0; row < H; ++row) { + float len = radius + 1; + float tempval = src[row][0]; + lineBuffer[0] = tempval; + for (int j = 1; j <= radius; j++) { + tempval += src[row][j]; + } + + tempval /= len; + dst[row][0] = tempval; + + for (int col = 1; col <= radius; ++col) { + lineBuffer[col] = src[row][col]; + tempval = (tempval * len + src[row][col + radius]) / (len + 1); + dst[row][col] = tempval; + ++len; + } + int pos = 0; + for (int col = radius + 1; col < W - radius; ++col) { + const float oldVal = lineBuffer[pos]; + lineBuffer[pos] = src[row][col]; + tempval = tempval + (src[row][col + radius] - oldVal) / len; + dst[row][col] = tempval; + ++pos; + pos = pos <= radius ? pos : 0; + } + + for (int col = W - radius; col < W; ++col) { + tempval = (tempval * len - lineBuffer[pos]) / (len - 1); + dst[row][col] = tempval; + --len; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + + //vertical blur +#ifdef __SSE2__ + vfloat (* const rowBuffer)[2] = (vfloat(*)[2]) buffer.get(); + const vfloat leninitv = F2V(radius + 1); + const vfloat onev = F2V(1.f); + vfloat tempv, temp1v, lenv, lenp1v, lenm1v, rlenv; + +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int col = 0; col < W - 7; col += 8) { + lenv = leninitv; + tempv = LVFU(dst[0][col]); + temp1v = LVFU(dst[0][col + 4]); + rowBuffer[0][0] = tempv; + rowBuffer[0][1] = temp1v; + + for (int i = 1; i <= radius; ++i) { + tempv = tempv + LVFU(dst[i][col]); + temp1v = temp1v + LVFU(dst[i][col + 4]); + } + + tempv = tempv / lenv; + temp1v = temp1v / lenv; + STVFU(dst[0][col], tempv); + STVFU(dst[0][col + 4], temp1v); + + for (int row = 1; row <= radius; ++row) { + rowBuffer[row][0] = LVFU(dst[row][col]); + rowBuffer[row][1] = LVFU(dst[row][col + 4]); + lenp1v = lenv + onev; + tempv = (tempv * lenv + LVFU(dst[row + radius][col])) / lenp1v; + temp1v = (temp1v * lenv + LVFU(dst[row + radius][col + 4])) / lenp1v; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + lenv = lenp1v; + } + + rlenv = onev / lenv; + int pos = 0; + for (int row = radius + 1; row < H - radius; ++row) { + vfloat oldVal0 = rowBuffer[pos][0]; + vfloat oldVal1 = rowBuffer[pos][1]; + rowBuffer[pos][0] = LVFU(dst[row][col]); + rowBuffer[pos][1] = LVFU(dst[row][col + 4]); + tempv = tempv + (LVFU(dst[row + radius][col]) - oldVal0) * rlenv ; + temp1v = temp1v + (LVFU(dst[row + radius][col + 4]) - oldVal1) * rlenv ; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + ++pos; + pos = pos <= radius ? pos : 0; + } + + for (int row = H - radius; row < H; ++row) { + lenm1v = lenv - onev; + tempv = (tempv * lenv - rowBuffer[pos][0]) / lenm1v; + temp1v = (temp1v * lenv - rowBuffer[pos][1]) / lenm1v; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + lenv = lenm1v; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + +#else + float (* const rowBuffer)[8] = (float(*)[8]) buffer.get(); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int col = 0; col < W - numCols + 1; col += 8) { + float len = radius + 1; + + for (int k = 0; k < numCols; ++k) { + rowBuffer[0][k] = dst[0][col + k]; + } + + for (int i = 1; i <= radius; ++i) { + for (int k = 0; k < numCols; ++k) { + dst[0][col + k] += dst[i][col + k]; + } + } + + for(int k = 0; k < numCols; ++k) { + dst[0][col + k] /= len; + } + + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < numCols; ++k) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = (dst[row - 1][col + k] * len + dst[row + radius][col + k]) / (len + 1); + } + + len ++; + } + + int pos = 0; + for (int row = radius + 1; row < H - radius; ++row) { + for(int k = 0; k < numCols; ++k) { + float oldVal = rowBuffer[pos][k]; + rowBuffer[pos][k] = dst[row][col + k]; + dst[row][col + k] = dst[row - 1][col + k] + (dst[row + radius][col + k] - oldVal) / len; + } + ++pos; + pos = pos <= radius ? pos : 0; + } + + for (int row = H - radius; row < H; ++row) { + for(int k = 0; k < numCols; ++k) { + dst[row][col + k] = (dst[row - 1][col + k] * len - rowBuffer[pos][k]) / (len - 1); + } + len --; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + +#endif + //vertical blur, remaining columns +#ifdef _OPENMP + #pragma omp single +#endif + { + const int remaining = W % numCols; + + if (remaining > 0) { + float (* const rowBuffer)[8] = (float(*)[8]) buffer.get(); + const int col = W - remaining; + + float len = radius + 1; + for(int k = 0; k < remaining; ++k) { + rowBuffer[0][k] = dst[0][col + k]; + } + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < remaining; ++k) { + dst[0][col + k] += dst[row][col + k]; + } + } + for(int k = 0; k < remaining; ++k) { + dst[0][col + k] /= len; + } + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < remaining; ++k) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = (dst[row - 1][col + k] * len + dst[row + radius][col + k]) / (len + 1); + } + len ++; + } + const float rlen = 1.f / len; + int pos = 0; + for (int row = radius + 1; row < H - radius; ++row) { + for(int k = 0; k < remaining; ++k) { + float oldVal = rowBuffer[pos][k]; + rowBuffer[pos][k] = dst[row][col + k]; + dst[row][col + k] = dst[row - 1][col + k] + (dst[row + radius][col + k] - oldVal) * rlen; + } + ++pos; + pos = pos <= radius ? pos : 0; + } + for (int row = H - radius; row < H; ++row) { + for(int k = 0; k < remaining; ++k) { + dst[row][col + k] = (dst[(row - 1)][col + k] * len - rowBuffer[pos][k]) / (len - 1); + } + len --; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + } + } +} + +void boxabsblur(float** src, float** dst, int radius, int W, int H, bool multiThread) +{ + //abs box blur using rowbuffers and linebuffers instead of a full size buffer, W should be a multiple of 16 + + if (radius == 0) { + if (src != dst) { +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W; ++col) { + dst[row][col] = std::fabs(src[row][col]); + } + } + } + return; + } + + constexpr int numCols = 16; // process numCols columns at once for better usage of L1 cpu cache +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + float buffer[numCols * (radius + 1)] ALIGNED64; + + //horizontal blur + float* const lineBuffer = buffer; +#ifdef _OPENMP + #pragma omp for +#endif + for (int row = 0; row < H; ++row) { + float len = radius + 1; + float tempval = std::fabs(src[row][0]); + lineBuffer[0] = tempval; + for (int j = 1; j <= radius; j++) { + tempval += std::fabs(src[row][j]); + } + + tempval /= len; + dst[row][0] = tempval; + + for (int col = 1; col <= radius; ++col) { + lineBuffer[col] = std::fabs(src[row][col]); + tempval = (tempval * len + std::fabs(src[row][col + radius])) / (len + 1); + dst[row][col] = tempval; + ++len; + } + + const float rlen = 1.f / len; + int pos = 0; + for (int col = radius + 1; col < W - radius; ++col) { + const float oldVal = lineBuffer[pos]; + lineBuffer[pos] = std::fabs(src[row][col]); + tempval = tempval + (std::fabs(src[row][col + radius]) - oldVal) * rlen; + dst[row][col] = tempval; + ++pos; + pos = pos <= radius ? pos : 0; + } + + for (int col = W - radius; col < W; ++col) { + tempval = (tempval * len - lineBuffer[pos]) / (len - 1); + dst[row][col] = tempval; + --len; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + + //vertical blur + float (* const rowBuffer)[numCols] = (float(*)[numCols]) buffer; +#ifdef _OPENMP + #pragma omp for +#endif + + for (int col = 0; col < W; col += numCols) { + float len = radius + 1; + + for (int k = 0; k < numCols; ++k) { + rowBuffer[0][k] = dst[0][col + k]; + } + + for (int i = 1; i <= radius; ++i) { + for (int k = 0; k < numCols; ++k) { + dst[0][col + k] += dst[i][col + k]; + } + } + + for(int k = 0; k < numCols; ++k) { + dst[0][col + k] /= len; + } + + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < numCols; ++k) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = (dst[row - 1][col + k] * len + dst[row + radius][col + k]) / (len + 1); + } + + ++len; + } + + const float rlen = 1.f / len; + int pos = 0; + for (int row = radius + 1; row < H - radius; ++row) { + for(int k = 0; k < numCols; ++k) { + float oldVal = rowBuffer[pos][k]; + rowBuffer[pos][k] = dst[row][col + k]; + dst[row][col + k] = dst[row - 1][col + k] + (dst[row + radius][col + k] - oldVal) * rlen; + } + ++pos; + pos = pos <= radius ? pos : 0; + } + + for (int row = H - radius; row < H; ++row) { + for(int k = 0; k < numCols; ++k) { + dst[row][col + k] = (dst[row - 1][col + k] * len - rowBuffer[pos][k]) / (len - 1); + } + --len; + ++pos; + pos = pos <= radius ? pos : 0; + } + } + } +} + +void boxblur(float* src, float* dst, int radius, int W, int H, bool multiThread) +{ + float* srcp[H]; + float* dstp[H]; + for (int i = 0; i < H; ++i) { + srcp[i] = src + i * W; + dstp[i] = dst + i * W; + } + boxblur(srcp, dstp, radius, W, H, multiThread); +} + +void boxabsblur(float* src, float* dst, int radius, int W, int H, bool multiThread) +{ + float* srcp[H]; + float* dstp[H]; + for (int i = 0; i < H; ++i) { + srcp[i] = src + i * W; + dstp[i] = dst + i * W; + } + boxabsblur(srcp, dstp, radius, W, H, multiThread); +} + +} diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index da302964b..57fba9119 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (C) 2010 Emil Martinec + * Copyright (C) 2019 Ingo Weyrich * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,632 +15,15 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ -#ifndef _BOXBLUR_H_ -#define _BOXBLUR_H_ - -#include -#include -#include -#include -#include "alignedbuffer.h" -#include "rt_math.h" -#include "opthelper.h" - +*/ +#pragma once namespace rtengine { -// classical filtering if the support window is small: - -template void boxblur (T** src, A** dst, int radx, int rady, int W, int H) -{ - //box blur image; box range = (radx,rady) - assert(2*radx+1 < W); - assert(2*rady+1 < H); - - AlignedBuffer* buffer = new AlignedBuffer (W * H); - float* temp = buffer->data; - - if (radx == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = (float)src[row][col]; - } - } else { - //horizontal blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - int len = radx + 1; - temp[row * W + 0] = (float)src[row][0] / len; - - for (int j = 1; j <= radx; j++) { - temp[row * W + 0] += (float)src[row][j] / len; - } - - for (int col = 1; col <= radx; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len + (float)src[row][col + radx]) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - temp[row * W + col] = temp[row * W + col - 1] + ((float)(src[row][col + radx] - src[row][col - radx - 1])) / len; - } - - for (int col = W - radx; col < W; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len - src[row][col - radx - 1]) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row][col] = temp[row * W + col]; - } - } else { - //vertical blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0][col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0][col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row][col] = (dst[(row - 1)][col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row][col] = dst[(row - 1)][col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row][col] = (dst[(row - 1)][col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - - delete buffer; +void boxblur(float** src, float** dst, int radius, int W, int H, bool multiThread); +void boxblur(float* src, float* dst, int radius, int W, int H, bool multiThread); +void boxabsblur(float** src, float** dst, int radius, int W, int H, bool multiThread); +void boxabsblur(float* src, float* dst, int radius, int W, int H, bool multiThread); } - -template void boxblur (T** src, A** dst, T* buffer, int radx, int rady, int W, int H) -{ - //box blur image; box range = (radx,rady) - - float* temp = buffer; - - if (radx == 0) { -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = (float)src[row][col]; - } - } else { - //horizontal blur -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 0; row < H; row++) { - float len = radx + 1; - float tempval = (float)src[row][0]; - - for (int j = 1; j <= radx; j++) { - tempval += (float)src[row][j]; - } - - tempval /= len; - temp[row * W + 0] = tempval; - - for (int col = 1; col <= radx; col++) { - temp[row * W + col] = tempval = (tempval * len + (float)src[row][col + radx]) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - temp[row * W + col] = tempval = tempval + ((float)(src[row][col + radx] - src[row][col - radx - 1])) / len; - } - - for (int col = W - radx; col < W; col++) { - temp[row * W + col] = tempval = (tempval * len - src[row][col - radx - 1]) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row][col] = temp[row * W + col]; - } - } else { - const int numCols = 8; // process numCols columns at once for better usage of L1 cpu cache -#ifdef __SSE2__ - vfloat leninitv = F2V( (float)(rady + 1)); - vfloat onev = F2V( 1.f ); - vfloat tempv, temp1v, lenv, lenp1v, lenm1v, rlenv; - -#ifdef _OPENMP - #pragma omp for -#endif - - for (int col = 0; col < W - 7; col += 8) { - lenv = leninitv; - tempv = LVFU(temp[0 * W + col]); - temp1v = LVFU(temp[0 * W + col + 4]); - - for (int i = 1; i <= rady; i++) { - tempv = tempv + LVFU(temp[i * W + col]); - temp1v = temp1v + LVFU(temp[i * W + col + 4]); - } - - tempv = tempv / lenv; - temp1v = temp1v / lenv; - STVFU( dst[0][col], tempv); - STVFU( dst[0][col + 4], temp1v); - - for (int row = 1; row <= rady; row++) { - lenp1v = lenv + onev; - tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; - temp1v = (temp1v * lenv + LVFU(temp[(row + rady) * W + col + 4])) / lenp1v; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); - lenv = lenp1v; - } - - rlenv = onev / lenv; - - for (int row = rady + 1; row < H - rady; row++) { - tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; - temp1v = temp1v + (LVFU(temp[(row + rady) * W + col + 4]) - LVFU(temp[(row - rady - 1) * W + col + 4])) * rlenv ; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); - } - - for (int row = H - rady; row < H; row++) { - lenm1v = lenv - onev; - tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; - temp1v = (temp1v * lenv - LVFU(temp[(row - rady - 1) * W + col + 4])) / lenm1v; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); - lenv = lenm1v; - } - } - -#else - //vertical blur -#ifdef _OPENMP - #pragma omp for -#endif - - for (int col = 0; col < W - numCols + 1; col += 8) { - float len = rady + 1; - - for(int k = 0; k < numCols; k++) { - dst[0][col + k] = temp[0 * W + col + k]; - } - - for (int i = 1; i <= rady; i++) { - for(int k = 0; k < numCols; k++) { - dst[0][col + k] += temp[i * W + col + k]; - } - } - - for(int k = 0; k < numCols; k++) { - dst[0][col + k] /= len; - } - - for (int row = 1; row <= rady; row++) { - for(int k = 0; k < numCols; k++) { - dst[row][col + k] = (dst[(row - 1)][col + k] * len + temp[(row + rady) * W + col + k]) / (len + 1); - } - - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - for(int k = 0; k < numCols; k++) { - dst[row][col + k] = dst[(row - 1)][col + k] + (temp[(row + rady) * W + col + k] - temp[(row - rady - 1) * W + col + k]) / len; - } - } - - for (int row = H - rady; row < H; row++) { - for(int k = 0; k < numCols; k++) { - dst[row][col + k] = (dst[(row - 1)][col + k] * len - temp[(row - rady - 1) * W + col + k]) / (len - 1); - } - - len --; - } - } - -#endif -#ifdef _OPENMP - #pragma omp single -#endif - - for (int col = W - (W % numCols); col < W; col++) { - float len = rady + 1; - dst[0][col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0][col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row][col] = (dst[(row - 1)][col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row][col] = dst[(row - 1)][col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row][col] = (dst[(row - 1)][col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - -} - -template void boxblur (T* src, A* dst, A* buffer, int radx, int rady, int W, int H) -{ - //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) - - float* temp = buffer; - - if (radx == 0) { - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = src[row * W + col]; - } - } else { - //horizontal blur - for (int row = H - 1; row >= 0; row--) { - int len = radx + 1; - float tempval = (float)src[row * W]; - - for (int j = 1; j <= radx; j++) { - tempval += (float)src[row * W + j]; - } - - tempval = tempval / len; - temp[row * W] = tempval; - - for (int col = 1; col <= radx; col++) { - tempval = (tempval * len + src[row * W + col + radx]) / (len + 1); - temp[row * W + col] = tempval; - len ++; - } - - float reclen = 1.f / len; - - for (int col = radx + 1; col < W - radx; col++) { - tempval = tempval + ((float)(src[row * W + col + radx] - src[row * W + col - radx - 1])) * reclen; - temp[row * W + col] = tempval; - } - - for (int col = W - radx; col < W; col++) { - tempval = (tempval * len - src[row * W + col - radx - 1]) / (len - 1); - temp[row * W + col] = tempval; - len --; - } - } - } - - if (rady == 0) { - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row * W + col] = temp[row * W + col]; - } - } else { - //vertical blur -#ifdef __SSE2__ - vfloat leninitv = F2V( (float)(rady + 1)); - vfloat onev = F2V( 1.f ); - vfloat tempv, temp1v, lenv, lenp1v, lenm1v, rlenv; - int col; - - for (col = 0; col < W - 7; col += 8) { - lenv = leninitv; - tempv = LVFU(temp[0 * W + col]); - temp1v = LVFU(temp[0 * W + col + 4]); - - for (int i = 1; i <= rady; i++) { - tempv = tempv + LVFU(temp[i * W + col]); - temp1v = temp1v + LVFU(temp[i * W + col + 4]); - } - - tempv = tempv / lenv; - temp1v = temp1v / lenv; - STVFU( dst[0 * W + col], tempv); - STVFU( dst[0 * W + col + 4], temp1v); - - for (int row = 1; row <= rady; row++) { - lenp1v = lenv + onev; - tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; - temp1v = (temp1v * lenv + LVFU(temp[(row + rady) * W + col + 4])) / lenp1v; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); - lenv = lenp1v; - } - - rlenv = onev / lenv; - - for (int row = rady + 1; row < H - rady; row++) { - tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; - temp1v = temp1v + (LVFU(temp[(row + rady) * W + col + 4]) - LVFU(temp[(row - rady - 1) * W + col + 4])) * rlenv ; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); - } - - for (int row = H - rady; row < H; row++) { - lenm1v = lenv - onev; - tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; - temp1v = (temp1v * lenv - LVFU(temp[(row - rady - 1) * W + col + 4])) / lenm1v; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); - lenv = lenm1v; - } - } - - for (; col < W - 3; col += 4) { - lenv = leninitv; - tempv = LVFU(temp[0 * W + col]); - - for (int i = 1; i <= rady; i++) { - tempv = tempv + LVFU(temp[i * W + col]); - } - - tempv = tempv / lenv; - STVFU( dst[0 * W + col], tempv); - - for (int row = 1; row <= rady; row++) { - lenp1v = lenv + onev; - tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; - STVFU( dst[row * W + col], tempv); - lenv = lenp1v; - } - - rlenv = onev / lenv; - - for (int row = rady + 1; row < H - rady; row++) { - tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; - STVFU( dst[row * W + col], tempv); - } - - for (int row = H - rady; row < H; row++) { - lenm1v = lenv - onev; - tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; - STVFU( dst[row * W + col], tempv); - lenv = lenm1v; - } - } - - for (; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - -#else - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - -#endif - } - -} - -template void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H, float * temp) -{ - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) - - if (radx == 0) { - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = fabs(src[row * W + col]); - } - } else { - //horizontal blur - for (int row = 0; row < H; row++) { - int len = radx + 1; - float tempval = fabsf((float)src[row * W + 0]); - - for (int j = 1; j <= radx; j++) { - tempval += fabsf((float)src[row * W + j]); - } - - tempval /= len; - temp[row * W + 0] = tempval; - - for (int col = 1; col <= radx; col++) { - tempval = (tempval * len + fabsf(src[row * W + col + radx])) / (len + 1); - temp[row * W + col] = tempval; - len ++; - } - - float rlen = 1.f / (float)len; - - for (int col = radx + 1; col < W - radx; col++) { - tempval = tempval + ((float)(fabsf(src[row * W + col + radx]) - fabsf(src[row * W + col - radx - 1]))) * rlen; - temp[row * W + col] = tempval; - } - - for (int col = W - radx; col < W; col++) { - tempval = (tempval * len - fabsf(src[row * W + col - radx - 1])) / (len - 1); - temp[row * W + col] = tempval; - len --; - } - } - } - - if (rady == 0) { - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row * W + col] = temp[row * W + col]; - } - } else { - //vertical blur -#ifdef __SSE2__ - vfloat leninitv = F2V( (float)(rady + 1)); - vfloat onev = F2V( 1.f ); - vfloat tempv, lenv, lenp1v, lenm1v, rlenv; - - for (int col = 0; col < W - 3; col += 4) { - lenv = leninitv; - tempv = LVF(temp[0 * W + col]); - - for (int i = 1; i <= rady; i++) { - tempv = tempv + LVF(temp[i * W + col]); - } - - tempv = tempv / lenv; - STVF(dst[0 * W + col], tempv); - - for (int row = 1; row <= rady; row++) { - lenp1v = lenv + onev; - tempv = (tempv * lenv + LVF(temp[(row + rady) * W + col])) / lenp1v; - STVF(dst[row * W + col], tempv); - lenv = lenp1v; - } - - rlenv = onev / lenv; - - for (int row = rady + 1; row < H - rady; row++) { - tempv = tempv + (LVF(temp[(row + rady) * W + col]) - LVF(temp[(row - rady - 1) * W + col])) * rlenv; - STVF(dst[row * W + col], tempv); - } - - for (int row = H - rady; row < H; row++) { - lenm1v = lenv - onev; - tempv = (tempv * lenv - LVF(temp[(row - rady - 1) * W + col])) / lenm1v; - STVF(dst[row * W + col], tempv); - lenv = lenm1v; - } - } - - for (int col = W - (W % 4); col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - -#else - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - -#endif - } - -} - -} -#endif /* _BOXBLUR_H_ */ diff --git a/rtengine/cJSON.c b/rtengine/cJSON.c index fb8ce27e8..130c8e2a5 100644 --- a/rtengine/cJSON.c +++ b/rtengine/cJSON.c @@ -445,9 +445,7 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) p->buffer = NULL; return NULL; - } - if (newbuffer) - { + } else { memcpy(newbuffer, p->buffer, p->offset + 1); } p->hooks.deallocate(p->buffer); @@ -1436,7 +1434,7 @@ fail: static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) { unsigned char *output_pointer = NULL; - size_t length = 0; + size_t length; cJSON *current_element = item->child; if (output_buffer == NULL) diff --git a/rtengine/calc_distort.h b/rtengine/calc_distort.h index 711bf9515..7d0c5ef54 100644 --- a/rtengine/calc_distort.h +++ b/rtengine/calc_distort.h @@ -1,4 +1,3 @@ -#ifndef CALC_DISTORTION__H -#define CALC_DISTORTION__H +#pragma once + int calcDistortion (unsigned char* img1, unsigned char* img2, int ncols, int nrows, int nfactor, double &distortion); -#endif diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index 43de5d688..e8f7b1cbf 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -2,6 +2,9 @@ * This file is part of RawTherapee. */ #include "camconst.h" +#include +#include +#include #include "settings.h" #include "rt_math.h" #include @@ -17,8 +20,6 @@ namespace rtengine { -extern const Settings* settings; - CameraConst::CameraConst() : pdafOffset(0) { memset(dcraw_matrix, 0, sizeof(dcraw_matrix)); diff --git a/rtengine/camconst.h b/rtengine/camconst.h index eb43da483..1096e1767 100644 --- a/rtengine/camconst.h +++ b/rtengine/camconst.h @@ -1,11 +1,11 @@ /* * This file is part of RawTherapee. */ -#ifndef __CAMCONST__ -#define __CAMCONST__ +#pragma once -#include +#include #include +#include namespace rtengine { @@ -72,5 +72,3 @@ public: }; } - -#endif diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 7f481e104..8639ea2e1 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1,4 +1,5 @@ /* +vim: set syntax=javascript: DO NOT EDIT THIS FILE! @@ -1137,6 +1138,16 @@ Camera constants: } }, + { // Quality C, only raw crop + "make_model": [ "Canon EOS M6 Mark II", "Canon EOS 90D" ], + "raw_crop": [ 144, 72, 6984, 4660 ] + }, + + { // Quality C, only raw crop + "make_model": [ "Canon EOS R" ], + "raw_crop": [ 144, 46, 6744, 4500 ] + }, + // Canon Powershot { // Quality C, CHDK DNGs, raw frame correction "make_model": "Canon PowerShot A3100 IS", @@ -1277,6 +1288,16 @@ Camera constants: "ranges": { "white": 16100 } }, + { // Quality C + "make_model": "Fujifilm X10", + "ranges": { "white": 3788 } + }, + + { // Quality C + "make_model": "Fujifilm HS30EXR", + "ranges": { "white": 3765 } + }, + { // Quality B "make_model": "FUJIFILM X70", "dcraw_matrix": [ 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 ], // DNG_v9.4 D65 @@ -1481,6 +1502,12 @@ Camera constants: } }, + { // Quality B + "make_model": "NIKON COOLPIX P1000", + "dcraw_matrix": [ 14294, -6116, -1333, -1628, 10219, 1637, -14, 1158, 5022 ], // ColorMatrix2 from Adobe DNG Converter 11.4 + "ranges": { "black": 200, "white": 4093 } + }, + { // Quality B, no LENR samples "make_model": "Nikon D5", "dcraw_matrix": [ 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 ], // adobe dng_v9.5 d65 @@ -2136,6 +2163,31 @@ Camera constants: } }, + { // Quality A, issue #5204. + "make_model": [ "Panasonic DC-S1" ], + "dcraw_matrix": [ 9744, -3905, -779, -4899, 12807, 2324, -798, 1630, 5827 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 11.4 + "ranges": { + "white": [ + { "iso": 50, "levels": 8400 }, // LENR 8000 + { "iso": 64, "levels": 10450 }, // LENR 10000 + { "iso": 80, "levels": 13050 }, // LENR 12400 + { "iso": 100, "levels": 16320 } + ] + } + }, + + { // Quality X, issue #5204. No white frames available. + "make_model": [ "Panasonic DC-S1R" ], + "dcraw_matrix": [ 11822, -5321, -1249, -5958, 15114, 766, -614, 1264, 7043 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 11.4 + "ranges": { + "white": [ + { "iso": 50, "levels": 9500 }, + { "iso": [64, 80], "levels": 11600 }, + { "iso": 100, "levels": 16336 } + ] + } + }, + { // Quality B, per ISO info missing "make_model": "PENTAX K-x", "dcraw_matrix": [ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 ], // adobe dcp d65 @@ -2474,7 +2526,7 @@ Camera constants: { // Quality C, "make_model": "Sony ILCE-7RM4", - "raw_crop": [ 0, 0, 9568, 0 ] // full raw frame 9600x6376 - 32 rightmost columns are garbage + "raw_crop": [ 0, 0, -32, 0 ] // full raw frame 9600x6376 - 32 rightmost columns are garbage. Using -32 instead of 9568 to support also 16-shot pixelshift files }, { // Quality B, color matrix copied from a7rm2 diff --git a/rtengine/canon_cr3_decoder.cc b/rtengine/canon_cr3_decoder.cc new file mode 100644 index 000000000..6274154cb --- /dev/null +++ b/rtengine/canon_cr3_decoder.cc @@ -0,0 +1,3241 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 RawTherapee development team + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +// Code adapted from ART +/* + * + * This file is part of ART. + * + * ART is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ART is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ART. If not, see . +*/ + +// Code adapted from libraw +/* -*- C++ -*- + * Copyright 2019 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +*/ + +#include +#include +#include +#include +#include + +#include "dcraw.h" + +#include "rt_math.h" + +void DCraw::parse_canon_cr3() +{ + strncpy(make, "Canon", sizeof(make)); + + unsigned long long szAtomList = ifp->size; + short nesting = -1; + char AtomNameStack[128]; + unsigned short nTrack = 0; + short TrackType; + + const int err = parseCR3(0, szAtomList, nesting, AtomNameStack, nTrack, TrackType); + + if (err == 0 || err == -14) { // no error, or too deep nesting + selectCRXTrack(nTrack); + } +} + +void DCraw::selectCRXTrack(unsigned short maxTrack) +{ + std::int64_t bitcounts[CanonCR3Data::CRXTRACKS_MAXCOUNT] = {}; + std::int64_t maxbitcount = 0; + std::uint32_t maxjpegbytes = 0; + + for (unsigned int i = 0; i <= maxTrack && i < RT_canon_CR3_data.CRXTRACKS_MAXCOUNT; ++i) { + CanonCR3Data::crx_data_header_t* const d = &RT_canon_CR3_data.crx_header[i]; + + if (d->MediaType == 1) { // RAW + bitcounts[i] = std::int64_t(d->nBits) * std::int64_t(d->f_width) * std::int64_t(d->f_height); + + if (bitcounts[i] > maxbitcount) { + maxbitcount = bitcounts[i]; + } + } else if (d->MediaType == 2) { // JPEG + if (d->MediaSize > maxjpegbytes) { + maxjpegbytes = d->MediaSize; + thumb_offset = d->MediaOffset; + thumb_length = d->MediaSize; + } + } + } + + if (maxbitcount < 8) { + return; + } + + bool has_framei = false; + unsigned int framei = 0; + unsigned int framecnt = 0; + + for (unsigned int i = 0; i <= maxTrack && i < RT_canon_CR3_data.CRXTRACKS_MAXCOUNT; ++i) { + if (bitcounts[i] == maxbitcount) { + if (framecnt <= shot_select) { + has_framei = true; + framei = i; + } + + framecnt++; + } + } + + is_raw = framecnt; + + if (has_framei) { + CanonCR3Data::crx_data_header_t* const d = &RT_canon_CR3_data.crx_header[framei]; + data_offset = d->MediaOffset; + // data_size = d->MediaSize; + raw_width = d->f_width; + raw_height = d->f_height; + load_raw = &DCraw::crxLoadRaw; + + switch (d->cfaLayout) { + case 0: { + filters = 0x94949494; + break; + } + + case 1: { + filters = 0x61616161; + break; + } + + case 2: { + filters = 0x49494949; + break; + } + + case 3: { + filters = 0x16161616; + break; + } + } + + RT_canon_CR3_data.crx_track_selected = framei; + + int tiff_idx = -1; + std::int64_t tpixels = 0; + + for (unsigned int i = 0; i < tiff_nifds; ++i) { + if (std::int64_t(tiff_ifd[i].height) * std::int64_t(tiff_ifd[i].height) > tpixels) { + tpixels = std::int64_t(tiff_ifd[i].height) * std::int64_t(tiff_ifd[i].height); + tiff_idx = i; + } + } + + if (tiff_idx >= 0) { + flip = tiff_ifd[tiff_idx].flip; + } + } +} + +int DCraw::parseCR3( + unsigned long long oAtomList, + unsigned long long szAtomList, + short& nesting, + char* AtomNameStack, + unsigned short& nTrack, + short& TrackType +) +{ + /* + Atom starts with 4 bytes for Atom size and 4 bytes containing Atom name + Atom size includes the length of the header and the size of all "contained" + Atoms if Atom size == 1, Atom has the extended size stored in 8 bytes located + after the Atom name if Atom size == 0, it is the last top-level Atom extending + to the end of the file Atom name is often a 4 symbol mnemonic, but can be a + 4-byte integer + */ + const char UIID_Canon[17] = + "\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48"; +// const char UIID_Preview[17] = +// "\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16"; + + /* + AtomType = 0 - unknown: "unk." + AtomType = 1 - container atom: "cont" + AtomType = 2 - leaf atom: "leaf" + AtomType = 3 - can be container, can be leaf: "both" + */ +// const char sAtomeType[4][5] = {"unk.", "cont", "leaf", "both"}; + short AtomType; + static const struct { + char AtomName[5]; + short AtomType; + } AtomNamesList[] = { + {"dinf", 1}, + {"edts", 1}, + {"fiin", 1}, + {"ipro", 1}, + {"iprp", 1}, + {"mdia", 1}, + {"meco", 1}, + {"mere", 1}, + {"mfra", 1}, + {"minf", 1}, + {"moof", 1}, + {"moov", 1}, + {"mvex", 1}, + {"paen", 1}, + {"schi", 1}, + {"sinf", 1}, + {"skip", 1}, + {"stbl", 1}, + {"stsd", 1}, + {"strk", 1}, + {"tapt", 1}, + {"traf", 1}, + {"trak", 1}, + + {"cdsc", 2}, + {"colr", 2}, + {"dimg", 2}, + // {"dref", 2}, + {"free", 2}, + {"frma", 2}, + {"ftyp", 2}, + {"hdlr", 2}, + {"hvcC", 2}, + {"iinf", 2}, + {"iloc", 2}, + {"infe", 2}, + {"ipco", 2}, + {"ipma", 2}, + {"iref", 2}, + {"irot", 2}, + {"ispe", 2}, + {"meta", 2}, + {"mvhd", 2}, + {"pitm", 2}, + {"pixi", 2}, + {"schm", 2}, + {"thmb", 2}, + {"tkhd", 2}, + {"url ", 2}, + {"urn ", 2}, + + {"CCTP", 1}, + {"CRAW", 1}, + + {"JPEG", 2}, + {"CDI1", 2}, + {"CMP1", 2}, + + {"CNCV", 2}, + {"CCDT", 2}, + {"CTBO", 2}, + {"CMT1", 2}, + {"CMT2", 2}, + {"CMT3", 2}, + {"CMT4", 2}, + {"THMB", 2}, + {"co64", 2}, + {"mdat", 2}, + {"mdhd", 2}, + {"nmhd", 2}, + {"stsc", 2}, + {"stsz", 2}, + {"stts", 2}, + {"vmhd", 2}, + + {"dref", 3}, + {"uuid", 3}, + }; + + const char sHandlerType[5][5] = { + "unk.", + "soun", + "vide", + "hint", + "meta" + }; + + int err = 0; + + unsigned short tL; // Atom length represented in 4 or 8 bytes + char nmAtom[5]; // Atom name + unsigned long long oAtom; + unsigned long long szAtom; // Atom offset and Atom size + unsigned long long oAtomContent; + unsigned long long szAtomContent; // offset and size of Atom content + unsigned long long lHdr; + + char UIID[16]; + uchar CMP1[36]; + char HandlerType[5]; + char MediaFormatID[5]; +// unsigned int ImageWidth, ImageHeight; + unsigned long relpos_inDir; + unsigned long relpos_inBox; + unsigned int szItem; + unsigned int Tag; + unsigned int lTag; + unsigned short tItem; + + nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0'; + strncpy(HandlerType, sHandlerType[0], sizeof(HandlerType)); +// ImageWidth = ImageHeight = 0U; + oAtom = oAtomList; + ++nesting; + + if (nesting > 31) { + return -14; // too deep nesting + } + + short s_order = order; + + const auto is_bad_header = + [this]() -> bool + { + return + ( + order != 0x4D4D + && order != 0x4949 + ) + || get2() != 0x002A + || get4() != 0x00000008; + }; + + while ((oAtom + 8) <= (oAtomList + szAtomList)) { + lHdr = 0U; + err = 0; + order = 0x4D4D; + fseek(ifp, oAtom, SEEK_SET); + szAtom = get4(); + for (unsigned int c = 0; c < 4; ++c) { + nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp); + } + AtomNameStack[(nesting + 1) * 4] = '\0'; + tL = 4; + AtomType = 0; + + for (const auto& atom : AtomNamesList) { + if (!strcmp(nmAtom, atom.AtomName)) { + AtomType = atom.AtomType; + break; + } + } + + if (!AtomType) { + err = 1; + } + + if (szAtom == 0) { + if (nesting != 0) { + err = -2; + goto fin; + } + + szAtom = szAtomList - oAtom; + oAtomContent = oAtom + 8; + szAtomContent = szAtom - 8; + } else if (szAtom == 1) { + if ((oAtom + 16) > (oAtomList + szAtomList)) { + err = -3; + goto fin; + } + + tL = 8; + szAtom = (static_cast(get4()) << 32) | get4(); + oAtomContent = oAtom + 16; + szAtomContent = szAtom - 16; + } else { + oAtomContent = oAtom + 8; + szAtomContent = szAtom - 8; + } + + if (!strcmp(nmAtom, "trak")) { + nTrack++; + TrackType = 0; + + if (nTrack >= RT_canon_CR3_data.CRXTRACKS_MAXCOUNT) { + break; + } + } + + if (!strcmp(AtomNameStack, "moovuuid")) { + lHdr = 16; + fread(UIID, 1, lHdr, ifp); + + if (!strncmp(UIID, UIID_Canon, lHdr)) { + AtomType = 1; + } else { + fseek(ifp, -lHdr, SEEK_CUR); + } + } else if (!strcmp(AtomNameStack, "moovuuidCCTP")) { + lHdr = 12; + } else if (!strcmp(AtomNameStack, "moovuuidCMT1")) { + const short q_order = order; + order = get2(); + + if (tL != 4 || is_bad_header()) { + err = -4; + goto fin; + } + + parse_tiff_ifd(oAtomContent); + order = q_order; + } else if (!strcmp(AtomNameStack, "moovuuidCMT2")) { + const short q_order = order; + order = get2(); + + if (tL != 4 || is_bad_header()) { + err = -5; + goto fin; + } + + parse_exif(oAtomContent); + order = q_order; + } else if (!strcmp(AtomNameStack, "moovuuidCMT3")) { + const short q_order = order; + order = get2(); + + if (tL != 4 || is_bad_header()) { + err = -6; + goto fin; + } + + fseek(ifp, -12L, SEEK_CUR); + parse_makernote(oAtomContent, 0); + order = q_order; + } else if (!strcmp(AtomNameStack, "moovuuidCMT4")) { + const short q_order = order; + order = get2(); + + if (tL != 4 || is_bad_header()) { + err = -6; + goto fin; + } + + const long off = ftell(ifp); + parse_gps(oAtomContent); + fseek(ifp, off, SEEK_SET); +// parse_gps_libraw(oAtomContent); + order = q_order; + } else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr")) { + fseek(ifp, 8, SEEK_CUR); + for (unsigned int c = 0; c < 4; ++c) { + HandlerType[c] = fgetc(ifp); + } + + for (unsigned int c = 1; c < sizeof(sHandlerType) / sizeof(*sHandlerType); ++c) { + if (!strcmp(HandlerType, sHandlerType[c])) { + TrackType = c; + break; + } + } + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsd")) { + if (szAtomContent >= 16) { + fseek(ifp, 12, SEEK_CUR); + lHdr = 8; + } else { + err = -7; + goto fin; + } + + for (unsigned int c = 0; c < 4; ++c) { + MediaFormatID[c] = fgetc(ifp); + } + + if (TrackType == 2 && !strcmp(MediaFormatID, "CRAW")) { + if (szAtomContent >= 44) { + fseek(ifp, 24, SEEK_CUR); + } else { + err = -8; + goto fin; + } + } else { + AtomType = 2; // only continue for CRAW + lHdr = 0; + } + + /*ImageWidth = */ get2(); + /*ImageHeight = */ get2(); + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW")) { + lHdr = 82; + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCMP1")) { + if (szAtomContent >= 40) { + fread(CMP1, 1, 36, ifp); + } else { + err = -7; + goto fin; + } + + if (crxParseImageHeader(CMP1, nTrack)) { + RT_canon_CR3_data.crx_header[nTrack].MediaType = 1; + } + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG")) { + RT_canon_CR3_data.crx_header[nTrack].MediaType = 2; + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz")) { + if (szAtomContent == 12) { + fseek(ifp, 4, SEEK_CUR); + } else if (szAtomContent == 16) { + fseek(ifp, 12, SEEK_CUR); + } else { + err = -9; + goto fin; + } + + RT_canon_CR3_data.crx_header[nTrack].MediaSize = get4(); + } else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64")) { + if (szAtomContent == 16) { + fseek(ifp, 8, SEEK_CUR); + } else { + err = -10; + goto fin; + } + + RT_canon_CR3_data.crx_header[nTrack].MediaOffset = (static_cast(get4()) << 32) | get4(); + } + + if ( + RT_canon_CR3_data.crx_header[nTrack].MediaSize + && RT_canon_CR3_data.crx_header[nTrack].MediaOffset + && oAtom + szAtom >= oAtomList + szAtomList + && !strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20) + ) { + if (TrackType == 4 && !strcmp(MediaFormatID, "CTMD")) { + order = 0x4949; + relpos_inDir = 0; + + while (relpos_inDir + 6 < RT_canon_CR3_data.crx_header[nTrack].MediaSize) { + fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inDir, SEEK_SET); + szItem = get4(); + tItem = get2(); + + if ((relpos_inDir + szItem) > RT_canon_CR3_data.crx_header[nTrack].MediaSize) { + err = -11; + goto fin; + } + + if ( + tItem == 7 + || tItem == 8 + || tItem == 9 + ) { + relpos_inBox = relpos_inDir + 12; + + while (relpos_inBox + 8 < relpos_inDir + szItem) { + fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox, SEEK_SET); + lTag = get4(); + Tag = get4(); + + if (lTag < 8) { + err = -12; + goto fin; + } else if (relpos_inBox + lTag > relpos_inDir + szItem) { + err = -11; + goto fin; + } + + if ( + Tag == 0x927C + && ( + tItem == 7 + || tItem == 8 + ) + ) { + fseek(ifp, RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox + 8, SEEK_SET); + const short q_order = order; + order = get2(); + + if (is_bad_header()) { + err = -13; + goto fin; + } + + fseek(ifp, -8, SEEK_CUR); + RT_canon_CR3_data.CR3_CTMDtag = 1; + parse_makernote(RT_canon_CR3_data.crx_header[nTrack].MediaOffset + relpos_inBox + 8, 0); + RT_canon_CR3_data.CR3_CTMDtag = 0; + order = q_order; + } + + relpos_inBox += lTag; + } + } + + relpos_inDir += szItem; + } + + order = 0x4D4D; + } + } + + if (AtomType == 1) { + err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting, AtomNameStack, nTrack, TrackType); + + if (err) { + goto fin; + } + } + + oAtom += szAtom; + } + +fin: + --nesting; + + if (nesting >= 0) { + AtomNameStack[nesting * 4] = '\0'; + } + + order = s_order; + return err; +} + +// ----------------------------------------------------------------------------- + +namespace +{ + +unsigned int sgetn(int n, unsigned char* s) +{ + unsigned int result = 0; + + while (n-- > 0) { + result = (result << 8) | (*s++); + } + + return result; +} + +// this should be divisible by 4 +constexpr std::uint64_t CRX_BUF_SIZE = 0x10000; + +#if !defined (_WIN32) || (defined (__GNUC__) && !defined (__INTRINSIC_SPECIAL__BitScanReverse)) +/* __INTRINSIC_SPECIAL__BitScanReverse found in MinGW32-W64 v7.30 headers, may be there is a better solution? */ +inline void _BitScanReverse(std::uint32_t* Index, unsigned long Mask) +{ + *Index = sizeof(unsigned long) * 8 - 1 - __builtin_clzl(Mask); +} +std::uint32_t _byteswap_ulong(std::uint32_t x) +{ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return x; +#else + return __builtin_bswap32(x); +#endif +} +#endif + +struct LibRaw_abstract_datastream { + IMFILE* ifp; + + void lock() + { + } + void unlock() + { + } + void seek(long p, int how) + { + fseek(ifp, p, how); + } + int read(void* dst, int es, int count) + { + return fread(dst, es, count, ifp); + } +}; + +struct CrxBitstream { + std::uint8_t mdatBuf[CRX_BUF_SIZE]; + std::uint64_t mdatSize; + std::uint64_t curBufOffset; + std::uint32_t curPos; + std::uint32_t curBufSize; + std::uint32_t bitData; + std::int32_t bitsLeft; + LibRaw_abstract_datastream* input; +}; + +struct CrxBandParam { + CrxBitstream bitStream; + std::int16_t subbandWidth; + std::int16_t subbandHeight; + std::int32_t roundedBitsMask; + std::int32_t roundedBits; + std::int16_t curLine; + std::int32_t* lineBuf0; + std::int32_t* lineBuf1; + std::int32_t* lineBuf2; + std::int32_t sParam; + std::int32_t kParam; + std::int32_t* paramData; + std::int32_t* nonProgrData; + bool supportsPartial; +}; + +struct CrxWaveletTransform { + std::int32_t* subband0Buf; + std::int32_t* subband1Buf; + std::int32_t* subband2Buf; + std::int32_t* subband3Buf; + std::int32_t* lineBuf[8]; + std::int16_t curLine; + std::int16_t curH; + std::int8_t fltTapH; + std::int16_t height; + std::int16_t width; +}; + +struct CrxSubband { + CrxBandParam* bandParam; + std::uint64_t mdatOffset; + std::uint8_t* bandBuf; + std::int32_t bandSize; + std::uint64_t dataSize; + bool supportsPartial; + std::int32_t quantValue; + std::uint16_t width; + std::uint16_t height; + std::int32_t paramK; + std::int64_t dataOffset; +}; + +struct CrxPlaneComp { + std::uint8_t* compBuf; + CrxSubband* subBands; + CrxWaveletTransform* waveletTransform; + std::int8_t compNumber; + std::int64_t dataOffset; + std::int32_t compSize; + bool supportsPartial; + std::int32_t roundedBitsMask; + std::int8_t tileFlag; +}; + +struct CrxTile { + CrxPlaneComp* comps; + std::int8_t tileFlag; + std::int8_t tileNumber; + std::int64_t dataOffset; + std::int32_t tileSize; + std::uint16_t width; + std::uint16_t height; +}; + +struct CrxImage { + std::uint8_t nPlanes; + std::uint16_t planeWidth; + std::uint16_t planeHeight; + std::uint8_t samplePrecision; + std::uint8_t subbandCount; + std::uint8_t levels; + std::uint8_t nBits; + std::uint8_t encType; + std::uint8_t tileCols; + std::uint8_t tileRows; + CrxTile* tiles; + std::uint64_t mdatOffset; + std::uint64_t mdatSize; + std::int16_t* outBufs[4]; // one per plane + std::int16_t* planeBuf; + LibRaw_abstract_datastream* input; +}; + +enum TileFlags { + E_HAS_TILES_ON_THE_RIGHT = 1, + E_HAS_TILES_ON_THE_LEFT = 2, + E_HAS_TILES_ON_THE_BOTTOM = 4, + E_HAS_TILES_ON_THE_TOP = 8 +}; + +const std::int32_t exCoefNumTbl[0x120] = { + // level 1 + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + // level 2 + 1, 1, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 3, 2, 1, 0, 1, 0, 0, 0, 0, 0, 1, + 2, 4, 4, 2, 1, 2, 1, 0, 0, 0, 0, 1, 1, 4, 3, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, + 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 3, 2, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 4, + 4, 2, 1, 2, 1, 0, 0, 0, 0, 1, 1, 4, 3, 1, 1, 1, 1, 0, 0, 0, 0, + + // level 3 + 1, 1, 7, 7, 1, 1, 3, 3, 1, 1, 1, 1, 1, 0, 7, 6, 1, 0, 3, 2, 1, 0, 1, 0, 1, + 2, 10, 10, 2, 2, 5, 4, 2, 1, 2, 1, 1, 1, 10, 9, 1, 2, 4, 4, 2, 1, 2, 1, 1, + 1, 9, 9, 1, 2, 4, 4, 2, 1, 2, 1, 1, 0, 9, 8, 1, 1, 4, 3, 1, 1, 1, 1, 1, 2, + 8, 8, 2, 1, 4, 3, 1, 1, 1, 1, 1, 1, 8, 7, 1, 1, 3, 3, 1, 1, 1, 1 +}; + +const std::uint32_t JS[32] = { + 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0010, 0x0010, 0x0020, 0x0020, 0x0040, 0x0040, 0x0080, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 +}; + +const std::uint32_t J[32] = { + 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, + 0x2, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, + 0x7, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF +}; + +inline void crxFillBuffer(CrxBitstream* bitStrm) +{ + if (bitStrm->curPos >= bitStrm->curBufSize && bitStrm->mdatSize) { + bitStrm->curPos = 0; + bitStrm->curBufOffset += bitStrm->curBufSize; +#ifdef _OPENMP + #pragma omp critical +#endif + { +#ifndef _OPENMP + bitStrm->input->lock(); +#endif + bitStrm->input->seek(bitStrm->curBufOffset, SEEK_SET); + bitStrm->curBufSize = bitStrm->input->read(bitStrm->mdatBuf, 1, std::min(bitStrm->mdatSize, CRX_BUF_SIZE)); +#ifndef _OPENMP + bitStrm->input->unlock(); +#endif + + if (bitStrm->curBufSize < 1) { // nothing read + throw std::exception(); + } + + bitStrm->mdatSize -= bitStrm->curBufSize; + } + } +} + +inline int crxBitstreamGetZeros(CrxBitstream* bitStrm) +{ +// std::uint32_t bitData = bitStrm->bitData; + std::uint32_t nonZeroBit = 0; + std::uint64_t nextData = 0; + std::int32_t result = 0; + + if (bitStrm->bitData) { + _BitScanReverse(&nonZeroBit, bitStrm->bitData); + result = 31 - nonZeroBit; + bitStrm->bitData <<= 32 - nonZeroBit; + bitStrm->bitsLeft -= 32 - nonZeroBit; + } else { + std::uint32_t bitsLeft = bitStrm->bitsLeft; + + while (true) { + while (bitStrm->curPos + 4 <= bitStrm->curBufSize) { + nextData = _byteswap_ulong(*reinterpret_cast(bitStrm->mdatBuf + bitStrm->curPos)); + bitStrm->curPos += 4; + crxFillBuffer(bitStrm); + + if (nextData) { + _BitScanReverse(&nonZeroBit, static_cast(nextData)); + result = bitsLeft + 31 - nonZeroBit; + bitStrm->bitData = nextData << (32 - nonZeroBit); + bitStrm->bitsLeft = nonZeroBit; + return result; + } + + bitsLeft += 32; + } + + if (bitStrm->curBufSize < bitStrm->curPos + 1) { + break; // error + } + + nextData = bitStrm->mdatBuf[bitStrm->curPos++]; + crxFillBuffer(bitStrm); + + if (nextData) { + break; + } + + bitsLeft += 8; + } + + _BitScanReverse(&nonZeroBit, static_cast(nextData)); + result = static_cast(bitsLeft + 7 - nonZeroBit); + bitStrm->bitData = nextData << (32 - nonZeroBit); + bitStrm->bitsLeft = nonZeroBit; + } + + return result; +} + +inline std::uint32_t crxBitstreamGetBits(CrxBitstream* bitStrm, int bits) +{ + int bitsLeft = bitStrm->bitsLeft; + std::uint32_t bitData = bitStrm->bitData; + std::uint32_t nextWord; + std::uint8_t nextByte; + std::uint32_t result; + + if (bitsLeft < bits) { + // get them from stream + if (bitStrm->curPos + 4 <= bitStrm->curBufSize) { + nextWord = _byteswap_ulong(*reinterpret_cast(bitStrm->mdatBuf + bitStrm->curPos)); + bitStrm->curPos += 4; + crxFillBuffer(bitStrm); + bitStrm->bitsLeft = 32 - (bits - bitsLeft); + result = ((nextWord >> bitsLeft) | bitData) >> (32 - bits); + bitStrm->bitData = nextWord << (bits - bitsLeft); + return result; + } + + // less than a word left - read byte at a time + do { + if (bitStrm->curPos >= bitStrm->curBufSize) { + break; // error + } + + bitsLeft += 8; + nextByte = bitStrm->mdatBuf[bitStrm->curPos++]; + crxFillBuffer(bitStrm); + bitData |= nextByte << (32 - bitsLeft); + } while (bitsLeft < bits); + } + + result = bitData >> (32 - bits); // 32-bits + bitStrm->bitData = bitData << bits; + bitStrm->bitsLeft = bitsLeft - bits; + return result; +} + +inline std::int32_t crxPredictKParameter(std::int32_t prevK, std::int32_t bitCode, std::int32_t maxVal = 0) +{ + const std::int32_t newKParam = + prevK + - (bitCode < (1 << prevK >> 1)) + + ((bitCode >> prevK) > 2) + ((bitCode >> prevK) > 5); + + return + !maxVal || newKParam < maxVal + ? newKParam + : maxVal; +} + +inline void crxDecodeSymbolL1(CrxBandParam* param, bool doMedianPrediction, bool notEOL = false) +{ + if (doMedianPrediction) { + const std::int32_t delta = param->lineBuf0[1] - param->lineBuf0[0]; + const std::int32_t symb[4] = { + delta + param->lineBuf1[0], + delta + param->lineBuf1[0], + param->lineBuf1[0], + param->lineBuf0[1] + }; + + param->lineBuf1[1] = symb[ + (((param->lineBuf0[0] < param->lineBuf1[0]) ^ (delta < 0)) << 1) + + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (delta < 0)) + ]; + } else { + param->lineBuf1[1] = param->lineBuf0[1]; + } + + // get next error symbol + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + // add converted (+/-) error code to predicted value + param->lineBuf1[1] += -(bitCode & 1) ^ (bitCode >> 1); + + // for not end of the line - use one symbol ahead to estimate next K + if (notEOL) { + const std::int32_t nextDelta = (param->lineBuf0[2] - param->lineBuf0[1]) << 1; + bitCode = (bitCode + std::abs(nextDelta)) >> 1; + ++param->lineBuf0; + } + + // update K parameter + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + + ++param->lineBuf1; +} + +bool crxDecodeLine(CrxBandParam* param) +{ + int length = param->subbandWidth; + + param->lineBuf1[0] = param->lineBuf0[1]; + + for (; length > 1; --length) { + if (param->lineBuf1[0] != param->lineBuf0[1] || param->lineBuf1[0] != param->lineBuf0[2]) { + crxDecodeSymbolL1(param, true, true); + } else { + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + int nSyms = 1; + + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (nSyms > length) { + nSyms = length; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (nSyms == length) { + break; + } + } + + if (nSyms < length) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + + if (nSyms > length) { + return false; + } + } + + length -= nSyms; + + // copy symbol nSyms times + param->lineBuf0 += nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + } + + if (length > 0) { + crxDecodeSymbolL1(param, false, length > 1); + } + } + } + + if (length == 1) { + crxDecodeSymbolL1(param, true, false); + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return true; +} + +inline void crxDecodeSymbolL1Rounded(CrxBandParam* param, bool doSym = true, bool doCode = true) +{ + std::int32_t sym = param->lineBuf0[1]; + + if (doSym) { + // calculate the next symbol gradient + const std::int32_t deltaH = param->lineBuf0[1] - param->lineBuf0[0]; + const std::int32_t symb[4] = { + deltaH + param->lineBuf1[0], + deltaH + param->lineBuf1[0], + param->lineBuf1[0], + param->lineBuf0[1] + }; + sym = symb[ + (((param->lineBuf0[0] < param->lineBuf1[0]) ^ (deltaH < 0)) << 1) + + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (deltaH < 0)) + ]; + } + + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + std::int32_t code = -(bitCode & 1) ^ (bitCode >> 1); + param->lineBuf1[1] = param->roundedBitsMask * 2 * code + (code < 0) + sym; + + if (doCode) { + if (param->lineBuf0[2] > param->lineBuf0[1]) { + code = (param->lineBuf0[2] - param->lineBuf0[1] + param->roundedBitsMask - 1) >> param->roundedBits; + } else { + code = -((param->lineBuf0[1] - param->lineBuf0[2] + param->roundedBitsMask) >> param->roundedBits); + } + + param->kParam = crxPredictKParameter(param->kParam, (bitCode + 2 * std::abs(code)) >> 1, 15); + } else { + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + } + + ++param->lineBuf1; +} + +bool crxDecodeLineRounded(CrxBandParam* param) +{ + bool valueReached = false; + + param->lineBuf0[0] = param->lineBuf0[1]; + param->lineBuf1[0] = param->lineBuf0[1]; + std::int32_t length = param->subbandWidth; + + for (; length > 1; --length) { + if (std::abs(param->lineBuf0[2] - param->lineBuf0[1]) > param->roundedBitsMask) { + crxDecodeSymbolL1Rounded(param); + ++param->lineBuf0; + valueReached = true; + } else if (valueReached || std::abs(param->lineBuf0[0] - param->lineBuf1[0]) > param->roundedBitsMask) { + crxDecodeSymbolL1Rounded(param); + ++param->lineBuf0; + valueReached = false; + } else { + int nSyms = 0; + + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms = 1; + + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (nSyms > length) { + nSyms = length; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (nSyms == length) { + break; + } + } + + if (nSyms < length) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + } + + if (nSyms > length) { + return false; + } + } + + length -= nSyms; + + // copy symbol nSyms times + param->lineBuf0 += nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length > 1) { + crxDecodeSymbolL1Rounded(param, false); + ++param->lineBuf0; + valueReached = std::abs(param->lineBuf0[1] - param->lineBuf0[0]) > param->roundedBitsMask; + } else if (length == 1) { + crxDecodeSymbolL1Rounded(param, false, false); + } + } + } + + if (length == 1) { + crxDecodeSymbolL1Rounded(param, true, false); + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return true; +} + +bool crxDecodeLineNoRefPrevLine(CrxBandParam* param) +{ + std::int32_t i = 0; + + for (; i < param->subbandWidth - 1; ++i) { + if (param->lineBuf0[i + 2] || param->lineBuf0[i + 1] || param->lineBuf1[i]) { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode); + + if (param->lineBuf2[i + 1] - param->kParam <= 1) { + if (param->kParam >= 15) { + param->kParam = 15; + } + } else { + ++param->kParam; + } + } else { + int nSyms = 0; + + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms = 1; + + if (i != param->subbandWidth - 1) { + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (i + nSyms > param->subbandWidth) { + nSyms = param->subbandWidth - i; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (i + nSyms == param->subbandWidth) { + break; + } + } + + if (i + nSyms < param->subbandWidth) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + } + + if (i + nSyms > param->subbandWidth) { + return false; + } + } + } else if (i > param->subbandWidth) { + return false; + } + + if (nSyms > 0) { + memset(param->lineBuf1 + i + 1, 0, nSyms * sizeof(std::int32_t)); + memset(param->lineBuf2 + i, 0, nSyms * sizeof(std::int32_t)); + i += nSyms; + } + + if (i >= param->subbandWidth - 1) { + if (i == param->subbandWidth - 1) { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[i + 1] = -((bitCode + 1) & 1) ^ ((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[i] = param->kParam; + } + + continue; + } else { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[i + 1] = -((bitCode + 1) & 1) ^ ((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode); + + if (param->lineBuf2[i + 1] - param->kParam <= 1) { + if (param->kParam >= 15) { + param->kParam = 15; + } + } else { + ++param->kParam; + } + } + } + + param->lineBuf2[i] = param->kParam; + } + + if (i == param->subbandWidth - 1) { + std::int32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[i] = param->kParam; + } + + return true; +} + +bool crxDecodeTopLine(CrxBandParam* param) +{ + param->lineBuf1[0] = 0; + + std::int32_t length = param->subbandWidth; + + // read the line from bitstream + for (; length > 1; --length) { + if (param->lineBuf1[0]) { + param->lineBuf1[1] = param->lineBuf1[0]; + } else { + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + int nSyms = 1; + + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (nSyms > length) { + nSyms = length; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (nSyms == length) { + break; + } + } + + if (nSyms < length) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + + if (nSyms > length) { + return false; + } + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length <= 0) { + break; + } + } + + param->lineBuf1[1] = 0; + } + + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[1] += -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + if (length == 1) { + param->lineBuf1[1] = param->lineBuf1[0]; + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[1] += -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return true; +} + +bool crxDecodeTopLineRounded(CrxBandParam* param) +{ + param->lineBuf1[0] = 0; + + std::int32_t length = param->subbandWidth; + + // read the line from bitstream + for (; length > 1; --length) { + if (std::abs(param->lineBuf1[0]) > param->roundedBitsMask) { + param->lineBuf1[1] = param->lineBuf1[0]; + } else { + int nSyms = 0; + + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms = 1; + + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (nSyms > length) { + nSyms = length; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (nSyms == length) { + break; + } + } + + if (nSyms < length) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + + if (nSyms > length) { + return false; + } + } + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length <= 0) { + break; + } + + param->lineBuf1[1] = 0; + } + + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + const std::int32_t sVal = -(bitCode & 1) ^ (bitCode >> 1); + param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + if (length == 1) { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + const std::int32_t sVal = -(bitCode & 1) ^ (bitCode >> 1); + param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return true; +} + +bool crxDecodeTopLineNoRefPrevLine(CrxBandParam* param) +{ + param->lineBuf0[0] = 0; + param->lineBuf1[0] = 0; + std::int32_t length = param->subbandWidth; + + for (; length > 1; --length) { + if (param->lineBuf1[0]) { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[1] = -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + } else { + int nSyms = 0; + + if (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms = 1; + + while (crxBitstreamGetBits(¶m->bitStream, 1)) { + nSyms += JS[param->sParam]; + + if (nSyms > length) { + nSyms = length; + break; + } + + if (param->sParam < 31) { + ++param->sParam; + } + + if (nSyms == length) { + break; + } + } + + if (nSyms < length) { + if (J[param->sParam]) { + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + } + + if (param->sParam > 0) { + --param->sParam; + } + + if (nSyms > length) { + return false; + } + } + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) { + param->lineBuf2[0] = 0; + param->lineBuf1[1] = 0; + ++param->lineBuf1; + ++param->lineBuf2; + } + + if (length <= 0) { + break; + } + + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[1] = -((bitCode + 1) & 1) ^ ((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + } + + param->lineBuf2[0] = param->kParam; + ++param->lineBuf2; + ++param->lineBuf1; + } + + if (length == 1) { + std::uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + + if (bitCode >= 41) { + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + } else if (param->kParam) { + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + } + + param->lineBuf1[1] = -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[0] = param->kParam; + ++param->lineBuf1; + } + + param->lineBuf1[1] = 0; + + return true; +} + +bool crxDecodeLine(CrxBandParam* param, std::uint8_t* bandBuf) +{ + if (!param || !bandBuf) { + return false; + } + + if (param->curLine >= param->subbandHeight) { + return false; + } + + if (param->curLine == 0) { + const std::int32_t lineLength = param->subbandWidth + 2; + + param->sParam = 0; + param->kParam = 0; + + if (param->supportsPartial) { + if (param->roundedBitsMask <= 0) { + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeTopLine(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } else { + param->roundedBits = 1; + + if (param->roundedBitsMask & ~1) { + while (param->roundedBitsMask >> param->roundedBits) { + ++param->roundedBits; + } + } + + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeTopLineRounded(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } + } else { + param->lineBuf2 = param->nonProgrData; + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeTopLineNoRefPrevLine(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } + } else if (!param->supportsPartial) { + const std::int32_t lineLength = param->subbandWidth + 2; + param->lineBuf2 = param->nonProgrData; + + if (param->curLine & 1) { + param->lineBuf1 = param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } else { + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeLineNoRefPrevLine(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } else if (param->roundedBitsMask <= 0) { + const std::int32_t lineLength = param->subbandWidth + 2; + + if (param->curLine & 1) { + param->lineBuf1 = param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } else { + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeLine(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } else { + const std::int32_t lineLength = param->subbandWidth + 2; + + if (param->curLine & 1) { + param->lineBuf1 = param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } else { + param->lineBuf0 = param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + + const std::int32_t* const lineBuf = param->lineBuf1 + 1; + + if (!crxDecodeLineRounded(param)) { + return false; + } + + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(std::int32_t)); + ++param->curLine; + } + + return true; +} + +bool crxDecodeLineWithIQuantization(CrxSubband* subband) +{ + constexpr std::int32_t q_step_tbl[6] = {0x28, 0x2D, 0x33, 0x39, 0x40, 0x48}; + + if (!subband->dataSize) { + memset(subband->bandBuf, 0, subband->bandSize); + return true; + } + + if (subband->supportsPartial) { + std::uint32_t bitCode = crxBitstreamGetZeros(&subband->bandParam->bitStream); + + if (bitCode >= 23) { + bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, 8); + } else if (subband->paramK) { + bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, subband->paramK) | (bitCode << subband->paramK); + } + + subband->quantValue += -(bitCode & 1) ^ (bitCode >> 1); // converting encoded to signed integer + subband->paramK = crxPredictKParameter(subband->paramK, bitCode); + + if (subband->paramK > 7) { + return false; + } + } + + if (!crxDecodeLine(subband->bandParam, subband->bandBuf)) { + return false; + } + + if (subband->width == 0) { + return true; + } + + // update subband buffers + std::int32_t* const bandBuf = reinterpret_cast(subband->bandBuf); + std::int32_t qScale = q_step_tbl[subband->quantValue % 6] >> (6 - subband->quantValue / 6); + + if (subband->quantValue / 6 >= 6) { + qScale = q_step_tbl[subband->quantValue % 6] * (1 << (subband->quantValue / 6 + 26)); + } + + if (qScale != 1) { + for (std::int32_t i = 0; i < subband->width; ++i) { + bandBuf[i] *= qScale; + } + } + + return true; +} + +void crxHorizontal53( + std::int32_t* lineBufLA, + std::int32_t* lineBufLB, + CrxWaveletTransform* wavelet, + std::uint32_t tileFlag +) +{ + std::int32_t* band0Buf = wavelet->subband0Buf; + std::int32_t* band1Buf = wavelet->subband1Buf; + std::int32_t* band2Buf = wavelet->subband2Buf; + std::int32_t* band3Buf = wavelet->subband3Buf; + + if (wavelet->width <= 1) { + lineBufLA[0] = band0Buf[0]; + lineBufLB[0] = band2Buf[0]; + } else { + if (tileFlag & E_HAS_TILES_ON_THE_LEFT) { + lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band1Buf; + ++band3Buf; + } else { + lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + + ++band0Buf; + ++band2Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) { + std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLA[1] = band1Buf[0] + ((delta + lineBufLA[0]) >> 1); + lineBufLA[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufLB[1] = band3Buf[0] + ((delta + lineBufLB[0]) >> 1); + lineBufLB[2] = delta; + + ++band0Buf; + ++band1Buf; + ++band2Buf; + ++band3Buf; + lineBufLA += 2; + lineBufLB += 2; + } + + if (tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + const std::int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLA[1] = band1Buf[0] + ((deltaA + lineBufLA[0]) >> 1); + + const std::int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufLB[1] = band3Buf[0] + ((deltaB + lineBufLB[0]) >> 1); + + if (wavelet->width & 1) { + lineBufLA[2] = deltaA; + lineBufLB[2] = deltaB; + } + } else if (wavelet->width & 1) { + lineBufLA[1] = band1Buf[0] + ((lineBufLA[0] + band0Buf[0] - ((band1Buf[0] + 1) >> 1)) >> 1); + lineBufLA[2] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + + lineBufLB[1] = band3Buf[0] + ((lineBufLB[0] + band2Buf[0] - ((band3Buf[0] + 1) >> 1)) >> 1); + lineBufLB[2] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } else { + lineBufLA[1] = lineBufLA[0] + band1Buf[0]; + lineBufLB[1] = lineBufLB[0] + band3Buf[0]; + } + } +} + +std::int32_t* crxIdwt53FilterGetLine(CrxPlaneComp* comp, std::int32_t level) +{ + std::int32_t* const result = comp->waveletTransform[level].lineBuf[ + (comp->waveletTransform[level].fltTapH - comp->waveletTransform[level].curH + 5) % 5 + 3 + ]; + --comp->waveletTransform[level].curH; + return result; +} + +bool crxIdwt53FilterDecode(CrxPlaneComp* comp, std::int32_t level) +{ + if (comp->waveletTransform[level].curH) { + return true; + } + + CrxSubband* const sband = comp->subBands + 3 * level; + + if (comp->waveletTransform[level].height - 3 <= comp->waveletTransform[level].curLine && !(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) { + if (comp->waveletTransform[level].height & 1) { + if (level) { + if (!crxIdwt53FilterDecode(comp, level - 1)) { + return false; + } + } else if (!crxDecodeLineWithIQuantization(sband)) { + return false; + } + + if (!crxDecodeLineWithIQuantization(sband + 1)) { + return false; + } + } + } else { + if (level) { + if (!crxIdwt53FilterDecode(comp, level - 1)) { + return false; + } + } else if (!crxDecodeLineWithIQuantization(sband)) { // LL band + return false; + } + + if ( + !crxDecodeLineWithIQuantization(sband + 1) // HL band + || !crxDecodeLineWithIQuantization(sband + 2) // LH band + || !crxDecodeLineWithIQuantization(sband + 3) // HH band + ) { + return false; + } + } + + return true; +} + +bool crxIdwt53FilterTransform(CrxPlaneComp* comp, std::uint32_t level) +{ + CrxWaveletTransform* const wavelet = comp->waveletTransform + level; + + if (wavelet->curH) { + return true; + } + + if (wavelet->curLine >= wavelet->height - 3) { + if (!(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) { + if (wavelet->height & 1) { + if (level) { + if (!wavelet[-1].curH) { + if (!crxIdwt53FilterTransform(comp, level - 1)) { + return false; + } + } + + wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); + } + + const std::int32_t* band0Buf = wavelet->subband0Buf; + const std::int32_t* band1Buf = wavelet->subband1Buf; + const std::int32_t* const lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + std::int32_t* const lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + std::int32_t* const lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; + + std::int32_t* lineBufL0 = wavelet->lineBuf[0]; + std::int32_t* lineBufL1 = wavelet->lineBuf[1]; + wavelet->lineBuf[1] = wavelet->lineBuf[2]; + wavelet->lineBuf[2] = lineBufL1; + + // process L bands + if (wavelet->width <= 1) { + lineBufL0[0] = band0Buf[0]; + } else { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + ++band1Buf; + } else { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + } + + ++band0Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) { + const std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + lineBufL0[2] = delta; + ++band0Buf; + ++band1Buf; + lineBufL0 += 2; + } + + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + const std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + + if (wavelet->width & 1) { + lineBufL0[2] = delta; + } + } else if (wavelet->width & 1) { + const std::int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + lineBufL0[2] = delta; + } else { + lineBufL0[1] = band1Buf[0] + lineBufL0[0]; + } + } + + // process H bands + lineBufL0 = wavelet->lineBuf[0]; + lineBufL1 = wavelet->lineBuf[1]; + + for (std::int32_t i = 0; i < wavelet->width; ++i) { + const std::int32_t delta = lineBufL0[i] - ((lineBufL1[i] + 1) >> 1); + lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); + lineBufH2[i] = delta; + } + + wavelet->curH += 3; + wavelet->curLine += 3; + wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; + } else { + std::int32_t* const lineBufL2 = wavelet->lineBuf[2]; + const std::int32_t* const lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + std::int32_t* const lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + wavelet->lineBuf[1] = lineBufL2; + wavelet->lineBuf[2] = wavelet->lineBuf[1]; + + for (std::int32_t i = 0; i < wavelet->width; ++i) { + lineBufH1[i] = lineBufH0[i] + lineBufL2[i]; + } + + wavelet->curH += 2; + wavelet->curLine += 2; + wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; + } + } + } else { + if (level) { + if (!wavelet[-1].curH && !crxIdwt53FilterTransform(comp, level - 1)) { + return false; + } + + wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); + } + + const std::int32_t* band0Buf = wavelet->subband0Buf; + const std::int32_t* band1Buf = wavelet->subband1Buf; + const std::int32_t* band2Buf = wavelet->subband2Buf; + const std::int32_t* band3Buf = wavelet->subband3Buf; + + std::int32_t* lineBufL0 = wavelet->lineBuf[0]; + std::int32_t* lineBufL1 = wavelet->lineBuf[1]; + const std::int32_t* const lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + std::int32_t* const lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + std::int32_t* const lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; + + wavelet->lineBuf[1] = wavelet->lineBuf[2]; + wavelet->lineBuf[2] = lineBufL1; + + // process L bands + if (wavelet->width <= 1) { + lineBufL0[0] = band0Buf[0]; + lineBufL1[0] = band2Buf[0]; + } else { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band1Buf; + ++band3Buf; + } else { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + + ++band0Buf; + ++band2Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) { + std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); + lineBufL0[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); + lineBufL1[2] = delta; + + ++band0Buf; + ++band1Buf; + ++band2Buf; + ++band3Buf; + lineBufL0 += 2; + lineBufL1 += 2; + } + + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + const std::int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((deltaA + lineBufL0[0]) >> 1); + + const std::int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL1[1] = band3Buf[0] + ((deltaB + lineBufL1[0]) >> 1); + + if (wavelet->width & 1) { + lineBufL0[2] = deltaA; + lineBufL1[2] = deltaB; + } + } else if (wavelet->width & 1) { + std::int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); + lineBufL0[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); + lineBufL1[2] = delta; + } else { + lineBufL0[1] = lineBufL0[0] + band1Buf[0]; + lineBufL1[1] = lineBufL1[0] + band3Buf[0]; + } + } + + // process H bands + lineBufL0 = wavelet->lineBuf[0]; + lineBufL1 = wavelet->lineBuf[1]; + const std::int32_t* lineBufL2 = wavelet->lineBuf[2]; + + for (std::int32_t i = 0; i < wavelet->width; ++i) { + const std::int32_t delta = lineBufL0[i] - ((lineBufL2[i] + lineBufL1[i] + 2) >> 2); + lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); + lineBufH2[i] = delta; + } + + if (wavelet->curLine >= wavelet->height - 3 && (wavelet->height & 1)) { + wavelet->curH += 3; + wavelet->curLine += 3; + wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; + } else { + wavelet->curH += 2; + wavelet->curLine += 2; + wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; + } + } + + return true; +} + +bool crxIdwt53FilterInitialize(CrxPlaneComp* comp, std::int32_t prevLevel) +{ + if (prevLevel < 0) { + return true; + } + + for (int curLevel = 0, curBand = 0; curLevel < prevLevel + 1; ++curLevel, curBand += 3) { + CrxWaveletTransform* const wavelet = comp->waveletTransform + curLevel; + + if (curLevel) { + wavelet[0].subband0Buf = crxIdwt53FilterGetLine(comp, curLevel - 1); + } else if (!crxDecodeLineWithIQuantization(comp->subBands + curBand)) { + return false; + } + + std::int32_t* lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + + if (wavelet->height > 1) { + if ( + !crxDecodeLineWithIQuantization(comp->subBands + curBand + 1) + || !crxDecodeLineWithIQuantization(comp->subBands + curBand + 2) + || !crxDecodeLineWithIQuantization(comp->subBands + curBand + 3) + ) { + return false; + } + + std::int32_t* const lineBufL0 = wavelet->lineBuf[0]; + const std::int32_t* const lineBufL1 = wavelet->lineBuf[1]; + std::int32_t* lineBufL2 = wavelet->lineBuf[2]; + + if (comp->tileFlag & E_HAS_TILES_ON_THE_TOP) { + crxHorizontal53(lineBufL0, wavelet->lineBuf[1], wavelet, comp->tileFlag); + + if (!crxDecodeLineWithIQuantization(comp->subBands + curBand + 3)|| !crxDecodeLineWithIQuantization(comp->subBands + curBand + 2)) { + return false; + } + + const std::int32_t* band2Buf = wavelet->subband2Buf; + const std::int32_t* band3Buf = wavelet->subband3Buf; + + // process L band + if (wavelet->width <= 1) { + lineBufL2[0] = band2Buf[0]; + } else { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { + lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band3Buf; + } else { + lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + + ++band2Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) { + const std::int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + lineBufL2[2] = delta; + + ++band2Buf; + ++band3Buf; + lineBufL2 += 2; + } + + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + const std::int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + + if (wavelet->width & 1) { + lineBufL2[2] = delta; + } + } else if (wavelet->width & 1) { + const std::int32_t delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + lineBufL2[2] = delta; + } else { + lineBufL2[1] = band3Buf[0] + lineBufL2[0]; + } + } + + // process H band + for (std::int32_t i = 0; i < wavelet->width; ++i) { + lineBufH0[i] = lineBufL0[i] - ((lineBufL1[i] + lineBufL2[i] + 2) >> 2); + } + } else { + crxHorizontal53(lineBufL0, wavelet->lineBuf[2], wavelet, comp->tileFlag); + + for (int i = 0; i < wavelet->width; ++i) { + lineBufH0[i] = lineBufL0[i] - ((lineBufL2[i] + 1) >> 1); + } + } + + if (!crxIdwt53FilterDecode(comp, curLevel) || !crxIdwt53FilterTransform(comp, curLevel)) { + return false; + } + } else { + if (!crxDecodeLineWithIQuantization(comp->subBands + curBand + 1)) { + return false; + } + + const std::int32_t* band0Buf = wavelet->subband0Buf; + const std::int32_t* band1Buf = wavelet->subband1Buf; + + // process H band + if (wavelet->width <= 1) { + lineBufH0[0] = band0Buf[0]; + } else { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) { + lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + ++band1Buf; + } else { + lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + } + + ++band0Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) { + std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + + ++band0Buf; + ++band1Buf; + lineBufH0 += 2; + } + + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + const std::int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + } else if (wavelet->width & 1) { + const std::int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + } else { + lineBufH0[1] = band1Buf[0] + lineBufH0[0]; + } + } + + ++wavelet->curLine; + ++wavelet->curH; + wavelet->fltTapH = (wavelet->fltTapH + 1) % 5; + } + } + + return true; +} + +void crxFreeSubbandData(CrxImage* image, CrxPlaneComp* comp) +{ + if (comp->compBuf) { + free(comp->compBuf); + comp->compBuf = nullptr; + } + + if (!comp->subBands) { + return; + } + + for (std::int32_t i = 0; i < image->subbandCount; ++i) { + if (comp->subBands[i].bandParam) { + free(comp->subBands[i].bandParam); + comp->subBands[i].bandParam = nullptr; + } + + comp->subBands[i].bandBuf = nullptr; + comp->subBands[i].bandSize = 0; + } +} + +void crxConvertPlaneLine( + CrxImage* img, + int imageRow, + int imageCol = 0, + int plane = 0, + const std::int32_t* lineData = nullptr, + int lineLength = 0 +) +{ + if (lineData) { + std::uint64_t rawOffset = 4 * img->planeWidth * imageRow + 2 * imageCol; + + if (img->encType == 1) { + const std::int32_t maxVal = 1 << (img->nBits - 1); + const std::int32_t minVal = -maxVal; + + for (int i = 0; i < lineLength; ++i) { + img->outBufs[plane][rawOffset + 2 * i] = rtengine::LIM(lineData[i], minVal, maxVal - 1); + } + } else if (img->encType == 3) { + // copy to intermediate planeBuf + rawOffset = plane * img->planeWidth * img->planeHeight + img->planeWidth * imageRow + imageCol; + + for (int i = 0; i < lineLength; ++i) { + img->planeBuf[rawOffset + i] = lineData[i]; + } + } else if (img->nPlanes == 4) { + const std::int32_t median = 1 << (img->nBits - 1); + const std::int32_t maxVal = (1 << img->nBits) - 1; + + for (int i = 0; i < lineLength; ++i) { + img->outBufs[plane][rawOffset + 2 * i] = rtengine::LIM(median + lineData[i], 0, maxVal); + } + } else if (img->nPlanes == 1) { + const std::int32_t maxVal = (1 << img->nBits) - 1; + const std::int32_t median = 1 << (img->nBits - 1); + + rawOffset = img->planeWidth * imageRow + imageCol; + + for (int i = 0; i < lineLength; ++i) { + img->outBufs[0][rawOffset + i] = rtengine::LIM(median + lineData[i], 0, maxVal); + } + } + } else if (img->encType == 3 && img->planeBuf) { + const std::int32_t planeSize = img->planeWidth * img->planeHeight; + const std::int16_t* const plane0 = img->planeBuf + imageRow * img->planeWidth; + const std::int16_t* const plane1 = plane0 + planeSize; + const std::int16_t* const plane2 = plane1 + planeSize; + const std::int16_t* const plane3 = plane2 + planeSize; + + const std::int32_t median = 1 << (img->nBits - 1) << 10; + const std::int32_t maxVal = (1 << img->nBits) - 1; + const std::uint32_t rawLineOffset = 4 * img->planeWidth * imageRow; + + // for this stage - all except imageRow is ignored + for (int i = 0; i < img->planeWidth; ++i) { + std::int32_t gr = median + (plane0[i] << 10) - 168 * plane1[i] - 585 * plane3[i]; + + if (gr < 0) { + gr = -(((std::abs(gr) + 512) >> 9) & ~1); + } else { + gr = ((std::abs(gr) + 512) >> 9) & ~1; + } + + // Essentially R = round(median + P0 + 1.474*P3) + std::int32_t val = (median + (plane0[i] << 10) + 1510 * plane3[i] + 512) >> 10; + img->outBufs[0][rawLineOffset + 2 * i] = rtengine::LIM(val, 0, maxVal); + // Essentially G1 = round(median + P0 + P2 - 0.164*P1 - 0.571*P3) + val = (plane2[i] + gr + 1) >> 1; + img->outBufs[1][rawLineOffset + 2 * i] = rtengine::LIM(val, 0, maxVal); + // Essentially G1 = round(median + P0 - P2 - 0.164*P1 - 0.571*P3) + val = (gr - plane2[i] + 1) >> 1; + img->outBufs[2][rawLineOffset + 2 * i] = rtengine::LIM(val, 0, maxVal); + // Essentially B = round(median + P0 + 1.881*P1) + val = (median + (plane0[i] << 10) + 1927 * plane1[i] + 512) >> 10; + img->outBufs[3][rawLineOffset + 2 * i] = rtengine::LIM(val, 0, maxVal); + } + } +} + +bool crxParamInit( + CrxBandParam** param, + std::uint64_t subbandMdatOffset, + std::uint64_t subbandDataSize, + std::uint32_t subbandWidth, + std::uint32_t subbandHeight, + bool supportsPartial, + std::uint32_t roundedBitsMask, + LibRaw_abstract_datastream* input +) +{ + const std::int32_t progrDataSize = + supportsPartial + ? 0 + : sizeof(std::int32_t) * subbandWidth; + const std::int32_t paramLength = 2 * subbandWidth + 4; + + std::uint8_t* paramBuf = static_cast(calloc(1, sizeof(CrxBandParam) + sizeof(std::int32_t) * paramLength + progrDataSize)); + + if (!paramBuf) { + return false; + } + + *param = reinterpret_cast(paramBuf); + + paramBuf += sizeof(CrxBandParam); + + (*param)->paramData = reinterpret_cast(paramBuf); + (*param)->nonProgrData = + progrDataSize + ? (*param)->paramData + paramLength + : nullptr; + (*param)->subbandWidth = subbandWidth; + (*param)->subbandHeight = subbandHeight; + (*param)->roundedBits = 0; + (*param)->curLine = 0; + (*param)->roundedBitsMask = roundedBitsMask; + (*param)->supportsPartial = supportsPartial; + (*param)->bitStream.bitData = 0; + (*param)->bitStream.bitsLeft = 0; + (*param)->bitStream.mdatSize = subbandDataSize; + (*param)->bitStream.curPos = 0; + (*param)->bitStream.curBufSize = 0; + (*param)->bitStream.curBufOffset = subbandMdatOffset; + (*param)->bitStream.input = input; + + crxFillBuffer(&(*param)->bitStream); + + return true; +} + +bool crxSetupSubbandData( + CrxImage* img, + CrxPlaneComp* planeComp, + const CrxTile* tile, + std::uint32_t mdatOffset +) +{ + long compDataSize = 0; + long waveletDataOffset = 0; + long compCoeffDataOffset = 0; + const std::int32_t toSubbands = 3 * img->levels + 1; + + CrxSubband* const subbands = planeComp->subBands; + + // calculate sizes + for (std::int32_t subbandNum = 0; subbandNum < toSubbands; ++subbandNum) { + subbands[subbandNum].bandSize = subbands[subbandNum].width * sizeof(std::int32_t); // 4 bytes + compDataSize += subbands[subbandNum].bandSize; + } + + if (img->levels) { + const std::int32_t encLevels = + img->levels + ? img->levels + : 1; + waveletDataOffset = (compDataSize + 7) & ~7; + compDataSize = (sizeof(CrxWaveletTransform) * encLevels + waveletDataOffset + 7) & ~7; + compCoeffDataOffset = compDataSize; + + // calc wavelet line buffer sizes (always at one level up from current) + for (int level = 0; level < img->levels; ++level) { + if (level < img->levels - 1) { + compDataSize += 8 * sizeof(std::int32_t) * planeComp->subBands[3 * (level + 1) + 2].width; + } else { + compDataSize += 8 * sizeof(std::int32_t) * tile->width; + } + } + } + + // buffer allocation + planeComp->compBuf = static_cast(malloc(compDataSize)); + + if (!planeComp->compBuf) { + return false; + } + + // subbands buffer and sizes initialisation + const std::uint64_t subbandMdatOffset = img->mdatOffset + mdatOffset; + std::uint8_t* subbandBuf = planeComp->compBuf; + + for (std::int32_t subbandNum = 0; subbandNum < toSubbands; ++subbandNum) { + subbands[subbandNum].bandBuf = subbandBuf; + subbandBuf += subbands[subbandNum].bandSize; + subbands[subbandNum].mdatOffset = subbandMdatOffset + subbands[subbandNum].dataOffset; + } + + // wavelet data initialisation + if (img->levels) { + CrxWaveletTransform* const waveletTransforms = reinterpret_cast(planeComp->compBuf + waveletDataOffset); + std::int32_t* paramData = reinterpret_cast(planeComp->compBuf + compCoeffDataOffset); + + planeComp->waveletTransform = waveletTransforms; + waveletTransforms[0].subband0Buf = reinterpret_cast(subbands->bandBuf); + + for (int level = 0; level < img->levels; ++level) { + const std::int32_t band = 3 * level + 1; + + std::int32_t transformWidth = 0; + + if (level >= img->levels - 1) { + waveletTransforms[level].height = tile->height; + transformWidth = tile->width; + } else { + waveletTransforms[level].height = subbands[band + 3].height; + transformWidth = subbands[band + 4].width; + } + + waveletTransforms[level].width = transformWidth; + waveletTransforms[level].lineBuf[0] = paramData; + waveletTransforms[level].lineBuf[1] = waveletTransforms[level].lineBuf[0] + transformWidth; + waveletTransforms[level].lineBuf[2] = waveletTransforms[level].lineBuf[1] + transformWidth; + waveletTransforms[level].lineBuf[3] = waveletTransforms[level].lineBuf[2] + transformWidth; + waveletTransforms[level].lineBuf[4] = waveletTransforms[level].lineBuf[3] + transformWidth; + waveletTransforms[level].lineBuf[5] = waveletTransforms[level].lineBuf[4] + transformWidth; + waveletTransforms[level].lineBuf[6] = waveletTransforms[level].lineBuf[5] + transformWidth; + waveletTransforms[level].lineBuf[7] = waveletTransforms[level].lineBuf[6] + transformWidth; + waveletTransforms[level].curLine = 0; + waveletTransforms[level].curH = 0; + waveletTransforms[level].fltTapH = 0; + waveletTransforms[level].subband1Buf = reinterpret_cast(subbands[band].bandBuf); + waveletTransforms[level].subband2Buf = reinterpret_cast(subbands[band + 1].bandBuf); + waveletTransforms[level].subband3Buf = reinterpret_cast(subbands[band + 2].bandBuf); + + paramData = waveletTransforms[level].lineBuf[7] + transformWidth; + } + } + + // decoding params and bitstream initialisation + for (std::int32_t subbandNum = 0; subbandNum < toSubbands; ++subbandNum) { + if (subbands[subbandNum].dataSize) { + bool supportsPartial = false; + std::uint32_t roundedBitsMask = 0; + + if (planeComp->supportsPartial && subbandNum == 0) { + roundedBitsMask = planeComp->roundedBitsMask; + supportsPartial = true; + } + + if ( + !crxParamInit( + &subbands[subbandNum].bandParam, + subbands[subbandNum].mdatOffset, + subbands[subbandNum].dataSize, + subbands[subbandNum].width, + subbands[subbandNum].height, + supportsPartial, + roundedBitsMask, + img->input + ) + ) { + return false; + } + } + } + + return true; +} + +} // namespace + +bool DCraw::crxDecodePlane(void* p, std::uint32_t planeNumber) +{ + CrxImage* const img = static_cast(p); + int imageRow = 0; + + for (int tRow = 0; tRow < img->tileRows; ++tRow) { + int imageCol = 0; + + for (int tCol = 0; tCol < img->tileCols; ++tCol) { + const CrxTile* const tile = img->tiles + tRow * img->tileRows + tCol; + CrxPlaneComp* const planeComp = tile->comps + planeNumber; + const std::uint64_t tileMdatOffset = tile->dataOffset + planeComp->dataOffset; + + // decode single tile + if (!crxSetupSubbandData(img, planeComp, tile, tileMdatOffset)) { + return false; + } + + if (img->levels) { + if (!crxIdwt53FilterInitialize(planeComp, img->levels - 1)) { + return false; + } + + for (int i = 0; i < tile->height; ++i) { + if (!crxIdwt53FilterDecode(planeComp, img->levels - 1) || !crxIdwt53FilterTransform(planeComp, img->levels - 1)) { + return false; + } + + const std::int32_t* const lineData = crxIdwt53FilterGetLine(planeComp, img->levels - 1); + crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); + } + } else { + // we have the only subband in this case + if (!planeComp->subBands->dataSize) { + memset(planeComp->subBands->bandBuf, 0, planeComp->subBands->bandSize); + return true; + } + + for (int i = 0; i < tile->height; ++i) { + if (!crxDecodeLine(planeComp->subBands->bandParam, planeComp->subBands->bandBuf)) { + return false; + } + + const std::int32_t* const lineData = reinterpret_cast(planeComp->subBands->bandBuf); + crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); + } + } + + imageCol += tile->width; + } + + imageRow += img->tiles[tRow * img->tileRows].height; + } + + return true; +} + +namespace +{ + +using crx_data_header_t = DCraw::CanonCR3Data::crx_data_header_t; + +bool crxReadSubbandHeaders( + CrxImage* img, + CrxTile* tile, + CrxPlaneComp* comp, + std::uint8_t** subbandMdatPtr, + std::uint32_t* mdatSize +) +{ + CrxSubband* band = comp->subBands + img->subbandCount - 1; // set to last band + std::uint32_t bandHeight = tile->height; + std::uint32_t bandWidth = tile->width; + std::int32_t bandWidthExCoef = 0; + std::int32_t bandHeightExCoef = 0; + + if (img->levels) { + // Build up subband sequences to crxDecode to a level in a header + + // Coefficient structure is a bit unclear and convoluted: + // 3 levels max - 8 groups (for tile width rounded to 8 bytes) + // of 3 band per level 4 sets of coefficients for each + const std::int32_t* rowExCoef = exCoefNumTbl + 0x60 * (img->levels - 1) + 12 * (tile->width & 7); + const std::int32_t* colExCoef = exCoefNumTbl + 0x60 * (img->levels - 1) + 12 * (tile->height & 7); + + for (int level = 0; level < img->levels; ++level) { + const std::int32_t widthOddPixel = bandWidth & 1; + const std::int32_t heightOddPixel = bandHeight & 1; + bandWidth = (widthOddPixel + bandWidth) >> 1; + bandHeight = (heightOddPixel + bandHeight) >> 1; + + std::int32_t bandWidthExCoef0 = 0; + std::int32_t bandWidthExCoef1 = 0; + std::int32_t bandHeightExCoef0 = 0; + std::int32_t bandHeightExCoef1 = 0; + + if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + bandWidthExCoef0 = rowExCoef[0]; + bandWidthExCoef1 = rowExCoef[1]; + } + + if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT) { + ++bandWidthExCoef0; + } + + if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) { + bandHeightExCoef0 = colExCoef[0]; + bandHeightExCoef1 = colExCoef[1]; + } + + if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP) { + ++bandHeightExCoef0; + } + + band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel; + band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel; + + band[-1].width = bandWidth + bandWidthExCoef1; + band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel; + + band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel; + band[-2].height = bandHeight + bandHeightExCoef1; + + rowExCoef += 4; + colExCoef += 4; + band -= 3; + } + + bandWidthExCoef = 0; + bandHeightExCoef = 0; + + if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) { + bandWidthExCoef = exCoefNumTbl[0x60 * (img->levels - 1) + 12 * (tile->width & 7) + 4 * (img->levels - 1) + 1]; + } + + if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) { + bandHeightExCoef = exCoefNumTbl[0x60 * (img->levels - 1) + 12 * (tile->height & 7) + 4 * (img->levels - 1) + 1]; + } + } + + band->width = bandWidthExCoef + bandWidth; + band->height = bandHeightExCoef + bandHeight; + + if (!img->subbandCount) { + return true; + } + + std::int32_t subbandOffset = 0; + band = comp->subBands; + + for (unsigned int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++) { + if (*mdatSize < 0xC) { + return false; + } + + if (sgetn(2, *subbandMdatPtr) != 0xFF03) { + return false; + } + + const std::uint32_t bitData = sgetn(4, *subbandMdatPtr + 8); + const std::uint32_t subbandSize = sgetn(4, *subbandMdatPtr + 4); + + if (curSubband != bitData >> 28) { + band->dataSize = subbandSize; + return false; + } + + band->dataSize = subbandSize - (bitData & 0x7FF); + band->supportsPartial = bitData & 0x8000; + band->dataOffset = subbandOffset; + band->quantValue = (bitData >> 19) & 0xFF; + band->paramK = 0; + band->bandParam = nullptr; + band->bandBuf = nullptr; + band->bandSize = 0; + + subbandOffset += subbandSize; + + *subbandMdatPtr += 0xC; + *mdatSize -= 0xC; + } + + return true; +} + +bool crxReadImageHeaders( + crx_data_header_t* hdr, + CrxImage* img, + std::uint8_t* mdatPtr, + std::uint32_t mdatSize +) +{ + const unsigned int nTiles = img->tileRows * img->tileCols; + + if (!nTiles) { + return false; + } + + if (!img->tiles) { + img->tiles = static_cast( + malloc( + sizeof(CrxTile) * nTiles + + sizeof(CrxPlaneComp) * nTiles * img->nPlanes + + sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount + ) + ); + + if (!img->tiles) { + return false; + } + + // memory areas in allocated chunk + CrxTile* tile = img->tiles; + CrxPlaneComp* const comps = reinterpret_cast(tile + nTiles); + CrxSubband* const bands = reinterpret_cast(comps + img->nPlanes * nTiles); + + for (unsigned int curTile = 0; curTile < nTiles; curTile++, tile++) { + tile->tileFlag = 0; // tile neighbouring flags + tile->tileNumber = curTile; + tile->tileSize = 0; + tile->comps = comps + curTile * img->nPlanes; + + if ((curTile + 1) % img->tileCols) { + // not the last tile in a tile row + tile->width = hdr->tileWidth; + + if (img->tileCols > 1) { + tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT; + + if (curTile % img->tileCols) { + // not the first tile in tile row + tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT; + } + } + } else { + // last tile in a tile row + tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1); + + if (img->tileCols > 1) { + tile->tileFlag = E_HAS_TILES_ON_THE_LEFT; + } + } + + if (curTile < nTiles - img->tileCols) { + // in first tile row + tile->height = hdr->tileHeight; + + if (img->tileRows > 1) { + tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM; + + if (curTile >= img->tileCols) { + tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; + } + } + } else { + // non first tile row + tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1); + + if (img->tileRows > 1) { + tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; + } + } + + if (img->nPlanes) { + CrxPlaneComp* comp = tile->comps; + CrxSubband* band = bands + curTile * img->nPlanes * img->subbandCount; + + for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++) { + comp->compNumber = curComp; + comp->supportsPartial = true; + comp->tileFlag = tile->tileFlag; + comp->subBands = band; + comp->compBuf = nullptr; + comp->waveletTransform = nullptr; + + if (img->subbandCount) { + for (int curBand = 0; curBand < img->subbandCount; curBand++, band++) { + band->supportsPartial = false; + band->quantValue = 4; + band->bandParam = nullptr; + band->dataSize = 0; + } + } + } + } + } + } + + std::uint32_t tileOffset = 0; + std::uint32_t dataSize = mdatSize; + std::uint8_t* dataPtr = mdatPtr; + CrxTile* tile = img->tiles; + + for (unsigned int curTile = 0; curTile < nTiles; curTile++, tile++) { + if (dataSize < 0xC) { + return false; + } + + if (sgetn(2, dataPtr) != 0xFF01) { + return false; + } + + if (sgetn(2, dataPtr + 8) != curTile) { + return false; + } + + dataSize -= 0xC; + + tile->tileSize = sgetn(4, dataPtr + 4); + tile->dataOffset = tileOffset; + + const std::int32_t hdrExtraBytes = sgetn(2, dataPtr + 2) - 8; + tileOffset += tile->tileSize; + dataPtr += hdrExtraBytes + 0xC; + dataSize -= hdrExtraBytes; + + std::uint32_t compOffset = 0; + CrxPlaneComp* comp = tile->comps; + + for (int compNum = 0; compNum < img->nPlanes; compNum++, comp++) { + if (dataSize < 0xC) { + return false; + } + + if (sgetn(2, dataPtr) != 0xFF02) { + return false; + } + + if (compNum != dataPtr[8] >> 4) { + return false; + } + + comp->compSize = sgetn(4, dataPtr + 4); + + std::int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3; + comp->supportsPartial = (dataPtr[8] & 8) != 0; + + comp->dataOffset = compOffset; + comp->tileFlag = tile->tileFlag; + + compOffset += comp->compSize; + dataSize -= 0xC; + dataPtr += 0xC; + + comp->roundedBitsMask = 0; + + if (compHdrRoundedBits) { + if (img->levels || !comp->supportsPartial) { + return false; + } + + comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1); + } + + if (!crxReadSubbandHeaders(img, tile, comp, &dataPtr, &dataSize)) { + return false; + } + } + } + + return true; +} + +bool crxSetupImageData( + crx_data_header_t* hdr, + CrxImage* img, + std::int16_t* outBuf, + std::uint64_t mdatOffset, + std::uint32_t mdatSize, + std::uint8_t* mdatHdrPtr +) +{ + constexpr bool IncrBitTable[32] = { + false, false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, + false, false, true, false, false, true, true, true, false, true, true, true, false, false, false, false + }; + + img->planeWidth = hdr->f_width; + img->planeHeight = hdr->f_height; + + if ( + hdr->tileWidth < 0x16 + || hdr->tileHeight < 0x16 + || img->planeWidth > 0x7FFF + || img->planeHeight > 0x7FFF + ) { + return false; + } + + img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth; + img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight; + + if (img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 || img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16) { + return false; + } + + img->tiles = nullptr; + img->levels = hdr->imageLevels; + img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL + img->nPlanes = hdr->nPlanes; + img->nBits = hdr->nBits; + img->encType = hdr->encType; + img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1; + img->mdatOffset = mdatOffset + hdr->mdatHdrSize; + img->mdatSize = mdatSize; + img->planeBuf = nullptr; + img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = nullptr; + + // The encoding type 3 needs all 4 planes to be decoded to generate row of + // RGGB values. It seems to be using some other colour space for raw encoding + // It is a massive buffer so ideallly it will need a different approach: + // decode planes line by line and convert single line then without + // intermediate plane buffer. At the moment though it's too many changes so + // left as is. + if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8) { + img->planeBuf = static_cast( + malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3)) + ); + + if (!img->planeBuf) { + return false; + } + } + + const std::int32_t rowSize = 2 * img->planeWidth; + + if (img->nPlanes == 1) { + img->outBufs[0] = outBuf; + } else { + switch (hdr->cfaLayout) { + case 0: { + // R G + // G B + img->outBufs[0] = outBuf; + img->outBufs[1] = outBuf + 1; + img->outBufs[2] = outBuf + rowSize; + img->outBufs[3] = img->outBufs[2] + 1; + break; + } + + case 1: { + // G R + // B G + img->outBufs[1] = outBuf; + img->outBufs[0] = outBuf + 1; + img->outBufs[3] = outBuf + rowSize; + img->outBufs[2] = img->outBufs[3] + 1; + break; + } + + case 2: { + // G B + // R G + img->outBufs[2] = outBuf; + img->outBufs[3] = outBuf + 1; + img->outBufs[0] = outBuf + rowSize; + img->outBufs[1] = img->outBufs[0] + 1; + break; + } + + case 3: { + // B G + // G R + img->outBufs[3] = outBuf; + img->outBufs[2] = outBuf + 1; + img->outBufs[1] = outBuf + rowSize; + img->outBufs[0] = img->outBufs[1] + 1; + break; + } + } + } + + // read header + return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatSize); +} + +void crxFreeImageData(CrxImage* img) +{ + CrxTile* tile = img->tiles; + const int nTiles = img->tileRows * img->tileCols; + + if (img->tiles) { + for (std::int32_t curTile = 0; curTile < nTiles; curTile++, tile++) { + if (tile[curTile].comps) { + for (std::int32_t curPlane = 0; curPlane < img->nPlanes; ++curPlane) { + crxFreeSubbandData(img, tile[curTile].comps + curPlane); + } + } + } + + free(img->tiles); + img->tiles = nullptr; + } + + if (img->planeBuf) { + free(img->planeBuf); + img->planeBuf = nullptr; + } +} + +} // namespace + +void DCraw::crxLoadDecodeLoop(void* img, int nPlanes) +{ +#ifdef _OPENMP + bool results[4]; // nPlanes is always <= 4 + #pragma omp parallel for + + for (std::int32_t plane = 0; plane < nPlanes; ++plane) { + results[plane] = crxDecodePlane(img, plane); + } + + for (std::int32_t plane = 0; plane < nPlanes; ++plane) { + if (!results[plane]) { + derror(); + } + } + +#else + + for (std::int32_t plane = 0; plane < nPlanes; ++plane) { + if (!crxDecodePlane(img, plane)) { + derror(); + } + } + +#endif +} + +void DCraw::crxConvertPlaneLineDf(void* p, int imageRow) +{ + crxConvertPlaneLine(static_cast(p), imageRow); +} + +void DCraw::crxLoadFinalizeLoopE3(void* p, int planeHeight) +{ +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < planeHeight; ++i) { + crxConvertPlaneLineDf(p, i); + } +} + +void DCraw::crxLoadRaw() +{ + CrxImage img; + + if (RT_canon_CR3_data.crx_track_selected >= RT_canon_CR3_data.CRXTRACKS_MAXCOUNT) { + derror(); + } + + crx_data_header_t hdr = RT_canon_CR3_data.crx_header[RT_canon_CR3_data.crx_track_selected]; + + LibRaw_abstract_datastream input = {ifp}; + img.input = &input; // libraw_internal_data.internal_data.input; + + // update sizes for the planes + if (hdr.nPlanes == 4) { + hdr.f_width >>= 1; + hdr.f_height >>= 1; + hdr.tileWidth >>= 1; + hdr.tileHeight >>= 1; + } + +// /*imgdata.color.*/maximum = (1 << hdr.nBits) - 1; + + std::uint8_t* const hdrBuf = static_cast(malloc(hdr.mdatHdrSize)); + + // read image header +#ifdef _OPENMP + #pragma omp critical +#endif + { +#ifndef _OPENMP + /*libraw_internal_data.internal_data.input->*/ input.lock(); +#endif + /*libraw_internal_data.internal_data.input->*/ input.seek(data_offset, SEEK_SET); + /*libraw_internal_data.internal_data.input->*/ input.read(hdrBuf, 1, hdr.mdatHdrSize); +#ifndef _OPENMP + /*libraw_internal_data.internal_data.input->*/ input.unlock(); +#endif + } + + // parse and setup the image data + if (!crxSetupImageData(&hdr, &img, reinterpret_cast(raw_image), hdr.MediaOffset /*data_offset*/, hdr.MediaSize /*RT_canon_CR3_data.data_size*/, hdrBuf)) { + derror(); + } + + free(hdrBuf); + + crxLoadDecodeLoop(&img, hdr.nPlanes); + + if (img.encType == 3) { + crxLoadFinalizeLoopE3(&img, img.planeHeight); + } + + crxFreeImageData(&img); +} + +bool DCraw::crxParseImageHeader(uchar* cmp1TagData, unsigned int nTrack) +{ + if (nTrack >= RT_canon_CR3_data.CRXTRACKS_MAXCOUNT) { + return false; + } + + if (!cmp1TagData) { + return false; + } + + crx_data_header_t* const hdr = &RT_canon_CR3_data.crx_header[nTrack]; + + hdr->version = sgetn(2, cmp1TagData + 4); + hdr->f_width = sgetn(4, cmp1TagData + 8); + hdr->f_height = sgetn(4, cmp1TagData + 12); + hdr->tileWidth = sgetn(4, cmp1TagData + 16); + hdr->tileHeight = sgetn(4, cmp1TagData + 20); + hdr->nBits = cmp1TagData[24]; + hdr->nPlanes = cmp1TagData[25] >> 4; + hdr->cfaLayout = cmp1TagData[25] & 0xF; + hdr->encType = cmp1TagData[26] >> 4; + hdr->imageLevels = cmp1TagData[26] & 0xF; + hdr->hasTileCols = cmp1TagData[27] >> 7; + hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1; + hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28); + + // validation + if (hdr->version != 0x100 || !hdr->mdatHdrSize) { + return false; + } + + if (hdr->encType == 1) { + if (hdr->nBits > 15) { + return false; + } + } else { + if (hdr->encType && hdr->encType != 3) { + return false; + } + + if (hdr->nBits > 14) { + return false; + } + } + + if (hdr->nPlanes == 1) { + if (hdr->cfaLayout || hdr->encType) { + return false; + } + + if (hdr->nBits != 8) { + return false; + } + } else if ( + hdr->nPlanes != 4 + || (hdr->f_width & 1) + || (hdr->f_height & 1) + || (hdr->tileWidth & 1) + || (hdr->tileHeight & 1) + || hdr->cfaLayout > 3 + || ( + hdr->encType + && hdr->encType != 1 + && hdr->encType != 3 + ) + || hdr->nBits == 8 + ) { + return false; + } + + if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height) { + return false; + } + + if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1) { + return false; + } + + return true; +} diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 8d9ee5b64..e8770f95a 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -20,18 +20,14 @@ #include #include "rtengine.h" +#include "rawimage.h" #include "rawimagesource.h" #include "rt_math.h" -#include "improcfun.h" #include "procparams.h" #include "color.h" -#include "gauss.h" #include "rt_algo.h" //#define BENCHMARK #include "StopWatch.h" -#ifdef _OPENMP -#include -#endif #include "opthelper.h" #include "../rtgui/multilangmgr.h" @@ -103,33 +99,48 @@ void compute3x3kernel(float sigma, float kernel[3][3]) { } } -inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const 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]) { const float c11 = kernel[0][0]; const float c10 = kernel[0][1]; const float c00 = kernel[1][1]; - for (int i = 1; i < H - 1; i++) { - dst[i][0] = 1.f; - for (int j = 1; j < W - 1; j++) { + for (int i = 1; i < tileSize - 1; i++) { + 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]) + c00 * src[i][j]; dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 1] = 1.f; - } - // first and last row - for (int j = 0; j < W; ++j) { - dst[0][j] = 1.f; - } - for (int j = 0; j < W; ++j) { - dst[H - 1][j] = 1.f; } } -inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[5][5]) +inline 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]; @@ -138,10 +149,9 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES const float c10 = kernel[1][2]; const float c00 = kernel[2][2]; - for (int i = 2; i < H - 2; ++i) { - dst[i][0] = dst[i][1] = 1.f; + for (int i = 2; i < tileSize - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 2; j < W - 2; ++j) { + 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]) + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + @@ -150,23 +160,10 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 2] = dst[i][W - 1] = 1.f; - } - - // first and last rows - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } - for (int i = H - 2 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } } } -inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[7][7]) +inline 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]; @@ -178,10 +175,9 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST const float c10 = kernel[2][3]; const float c00 = kernel[3][3]; - for (int i = 3; i < H - 3; ++i) { - dst[i][0] = dst[i][1] = dst[i][2] = 1.f; + for (int i = 3; i < tileSize - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 3; j < W - 3; ++j) { + 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]) + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + @@ -193,30 +189,17 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; - } - - // first and last rows - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } - for (int i = H - 3 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } } } -inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[3][3]) +inline 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 < H - 1; i++) { - for (int j = 1; j < W - 1; j++) { + for (int i = 1; i < tileSize - 1; i++) { + 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]) + c00 * src[i][j]; @@ -226,7 +209,7 @@ inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int W } -inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[5][5]) +inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[5][5]) { const float c21 = kernel[0][1]; @@ -235,9 +218,9 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int const float c10 = kernel[1][2]; const float c00 = kernel[2][2]; - for (int i = 2; i < H - 2; ++i) { + for (int i = 2; i < tileSize - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 2; j < W - 2; ++j) { + 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]) + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + @@ -249,7 +232,7 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int } } -inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[7][7]) +inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[7][7]) { const float c31 = kernel[0][2]; @@ -261,9 +244,9 @@ inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int W const float c10 = kernel[2][3]; const float c00 = kernel[3][3]; - for (int i = 3; i < H - 3; ++i) { + for (int i = 3; i < tileSize - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 3; j < W - 3; ++j) { + 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]) + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + @@ -426,98 +409,118 @@ float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLi #ifdef _OPENMP #pragma omp parallel for reduction(max:maxRatio) schedule(dynamic, 16) #endif - for (int row = starty + 3; row < H - 4; row += 3) { - for (int col = startx + 3; col < W - 4; col += 3) { - const float valtl = rawData[row][col]; - const float valtr = rawData[row][col + 1]; - const float valbl = rawData[row + 1][col]; - const float valbr = rawData[row + 1][col + 1]; - if (valtl > 1.f) { - const float maxValtltr = std::max(valtl, valtr); - if (valtr > 1.f && maxValtltr > lowerLimit) { - const float minVal = std::min(valtl, valtr); - if (UNLIKELY(maxValtltr > maxRatio * minVal)) { - bool clipped = false; - if (maxValtltr == valtl) { // check for influence by clipped green in neighborhood - if (rtengine::max(rawData[row - 1][col - 1], valtr, valbl, valbr) >= upperLimit) { - clipped = true; + for (int row = starty + 2; row < H - 4; row += 3) { + for (int col = startx + 2; col < W - 4; col += 3) { + const float valp1p1 = rawData[row + 1][col + 1]; + const bool squareClipped = rtengine::max(valp1p1, rawData[row + 1][col + 2], rawData[row + 2][col + 1], rawData[row + 2][col + 2]) >= upperLimit; + const float greenSolitary = rawData[row][col]; + if (greenSolitary > 1.f && std::max(rawData[row - 1][col - 1], rawData[row - 1][col + 1]) < upperLimit) { + if (greenSolitary < upperLimit) { + const float valp1m1 = rawData[row + 1][col - 1]; + if (valp1m1 > 1.f && rtengine::max(rawData[row + 1][col - 2], valp1m1, rawData[row + 2][col - 2], rawData[row + 1][col - 1]) < upperLimit) { + const float maxVal = std::max(greenSolitary, valp1m1); + if (maxVal > lowerLimit) { + const float minVal = std::min(greenSolitary, valp1m1); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; } - } else { // check for influence by clipped green in neighborhood - if (rtengine::max(rawData[row - 1][col + 2], valtl, valbl, valbr) >= upperLimit) { - clipped = true; - } - } - if (!clipped) { - maxRatio = maxValtltr / minVal; } } - } - const float maxValtlbl = std::max(valtl, valbl); - if (valbl > 1.f && maxValtlbl > lowerLimit) { - const float minVal = std::min(valtl, valbl); - if (UNLIKELY(maxValtlbl > maxRatio * minVal)) { - bool clipped = false; - if (maxValtlbl == valtl) { // check for influence by clipped green in neighborhood - if (rtengine::max(rawData[row - 1][col - 1], valtr, valbl, valbr) >= upperLimit) { - clipped = true; + if (valp1p1 > 1.f && !squareClipped) { + const float maxVal = std::max(greenSolitary, valp1p1); + if (maxVal > lowerLimit) { + const float minVal = std::min(greenSolitary, valp1p1); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; } - } else { // check for influence by clipped green in neighborhood - if (rtengine::max(valtl, valtr, rawData[row + 2][col - 1], valbr) >= upperLimit) { - clipped = true; - } - } - if (!clipped) { - maxRatio = maxValtlbl / minVal; } } } } - if (valbr > 1.f) { - const float maxValblbr = std::max(valbl, valbr); - if (valbl > 1.f && maxValblbr > lowerLimit) { - const float minVal = std::min(valbl, valbr); - if (UNLIKELY(maxValblbr > maxRatio * minVal)) { - bool clipped = false; - if (maxValblbr == valbr) { // check for influence by clipped green in neighborhood - if (rtengine::max(valtl, valtr, valbl, rawData[row + 2][col + 2]) >= upperLimit) { - clipped = true; - } - } else { // check for influence by clipped green in neighborhood - if (rtengine::max(valtl, valtr, rawData[row + 2][col - 1], valbr) >= upperLimit) { - clipped = true; + if (!squareClipped) { + const float valp2p2 = rawData[row + 2][col + 2]; + if (valp2p2 > 1.f) { + if (valp1p1 > 1.f) { + const float maxVal = std::max(valp1p1, valp2p2); + if (maxVal > lowerLimit) { + const float minVal = std::min(valp1p1, valp2p2); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; } } - if (!clipped) { - maxRatio = maxValblbr / minVal; + } + const float greenSolitaryRight = rawData[row + 3][col + 3]; + if (rtengine::max(greenSolitaryRight, rawData[row + 4][col + 2], rawData[row + 4][col + 4]) < upperLimit) { + if (greenSolitaryRight > 1.f) { + const float maxVal = std::max(greenSolitaryRight, valp2p2); + if (maxVal > lowerLimit) { + const float minVal = std::min(greenSolitaryRight, valp2p2); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; + } + } } } } - const float maxValtrbr = std::max(valtr, valbr); - if (valtr > 1.f && maxValtrbr > lowerLimit) { - const float minVal = std::min(valtr, valbr); - if (UNLIKELY(maxValtrbr > maxRatio * minVal)) { - if (maxValtrbr == valbr) { // check for influence by clipped green in neighborhood - if (rtengine::max(valtl, valtr, valbl, rawData[row + 2][col + 2]) >= upperLimit) { - continue; - } - } else { // check for influence by clipped green in neighborhood - if (rtengine::max(rawData[row - 1][col + 2], valtl, valbl, valbr) >= upperLimit) { - continue; + const float valp1p2 = rawData[row + 1][col + 2]; + const float valp2p1 = rawData[row + 2][col + 1]; + if (valp2p1 > 1.f) { + if (valp1p2 > 1.f) { + const float maxVal = std::max(valp1p2, valp2p1); + if (maxVal > lowerLimit) { + const float minVal = std::min(valp1p2, valp2p1); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; + } + } + } + const float greenSolitaryLeft = rawData[row + 3][col]; + if (rtengine::max(greenSolitaryLeft, rawData[row + 4][col - 1], rawData[row + 4][col + 1]) < upperLimit) { + if (greenSolitaryLeft > 1.f) { + const float maxVal = std::max(greenSolitaryLeft, valp2p1); + if (maxVal > lowerLimit) { + const float minVal = std::min(greenSolitaryLeft, valp2p1); + if (UNLIKELY(maxVal > maxRatio * minVal)) { + maxRatio = maxVal / minVal; + } } } - maxRatio = maxValtrbr / minVal; } } } } } - return std::sqrt((1.f / (std::log(1.f / maxRatio))) / -2.f); + return std::sqrt((1.f / (std::log(1.f / maxRatio) / 2.f)) / -2.f); } -void CaptureDeconvSharpening (float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, int iterations, rtengine::ProgressListener* plistener, double startVal, double endVal) + +bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int border) +{ + bool stopped = false; + for (int ii = border; !stopped && 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; + } + } +#else + for (int jj = border; jj < fullTileSize - border; ++jj) { + if (tmpIThr[ii][jj] < iterCheck[ii - border][jj - border]) { + stopped = true; + break; + } + } +#endif + } + return stopped; +} + +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) { BENCHFUN - const bool is5x5 = (sigma <= 0.84); - const bool is3x3 = (sigma < 0.6); + const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0); + const bool is3x3 = (sigma < 0.6 && sigmaCornerOffset == 0.0); float kernel7[7][7]; float kernel5[5][5]; float kernel3[3][3]; @@ -529,12 +532,16 @@ BENCHFUN compute7x7kernel(sigma, kernel7); } - constexpr int tileSize = 194; - constexpr int border = 3; - constexpr int fullTileSize = tileSize + 2 * border; + constexpr int tileSize = 32; + const int border = iterations <= 30 ? 5 : 7; + const int fullTileSize = tileSize + 2 * border; + const float cornerRadius = std::min(1.15f, sigma + sigmaCornerOffset); + const float cornerDistance = sqrt(rtengine::SQR(W * 0.5f) + rtengine::SQR(H * 0.5f)); + const float distanceFactor = (cornerRadius - sigma) / cornerDistance; double progress = startVal; const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H); + #ifdef _OPENMP #pragma omp parallel #endif @@ -543,7 +550,11 @@ BENCHFUN array2D tmpIThr(fullTileSize, fullTileSize); array2D tmpThr(fullTileSize, fullTileSize); array2D lumThr(fullTileSize, fullTileSize); -#pragma omp for schedule(dynamic,2) collapse(2) + array2D iterCheck(tileSize, tileSize); + initTile(tmpThr, fullTileSize); +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) collapse(2) +#endif for (int i = border; i < H - border; i+= tileSize) { for(int j = border; j < W - border; j+= tileSize) { const bool endOfCol = (i + tileSize + border) >= H; @@ -551,13 +562,27 @@ BENCHFUN // fill tiles if (endOfRow || endOfCol) { // special handling for small tiles at end of row or column - for (int k = 0, ii = endOfCol ? H - fullTileSize : i; k < fullTileSize; ++k, ++ii) { - for (int l = 0, jj = endOfRow ? W - fullTileSize : j; l < fullTileSize; ++l, ++jj) { - tmpIThr[k][l] = oldLuminance[ii - border][jj - border]; - lumThr[k][l] = oldLuminance[ii - border][jj - border]; + 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; + } + } + } + for (int k = 0, ii = endOfCol ? H - fullTileSize : i - border; k < fullTileSize; ++k, ++ii) { + for (int l = 0, jj = endOfRow ? W - fullTileSize : j - border; l < fullTileSize; ++l, ++jj) { + tmpIThr[k][l] = oldLuminance[ii][jj]; + lumThr[k][l] = oldLuminance[ii][jj]; } } } else { + 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; + } + } + } for (int ii = i; ii < i + fullTileSize; ++ii) { for (int jj = j; jj < j + fullTileSize; ++jj) { tmpIThr[ii - i][jj - j] = oldLuminance[ii - border][jj - border]; @@ -565,36 +590,76 @@ BENCHFUN } } } + bool stopped = false; if (is3x3) { - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 3x3 gaussian blur and divide luminance by result of gaussian blur - gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel3); - gauss3x3mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel3); + gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3); + gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } else if (is5x5) { - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 5x5 gaussian blur and divide luminance by result of gaussian blur - gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel5); - gauss5x5mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel5); + gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5); + gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } else { - for (int k = 0; k < iterations; ++k) { - // apply 7x7 gaussian blur and divide luminance by result of gaussian blur - gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel7); - gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel7); + if (sigmaCornerOffset != 0.0) { + const float distance = sqrt(rtengine::SQR(i + tileSize / 2 - H / 2) + rtengine::SQR(j + tileSize / 2 - W / 2)); + const float sigmaTile = static_cast(sigma) + distanceFactor * distance; + if (sigmaTile >= 0.4f) { + if (sigmaTile > 0.84) { // have to use 7x7 kernel + float lkernel7[7][7]; + compute7x7kernel(static_cast(sigma) + distanceFactor * distance, lkernel7); + for (int k = 0; k < iterations && !stopped; ++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); + } + } + } else { // can use 5x5 kernel + float lkernel7[5][5]; + compute5x5kernel(static_cast(sigma) + distanceFactor * distance, lkernel7); + for (int k = 0; k < iterations && !stopped; ++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); + } + } + } + } + } else { + for (int k = 0; k < iterations && !stopped; ++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 (endOfRow || endOfCol) { // special handling for small tiles at end of row or column - for (int k = border, ii = endOfCol ? H - fullTileSize - border : i - border; k < fullTileSize - border; ++k) { - for (int l = border, jj = endOfRow ? W - fullTileSize - border : j - border; l < fullTileSize - border; ++l) { - luminance[ii + k][jj + l] = rtengine::intp(blend[ii + k][jj + l], max(tmpIThr[k][l], 0.0f), luminance[ii + k][jj + l]); + 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]); } } } 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], 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], std::max(tmpIThr[ii][jj], 0.0f), luminance[i + ii - border][j + jj - border]); } } } @@ -627,7 +692,7 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams plistener->setProgress(0.0); } BENCHFUN - const float xyz_rgb[3][3] = { // XYZ from RGB + constexpr float xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, { 0.019334, 0.119193, 0.950227 } @@ -637,13 +702,15 @@ BENCHFUN const float clipVal = (ri->get_white(1) - ri->get_cblack(1)) * scale_mul[1]; - array2D& redVals = redCache ? *redCache : red; - array2D& greenVals = greenCache ? *greenCache : green; - array2D& blueVals = blueCache ? *blueCache : blue; + const array2D& redVals = redCache ? *redCache : red; + const array2D& greenVals = greenCache ? *greenCache : green; + const array2D& blueVals = blueCache ? *blueCache : blue; array2D clipMask(W, H); constexpr float clipLimit = 0.95f; - if (ri->getSensorType() == ST_BAYER) { + constexpr float maxSigma = 1.15f; + + if (getSensorType() == ST_BAYER) { const float whites[2][2] = { {(ri->get_white(FC(0,0)) - c_black[FC(0,0)]) * scale_mul[FC(0,0)] * clipLimit, (ri->get_white(FC(0,1)) - c_black[FC(0,1)]) * scale_mul[FC(0,1)] * clipLimit}, {(ri->get_white(FC(1,0)) - c_black[FC(1,0)]) * scale_mul[FC(1,0)] * clipLimit, (ri->get_white(FC(1,1)) - c_black[FC(1,1)]) * scale_mul[FC(1,1)] * clipLimit} @@ -651,9 +718,9 @@ BENCHFUN buildClipMaskBayer(rawData, W, H, clipMask, whites); const unsigned int fc[2] = {FC(0,0), FC(1,0)}; if (sharpeningParams.autoRadius) { - radius = calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc); + radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), maxSigma); } - } else if (ri->getSensorType() == ST_FUJI_XTRANS) { + } else if (getSensorType() == ST_FUJI_XTRANS) { float whites[6][6]; for (int i = 0; i < 6; ++i) { for (int j = 0; j < 6; ++j) { @@ -679,14 +746,14 @@ BENCHFUN } } if (sharpeningParams.autoRadius) { - radius = calcRadiusXtrans(rawData, W, H, 1000.f, clipVal, i, j); + radius = std::min(calcRadiusXtrans(rawData, W, H, 1000.f, clipVal, i, j), maxSigma); } } else if (ri->get_colors() == 1) { buildClipMaskMono(rawData, W, H, clipMask, (ri->get_white(0) - c_black[0]) * scale_mul[0] * clipLimit); if (sharpeningParams.autoRadius) { const unsigned int fc[2] = {0, 0}; - radius = calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc); + radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), maxSigma); } } @@ -740,14 +807,13 @@ BENCHFUN array2D& L = Lbuffer ? *Lbuffer : red; array2D& YOld = YOldbuffer ? * YOldbuffer : green; array2D& YNew = YNewbuffer ? * YNewbuffer : blue; - const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); - Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], gamma, W); + Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], W); } if (plistener) { plistener->setProgress(0.1); @@ -760,7 +826,7 @@ BENCHFUN } conrastThreshold = contrast * 100.f; - CaptureDeconvSharpening(YNew, YOld, blend, W, H, radius, sharpeningParams.deconviter, plistener, 0.2, 0.9); + CaptureDeconvSharpening(clipMask, YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9); if (plistener) { plistener->setProgress(0.9); } @@ -770,9 +836,8 @@ BENCHFUN for (int i = 0; i < H; ++i) { int j = 0; #ifdef __SSE2__ - const vfloat gammav = F2V(gamma); for (; j < W - 3; j += 4) { - const vfloat factor = pow_F(vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); + const vfloat factor = vmaxf(LVFU(YNew[i][j]), ZEROV) / 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); @@ -780,7 +845,7 @@ BENCHFUN #endif for (; j < W; ++j) { - const float factor = pow_F(std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f), gamma); + const float factor = std::max(YNew[i][j], 0.f) / 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; @@ -793,6 +858,7 @@ BENCHFUN if (plistener) { plistener->setProgress(1.0); } + rgbSourceModified = false; } } /* namespace */ diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc index 5f6e46f8f..ba26740c1 100644 --- a/rtengine/cfa_linedn_RT.cc +++ b/rtengine/cfa_linedn_RT.cc @@ -24,7 +24,6 @@ #include -#include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" @@ -63,7 +62,7 @@ void RawImageSource::CLASS cfa_linedn(float noise, bool horizontal, bool vertica // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% float noisevar = SQR(3 * noise * 65535); // _noise_ (as a fraction of saturation) is input to the algorithm float noisevarm4 = 4.0f * noisevar; - float* RawDataTmp = (float*)malloc( width * height * sizeof(float)); + float* RawDataTmp = (float*)malloc(static_cast(width) * height * sizeof(float)); #ifdef _OPENMP #pragma omp parallel #endif diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index dfef273d6..c7e49b2ed 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -17,10 +17,10 @@ * along with RawTherapee. If not, see . */ #include "ciecam02.h" -#include "rtengine.h" +#include "rt_math.h" #include "curves.h" #include -#include "sleef.c" +#include "sleef.h" #ifdef _DEBUG #include "settings.h" @@ -34,10 +34,6 @@ namespace rtengine { -#ifdef _DEBUG -extern const Settings* settings; -#endif - void Ciecam02::curvecolorfloat (float satind, float satval, float &sres, float parsat) { if (satind > 0.f) { @@ -145,8 +141,8 @@ void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf } outCurve *= 32767.f; - //printf("out500=%f out15000=%f\n", outCurve[500], outCurve[15000]); - //outCurve.dump("brig"); + //printf("out500=%f out15000=%f\n", outCurve[500], outCurve[15000]); + //outCurve.dump("brig"); } /** @@ -408,7 +404,7 @@ void Ciecam02::calculate_abfloat ( vfloat &aa, vfloat &bb, vfloat h, vfloat e, v #endif void Ciecam02::initcam1float (float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, - float &cz, float &aw, float &wh, float &pfl, float &fl, float &c) + float &cz, float &aw, float &wh, float &pfl, float &fl, float c) { n = yb / yw; diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h index fea35ab12..75ccfaa8c 100644 --- a/rtengine/ciecam02.h +++ b/rtengine/ciecam02.h @@ -16,12 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CIECAM02_ -#define _CIECAM02_ +#pragma once + #include -#include "LUT.h" +#include + #include "opthelper.h" +template +class LUT; + +using LUTu = LUT; +using LUTf = LUT; + namespace rtengine { @@ -77,7 +84,7 @@ public: * Forward transform from XYZ to CIECAM02 JCh. */ static void initcam1float (float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, - float &cz, float &aw, float &wh, float &pfl, float &fl, float &c); + float &cz, float &aw, float &wh, float &pfl, float &fl, float c); static void initcam2float (float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, float &cz, float &aw, float &fl); @@ -106,4 +113,3 @@ public: }; } -#endif diff --git a/rtengine/cieimage.cc b/rtengine/cieimage.cc index be122febf..f19808df7 100644 --- a/rtengine/cieimage.cc +++ b/rtengine/cieimage.cc @@ -1,5 +1,7 @@ #include "cieimage.h" -#include + +#include +#include namespace rtengine { @@ -10,7 +12,6 @@ CieImage::CieImage (int w, int h) : fromImage(false), W(w), H(h) M_p = new float*[H]; C_p = new float*[H]; sh_p = new float*[H]; - // ch_p = new float*[H]; h_p = new float*[H]; // Initialize the pointers to zero @@ -98,9 +99,6 @@ CieImage::CieImage (int w, int h) : fromImage(false), W(w), H(h) ++c; - // for (int i=0; i. */ -#ifndef _CIEIMAGE_H_ -#define _CIEIMAGE_H_ +#pragma once -#include "image16.h" #include "noncopyable.h" namespace rtengine @@ -39,7 +37,6 @@ public: float** M_p; float** C_p; float** sh_p; -// float** ch_p; float** h_p; CieImage (int w, int h); @@ -50,4 +47,3 @@ public: }; } -#endif diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index 10b7a2c38..e3bd9c988 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -1,7 +1,11 @@ #include +#include +#include + #include "clutstore.h" +#include "colortemp.h" #include "iccstore.h" #include "imagefloat.h" #include "opthelper.h" diff --git a/rtengine/clutstore.h b/rtengine/clutstore.h index cd94bc18b..7c570df98 100644 --- a/rtengine/clutstore.h +++ b/rtengine/clutstore.h @@ -3,8 +3,6 @@ #include #include -#include - #include "cache.h" #include "alignedbuffer.h" #include "noncopyable.h" diff --git a/rtengine/color.cc b/rtengine/color.cc index 7a91f0073..8d20fb9ba 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -20,18 +20,19 @@ #include "rtengine.h" #include "color.h" #include "iccmatrices.h" -#include "mytime.h" -#include "sleef.c" +#include "sleef.h" #include "opthelper.h" #include "iccstore.h" +#ifdef _DEBUG +#include "mytime.h" +#endif + using namespace std; namespace rtengine { -extern const Settings* settings; - cmsToneCurve* Color::linearGammaTRC; LUTf Color::cachef; LUTf Color::cachefy; diff --git a/rtengine/color.h b/rtengine/color.h index b859fb0cf..d9c344c27 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -20,14 +20,13 @@ #pragma once #include -#include +#include #include "rt_math.h" #include "LUT.h" -#include "labimage.h" #include "iccmatrices.h" #include "lcms2.h" -#include "sleef.c" +#include "sleef.h" #define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c) @@ -210,6 +209,13 @@ public: return r * workingspace[1][0] + g * workingspace[1][1] + b * workingspace[1][2]; } +#ifdef __SSE2__ + static vfloat rgbLuminance(vfloat r, vfloat g, vfloat b, const vfloat workingspace[3]) + { + return r * workingspace[0] + g * workingspace[1] + b * workingspace[2]; + } +#endif + /** * @brief Convert red/green/blue to L*a*b * @brief Convert red/green/blue to hue/saturation/luminance @@ -1063,12 +1069,11 @@ public: */ static inline double gamma2 (double x) // g3 1+g4 { - // return x <= 0.003041 ? x * 12.92310 : 1.055 * exp(log(x) / 2.39990) - 0.055;//calculate with calcgamma + // return x <= 0.003041 ? x * 12.92310 : 1.055 * exp(log(x) / 2.39990) - 0.055;//calculate with calcgamma //return x <= 0.0031308 ? x * 12.92310 : 1.055 * exp(log(x) / sRGBGammaCurve) - 0.055;//standard discontinuous - //very small differences between the 2 + //very small differences between the 2 return x <= 0.003040 ? x * 12.92310 : 1.055 * exp(log(x) / sRGBGammaCurve) - 0.055;//continuous - // return x <= 0.003041 ? x * 12.92310 : 1.055011 * exp(log(x) / sRGBGammaCurve) - 0.055011;//continuous - + // return x <= 0.003041 ? x * 12.92310 : 1.055011 * exp(log(x) / sRGBGammaCurve) - 0.055011;//continuous } @@ -1080,12 +1085,11 @@ public: */ static inline double igamma2 (double x) //g2 { - // return x <= 0.039289 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * 2.39990);//calculate with calcgamma - // return x <= 0.04045 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * sRGBGammaCurve);//standard discontinuous - //very small differences between the 4 + // return x <= 0.039289 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * 2.39990);//calculate with calcgamma + // return x <= 0.04045 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * sRGBGammaCurve);//standard discontinuous + //very small differences between the 4 return x <= 0.039286 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * sRGBGammaCurve);//continuous - // return x <= 0.039293 ? x / 12.92310 : exp(log((x + 0.055011) / 1.055011) * sRGBGammaCurve);//continuous - + // return x <= 0.039293 ? x / 12.92310 : exp(log((x + 0.055011) / 1.055011) * sRGBGammaCurve);//continuous } @@ -1804,11 +1808,9 @@ public: return (hr); } - static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) { - gamma = 1.f / gamma; + static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, int W) { int i = 0; #ifdef __SSE2__ - const vfloat gammav = F2V(gamma); const vfloat c1v = F2V(0.2627f); const vfloat c2v = F2V(0.6780f); const vfloat c3v = F2V(0.0593f); @@ -1816,7 +1818,7 @@ public: const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - vfloat yv = pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav); + vfloat yv = c1v * Rv + c2v * Gv + c3v * Bv; STVFU(Y1[i], yv); STVFU(Y2[i], yv); } @@ -1825,7 +1827,7 @@ public: const float r = std::max(R[i], 0.f); const float g = std::max(G[i], 0.f); const float b = std::max(B[i], 0.f); - Y1[i] = Y2[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); + Y1[i] = Y2[i] = 0.2627f * r + 0.6780f * g + 0.0593f * b; } } diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 3ddbdc28a..02d3e0e6d 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -16,19 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include + #include "colortemp.h" -#include "rtengine.h" +#include "iccmatrices.h" +#include "rt_math.h" #include #include #include -#include "sleef.c" +#include "sleef.h" #include "settings.h" namespace rtengine { -extern const Settings* settings; - static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. {0.0000000, 0.000000, 0.000000}, {0.0000000, 0.000000, 0.000000}, {0.0001299, 0.0003917, 0.0006061}, {0.0002321, 0.000006965, 0.001086}, {0.0004149, 0.00001239, 0.001946}, {0.0007416, 0.00002202, 0.003846}, diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index da83177be..a38e01072 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _COLORTEMP_ -#define _COLORTEMP_ +#pragma once #include #include @@ -207,4 +206,3 @@ public: }; } -#endif diff --git a/rtengine/coord.h b/rtengine/coord.h index 5f16cf606..6a7decdda 100644 --- a/rtengine/coord.h +++ b/rtengine/coord.h @@ -17,8 +17,7 @@ * along with RawTherapee. If not, see . */ -#ifndef __COORD__ -#define __COORD__ +#pragma once namespace rtengine { @@ -253,5 +252,3 @@ inline const PolarCoord operator* (const double lhs, const PolarCoord& rhs) } } - -#endif diff --git a/rtengine/coord2d.h b/rtengine/coord2d.h index 252219e47..9f0784b9a 100644 --- a/rtengine/coord2d.h +++ b/rtengine/coord2d.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __COORD2D__ -#define __COORD2D__ +#pragma once namespace rtengine { @@ -35,5 +34,5 @@ public: y = y_; } }; + } -#endif diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index 91e71fcd5..c127a7adf 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -17,9 +17,7 @@ * 2010 Ilya Popov * 2012 Emil Martinec */ - -#ifndef CPLX_WAVELET_DEC_H_INCLUDED -#define CPLX_WAVELET_DEC_H_INCLUDED +#pragma once #include #include @@ -266,5 +264,3 @@ void wavelet_decomposition::reconstruct(E * dst, const float blend) } } - -#endif diff --git a/rtengine/cplx_wavelet_filter_coeffs.h b/rtengine/cplx_wavelet_filter_coeffs.h index 6b8255b89..6287fc03b 100644 --- a/rtengine/cplx_wavelet_filter_coeffs.h +++ b/rtengine/cplx_wavelet_filter_coeffs.h @@ -17,7 +17,7 @@ * 2012 Emil Martinec * 2014 Jacques Desmis */ - +#pragma once namespace rtengine { diff --git a/rtengine/cplx_wavelet_level.h b/rtengine/cplx_wavelet_level.h index 4c98addfe..09b4e4a88 100644 --- a/rtengine/cplx_wavelet_level.h +++ b/rtengine/cplx_wavelet_level.h @@ -17,10 +17,8 @@ * 2010 Ilya Popov * 2012 Emil Martinec * 2014 Ingo Weyrich - */ - -#ifndef CPLX_WAVELET_LEVEL_H_INCLUDED -#define CPLX_WAVELET_LEVEL_H_INCLUDED +*/ +#pragma once #include #include "rt_math.h" @@ -274,7 +272,7 @@ template void wavelet_level::SynthesisFilterHaarVertical (const T #pragma omp for nowait #endif - for(int i = 0; i < skip; i++) + for(int i = 0; i < std::min(skip, height); i++) { for(int j = 0; j < width; j++) { dst[width * i + j] = (srcLo[i * width + j] + srcHi[i * width + j]); @@ -759,5 +757,3 @@ template template void wavelet_level::reconstruct_lev } #endif } - -#endif diff --git a/rtengine/curves.cc b/rtengine/curves.cc index a7e3337c8..b2105a091 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -23,9 +23,6 @@ #include #include #include -#ifdef _OPENMP -#include -#endif #include "rt_math.h" @@ -514,7 +511,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou double shcompr, double br, double contr, const std::vector& curvePoints, const std::vector& curvePoints2, - LUTu & histogram, + const LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & customToneCurve1, diff --git a/rtengine/curves.h b/rtengine/curves.h index 25272d44c..bc8193b76 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -16,24 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __CURVES_H__ -#define __CURVES_H__ +#pragma once #include #include #include -#include +#include #include "rt_math.h" -#include "../rtgui/mycurve.h" -#include "../rtgui/myflatcurve.h" -#include "../rtgui/mydiagonalcurve.h" -#include "color.h" +#include "flatcurvetypes.h" +#include "diagonalcurvetypes.h" #include "pipettebuffer.h" #include "noncopyable.h" #include "LUT.h" - +#include "sleef.h" #define CURVES_MIN_POLY_POINTS 1000 #include "rt_math.h" @@ -354,7 +351,7 @@ public: public: static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, const std::vector& curvePoints, const std::vector& curvePoints2, - LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, + const LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, int skip = 1); static void curveBW (const std::vector& curvePointsbw, const std::vector& curvePointsbw2, const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, @@ -896,12 +893,6 @@ public: float *r, float *g, float *b) const; }; -class SatAndValueBlendingToneCurve : public ToneCurve -{ -public: - void Apply(float& r, float& g, float& b) const; -}; - class WeightedStdToneCurve : public ToneCurve { private: @@ -1271,45 +1262,6 @@ inline void WeightedStdToneCurve::BatchApply(const size_t start, const size_t en #endif } -// Tone curve modifying the value channel only, preserving hue and saturation -// values in 0xffff space -inline void SatAndValueBlendingToneCurve::Apply (float& ir, float& ig, float& ib) const -{ - - assert (lutToneCurve); - - float r = CLIP(ir); - float g = CLIP(ig); - float b = CLIP(ib); - - const float lum = (r + g + b) / 3.f; - const float newLum = lutToneCurve[lum]; - - if (newLum == lum) { - return; - } - - float h, s, v; - Color::rgb2hsvtc(r, g, b, h, s, v); - - float dV; - if (newLum > lum) { - // Linearly targeting Value = 1 and Saturation = 0 - const float coef = (newLum - lum) / (65535.f - lum); - dV = (1.f - v) * coef; - s *= 1.f - coef; - } else { - // Linearly targeting Value = 0 - const float coef = (newLum - lum) / lum ; - dV = v * coef; - } - Color::hsv2rgbdcp(h, s, v + dV, r, g, b); - - setUnlessOOG(ir, ig, ib, r, g, b); -} - } #undef CLIPI - -#endif diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 8127ebfcb..11fe306b8 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -21,22 +21,22 @@ #include #include #include +#include +#include +#include #include "dcp.h" #include "cJSON.h" +#include "color.h" #include "iccmatrices.h" #include "iccstore.h" -#include "improcfun.h" +#include "imagefloat.h" #include "rawimagesource.h" #include "rt_math.h" - -namespace rtengine -{ - -extern const Settings* settings; - -} +#include "utils.h" +#include "../rtexif/rtexif.h" +#include "../rtgui/options.h" using namespace rtengine; using namespace rtexif; @@ -432,7 +432,7 @@ std::map getAliases(const Glib::ustring& profile_dir) } -struct DCPProfile::ApplyState::Data { +struct DCPProfileApplyState::Data { float pro_photo[3][3]; float work[3][3]; bool already_pro_photo; @@ -441,14 +441,12 @@ struct DCPProfile::ApplyState::Data { float bl_scale; }; -DCPProfile::ApplyState::ApplyState() : +DCPProfileApplyState::DCPProfileApplyState() : data(new Data{}) { } -DCPProfile::ApplyState::~ApplyState() -{ -} +DCPProfileApplyState::~DCPProfileApplyState() = default; DCPProfile::DCPProfile(const Glib::ustring& filename) : has_color_matrix_1(false), @@ -1148,7 +1146,7 @@ void DCPProfile::apply( } } -void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out) +void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out) { as_out.data->use_tone_curve = use_tone_curve; as_out.data->apply_look_table = apply_look_table; @@ -1192,7 +1190,7 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use } } -void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const ApplyState& as_in) const +void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const { #define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) @@ -1868,7 +1866,7 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const if (res->isValid()) { // Add profile profile_cache[key] = res; - if (options.rtSettings.verbose) { + if (settings->verbose) { printf("DCP profile '%s' loaded from disk\n", filename.c_str()); } return res; diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 826f073a5..573349348 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -24,35 +24,23 @@ #include #include -#include +#include #include "../rtgui/threadutils.h" -#include "imagefloat.h" #include "curves.h" -#include "colortemp.h" #include "noncopyable.h" namespace rtengine { +class ColorTemp; +class Imagefloat; +class DCPProfileApplyState; + class DCPProfile final { public: - class ApplyState final - { - public: - ApplyState(); - ~ApplyState(); - - private: - struct Data; - - const std::unique_ptr data; - - friend class DCPProfile; - }; - struct Illuminants { short light_source_1; short light_source_2; @@ -86,8 +74,8 @@ public: const Matrix& cam_wb_matrix, bool apply_hue_sat_map = true ) const; - void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out); - void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const; + void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out); + void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const; private: struct HsbModify { @@ -148,6 +136,20 @@ private: AdobeToneCurve tone_curve; }; +class DCPProfileApplyState final +{ +public: + DCPProfileApplyState(); + ~DCPProfileApplyState(); + +private: + struct Data; + + const std::unique_ptr data; + + friend class DCPProfile; +}; + class DCPStore final : public NonCopyable { diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index e15a2bb0f..d5348286c 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -26,12 +26,13 @@ /*RT*/#include /*RT*/#endif +#include #include #include #include "opthelper.h" //#define BENCHMARK #include "StopWatch.h" - +#include "utils.h" #include #include @@ -2417,59 +2418,63 @@ void CLASS hasselblad_correct() void CLASS hasselblad_load_raw() { - struct jhead jh; - int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; - unsigned upix, urow, ucol; - ushort *ip; + struct jhead jh; + int diff[12]; - if (!ljpeg_start (&jh, 0)) return; - order = 0x4949; - ph1_bithuff_t ph1_bithuff(this, ifp, order); - hb_bits(-1); - back[4] = (int *) calloc (raw_width, 3*sizeof **back); - merror (back[4], "hasselblad_load_raw()"); - FORC3 back[c] = back[4] + c*raw_width; - cblack[6] >>= sh = tiff_samples > 1; - shot = LIM(shot_select, 1, tiff_samples) - 1; - for (row=0; row < raw_height; row++) { - FORC4 back[(c+3) & 3] = back[c]; - for (col=0; col < raw_width; col+=2) { - for (s=0; s < tiff_samples*2; s+=2) { - FORC(2) len[c] = ph1_huff(jh.huff[0]); - FORC(2) { - diff[s+c] = hb_bits(len[c]); - if ((diff[s+c] & (1 << (len[c]-1))) == 0) - diff[s+c] -= (1 << len[c]) - 1; - if (diff[s+c] == 65535) diff[s+c] = -32768; - } - } - for (s=col; s < col+2; s++) { - pred = 0x8000 + load_flags; - if (col) pred = back[2][s-2]; - if (col && row > 1) switch (jh.psv) { - case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; - } - f = (row & 1)*3 ^ ((col+s) & 1); - FORC (tiff_samples) { - pred += diff[(s & 1)*tiff_samples+c]; - upix = pred >> sh & 0xffff; - if (raw_image && c == shot) - RAW(row,s) = upix; - if (image) { - urow = row-top_margin + (c & 1); - ucol = col-left_margin - ((c >> 1) & 1); - ip = &image[urow*width+ucol][f]; - if (urow < height && ucol < width) - *ip = c < 4 ? upix : (*ip + upix) >> 1; - } - } - back[2][s] = pred; - } + if (!ljpeg_start (&jh, 0)) { + return; + } + order = 0x4949; + ph1_bithuff_t ph1_bithuff(this, ifp, order); + hb_bits(-1); + const int shot = LIM(shot_select, 1, tiff_samples) - 1; + const int predictor_init = static_cast(0x8000 + load_flags); + for (int row = 0; row < raw_height; ++row) { + int stashed_predictors[2] = {predictor_init, predictor_init}; + for (int col = 0; col < raw_width; col += 2) { + for (int s = 0; s < tiff_samples * 2; s += 2) { + const int len[2]= { + static_cast(ph1_huff(jh.huff[0])), + static_cast(ph1_huff(jh.huff[0])) + }; + for (int c = 0; c < 2; ++c) { + diff[s + c] = hb_bits(len[c]); + if ((diff[s + c] & (1 << (len[c] - 1))) == 0) { + diff[s + c] -= (1 << len[c]) - 1; + } + if (diff[s + c] == 65535) { + diff[s + c] = -32768; + } + } + } + for (int s = col; s < col + 2; ++s) { + int pred = stashed_predictors[s & 1]; + for (int c = 0; c < tiff_samples; ++c) { + pred += diff[(s & 1) * tiff_samples + c]; + const unsigned upix = pred & 0xffff; + if (raw_image && c == shot) { + RAW(row, s) = upix; + } + if (image) { + const int f = (row & 1) * 3 ^ ((col + s) & 1); + const unsigned urow = row - top_margin + (c & 1); + const unsigned ucol = col - left_margin - ((c >> 1) & 1); + ushort* const ip = &image[urow * width + ucol][f]; + if (urow < height && ucol < width) { + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + if (c == (tiff_samples-1)) { + stashed_predictors[s & 1] = pred; + } + } + } + } + } + ljpeg_end(&jh); + if (image) { + mix_green = 1; } - } - free (back[4]); - ljpeg_end (&jh); - if (image) mix_green = 1; } void CLASS leaf_hdr_load_raw() @@ -2683,93 +2688,6 @@ void CLASS canon_rmf_load_raw() maximum = curve[0x3ff]; } -unsigned CLASS pana_bits_t::operator() (int nbits, unsigned *bytes) -{ -/*RT static uchar buf[0x4000]; */ -/*RT static int vbits;*/ - int byte; - - if (!nbits && !bytes) return vbits=0; - if (!vbits) { - fread (buf+load_flags, 1, 0x4000-load_flags, ifp); - fread (buf, 1, load_flags, ifp); - } - if (encoding == 5) { - for (byte = 0; byte < 16; byte++) - { - bytes[byte] = buf[vbits++]; - vbits &= 0x3FFF; - } - return 0; - } else { - vbits = (vbits - nbits) & 0x1ffff; - byte = vbits >> 3 ^ 0x3ff0; - return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); - } -} - -void CLASS panasonic_load_raw() -{ - pana_bits_t pana_bits(ifp,load_flags, RT_pana_info.encoding); - int row, col, i, j, sh=0, pred[2], nonz[2]; - unsigned bytes[16] = {}; - ushort *raw_block_data; - - pana_bits(0, 0); - int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; - if (RT_pana_info.encoding == 5) { - for (row = 0; row < raw_height; row++) - { - raw_block_data = raw_image + row * raw_width; - - for (col = 0; col < raw_width; col += enc_blck_size) { - pana_bits(0, bytes); - - if (RT_pana_info.bpp == 12) { - raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; - raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); - raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; - raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); - raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; - raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); - raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; - raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); - raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; - raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); - } - else if (RT_pana_info.bpp == 14) { - raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); - raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + - ((bytes[3] & 0xF) << 10); - raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + - ((bytes[5] & 3) << 12); - raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); - raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); - raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); - raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); - raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); - raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); - } - } - } - } else { - for (row=0; row < height; row++) - for (col=0; col < raw_width; col++) { - if ((i = col % 14) == 0) - pred[0] = pred[1] = nonz[0] = nonz[1] = 0; - if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); - if (nonz[i & 1]) { - if ((j = pana_bits(8))) { - if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) - pred[i & 1] &= ~(-1 << sh); - pred[i & 1] += j << sh; - } - } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) - pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); - if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror(); - } - } -} void CLASS olympus_load_raw() { @@ -4216,8 +4134,8 @@ void CLASS foveon_interpolate() foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 - ddft[0][c][0] ) / 4 - ddft[0][c][1]; } - memcpy (black, black+8, sizeof *black*8); - memcpy (black+height-11, black+height-22, 11*sizeof *black); + memmove (black, black+8, sizeof *black*8); + memmove (black+height-11, black+height-22, 11*sizeof *black); memcpy (last, black, sizeof last); for (row=1; row < height-1; row++) { @@ -5677,13 +5595,26 @@ nf: order = 0x4949; else if (!strcmp (buf,"AOC") || !strcmp (buf,"QVC")) fseek (ifp, -4, SEEK_CUR); + // ALB -- taken from LibRaw ------------------------------------------------ + else if (!strncmp(buf, "CMT3", 4)) + { + order = sget2((uchar *)(buf + 4)); + fseek(ifp, 2L, SEEK_CUR); + } + else if (RT_canon_CR3_data.CR3_CTMDtag) + { + order = sget2((uchar *)buf); + fseek(ifp, -2L, SEEK_CUR); + } + // ------------------------------------------------------------------------- + else { fseek (ifp, -10, SEEK_CUR); if (!strncmp(make,"SAMSUNG",7)) base = ftell(ifp); } entries = get2(); - if (entries > 1000) return; + if (entries > 2000) return; morder = order; while (entries--) { order = morder; @@ -5888,16 +5819,335 @@ get2_256: parse_thumb_note (base, 136, 137); } if (tag == 0x4001 && len > 500) { - i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; - fseek (ifp, i, SEEK_CUR); - FORC4 cam_mul[c ^ (c >> 1)] = get2(); - for (i+=18; i <= len; i+=10) { - get2(); - FORC4 sraw_mul[c ^ (c >> 1)] = get2(); - if (sraw_mul[1] == 1170) break; + // i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; + // fseek (ifp, i, SEEK_CUR); + // FORC4 cam_mul[c ^ (c >> 1)] = get2(); + // for (i+=18; i <= len; i+=10) { + // get2(); + // FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + // if (sraw_mul[1] == 1170) break; + // } + // -- ALB -- adapted from LibRaw -------------------------------------- + int bls = 0; + long int offsetChannelBlackLevel = 0L; + long int offsetChannelBlackLevel2 = 0L; + long int offsetWhiteLevels = 0L; + struct { + int AverageBlackLevel; + int ColorDataSubVer; + int NormalWhiteLevel; + int SpecularWhiteLevel; + } imCanon = { 0, 0, 0, 0 }; + long int save1 = ftell(ifp); + + switch (len) + { + + case 582: + // imCanon.ColorDataVer = 1; // 20D / 350D + + fseek(ifp, save1 + (0x0019 << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x001e << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0041 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0046 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2(); + + // fseek(ifp, save1 + (0x0023 << 1), SEEK_SET); + // Canon_WBpresets(2, 2); + // fseek(ifp, save1 + (0x004b << 1), SEEK_SET); + // Canon_WBCTpresets(1); // ABCT + offsetChannelBlackLevel = save1 + (0x00a6 << 1); + break; + + case 653: + // imCanon.ColorDataVer = 2; // 1Dmk2 / 1DsMK2 + + // fseek(ifp, save1 + (0x0018 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + fseek(ifp, save1 + (0x0022 << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0090 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0095 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x009a << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2(); + + // fseek(ifp, save1 + (0x0027 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET); + // Canon_WBCTpresets(1); // ABCT + offsetChannelBlackLevel = save1 + (0x011e << 1); + break; + + case 796: + // imCanon.ColorDataVer = 3; // 1DmkIIN / 5D / 30D / 400D + // imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x003f << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0044 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0049 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0071 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0076 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x007b << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom][c ^ (c >> 1)] = get2(); + + // fseek(ifp, save1 + (0x004e << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); + // Canon_WBCTpresets(0); // BCAT + offsetChannelBlackLevel = save1 + (0x00c4 << 1); + break; + + // 1DmkIII / 1DSmkIII / 1DmkIV / 5DmkII + // 7D / 40D / 50D / 60D / 450D / 500D + // 550D / 1000D / 1100D + case 674: + case 692: + case 702: + case 1227: + case 1250: + case 1251: + case 1337: + case 1338: + case 1346: + // imCanon.ColorDataVer = 4; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x003f << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0044 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0049 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + + fseek(ifp, save1 + (0x004e << 1), SEEK_SET); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0053 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET); + // Canon_WBCTpresets(0); // BCAT + + if ((imCanon.ColorDataSubVer == 4) || + (imCanon.ColorDataSubVer == 5)) + { + offsetChannelBlackLevel = save1 + (0x02b4 << 1); + offsetWhiteLevels = save1 + (0x02b8 << 1); } + else if ((imCanon.ColorDataSubVer == 6) || + (imCanon.ColorDataSubVer == 7)) + { + offsetChannelBlackLevel = save1 + (0x02cb << 1); + offsetWhiteLevels = save1 + (0x02cf << 1); + } + else if (imCanon.ColorDataSubVer == 9) + { + offsetChannelBlackLevel = save1 + (0x02cf << 1); + offsetWhiteLevels = save1 + (0x02d3 << 1); + } + else + offsetChannelBlackLevel = save1 + (0x00e7 << 1); + break; + + case 5120: // PowerShot G10, G12, G5 X, G7 X, G9 X, EOS M3, EOS M5, EOS M6 + // imCanon.ColorDataVer = 5; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x0047 << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + + if (imCanon.ColorDataSubVer == 0xfffc) + { // -4: G7 X Mark II, G9 X Mark II, G1 X Mark III, M5, M100, M6 + // fseek(ifp, save1 + (0x004f << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, 8, SEEK_CUR); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = + // get2(); + // fseek(ifp, 8, SEEK_CUR); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Other][c ^ (c >> 1)] = get2(); + // fseek(ifp, 8, SEEK_CUR); + // Canon_WBpresets(8, 24); + // fseek(ifp, 168, SEEK_CUR); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][c ^ (c >> 1)] = get2(); + // fseek(ifp, 24, SEEK_CUR); + // Canon_WBCTpresets(2); // BCADT + offsetChannelBlackLevel = save1 + (0x014d << 1); + offsetWhiteLevels = save1 + (0x0569 << 1); + } + else if (imCanon.ColorDataSubVer == 0xfffd) + { // -3: M10/M3/G1 X/G1 X II/G10/G11/G12/G15/G16/G3 X/G5 X/G7 X/G9 + // X/S100/S110/S120/S90/S95/SX1 IX/SX50 HS/SX60 HS + // fseek(ifp, save1 + (0x004c << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // get2(); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = + // get2(); + // get2(); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Other][c ^ (c >> 1)] = get2(); + // get2(); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x00ba << 1), SEEK_SET); + // Canon_WBCTpresets(2); // BCADT + offsetChannelBlackLevel = save1 + (0x0108 << 1); + } + break; + + case 1273: + case 1275: + // imCanon.ColorDataVer = 6; // 600D / 1200D + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x003f << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0044 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0049 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + + fseek(ifp, save1 + (0x0062 << 1), SEEK_SET); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0067 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x00bc << 1), SEEK_SET); + // Canon_WBCTpresets(0); // BCAT + offsetChannelBlackLevel = save1 + (0x01df << 1); + offsetWhiteLevels = save1 + (0x01e3 << 1); + break; + + // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / EOS M / 7DmkII / 750D / 760D + case 1312: + case 1313: + case 1316: + case 1506: + // imCanon.ColorDataVer = 7; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x003f << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0044 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0049 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + + fseek(ifp, save1 + (0x007b << 1), SEEK_SET); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET); + // Canon_WBCTpresets(0); // BCAT + + if (imCanon.ColorDataSubVer == 10) + { + offsetChannelBlackLevel = save1 + (0x01f8 << 1); + offsetWhiteLevels = save1 + (0x01fc << 1); + } + else if (imCanon.ColorDataSubVer == 11) + { + offsetChannelBlackLevel = save1 + (0x02d8 << 1); + offsetWhiteLevels = save1 + (0x02dc << 1); + } + break; + + // 5DS / 5DS R / 80D / 1300D / 1500D / 3000D / 5D4 / 800D / 77D / 6D II / + // 200D + case 1560: + case 1592: + case 1353: + case 1602: + // imCanon.ColorDataVer = 8; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x003f << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // fseek(ifp, save1 + (0x0044 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0049 << 1), SEEK_SET); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + + fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x0107 << 1), SEEK_SET); + // Canon_WBCTpresets(0); // BCAT + + if (imCanon.ColorDataSubVer == 14) + { // 1300D / 1500D / 3000D + offsetChannelBlackLevel = save1 + (0x022c << 1); + offsetWhiteLevels = save1 + (0x0230 << 1); + } + else + { + offsetChannelBlackLevel = save1 + (0x030a << 1); + offsetWhiteLevels = save1 + (0x030e << 1); + } + break; + + case 1820: // M50, ColorDataSubVer 16 + case 1824: // EOS R, SX740HS, ColorDataSubVer 17 + case 1816: // EOS RP, SX70HS, ColorDataSubVer 18; + // EOS M6 Mark II, EOS 90D, G7XmkIII, ColorDataSubVer 19 + // imCanon.ColorDataVer = 9; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x0047 << 1), SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); + // get2(); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2(); + // get2(); + // FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2(); + // fseek(ifp, save1 + (0x0088 << 1), SEEK_SET); + // Canon_WBpresets(2, 12); + // fseek(ifp, save1 + (0x010a << 1), SEEK_SET); + // Canon_WBCTpresets(0); + offsetChannelBlackLevel = save1 + (0x0318 << 1); + offsetChannelBlackLevel2 = save1 + (0x0149 << 1); + offsetWhiteLevels = save1 + (0x031c << 1); + break; } - if (tag == 0x4021 && get4() && get4()) + + if (offsetChannelBlackLevel) + { + fseek(ifp, offsetChannelBlackLevel, SEEK_SET); + FORC4 + bls += (cblack/*imCanon.ChannelBlackLevel*/[c ^ (c >> 1)] = get2()); + imCanon.AverageBlackLevel = bls / 4; + // RT_blacklevel_from_constant = ThreeValBool::F; + } + if (offsetWhiteLevels) + { + if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L) + fseek(ifp, offsetWhiteLevels, SEEK_SET); + imCanon.NormalWhiteLevel = get2(); + imCanon.SpecularWhiteLevel = get2(); + // FORC4 + // imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel; + maximum = imCanon.SpecularWhiteLevel; + // RT_whitelevel_from_constant = ThreeValBool::F; + } + + if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2) + { + fseek(ifp, offsetChannelBlackLevel2, SEEK_SET); + FORC4 + bls += (cblack/*imCanon.ChannelBlackLevel*/[c ^ (c >> 1)] = get2()); + imCanon.AverageBlackLevel = bls / 4; + // RT_blacklevel_from_constant = ThreeValBool::F; + } + fseek(ifp, save1, SEEK_SET); + + //--------------------------------------------------------------------- + } if (tag == 0x4021 && get4() && get4()) FORC4 cam_mul[c] = 1024; if (tag == 0xa021) FORC4 cam_mul[c ^ (c >> 1)] = get4(); @@ -6765,7 +7015,8 @@ int CLASS parse_tiff (int base) void CLASS apply_tiff() { - int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i; + int max_samp=0, ties=0, /*os, ns,*/ raw=-1, thm=-1, i; + uint64_t os, ns; // RT struct jhead jh; thumb_misc = 16; @@ -6795,6 +7046,7 @@ void CLASS apply_tiff() } if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && // RT ns && ((ns > os && (ties = 1)) || (ns == os && shot_select == ties++))) { raw_width = tiff_ifd[i].width; @@ -6862,7 +7114,7 @@ void CLASS apply_tiff() load_raw = &CLASS olympus_load_raw; // ------- RT ------- if (!strncmp(make,"SONY",4) && - !strncmp(model,"ILCE-7RM3",9) && + (!strncmp(model,"ILCE-7RM3",9) || !strncmp(model,"ILCE-7RM4",9)) && tiff_samples == 4 && tiff_ifd[raw].bytes == raw_width*raw_height*tiff_samples*2) { load_raw = &CLASS sony_arq_load_raw; @@ -9395,6 +9647,11 @@ void CLASS identify() parse_foveon(); else if (!memcmp (head,"CI",2)) parse_cine(); + //--- RT ---------------------------------------------------------------- + else if (!memcmp(head + 4, "ftypcrx ", 8)) { + parse_canon_cr3(); + } + //------------------------------------------------------------------------- if (make[0] == 0) for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) if (fsize == table[i].fsize) { @@ -10754,8 +11011,6 @@ void CLASS nikon_14bit_load_raw() free(buf); } -//----------------------------------------------------------------------------- - /* RT: Delete from here */ /*RT*/#undef SQR /*RT*/#undef MAX diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index fdebda0cc..89c1fcaff 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -17,8 +17,7 @@ * along with RawTherapee. If not, see . */ -#ifndef DCRAW_H -#define DCRAW_H +#pragma once #include "myfile.h" #include @@ -69,6 +68,7 @@ public: gamm[0]=0.45;gamm[1]=4.5;gamm[2]=gamm[3]=gamm[4]=gamm[5]=0; user_mul[0]=user_mul[1]=user_mul[2]=user_mul[3]=0; greybox[0]=greybox[1]=0; greybox[2]=greybox[3]= UINT_MAX; + RT_canon_CR3_data.CR3_CTMDtag = 0; } protected: @@ -165,11 +165,39 @@ protected: PanasonicRW2Info(): bpp(0), encoding(0) {} }; PanasonicRW2Info RT_pana_info; +public: + struct CanonCR3Data { + // contents of tag CMP1 for relevant track in CR3 file + struct crx_data_header_t { + int32_t version; + int32_t f_width; + int32_t f_height; + int32_t tileWidth; + int32_t tileHeight; + int32_t nBits; + int32_t nPlanes; + int32_t cfaLayout; + int32_t encType; + int32_t imageLevels; + int32_t hasTileCols; + int32_t hasTileRows; + int32_t mdatHdrSize; + // Not from header, but from datastream + uint32_t MediaSize; + int64_t MediaOffset; + uint32_t MediaType; /* 1 -> /C/RAW, 2-> JPEG */ + }; + static constexpr size_t CRXTRACKS_MAXCOUNT = 16; + crx_data_header_t crx_header[CRXTRACKS_MAXCOUNT]; + unsigned int crx_track_selected; + short CR3_CTMDtag; + }; +protected: + CanonCR3Data RT_canon_CR3_data; float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; - int histogram[4][0x2000]; - void (DCraw::*write_thumb)(), (DCraw::*write_fun)(); + void (DCraw::*write_thumb)(); void (DCraw::*load_raw)(), (DCraw::*thumb_load_raw)(); jmp_buf failure; @@ -413,6 +441,9 @@ private: unsigned encoding; }; +void panasonicC6_load_raw(); +void panasonicC7_load_raw(); + void canon_rmf_load_raw(); void panasonic_load_raw(); void olympus_load_raw(); @@ -528,7 +559,20 @@ void shiftXtransMatrix( const int offsy, const int offsx) { void nikon_14bit_load_raw(); // ported from LibRaw +//----------------------------------------------------------------------------- +// Canon CR3 support ported from LibRaw +//----------------------------------------------------------------------------- +void parse_canon_cr3(); +void selectCRXTrack(unsigned short maxTrack); +int parseCR3(unsigned long long oAtomList, + unsigned long long szAtomList, short &nesting, + char *AtomNameStack, unsigned short &nTrack, short &TrackType); +bool crxDecodePlane(void *p, uint32_t planeNumber); +void crxLoadDecodeLoop(void *img, int nPlanes); +void crxConvertPlaneLineDf(void *p, int imageRow); +void crxLoadFinalizeLoopE3(void *p, int planeHeight); +void crxLoadRaw(); +bool crxParseImageHeader(uchar *cmp1TagData, unsigned int nTrack); +//----------------------------------------------------------------------------- + }; - - -#endif //DCRAW_H diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index f80982d8b..1bfb14040 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -17,12 +17,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include "cieimage.h" #include "curves.h" +#include "dcp.h" #include "dcrop.h" +#include "image8.h" +#include "imagefloat.h" +#include "labimage.h" #include "mytime.h" #include "procparams.h" #include "refreshmap.h" #include "rt_math.h" + #include "../rtgui/editcallbacks.h" namespace @@ -40,8 +47,6 @@ constexpr T skips(T a, T b) namespace rtengine { -extern const Settings* settings; - Crop::Crop(ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : PipetteBuffer(editDataProvider), origCrop(nullptr), spotCrop(nullptr), laboCrop(nullptr), labnCrop(nullptr), cropImg (nullptr), transCrop (nullptr), cieCrop (nullptr), @@ -191,18 +196,8 @@ void Crop::update(int todo) params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); - int tilesize; - int overlap; - - if (settings->leveldnti == 0) { - tilesize = 1024; - overlap = 128; - } - - if (settings->leveldnti == 1) { - tilesize = 768; - overlap = 96; - } + const int tilesize = settings->leveldnti == 0 ? 1024 : 768; + const int overlap = settings->leveldnti == 0 ? 128 : 96; int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; @@ -854,7 +849,7 @@ void Crop::update(int todo) } } double rrm, ggm, bbm; - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, as); LUTu histToneCurve; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index aa4a3a963..74ed58d83 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -21,8 +21,6 @@ #include "improccoordinator.h" #include "rtengine.h" #include "improcfun.h" -#include "image8.h" -#include "image16.h" #include "imagesource.h" #include "procevents.h" #include "pipettebuffer.h" @@ -31,6 +29,8 @@ namespace rtengine { +class Image8; + using namespace procparams; class ImProcCoordinator; diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 51db8bb3f..c48a002fb 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -21,13 +21,9 @@ #include "rawimagesource.h" #include "rawimage.h" -#include "mytime.h" -#include "image8.h" #include "rt_math.h" #include "color.h" #include "../rtgui/multilangmgr.h" -#include "procparams.h" -#include "sleef.c" #include "opthelper.h" #include "median.h" //#define BENCHMARK @@ -41,176 +37,13 @@ using namespace std; namespace rtengine { -extern const Settings* settings; - -#undef ABS - -#define ABS(a) ((a)<0?-(a):(a)) -#define CLIREF(x) LIM(x,-200000.0f,200000.0f) // avoid overflow : do not act directly on image[] or pix[] -#define x1125(a) (a + xdivf(a, 3)) -#define x0875(a) (a - xdivf(a, 3)) -#define x0250(a) xdivf(a, 2) -#define x00625(a) xdivf(a, 4) -#define x0125(a) xdivf(a, 3) - #undef fc #define fc(row,col) \ (ri->get_filters() >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) #define FORCC for (unsigned int c=0; c < colors; c++) -/* - Patterned Pixel Grouping Interpolation by Alain Desbiolles -*/ -void RawImageSource::ppg_demosaic() -{ - int width = W, height = H; - int dir[5] = { 1, width, -1, -width, 1 }; - int row, col, diff[2] = {}, guess[2], c, d, i; - float (*pix)[4]; - - float (*image)[4]; - - if (plistener) { - // looks like ppg isn't supported anymore - //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::ppg))); - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("GENERAL_NA"))); - plistener->setProgress (0.0); - } - - image = (float (*)[4]) calloc (H * W, sizeof * image); - - for (int ii = 0; ii < H; ii++) - for (int jj = 0; jj < W; jj++) { - image[ii * W + jj][fc(ii, jj)] = rawData[ii][jj]; - } - - border_interpolate(3, image); - - /* Fill in the green layer with gradients and pattern recognition: */ - for (row = 3; row < height - 3; row++) { - for (col = 3 + (FC(row, 3) & 1), c = FC(row, col); col < width - 3; col += 2) { - pix = image + row * width + col; - - for (i = 0; (d = dir[i]) > 0; i++) { - guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 - - pix[-2 * d][c] - pix[2 * d][c]; - diff[i] = ( ABS(pix[-2 * d][c] - pix[ 0][c]) + - ABS(pix[ 2 * d][c] - pix[ 0][c]) + - ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + - ( ABS(pix[ 3 * d][1] - pix[ d][1]) + - ABS(pix[-3 * d][1] - pix[-d][1]) ) * 2; - } - - d = dir[i = diff[0] > diff[1]]; - pix[0][1] = median(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); - } - - if(plistener) { - plistener->setProgress(0.33 * row / (height - 3)); - } - } - - /* Calculate red and blue for each green pixel: */ - for (row = 1; row < height - 1; row++) { - for (col = 1 + (FC(row, 2) & 1), c = FC(row, col + 1); col < width - 1; col += 2) { - pix = image + row * width + col; - - for (i = 0; (d = dir[i]) > 0; c = 2 - c, i++) - pix[0][c] = CLIP(0.5 * (pix[-d][c] + pix[d][c] + 2 * pix[0][1] - - pix[-d][1] - pix[d][1]) ); - } - - if(plistener) { - plistener->setProgress(0.33 + 0.33 * row / (height - 1)); - } - } - - /* Calculate blue for red pixels and vice versa: */ - for (row = 1; row < height - 1; row++) { - for (col = 1 + (FC(row, 1) & 1), c = 2 - FC(row, col); col < width - 1; col += 2) { - pix = image + row * width + col; - - for (i = 0; (d = dir[i] + dir[i + 1]) > 0; i++) { - diff[i] = ABS(pix[-d][c] - pix[d][c]) + - ABS(pix[-d][1] - pix[0][1]) + - ABS(pix[ d][1] - pix[0][1]); - guess[i] = pix[-d][c] + pix[d][c] + 2 * pix[0][1] - - pix[-d][1] - pix[d][1]; - } - - if (diff[0] != diff[1]) { - pix[0][c] = CLIP(guess[diff[0] > diff[1]] / 2); - } else { - pix[0][c] = CLIP((guess[0] + guess[1]) / 4); - } - } - - if(plistener) { - plistener->setProgress(0.67 + 0.33 * row / (height - 1)); - } - } - - red(W, H); - - for (int i = 0; i < H; i++) - for (int j = 0; j < W; j++) { - red[i][j] = image[i * W + j][0]; - } - - green(W, H); - - for (int i = 0; i < H; i++) - for (int j = 0; j < W; j++) { - green[i][j] = image[i * W + j][1]; - } - - blue(W, H); - - for (int i = 0; i < H; i++) - for (int j = 0; j < W; j++) { - blue[i][j] = image[i * W + j][2]; - } - - free (image); -} - -void RawImageSource::border_interpolate(unsigned int border, float (*image)[4], unsigned int start, unsigned int end) -{ - unsigned row, col, y, x, f; - float sum[8]; - unsigned int width = W, height = H; - unsigned int colors = 3; - - if (end == 0 ) { - end = H; - } - - for (row = start; row < end; row++) - for (col = 0; col < width; col++) { - if (col == border && row >= border && row < height - border) { - col = width - border; - } - - memset (sum, 0, sizeof sum); - - for (y = row - 1; y != row + 2; y++) - for (x = col - 1; x != col + 2; x++) - if (y < height && x < width) { - f = fc(y, x); - sum[f] += image[y * width + x][f]; - sum[f + 4]++; - } - - f = fc(row, col); - - FORCC if (c != f && sum[c + 4]) { - image[row * width + col][c] = sum[c] / sum[c + 4]; - } - } -} - -void RawImageSource::border_interpolate2( int winw, int winh, int lborders, const array2D &rawData, array2D &red, array2D &green, array2D &blue) +void RawImageSource::border_interpolate( int winw, int winh, int lborders, const array2D &rawData, array2D &red, array2D &green, array2D &blue) { int bord = lborders; int width = winw; @@ -365,751 +198,6 @@ void RawImageSource::border_interpolate2( int winw, int winh, int lborders, cons } -// Joint Demosaicing and Denoising using High Order Interpolation Techniques -// Revision 0.9.1a - 09/02/2010 - Contact info: luis.sanz.rodriguez@gmail.com -// Copyright Luis Sanz Rodriguez 2010 -// Adapted to RawTherapee by Jacques Desmis 3/2013 - -void RawImageSource::jdl_interpolate_omp() // from "Lassus" -{ - int width = W, height = H; - int row, col, c, d, i, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, z = 6 * u, indx, (*dif)[2], (*chr)[2]; - float f[4], g[4]; - float (*image)[4]; - image = (float (*)[4]) calloc (width * height, sizeof * image); - dif = (int (*)[2]) calloc(width * height, sizeof * dif); - chr = (int (*)[2]) calloc(width * height, sizeof * chr); - - if (plistener) { - // this function seems to be unused - //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::jdl))); - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("GENERAL_NA"))); - plistener->setProgress (0.0); - } - -#ifdef _OPENMP - #pragma omp parallel shared(image,width,height,u,w,v,y,x,z,dif,chr) private(row,col,f,g,indx,c,d,i) -#endif - { -#ifdef _OPENMP - #pragma omp for -#endif - - for (int ii = 0; ii < height; ii++) - for (int jj = 0; jj < width; jj++) { - image[ii * width + jj][fc(ii, jj)] = rawData[ii][jj]; - } - - border_interpolate(6, image); - -#ifdef _OPENMP - #pragma omp for -#endif - - for (row = 5; row < height - 5; row++) - for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col); col < u - 5; col += 2, indx += 2) { - f[0] = 1.f + abs(image[indx - u][1] - image[indx - w][1]) + abs(image[indx - u][1] - image[indx + u][1]) + abs(image[indx][c] - image[indx - v][c]) + abs(image[indx - v][c] - image[indx - x][c]); - f[1] = 1.f + abs(image[indx + 1][1] - image[indx + 3][1]) + abs(image[indx + 1][1] - image[indx - 1][1]) + abs(image[indx][c] - image[indx + 2][c]) + abs(image[indx + 2][c] - image[indx + 4][c]); - f[2] = 1.f + abs(image[indx - 1][1] - image[indx - 3][1]) + abs(image[indx - 1][1] - image[indx + 1][1]) + abs(image[indx][c] - image[indx - 2][c]) + abs(image[indx - 2][c] - image[indx - 4][c]); - f[3] = 1.f + abs(image[indx + u][1] - image[indx + w][1]) + abs(image[indx + u][1] - image[indx - u][1]) + abs(image[indx][c] - image[indx + v][c]) + abs(image[indx + v][c] - image[indx + x][c]); - g[0] = CLIP((22.f * image[indx - u][1] + 22.f * image[indx - w][1] + 2.f * image[indx - y][1] + 2.f * image[indx + u][1] + 40.f * image[indx][c] - 32.f * image[indx - v][c] - 8.f * image[indx - x][c]) / 48.f); - g[1] = CLIP((22.f * image[indx + 1][1] + 22.f * image[indx + 3][1] + 2.f * image[indx + 5][1] + 2.f * image[indx - 1][1] + 40.f * image[indx][c] - 32.f * image[indx + 2][c] - 8.f * image[indx + 4][c]) / 48.f); - g[2] = CLIP((22.f * image[indx - 1][1] + 22.f * image[indx - 3][1] + 2.f * image[indx - 5][1] + 2.f * image[indx + 1][1] + 40.f * image[indx][c] - 32.f * image[indx - 2][c] - 8.f * image[indx - 4][c]) / 48.f); - g[3] = CLIP((22.f * image[indx + u][1] + 22.f * image[indx + w][1] + 2.f * image[indx + y][1] + 2.f * image[indx - u][1] + 40.f * image[indx][c] - 32.f * image[indx + v][c] - 8.f * image[indx + x][c]) / 48.f); - dif[indx][0] = CLIP((f[3] * g[0] + f[0] * g[3]) / (f[0] + f[3])) - image[indx][c]; - dif[indx][1] = CLIP((f[2] * g[1] + f[1] * g[2]) / (f[1] + f[2])) - image[indx][c]; - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for (row = 6; row < height - 6; row++) - for (col = 6 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col) / 2; col < u - 6; col += 2, indx += 2) { - f[0] = 1.f + 78.f * SQR((float)dif[indx][0]) + 69.f * (SQR((float) dif[indx - v][0]) + SQR((float)dif[indx + v][0])) + 51.f * (SQR((float)dif[indx - x][0]) + SQR((float)dif[indx + x][0])) + 21.f * (SQR((float)dif[indx - z][0]) + SQR((float)dif[indx + z][0])) - 6.f * SQR((float)dif[indx - v][0] + dif[indx][0] + dif[indx + v][0]) - 10.f * (SQR((float)dif[indx - x][0] + dif[indx - v][0] + dif[indx][0]) + SQR((float)dif[indx][0] + dif[indx + v][0] + dif[indx + x][0])) - 7.f * (SQR((float)dif[indx - z][0] + dif[indx - x][0] + dif[indx - v][0]) + SQR((float)dif[indx + v][0] + dif[indx + x][0] + dif[indx + z][0])); - f[1] = 1.f + 78.f * SQR((float)dif[indx][1]) + 69.f * (SQR((float)dif[indx - 2][1]) + SQR((float)dif[indx + 2][1])) + 51.f * (SQR((float)dif[indx - 4][1]) + SQR((float)dif[indx + 4][1])) + 21.f * (SQR((float)dif[indx - 6][1]) + SQR((float)dif[indx + 6][1])) - 6.f * SQR((float)dif[indx - 2][1] + dif[indx][1] + dif[indx + 2][1]) - 10.f * (SQR((float)dif[indx - 4][1] + dif[indx - 2][1] + dif[indx][1]) + SQR((float)dif[indx][1] + dif[indx + 2][1] + dif[indx + 4][1])) - 7.f * (SQR((float)dif[indx - 6][1] + dif[indx - 4][1] + dif[indx - 2][1]) + SQR((float)dif[indx + 2][1] + dif[indx + 4][1] + dif[indx + 6][1])); - g[0] = median(0.725f * dif[indx][0] + 0.1375f * dif[indx - v][0] + 0.1375f * dif[indx + v][0], static_cast(dif[indx - v][0]), static_cast(dif[indx + v][0])); - g[1] = median(0.725f * dif[indx][1] + 0.1375f * dif[indx - 2][1] + 0.1375f * dif[indx + 2][1], static_cast(dif[indx - 2][1]), static_cast(dif[indx + 2][1])); - chr[indx][c] = (f[1] * g[0] + f[0] * g[1]) / (f[0] + f[1]); - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for (row = 6; row < height - 6; row++) - for (col = 6 + (FC(row, 2) & 1), indx = row * width + col, c = 1 - FC(row, col) / 2, d = 2 * c; col < u - 6; col += 2, indx += 2) { - f[0] = 1.f / (float)(1.f + fabs((float)chr[indx - u - 1][c] - chr[indx + u + 1][c]) + fabs((float)chr[indx - u - 1][c] - chr[indx - w - 3][c]) + fabs((float)chr[indx + u + 1][c] - chr[indx - w - 3][c])); - f[1] = 1.f / (float)(1.f + fabs((float)chr[indx - u + 1][c] - chr[indx + u - 1][c]) + fabs((float)chr[indx - u + 1][c] - chr[indx - w + 3][c]) + fabs((float)chr[indx + u - 1][c] - chr[indx - w + 3][c])); - f[2] = 1.f / (float)(1.f + fabs((float)chr[indx + u - 1][c] - chr[indx - u + 1][c]) + fabs((float)chr[indx + u - 1][c] - chr[indx + w + 3][c]) + fabs((float)chr[indx - u + 1][c] - chr[indx + w - 3][c])); - f[3] = 1.f / (float)(1.f + fabs((float)chr[indx + u + 1][c] - chr[indx - u - 1][c]) + fabs((float)chr[indx + u + 1][c] - chr[indx + w - 3][c]) + fabs((float)chr[indx - u - 1][c] - chr[indx + w + 3][c])); - g[0] = median(chr[indx - u - 1][c], chr[indx - w - 1][c], chr[indx - u - 3][c]); - g[1] = median(chr[indx - u + 1][c], chr[indx - w + 1][c], chr[indx - u + 3][c]); - g[2] = median(chr[indx + u - 1][c], chr[indx + w - 1][c], chr[indx + u - 3][c]); - g[3] = median(chr[indx + u + 1][c], chr[indx + w + 1][c], chr[indx + u + 3][c]); - chr[indx][c] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); - image[indx][1] = CLIP(image[indx][2 - d] + chr[indx][1 - c]); - image[indx][d] = CLIP(image[indx][1] - chr[indx][c]); - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for (row = 6; row < height - 6; row++) - for (col = 6 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col + 1) / 2, d = 2 * c; col < u - 6; col += 2, indx += 2) - for(i = 0; i <= 1; c = 1 - c, d = 2 * c, i++) { - f[0] = 1.f / (float)(1.f + fabs((float)chr[indx - u][c] - chr[indx + u][c]) + fabs((float)chr[indx - u][c] - chr[indx - w][c]) + fabs((float)chr[indx + u][c] - chr[indx - w][c])); - f[1] = 1.f / (float)(1.f + fabs((float)chr[indx + 1][c] - chr[indx - 1][c]) + fabs((float)chr[indx + 1][c] - chr[indx + 3][c]) + fabs((float)chr[indx - 1][c] - chr[indx + 3][c])); - f[2] = 1.f / (float)(1.f + fabs((float)chr[indx - 1][c] - chr[indx + 1][c]) + fabs((float)chr[indx - 1][c] - chr[indx - 3][c]) + fabs((float)chr[indx + 1][c] - chr[indx - 3][c])); - f[3] = 1.f / (float)(1.f + fabs((float)chr[indx + u][c] - chr[indx - u][c]) + fabs((float)chr[indx + u][c] - chr[indx + w][c]) + fabs((float)chr[indx - u][c] - chr[indx + w][c])); - g[0] = 0.875f * chr[indx - u][c] + 0.125f * chr[indx - w][c]; - g[1] = 0.875f * chr[indx + 1][c] + 0.125f * chr[indx + 3][c]; - g[2] = 0.875f * chr[indx - 1][c] + 0.125f * chr[indx - 3][c]; - g[3] = 0.875f * chr[indx + u][c] + 0.125f * chr[indx + w][c]; - image[indx][d] = CLIP(image[indx][1] - (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3])); - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for (int ii = 0; ii < height; ii++) { - for (int jj = 0; jj < width; jj++) { - red[ii][jj] = CLIP(image[ii * width + jj][0]); - green[ii][jj] = CLIP(image[ii * width + jj][1]); - blue[ii][jj] = CLIP(image[ii * width + jj][2]); - } - } - } // End of parallelization - free (image); - free(dif); - free(chr); - //RawImageSource::refinement_lassus(); -} - -// LSMME demosaicing algorithm -// L. Zhang and X. Wu, -// Color demozaicing via directional Linear Minimum Mean Square-error Estimation, -// IEEE Trans. on Image Processing, vol. 14, pp. 2167-2178, -// Dec. 2005. -// Adapted to RawTherapee by Jacques Desmis 3/2013 -// Improved speed and reduced memory consumption by Ingo Weyrich 2/2015 -//TODO Tiles to reduce memory consumption -void RawImageSource::lmmse_interpolate_omp(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations) -{ - const int width = winw, height = winh; - const int ba = 10; - const int rr1 = height + 2 * ba; - const int cc1 = width + 2 * ba; - const int w1 = cc1; - const int w2 = 2 * w1; - const int w3 = 3 * w1; - const int w4 = 4 * w1; - float h0, h1, h2, h3, h4, hs; - h0 = 1.0f; - h1 = exp( -1.0f / 8.0f); - h2 = exp( -4.0f / 8.0f); - h3 = exp( -9.0f / 8.0f); - h4 = exp(-16.0f / 8.0f); - hs = h0 + 2.0f * (h1 + h2 + h3 + h4); - h0 /= hs; - h1 /= hs; - h2 /= hs; - h3 /= hs; - h4 /= hs; - int passref = 0; - int iter = 0; - - if(iterations <= 4) { - iter = iterations - 1; - passref = 0; - } else if (iterations <= 6) { - iter = 3; - passref = iterations - 4; - } else if (iterations <= 8) { - iter = 3; - passref = iterations - 6; - } - - bool applyGamma = true; - - if(iterations == 0) { - applyGamma = false; - iter = 0; - } else { - applyGamma = true; - } - - float *rix[5]; - float *qix[5]; - float *buffer = (float *)calloc(rr1 * cc1 * 5 * sizeof(float), 1); - - if(buffer == nullptr) { // allocation of big block of memory failed, try to get 5 smaller ones - printf("lmmse_interpolate_omp: allocation of big memory block failed, try to get 5 smaller ones now...\n"); - bool allocationFailed = false; - - for(int i = 0; i < 5; i++) { - qix[i] = (float *)calloc(rr1 * cc1 * sizeof(float), 1); - - if(!qix[i]) { // allocation of at least one small block failed - allocationFailed = true; - } - } - - if(allocationFailed) { // fall back to igv_interpolate - printf("lmmse_interpolate_omp: allocation of 5 small memory blocks failed, falling back to igv_interpolate...\n"); - - for(int i = 0; i < 5; i++) { // free the already allocated buffers - if(qix[i]) { - free(qix[i]); - } - } - - igv_interpolate(winw, winh); - return; - } - } else { - qix[0] = buffer; - - for(int i = 1; i < 5; i++) { - qix[i] = qix[i - 1] + rr1 * cc1; - } - } - - if (plistener) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_LMMSE"))); - plistener->setProgress (0.0); - } - - - LUTf *gamtab; - - if(applyGamma) { - gamtab = &(Color::gammatab_24_17a); - } else { - gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); - gamtab->makeIdentity(65535.f); - } - - -#ifdef _OPENMP - #pragma omp parallel private(rix) -#endif - { -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rrr = ba; rrr < rr1 - ba; rrr++) { - for (int ccc = ba, row = rrr - ba; ccc < cc1 - ba; ccc++) { - int col = ccc - ba; - float *rix = qix[4] + rrr * cc1 + ccc; - rix[0] = (*gamtab)[rawData[row][col]]; - } - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.1); - } - } - - // G-R(B) -#ifdef _OPENMP - #pragma omp for schedule(dynamic,16) -#endif - - for (int rr = 2; rr < rr1 - 2; rr++) { - // G-R(B) at R(B) location - for (int cc = 2 + (FC(rr, 2) & 1); cc < cc1 - 2; cc += 2) { - rix[4] = qix[4] + rr * cc1 + cc; - float v0 = x00625(rix[4][-w1 - 1] + rix[4][-w1 + 1] + rix[4][w1 - 1] + rix[4][w1 + 1]) + x0250(rix[4][0]); - // horizontal - rix[0] = qix[0] + rr * cc1 + cc; - rix[0][0] = - x0250(rix[4][ -2] + rix[4][ 2]) + xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); - float Y = v0 + xdiv2f(rix[0][0]); - - if (rix[4][0] > 1.75f * Y) { - rix[0][0] = median(rix[0][0], rix[4][ -1], rix[4][ 1]); - } else { - rix[0][0] = LIM(rix[0][0], 0.0f, 1.0f); - } - - rix[0][0] -= rix[4][0]; - // vertical - rix[1] = qix[1] + rr * cc1 + cc; - rix[1][0] = -x0250(rix[4][-w2] + rix[4][w2]) + xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); - Y = v0 + xdiv2f(rix[1][0]); - - if (rix[4][0] > 1.75f * Y) { - rix[1][0] = median(rix[1][0], rix[4][-w1], rix[4][w1]); - } else { - rix[1][0] = LIM(rix[1][0], 0.0f, 1.0f); - } - - rix[1][0] -= rix[4][0]; - } - - // G-R(B) at G location - for (int ccc = 2 + (FC(rr, 3) & 1); ccc < cc1 - 2; ccc += 2) { - rix[0] = qix[0] + rr * cc1 + ccc; - rix[1] = qix[1] + rr * cc1 + ccc; - rix[4] = qix[4] + rr * cc1 + ccc; - rix[0][0] = x0250(rix[4][ -2] + rix[4][ 2]) - xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); - rix[1][0] = x0250(rix[4][-w2] + rix[4][w2]) - xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); - rix[0][0] = LIM(rix[0][0], -1.0f, 0.0f) + rix[4][0]; - rix[1][0] = LIM(rix[1][0], -1.0f, 0.0f) + rix[4][0]; - } - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.2); - } - } - - - // apply low pass filter on differential colors -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rr = 4; rr < rr1 - 4; rr++) - for (int cc = 4; cc < cc1 - 4; cc++) { - rix[0] = qix[0] + rr * cc1 + cc; - rix[2] = qix[2] + rr * cc1 + cc; - rix[2][0] = h0 * rix[0][0] + h1 * (rix[0][ -1] + rix[0][ 1]) + h2 * (rix[0][ -2] + rix[0][ 2]) + h3 * (rix[0][ -3] + rix[0][ 3]) + h4 * (rix[0][ -4] + rix[0][ 4]); - rix[1] = qix[1] + rr * cc1 + cc; - rix[3] = qix[3] + rr * cc1 + cc; - rix[3][0] = h0 * rix[1][0] + h1 * (rix[1][-w1] + rix[1][w1]) + h2 * (rix[1][-w2] + rix[1][w2]) + h3 * (rix[1][-w3] + rix[1][w3]) + h4 * (rix[1][-w4] + rix[1][w4]); - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.3); - } - } - - // interpolate G-R(B) at R(B) -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rr = 4; rr < rr1 - 4; rr++) { - int cc = 4 + (FC(rr, 4) & 1); -#ifdef __SSE2__ - __m128 p1v, p2v, p3v, p4v, p5v, p6v, p7v, p8v, p9v, muv, vxv, vnv, xhv, vhv, xvv, vvv; - __m128 epsv = _mm_set1_ps(1e-7); - __m128 ninev = _mm_set1_ps(9.f); - - for (; cc < cc1 - 10; cc += 8) { - rix[0] = qix[0] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - rix[2] = qix[2] + rr * cc1 + cc; - rix[3] = qix[3] + rr * cc1 + cc; - rix[4] = qix[4] + rr * cc1 + cc; - // horizontal - p1v = LC2VFU(rix[2][-4]); - p2v = LC2VFU(rix[2][-3]); - p3v = LC2VFU(rix[2][-2]); - p4v = LC2VFU(rix[2][-1]); - p5v = LC2VFU(rix[2][ 0]); - p6v = LC2VFU(rix[2][ 1]); - p7v = LC2VFU(rix[2][ 2]); - p8v = LC2VFU(rix[2][ 3]); - p9v = LC2VFU(rix[2][ 4]); - muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; - vxv = epsv + SQRV(p1v - muv) + SQRV(p2v - muv) + SQRV(p3v - muv) + SQRV(p4v - muv) + SQRV(p5v - muv) + SQRV(p6v - muv) + SQRV(p7v - muv) + SQRV(p8v - muv) + SQRV(p9v - muv); - p1v -= LC2VFU(rix[0][-4]); - p2v -= LC2VFU(rix[0][-3]); - p3v -= LC2VFU(rix[0][-2]); - p4v -= LC2VFU(rix[0][-1]); - p5v -= LC2VFU(rix[0][ 0]); - p6v -= LC2VFU(rix[0][ 1]); - p7v -= LC2VFU(rix[0][ 2]); - p8v -= LC2VFU(rix[0][ 3]); - p9v -= LC2VFU(rix[0][ 4]); - vnv = epsv + SQRV(p1v) + SQRV(p2v) + SQRV(p3v) + SQRV(p4v) + SQRV(p5v) + SQRV(p6v) + SQRV(p7v) + SQRV(p8v) + SQRV(p9v); - xhv = (LC2VFU(rix[0][0]) * vxv + LC2VFU(rix[2][0]) * vnv) / (vxv + vnv); - vhv = vxv * vnv / (vxv + vnv); - - // vertical - p1v = LC2VFU(rix[3][-w4]); - p2v = LC2VFU(rix[3][-w3]); - p3v = LC2VFU(rix[3][-w2]); - p4v = LC2VFU(rix[3][-w1]); - p5v = LC2VFU(rix[3][ 0]); - p6v = LC2VFU(rix[3][ w1]); - p7v = LC2VFU(rix[3][ w2]); - p8v = LC2VFU(rix[3][ w3]); - p9v = LC2VFU(rix[3][ w4]); - muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; - vxv = epsv + SQRV(p1v - muv) + SQRV(p2v - muv) + SQRV(p3v - muv) + SQRV(p4v - muv) + SQRV(p5v - muv) + SQRV(p6v - muv) + SQRV(p7v - muv) + SQRV(p8v - muv) + SQRV(p9v - muv); - p1v -= LC2VFU(rix[1][-w4]); - p2v -= LC2VFU(rix[1][-w3]); - p3v -= LC2VFU(rix[1][-w2]); - p4v -= LC2VFU(rix[1][-w1]); - p5v -= LC2VFU(rix[1][ 0]); - p6v -= LC2VFU(rix[1][ w1]); - p7v -= LC2VFU(rix[1][ w2]); - p8v -= LC2VFU(rix[1][ w3]); - p9v -= LC2VFU(rix[1][ w4]); - vnv = epsv + SQRV(p1v) + SQRV(p2v) + SQRV(p3v) + SQRV(p4v) + SQRV(p5v) + SQRV(p6v) + SQRV(p7v) + SQRV(p8v) + SQRV(p9v); - xvv = (LC2VFU(rix[1][0]) * vxv + LC2VFU(rix[3][0]) * vnv) / (vxv + vnv); - vvv = vxv * vnv / (vxv + vnv); - // interpolated G-R(B) - muv = (xhv * vvv + xvv * vhv) / (vhv + vvv); - STC2VFU(rix[4][0], muv); - } - -#endif - - for (; cc < cc1 - 4; cc += 2) { - rix[0] = qix[0] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - rix[2] = qix[2] + rr * cc1 + cc; - rix[3] = qix[3] + rr * cc1 + cc; - rix[4] = qix[4] + rr * cc1 + cc; - // horizontal - float p1 = rix[2][-4]; - float p2 = rix[2][-3]; - float p3 = rix[2][-2]; - float p4 = rix[2][-1]; - float p5 = rix[2][ 0]; - float p6 = rix[2][ 1]; - float p7 = rix[2][ 2]; - float p8 = rix[2][ 3]; - float p9 = rix[2][ 4]; - float mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; - float vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu); - p1 -= rix[0][-4]; - p2 -= rix[0][-3]; - p3 -= rix[0][-2]; - p4 -= rix[0][-1]; - p5 -= rix[0][ 0]; - p6 -= rix[0][ 1]; - p7 -= rix[0][ 2]; - p8 -= rix[0][ 3]; - p9 -= rix[0][ 4]; - float vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9); - float xh = (rix[0][0] * vx + rix[2][0] * vn) / (vx + vn); - float vh = vx * vn / (vx + vn); - - // vertical - p1 = rix[3][-w4]; - p2 = rix[3][-w3]; - p3 = rix[3][-w2]; - p4 = rix[3][-w1]; - p5 = rix[3][ 0]; - p6 = rix[3][ w1]; - p7 = rix[3][ w2]; - p8 = rix[3][ w3]; - p9 = rix[3][ w4]; - mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; - vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu); - p1 -= rix[1][-w4]; - p2 -= rix[1][-w3]; - p3 -= rix[1][-w2]; - p4 -= rix[1][-w1]; - p5 -= rix[1][ 0]; - p6 -= rix[1][ w1]; - p7 -= rix[1][ w2]; - p8 -= rix[1][ w3]; - p9 -= rix[1][ w4]; - vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9); - float xv = (rix[1][0] * vx + rix[3][0] * vn) / (vx + vn); - float vv = vx * vn / (vx + vn); - // interpolated G-R(B) - rix[4][0] = (xh * vv + xv * vh) / (vh + vv); - } - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.4); - } - } - - // copy CFA values -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rr = 0; rr < rr1; rr++) - for (int cc = 0, row = rr - ba; cc < cc1; cc++) { - int col = cc - ba; - int c = FC(rr, cc); - rix[c] = qix[c] + rr * cc1 + cc; - - if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { - rix[c][0] = (*gamtab)[rawData[row][col]]; - } else { - rix[c][0] = 0.f; - } - - if (c != 1) { - rix[1] = qix[1] + rr * cc1 + cc; - rix[4] = qix[4] + rr * cc1 + cc; - rix[1][0] = rix[c][0] + rix[4][0]; - } - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.5); - } - } - - // bilinear interpolation for R/B - // interpolate R/B at G location -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rr = 1; rr < rr1 - 1; rr++) - for (int cc = 1 + (FC(rr, 2) & 1), c = FC(rr, cc + 1); cc < cc1 - 1; cc += 2) { - rix[c] = qix[c] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - rix[c][0] = rix[1][0] + xdiv2f(rix[c][ -1] - rix[1][ -1] + rix[c][ 1] - rix[1][ 1]); - c = 2 - c; - rix[c] = qix[c] + rr * cc1 + cc; - rix[c][0] = rix[1][0] + xdiv2f(rix[c][-w1] - rix[1][-w1] + rix[c][w1] - rix[1][w1]); - c = 2 - c; - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.6); - } - } - - // interpolate R/B at B/R location -#ifdef _OPENMP - #pragma omp for -#endif - - for (int rr = 1; rr < rr1 - 1; rr++) - for (int cc = 1 + (FC(rr, 1) & 1), c = 2 - FC(rr, cc); cc < cc1 - 1; cc += 2) { - rix[c] = qix[c] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - rix[c][0] = rix[1][0] + x0250(rix[c][-w1] - rix[1][-w1] + rix[c][ -1] - rix[1][ -1] + rix[c][ 1] - rix[1][ 1] + rix[c][ w1] - rix[1][ w1]); - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - if (plistener) { - plistener->setProgress (0.7); - } - } - - }// End of parallelization 1 - - // median filter/ - for (int pass = 0; pass < iter; pass++) { - // Apply 3x3 median filter - // Compute median(R-G) and median(B-G) - -#ifdef _OPENMP - #pragma omp parallel for private(rix) -#endif - - for (int rr = 1; rr < rr1 - 1; rr++) { - for (int c = 0; c < 3; c += 2) { - int d = c + 3 - (c == 0 ? 0 : 1); - int cc = 1; -#ifdef __SSE2__ - - for (; cc < cc1 - 4; cc += 4) { - rix[d] = qix[d] + rr * cc1 + cc; - rix[c] = qix[c] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - // Assign 3x3 differential color values - const std::array p = { - LVFU(rix[c][-w1 - 1]) - LVFU(rix[1][-w1 - 1]), - LVFU(rix[c][-w1]) - LVFU(rix[1][-w1]), - LVFU(rix[c][-w1 + 1]) - LVFU(rix[1][-w1 + 1]), - LVFU(rix[c][ -1]) - LVFU(rix[1][ -1]), - LVFU(rix[c][ 0]) - LVFU(rix[1][ 0]), - LVFU(rix[c][ 1]) - LVFU(rix[1][ 1]), - LVFU(rix[c][ w1 - 1]) - LVFU(rix[1][ w1 - 1]), - LVFU(rix[c][ w1]) - LVFU(rix[1][ w1]), - LVFU(rix[c][ w1 + 1]) - LVFU(rix[1][ w1 + 1]) - }; - _mm_storeu_ps(&rix[d][0], median(p)); - } - -#endif - - for (; cc < cc1 - 1; cc++) { - rix[d] = qix[d] + rr * cc1 + cc; - rix[c] = qix[c] + rr * cc1 + cc; - rix[1] = qix[1] + rr * cc1 + cc; - // Assign 3x3 differential color values - const std::array p = { - rix[c][-w1 - 1] - rix[1][-w1 - 1], - rix[c][-w1] - rix[1][-w1], - rix[c][-w1 + 1] - rix[1][-w1 + 1], - rix[c][ -1] - rix[1][ -1], - rix[c][ 0] - rix[1][ 0], - rix[c][ 1] - rix[1][ 1], - rix[c][ w1 - 1] - rix[1][ w1 - 1], - rix[c][ w1] - rix[1][ w1], - rix[c][ w1 + 1] - rix[1][ w1 + 1] - }; - rix[d][0] = median(p); - } - } - } - - // red/blue at GREEN pixel locations & red/blue and green at BLUE/RED pixel locations -#ifdef _OPENMP - #pragma omp parallel for private (rix) -#endif - - for (int rr = 0; rr < rr1; rr++) { - rix[0] = qix[0] + rr * cc1; - rix[1] = qix[1] + rr * cc1; - rix[2] = qix[2] + rr * cc1; - rix[3] = qix[3] + rr * cc1; - rix[4] = qix[4] + rr * cc1; - int c0 = FC(rr, 0); - int c1 = FC(rr, 1); - - if(c0 == 1) { - c1 = 2 - c1; - int d = c1 + 3 - (c1 == 0 ? 0 : 1); - int cc; - - for (cc = 0; cc < cc1 - 1; cc += 2) { - rix[0][0] = rix[1][0] + rix[3][0]; - rix[2][0] = rix[1][0] + rix[4][0]; - rix[0]++; - rix[1]++; - rix[2]++; - rix[3]++; - rix[4]++; - rix[c1][0] = rix[1][0] + rix[d][0]; - rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); - rix[0]++; - rix[1]++; - rix[2]++; - rix[3]++; - rix[4]++; - } - - if(cc < cc1) { // remaining pixel, only if width is odd - rix[0][0] = rix[1][0] + rix[3][0]; - rix[2][0] = rix[1][0] + rix[4][0]; - } - } else { - c0 = 2 - c0; - int d = c0 + 3 - (c0 == 0 ? 0 : 1); - int cc; - - for (cc = 0; cc < cc1 - 1; cc += 2) { - rix[c0][0] = rix[1][0] + rix[d][0]; - rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); - rix[0]++; - rix[1]++; - rix[2]++; - rix[3]++; - rix[4]++; - rix[0][0] = rix[1][0] + rix[3][0]; - rix[2][0] = rix[1][0] + rix[4][0]; - rix[0]++; - rix[1]++; - rix[2]++; - rix[3]++; - rix[4]++; - } - - if(cc < cc1) { // remaining pixel, only if width is odd - rix[c0][0] = rix[1][0] + rix[d][0]; - rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); - } - } - } - } - - if (plistener) { - plistener->setProgress (0.8); - } - - if(applyGamma) { - gamtab = &(Color::igammatab_24_17); - } else { - gamtab->makeIdentity(); - } - - array2D* rgb[3]; - rgb[0] = &red; - rgb[1] = &green; - rgb[2] = &blue; - - // copy result back to image matrix -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < height; row++) { - for (int col = 0, rr = row + ba; col < width; col++) { - int cc = col + ba; - int c = FC(row, col); - - for (int ii = 0; ii < 3; ii++) - if (ii != c) { - float *rix = qix[ii] + rr * cc1 + cc; - (*(rgb[ii]))[row][col] = (*gamtab)[65535.f * rix[0]]; - } else { - (*(rgb[ii]))[row][col] = CLIP(rawData[row][col]); - } - } - } - - if (plistener) { - plistener->setProgress (1.0); - } - - if(buffer) { - free(buffer); - } else - for(int i = 0; i < 5; i++) { - free(qix[i]); - } - - if(!applyGamma) { - delete gamtab; - } - - if(iterations > 4 && iterations <= 6) { - refinement(passref); - } else if(iterations > 6) { - refinement_lassus(passref); - } - -} - /*** * * Bayer CFA Demosaicing using Integrated Gaussian Vector on Color Differences @@ -1145,7 +233,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) vdif = (float (*)) calloc( width * height / 2, sizeof * vdif ); hdif = (float (*)) calloc( width * height / 2, sizeof * hdif ); - chrarray = (float (*)) calloc( width * height, sizeof( float ) ); + chrarray = (float (*)) calloc(static_cast(width) * height, sizeof( float ) ); chr[0] = chrarray; chr[1] = chrarray + (width * height) / 2; @@ -1507,7 +595,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) } } }// End of parallelization - border_interpolate2(winw, winh, 8, rawData, red, green, blue); + border_interpolate(winw, winh, 8, rawData, red, green, blue); if (plistener) { plistener->setProgress (1.0); @@ -1564,8 +652,6 @@ void RawImageSource::igv_interpolate(int winw, int winh) rgb[c][indx] = CLIP(rawData[row][col]); //rawData = RT data } -// border_interpolate2(7, rgb); - #ifdef _OPENMP #pragma omp single #endif @@ -1740,9 +826,6 @@ void RawImageSource::igv_interpolate(int winw, int winh) if (plistener) { plistener->setProgress (0.91); } - - //Interpolate borders -// border_interpolate2(7, rgb); } /* #ifdef _OPENMP @@ -1770,7 +853,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) blue [row][col] = CLIP(rgb[1][indx] - 65535.f * chr[1][indx]); } }// End of parallelization - border_interpolate2(winw, winh, 8, rawData, red, green, blue); + border_interpolate(winw, winh, 8, rawData, red, green, blue); if (plistener) { @@ -1836,357 +919,6 @@ void RawImageSource::nodemosaic(bool bw) } } -/* - Refinement based on EECI demosaicing algorithm by L. Chang and Y.P. Tan - Paul Lee - Adapted for RawTherapee - Jacques Desmis 04/2013 -*/ - -#ifdef __SSE2__ -#define CLIPV(a) vclampf(a,ZEROV,c65535v) -#endif -void RawImageSource::refinement(int PassCount) -{ - MyTime t1e, t2e; - t1e.set(); - - int width = W; - int height = H; - int w1 = width; - int w2 = 2 * w1; - - if (plistener) { - plistener->setProgressStr (M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); - } - - array2D *rgb[3]; - rgb[0] = &red; - rgb[1] = &green; - rgb[2] = &blue; - - for (int b = 0; b < PassCount; b++) { - if (plistener) { - plistener->setProgress ((float)b / PassCount); - } - - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - float *pix[3]; - - /* Reinforce interpolated green pixels on RED/BLUE pixel locations */ -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 2; row < height - 2; row++) { - int col = 2 + (FC(row, 2) & 1); - int c = FC(row, col); -#ifdef __SSE2__ - __m128 dLv, dRv, dUv, dDv, v0v; - __m128 onev = _mm_set1_ps(1.f); - __m128 zd5v = _mm_set1_ps(0.5f); - __m128 c65535v = _mm_set1_ps(65535.f); - - for (; col < width - 8; col += 8) { - int indx = row * width + col; - pix[c] = (float*)(*rgb[c]) + indx; - pix[1] = (float*)(*rgb[1]) + indx; - dLv = onev / (onev + vabsf(LC2VFU(pix[c][ -2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); - dRv = onev / (onev + vabsf(LC2VFU(pix[c][ 2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); - dUv = onev / (onev + vabsf(LC2VFU(pix[c][-w2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); - dDv = onev / (onev + vabsf(LC2VFU(pix[c][ w2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); - v0v = CLIPV(LC2VFU(pix[c][0]) + zd5v + ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); - STC2VFU(pix[1][0], v0v); - } - -#endif - - for (; col < width - 2; col += 2) { - int indx = row * width + col; - pix[c] = (float*)(*rgb[c]) + indx; - pix[1] = (float*)(*rgb[1]) + indx; - float dL = 1.f / (1.f + fabsf(pix[c][ -2] - pix[c][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); - float dR = 1.f / (1.f + fabsf(pix[c][ 2] - pix[c][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); - float dU = 1.f / (1.f + fabsf(pix[c][-w2] - pix[c][0]) + fabsf(pix[1][w1] - pix[1][-w1])); - float dD = 1.f / (1.f + fabsf(pix[c][ w2] - pix[c][0]) + fabsf(pix[1][w1] - pix[1][-w1])); - float v0 = (pix[c][0] + 0.5f + ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); - pix[1][0] = CLIP(v0); - } - } - - /* Reinforce interpolated red/blue pixels on GREEN pixel locations */ -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 2; row < height - 2; row++) { - int col = 2 + (FC(row, 3) & 1); - int c = FC(row, col + 1); -#ifdef __SSE2__ - __m128 dLv, dRv, dUv, dDv, v0v; - __m128 onev = _mm_set1_ps(1.f); - __m128 zd5v = _mm_set1_ps(0.5f); - __m128 c65535v = _mm_set1_ps(65535.f); - - for (; col < width - 8; col += 8) { - int indx = row * width + col; - pix[1] = (float*)(*rgb[1]) + indx; - - for (int i = 0; i < 2; c = 2 - c, i++) { - pix[c] = (float*)(*rgb[c]) + indx; - dLv = onev / (onev + vabsf(LC2VFU(pix[1][ -2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][ 1]) - LC2VFU(pix[c][ -1]))); - dRv = onev / (onev + vabsf(LC2VFU(pix[1][ 2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][ 1]) - LC2VFU(pix[c][ -1]))); - dUv = onev / (onev + vabsf(LC2VFU(pix[1][-w2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][w1]) - LC2VFU(pix[c][-w1]))); - dDv = onev / (onev + vabsf(LC2VFU(pix[1][ w2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][w1]) - LC2VFU(pix[c][-w1]))); - v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v - ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); - STC2VFU(pix[c][0], v0v); - } - } - -#endif - - for (; col < width - 2; col += 2) { - int indx = row * width + col; - pix[1] = (float*)(*rgb[1]) + indx; - - for (int i = 0; i < 2; c = 2 - c, i++) { - pix[c] = (float*)(*rgb[c]) + indx; - float dL = 1.f / (1.f + fabsf(pix[1][ -2] - pix[1][0]) + fabsf(pix[c][ 1] - pix[c][ -1])); - float dR = 1.f / (1.f + fabsf(pix[1][ 2] - pix[1][0]) + fabsf(pix[c][ 1] - pix[c][ -1])); - float dU = 1.f / (1.f + fabsf(pix[1][-w2] - pix[1][0]) + fabsf(pix[c][w1] - pix[c][-w1])); - float dD = 1.f / (1.f + fabsf(pix[1][ w2] - pix[1][0]) + fabsf(pix[c][w1] - pix[c][-w1])); - float v0 = (pix[1][0] + 0.5f - ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); - pix[c][0] = CLIP(v0); - } - } - } - - /* Reinforce integrated red/blue pixels on BLUE/RED pixel locations */ -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 2; row < height - 2; row++) { - int col = 2 + (FC(row, 2) & 1); - int c = 2 - FC(row, col); -#ifdef __SSE2__ - __m128 dLv, dRv, dUv, dDv, v0v; - __m128 onev = _mm_set1_ps(1.f); - __m128 zd5v = _mm_set1_ps(0.5f); - __m128 c65535v = _mm_set1_ps(65535.f); - - for (; col < width - 8; col += 8) { - int indx = row * width + col; - pix[0] = (float*)(*rgb[0]) + indx; - pix[1] = (float*)(*rgb[1]) + indx; - pix[2] = (float*)(*rgb[2]) + indx; - int d = 2 - c; - dLv = onev / (onev + vabsf(LC2VFU(pix[d][ -2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); - dRv = onev / (onev + vabsf(LC2VFU(pix[d][ 2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); - dUv = onev / (onev + vabsf(LC2VFU(pix[d][-w2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); - dDv = onev / (onev + vabsf(LC2VFU(pix[d][ w2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); - v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v - ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); - STC2VFU(pix[c][0], v0v); - } - -#endif - - for (; col < width - 2; col += 2) { - int indx = row * width + col; - pix[0] = (float*)(*rgb[0]) + indx; - pix[1] = (float*)(*rgb[1]) + indx; - pix[2] = (float*)(*rgb[2]) + indx; - int d = 2 - c; - float dL = 1.f / (1.f + fabsf(pix[d][ -2] - pix[d][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); - float dR = 1.f / (1.f + fabsf(pix[d][ 2] - pix[d][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); - float dU = 1.f / (1.f + fabsf(pix[d][-w2] - pix[d][0]) + fabsf(pix[1][w1] - pix[1][-w1])); - float dD = 1.f / (1.f + fabsf(pix[d][ w2] - pix[d][0]) + fabsf(pix[1][w1] - pix[1][-w1])); - float v0 = (pix[1][0] + 0.5f - ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); - pix[c][0] = CLIP(v0); - } - } - } // end parallel - } - - t2e.set(); - - if (settings->verbose) { - printf("Refinement Lee %d usec\n", t2e.etime(t1e)); - } -} -#ifdef __SSE2__ -#undef CLIPV -#endif - - -// Refinement based on EECI demozaicing algorithm by L. Chang and Y.P. Tan -// from "Lassus" : Luis Sanz Rodriguez, adapted by Jacques Desmis - JDC - and Oliver Duis for RawTherapee -// increases the signal to noise ratio (PSNR) # +1 to +2 dB : tested with Dcraw : -// eg: Lighthouse + AMaZE : without refinement:39.96 dB, with refinement:41.86 dB -// reduce color artifacts, improves the interpolation -// but it's relatively slow -// -// Should be DISABLED if it decreases image quality by increases some image noise and generates blocky edges -void RawImageSource::refinement_lassus(int PassCount) -{ - // const int PassCount=1; - - // if (settings->verbose) printf("Refinement\n"); - - MyTime t1e, t2e; - t1e.set(); - int u = W, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u; - float (*image)[3]; - image = (float(*)[3]) calloc(W * H, sizeof * image); -#ifdef _OPENMP - #pragma omp parallel shared(image) -#endif - { - // convert red, blue, green to image -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H; i++) { - for (int j = 0; j < W; j++) { - image[i * W + j][0] = red [i][j]; - image[i * W + j][1] = green[i][j]; - image[i * W + j][2] = blue [i][j]; - } - } - - for (int b = 0; b < PassCount; b++) { - if (plistener) { - plistener->setProgressStr (M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); - plistener->setProgress ((float)b / PassCount); - } - - // Reinforce interpolated green pixels on RED/BLUE pixel locations -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 6; row < H - 6; row++) { - for (int col = 6 + (FC(row, 2) & 1), c = FC(row, col); col < W - 6; col += 2) { - float (*pix)[3] = image + row * W + col; - - // Cubic Spline Interpolation by Li and Randhawa, modified by Luis Sanz Rodriguez - - float f[4]; - f[0] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[-v][c]) - x0875(pix[0][c]) - x0250(pix[-x][c]))) + fabs(x0875(pix[u][1]) - x1125(pix[-u][1]) + x0250(pix[-w][1])) + fabs(x0875(pix[-w][1]) - x1125(pix[-u][1]) + x0250(pix[-y][1]))); - f[1] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[+2][c]) - x0875(pix[0][c]) - x0250(pix[+4][c]))) + fabs(x0875(pix[1][1]) - x1125(pix[-1][1]) + x0250(pix[+3][1])) + fabs(x0875(pix[+3][1]) - x1125(pix[+1][1]) + x0250(pix[+5][1]))); - f[2] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[-2][c]) - x0875(pix[0][c]) - x0250(pix[-4][c]))) + fabs(x0875(pix[1][1]) - x1125(pix[-1][1]) + x0250(pix[-3][1])) + fabs(x0875(pix[-3][1]) - x1125(pix[-1][1]) + x0250(pix[-5][1]))); - f[3] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[+v][c]) - x0875(pix[0][c]) - x0250(pix[+x][c]))) + fabs(x0875(pix[u][1]) - x1125(pix[-u][1]) + x0250(pix[+w][1])) + fabs(x0875(pix[+w][1]) - x1125(pix[+u][1]) + x0250(pix[+y][1]))); - - float g[4];//CLIREF avoid overflow - g[0] = pix[0][c] + (x0875(CLIREF(pix[-u][1] - pix[-u][c])) + x0125(CLIREF(pix[+u][1] - pix[+u][c]))); - g[1] = pix[0][c] + (x0875(CLIREF(pix[+1][1] - pix[+1][c])) + x0125(CLIREF(pix[-1][1] - pix[-1][c]))); - g[2] = pix[0][c] + (x0875(CLIREF(pix[-1][1] - pix[-1][c])) + x0125(CLIREF(pix[+1][1] - pix[+1][c]))); - g[3] = pix[0][c] + (x0875(CLIREF(pix[+u][1] - pix[+u][c])) + x0125(CLIREF(pix[-u][1] - pix[-u][c]))); - - pix[0][1] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); - - } - } - - // Reinforce interpolated red/blue pixels on GREEN pixel locations -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 6; row < H - 6; row++) { - for (int col = 6 + (FC(row, 3) & 1), c = FC(row, col + 1); col < W - 6; col += 2) { - float (*pix)[3] = image + row * W + col; - - for (int i = 0; i < 2; c = 2 - c, i++) { - float f[4]; - f[0] = 1.0f / (1.0f + xmul2f(fabs(x0875(pix[-v][1]) - x1125(pix[0][1]) + x0250(pix[-x][1]))) + fabs(pix[u] [c] - pix[-u][c]) + fabs(pix[-w][c] - pix[-u][c])); - f[1] = 1.0f / (1.0f + xmul2f(fabs(x0875(pix[+2][1]) - x1125(pix[0][1]) + x0250(pix[+4][1]))) + fabs(pix[+1][c] - pix[-1][c]) + fabs(pix[+3][c] - pix[+1][c])); - f[2] = 1.0f / (1.0f + xmul2f(fabs(x0875(pix[-2][1]) - x1125(pix[0][1]) + x0250(pix[-4][1]))) + fabs(pix[+1][c] - pix[-1][c]) + fabs(pix[-3][c] - pix[-1][c])); - f[3] = 1.0f / (1.0f + xmul2f(fabs(x0875(pix[+v][1]) - x1125(pix[0][1]) + x0250(pix[+x][1]))) + fabs(pix[u] [c] - pix[-u][c]) + fabs(pix[+w][c] - pix[+u][c])); - - float g[5];//CLIREF avoid overflow - g[0] = CLIREF(pix[-u][1] - pix[-u][c]); - g[1] = CLIREF(pix[+1][1] - pix[+1][c]); - g[2] = CLIREF(pix[-1][1] - pix[-1][c]); - g[3] = CLIREF(pix[+u][1] - pix[+u][c]); - g[4] = ((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3])); - pix[0][c] = pix[0][1] - (0.65f * g[4] + 0.35f * CLIREF(pix[0][1] - pix[0][c])); - } - } - } - - // Reinforce integrated red/blue pixels on BLUE/RED pixel locations -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 6; row < H - 6; row++) { - for (int col = 6 + (FC(row, 2) & 1), c = 2 - FC(row, col), d = 2 - c; col < W - 6; col += 2) { - float (*pix)[3] = image + row * W + col; - - float f[4]; - f[0] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[-v][d]) - x0875(pix[0][d]) - x0250(pix[-x][d]))) + fabs(x0875(pix[u][1]) - x1125(pix[-u][1]) + x0250(pix[-w][1])) + fabs(x0875(pix[-w][1]) - x1125(pix[-u][1]) + x0250(pix[-y][1]))); - f[1] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[+2][d]) - x0875(pix[0][d]) - x0250(pix[+4][d]))) + fabs(x0875(pix[1][1]) - x1125(pix[-1][1]) + x0250(pix[+3][1])) + fabs(x0875(pix[+3][1]) - x1125(pix[+1][1]) + x0250(pix[+5][1]))); - f[2] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[-2][d]) - x0875(pix[0][d]) - x0250(pix[-4][d]))) + fabs(x0875(pix[1][1]) - x1125(pix[-1][1]) + x0250(pix[-3][1])) + fabs(x0875(pix[-3][1]) - x1125(pix[-1][1]) + x0250(pix[-5][1]))); - f[3] = 1.0f / (1.0f + xmul2f(fabs(x1125(pix[+v][d]) - x0875(pix[0][d]) - x0250(pix[+x][d]))) + fabs(x0875(pix[u][1]) - x1125(pix[-u][1]) + x0250(pix[+w][1])) + fabs(x0875(pix[+w][1]) - x1125(pix[+u][1]) + x0250(pix[+y][1]))); - - float g[5]; - g[0] = (x0875((pix[-u][1] - pix[-u][c])) + x0125((pix[-v][1] - pix[-v][c]))); - g[1] = (x0875((pix[+1][1] - pix[+1][c])) + x0125((pix[+2][1] - pix[+2][c]))); - g[2] = (x0875((pix[-1][1] - pix[-1][c])) + x0125((pix[-2][1] - pix[-2][c]))); - g[3] = (x0875((pix[+u][1] - pix[+u][c])) + x0125((pix[+v][1] - pix[+v][c]))); - - g[4] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); - - const std::array p = { - pix[-u - 1][1] - pix[-u - 1][c], - pix[-u + 0][1] - pix[-u + 0][c], - pix[-u + 1][1] - pix[-u + 1][c], - pix[+0 - 1][1] - pix[+0 - 1][c], - pix[+0 + 0][1] - pix[+0 + 0][c], - pix[+0 + 1][1] - pix[+0 + 1][c], - pix[+u - 1][1] - pix[+u - 1][c], - pix[+u + 0][1] - pix[+u + 0][c], - pix[+u + 1][1] - pix[+u + 1][c] - }; - - const float med = median(p); - - pix[0][c] = LIM(pix[0][1] - (1.30f * g[4] - 0.30f * (pix[0][1] - pix[0][c])), 0.99f * (pix[0][1] - med), 1.01f * (pix[0][1] - med)); - - } - } - - } - - // put modified values to red, green, blue -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H; i++) { - for (int j = 0; j < W; j++) { - red [i][j] = image[i * W + j][0]; - green[i][j] = image[i * W + j][1]; - blue [i][j] = image[i * W + j][2]; - } - } - } - - free(image); - - t2e.set(); - - if (settings->verbose) { - printf("Refinement Lassus %d usec\n", t2e.etime(t1e)); - } -} - - /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -2813,7 +1545,7 @@ BENCHFUN free(buffer0); } - border_interpolate2(W, H, 1, rawData, red, green, blue); + border_interpolate(W, H, 1, rawData, red, green, blue); if(plistener) { plistener->setProgress (1.0); } diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 4877aacd8..1fb1d2e1b 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -16,23 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "dfmanager.h" -#include "../rtgui/options.h" -#include -#include "../rtgui/guiutils.h" -#include "rawimage.h" + #include #include #include -#include "imagedata.h" +#include #include +#include "dfmanager.h" +#include "../rtgui/options.h" +#include "rawimage.h" +#include "imagedata.h" +#include "utils.h" + namespace rtengine { -extern const Settings* settings; - // *********************** class dfInfo ************************************** +dfInfo::~dfInfo() +{ + delete ri; +} inline dfInfo& dfInfo::operator =(const dfInfo &o) { diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h index 23ca97d14..216dcfc53 100644 --- a/rtengine/dfmanager.h +++ b/rtengine/dfmanager.h @@ -19,17 +19,18 @@ #pragma once #include +#include #include #include #include #include "pixelsmap.h" -#include "rawimage.h" namespace rtengine { +class RawImage; class dfInfo { public: @@ -48,13 +49,7 @@ public: dfInfo( const dfInfo &o) : pathname(o.pathname), maker(o.maker), model(o.model), iso(o.iso), shutter(o.shutter), timestamp(o.timestamp), ri(nullptr) {} - ~dfInfo() - { - if( ri ) { - delete ri; - } - } - + ~dfInfo(); dfInfo &operator =(const dfInfo &o); bool operator <(const dfInfo &e2) const; diff --git a/rtengine/diagonalcurvetypes.h b/rtengine/diagonalcurvetypes.h new file mode 100644 index 000000000..0d304957a --- /dev/null +++ b/rtengine/diagonalcurvetypes.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2019 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ +#pragma once + +// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget +enum DiagonalCurveType { + DCT_Empty = -1, // Also used for identity curves + DCT_Linear, // 0 + DCT_Spline, // 1 + DCT_Parametric, // 2 + DCT_NURBS, // 3 + DCT_CatumullRom, // 4 + // Insert new curve type above this line + DCT_Unchanged // Must remain the last of the enum +}; diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index e822d8492..1f62badcb 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -18,12 +18,18 @@ * */ -#include +#include #include -#include "improcfun.h" +#include + #include "array2D.h" -#include "rt_math.h" +#include "cieimage.h" +#include "color.h" +#include "improcfun.h" +#include "LUT.h" #include "opthelper.h" +#include "rt_math.h" +#include "settings.h" namespace { @@ -71,8 +77,8 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = max(0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) { + for (int inbr = std::max(0, i - scalewin); inbr <= std::min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = std::max(0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) { const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; @@ -105,7 +111,7 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int inbr = std::max(0, i - scalewin); inbr <= std::min(height - 1, i + scalewin); inbr += scale) { for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; @@ -119,8 +125,8 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) { + for (int inbr = std::max(0, i - scalewin); inbr <= std::min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = j - scalewin; jnbr <= std::min(width - 1, j + scalewin); jnbr += scale) { const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; @@ -149,8 +155,8 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = max(0, j - scale); jnbr <= j + scale; jnbr += scale) { + for (int inbr = std::max(0, i - scale); inbr <= std::min(height - 1, i + scale); inbr += scale) { + for (int jnbr = std::max(0, j - scale); jnbr <= j + scale; jnbr += scale) { const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; @@ -182,7 +188,7 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int inbr = std::max(0, i - scale); inbr <= std::min(height - 1, i + scale); inbr += scale) { for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; @@ -196,8 +202,8 @@ void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int w float val = 0.f; float norm = 0.f; - for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) { + for (int inbr = std::max(0, i - scale); inbr <= std::min(height - 1, i + scale); inbr += scale) { + for (int jnbr = j - scale; jnbr <= std::min(width - 1, j + scale); jnbr += scale) { const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; @@ -346,8 +352,6 @@ void idirpyr_eq_channelcam(const float * const * data_coarse, const float * cons namespace rtengine { -extern const Settings* settings; - void ImProcFunctions::dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) { //sequence of scales diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index 60cce506b..69d1a189a 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -23,36 +23,40 @@ // //////////////////////////////////////////////////////////////// +#include "color.h" #include "jaggedarray.h" -#include "rtengine.h" -#include "rawimagesource.h" -#include "rt_math.h" #include "procparams.h" +#include "rawimagesource.h" +#include "rt_algo.h" +#include "rt_math.h" +#include "rtengine.h" + +#include "../rtgui/options.h" + //#define BENCHMARK #include "StopWatch.h" -#include "rt_algo.h" using namespace std; namespace rtengine { -void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, double &contrast, bool autoContrast) +void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams &raw, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, double &contrast, bool autoContrast) { BENCHFUN if (contrast == 0.f && !autoContrast) { // contrast == 0.0 means only first demosaicer will be used if(isBayer) { - if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) { + if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) ) { amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); - } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) { + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); - } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) { + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) { rcd_demosaic(options.chunkSizeRCD, options.measure); } } else { - if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) { + if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) ) { xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); } else { xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); @@ -62,28 +66,22 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi return; } - array2D redTmp(winw, winh); - array2D greenTmp(winw, winh); - array2D blueTmp(winw, winh); array2D L(winw, winh); if (isBayer) { - vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); - - if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { + if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT)) { amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); - } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) { + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); - } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) { + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) { rcd_demosaic(options.chunkSizeRCD, options.measure); } } else { - if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) { + if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) ) { xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); } else { xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); } - fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); } const float xyz_rgb[3][3] = { // XYZ from RGB @@ -110,6 +108,17 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi buildBlendMask(L, blend, winw, winh, contrastf, 1.f, autoContrast); contrast = contrastf * 100.f; + array2D& redTmp = L; // L is not needed anymore => reuse it + array2D greenTmp(winw, winh); + array2D blueTmp(winw, winh); + + if (isBayer) { + vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); + } else { + fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); + } + + // the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache #ifdef _OPENMP #pragma omp parallel for diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index af6ecd2ff..617ec2747 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -17,10 +17,15 @@ * along with RawTherapee. If not, see . */ -#include "../rtengine/dynamicprofile.h" +#include "dynamicprofile.h" #include #include +#include +#include + +#include "rtengine.h" +#include "../rtgui/options.h" using namespace rtengine; using namespace rtengine::procparams; @@ -176,7 +181,7 @@ bool DynamicProfileRules::loadRules() return false; } - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("loading dynamic profiles...\n"); } @@ -195,7 +200,7 @@ bool DynamicProfileRules::loadRules() return false; } - if (options.rtSettings.verbose) { + if (settings->verbose) { printf (" loading rule %d\n", serial); } @@ -225,7 +230,7 @@ bool DynamicProfileRules::loadRules() bool DynamicProfileRules::storeRules() { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("saving dynamic profiles...\n"); } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index aaffc5c4f..d91b91aee 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -16,12 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DYNAMICPROFILE_H_ -#define _DYNAMICPROFILE_H_ +#pragma once -#include +#include #include -#include "../rtgui/options.h" + +namespace rtengine +{ + class FramesMetaData; +} class DynamicProfileRule { @@ -76,5 +79,3 @@ public: const std::vector &getRules(); void setRules (const std::vector &r); }; - -#endif // _DYNAMICPROFILE_H_ diff --git a/rtengine/eahd_demosaic.cc b/rtengine/eahd_demosaic.cc index aa8fdf485..c470eb297 100644 --- a/rtengine/eahd_demosaic.cc +++ b/rtengine/eahd_demosaic.cc @@ -20,14 +20,13 @@ #include #include "color.h" +#include "rawimage.h" #include "rawimagesource.h" #include "rawimagesource_i.h" #include "jaggedarray.h" -#include "rawimage.h" #include "iccmatrices.h" #include "rt_math.h" #include "../rtgui/multilangmgr.h" -#include "procparams.h" //#define BENCHMARK #include "StopWatch.h" diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc index a40f107af..aaa5ceb02 100644 --- a/rtengine/fast_demo.cc +++ b/rtengine/fast_demo.cc @@ -25,12 +25,18 @@ #include #include "rawimagesource.h" #include "../rtgui/multilangmgr.h" -#include "procparams.h" #include "opthelper.h" using namespace std; using namespace rtengine; +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} +} + #define TS 224 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -67,6 +73,7 @@ void RawImageSource::fast_demosaic() } + const unsigned int cfarray[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; const int bord = 5; float clip_pt = 4 * 65535 * initialGain; @@ -117,12 +124,12 @@ void RawImageSource::fast_demosaic() for (int i1 = imin; i1 < imax; i1++) for (int j1 = jmin; j1 < j + 2; j1++) { - int c = FC(i1, j1); + int c = fc(cfarray, i1, j1); sum[c] += rawData[i1][j1]; sum[c + 3]++; } - int c = FC(i, j); + int c = fc(cfarray, i, j); if (c == 1) { red[i][j] = sum[0] / sum[3]; @@ -150,12 +157,12 @@ void RawImageSource::fast_demosaic() for (int i1 = imin; i1 < imax; i1++) for (int j1 = j - 1; j1 < jmax; j1++) { - int c = FC(i1, j1); + int c = fc(cfarray, i1, j1); sum[c] += rawData[i1][j1]; sum[c + 3]++; } - int c = FC(i, j); + int c = fc(cfarray, i, j); if (c == 1) { red[i][j] = sum[0] / sum[3]; @@ -193,12 +200,12 @@ void RawImageSource::fast_demosaic() for (int i1 = max(0, i - 1); i1 < i + 2; i1++) for (int j1 = j - 1; j1 < j + 2; j1++) { - int c = FC(i1, j1); + int c = fc(cfarray, i1, j1); sum[c] += rawData[i1][j1]; sum[c + 3]++; } - int c = FC(i, j); + int c = fc(cfarray, i, j); if (c == 1) { red[i][j] = sum[0] / sum[3]; @@ -224,12 +231,12 @@ void RawImageSource::fast_demosaic() for (int i1 = i - 1; i1 < min(i + 2, H); i1++) for (int j1 = j - 1; j1 < j + 2; j1++) { - int c = FC(i1, j1); + int c = fc(cfarray, i1, j1); sum[c] += rawData[i1][j1]; sum[c + 3]++; } - int c = FC(i, j); + int c = fc(cfarray, i, j); if (c == 1) { red[i][j] = sum[0] / sum[3]; @@ -282,7 +289,7 @@ void RawImageSource::fast_demosaic() vmask selmask; vmask andmask = _mm_set_epi32( 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ); - if(FC(top, left) == 1) { + if(fc(cfarray, top, left) == 1) { selmask = _mm_set_epi32( 0, 0xffffffff, 0, 0xffffffff ); } else { selmask = _mm_set_epi32( 0xffffffff, 0, 0xffffffff, 0 ); @@ -312,7 +319,7 @@ void RawImageSource::fast_demosaic() for (; j < right; j++, cc++) { - if (FC(i, j) == 1) { + if (fc(cfarray, i, j) == 1) { greentile[rr * TS + cc] = rawData[i][j]; } else { @@ -333,7 +340,7 @@ void RawImageSource::fast_demosaic() #else for (int j = left, cc = 0; j < right; j++, cc++) { - if (FC(i, j) == 1) { + if (fc(cfarray, i, j) == 1) { greentile[rr * TS + cc] = rawData[i][j]; } else { //compute directional weights using image gradients @@ -359,7 +366,7 @@ void RawImageSource::fast_demosaic() #endif for (int i = top + 1, rr = 1; i < bottom - 1; i++, rr++) { - if (FC(i, left + (FC(i, 2) & 1) + 1) == 0) + if (fc(cfarray, i, left + (fc(cfarray, i, 2) & 1) + 1) == 0) #ifdef __SSE2__ for (int j = left + 1, cc = 1; j < right - 1; j += 4, cc += 4) { //interpolate B/R colors at R/B sites @@ -369,7 +376,7 @@ void RawImageSource::fast_demosaic() #else - for (int cc = (FC(i, 2) & 1) + 1, j = left + cc; j < right - 1; j += 2, cc += 2) { + for (int cc = (fc(cfarray, i, 2) & 1) + 1, j = left + cc; j < right - 1; j += 2, cc += 2) { //interpolate B/R colors at R/B sites bluetile[rr * TS + cc] = greentile[rr * TS + cc] - 0.25f * ((greentile[(rr - 1) * TS + (cc - 1)] + greentile[(rr - 1) * TS + (cc + 1)] + greentile[(rr + 1) * TS + cc + 1] + greentile[(rr + 1) * TS + cc - 1]) - min(clip_pt, rawData[i - 1][j - 1] + rawData[i - 1][j + 1] + rawData[i + 1][j + 1] + rawData[i + 1][j - 1])); @@ -386,7 +393,7 @@ void RawImageSource::fast_demosaic() #else - for (int cc = (FC(i, 2) & 1) + 1, j = left + cc; j < right - 1; j += 2, cc += 2) { + for (int cc = (fc(cfarray, i, 2) & 1) + 1, j = left + cc; j < right - 1; j += 2, cc += 2) { //interpolate B/R colors at R/B sites redtile[rr * TS + cc] = greentile[rr * TS + cc] - 0.25f * ((greentile[(rr - 1) * TS + cc - 1] + greentile[(rr - 1) * TS + cc + 1] + greentile[(rr + 1) * TS + cc + 1] + greentile[(rr + 1) * TS + cc - 1]) - min(clip_pt, rawData[i - 1][j - 1] + rawData[i - 1][j + 1] + rawData[i + 1][j + 1] + rawData[i + 1][j - 1])); @@ -405,7 +412,7 @@ void RawImageSource::fast_demosaic() for (int i = top + 2, rr = 2; i < bottom - 2; i++, rr++) { #ifdef __SSE2__ - for (int cc = 2 + (FC(i, 2) & 1), j = left + cc; j < right - 2; j += 4, cc += 4) { + for (int cc = 2 + (fc(cfarray, i, 2) & 1), j = left + cc; j < right - 2; j += 4, cc += 4) { // no need to take care about the borders of the tile. There's enough free space. //interpolate R and B colors at G sites greenv = LVFU(greentile[rr * TS + cc]); @@ -429,7 +436,7 @@ void RawImageSource::fast_demosaic() #else - for (int cc = 2 + (FC(i, 2) & 1), j = left + cc; j < right - 2; j += 2, cc += 2) { + for (int cc = 2 + (fc(cfarray, i, 2) & 1), j = left + cc; j < right - 2; j += 2, cc += 2) { //interpolate R and B colors at G sites redtile[rr * TS + cc] = greentile[rr * TS + cc] - 0.25f * ((greentile[(rr - 1) * TS + cc] - redtile[(rr - 1) * TS + cc]) + (greentile[(rr + 1) * TS + cc] - redtile[(rr + 1) * TS + cc]) + (greentile[rr * TS + cc - 1] - redtile[rr * TS + cc - 1]) + (greentile[rr * TS + cc + 1] - redtile[rr * TS + cc + 1])); diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index e1a9134a8..ce60277e1 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -16,6 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include +#include + #include "ffmanager.h" #include "../rtgui/options.h" #include "rawimage.h" @@ -26,8 +30,6 @@ namespace rtengine { -extern const Settings* settings; - // *********************** class ffInfo ************************************** inline ffInfo& ffInfo::operator =(const ffInfo &o) @@ -50,6 +52,11 @@ inline ffInfo& ffInfo::operator =(const ffInfo &o) return *this; } +ffInfo::~ffInfo() +{ + delete ri; +} + bool ffInfo::operator <(const ffInfo &e2) const { if( this->maker.compare( e2.maker) >= 0 ) { diff --git a/rtengine/ffmanager.h b/rtengine/ffmanager.h index 537f8ee46..80ef5fa1c 100644 --- a/rtengine/ffmanager.h +++ b/rtengine/ffmanager.h @@ -19,16 +19,16 @@ #pragma once #include +#include #include #include #include -#include "rawimage.h" - namespace rtengine { +class RawImage; class ffInfo { public: @@ -48,13 +48,8 @@ public: ffInfo( const ffInfo &o) : pathname(o.pathname), maker(o.maker), model(o.model), lens(o.lens), aperture(o.aperture), focallength(o.focallength), timestamp(o.timestamp), ri(nullptr) {} - ~ffInfo() - { - if( ri ) { - delete ri; - } - } + ~ffInfo(); ffInfo &operator =(const ffInfo &o); bool operator <(const ffInfo &e2) const; diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 1a7270b82..1f27983ed 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -19,28 +19,20 @@ #include #include -#ifdef _OPENMP -#include -#endif - +#include "rawimage.h" #include "rawimagesource.h" +#include "coord.h" #include "mytime.h" #include "opthelper.h" +#include "pixelsmap.h" #include "procparams.h" #include "rt_algo.h" #include "rtengine.h" - +#include "sleef.h" //#define BENCHMARK #include "StopWatch.h" -namespace rtengine -{ - -extern const Settings* settings; - -} - namespace { @@ -77,8 +69,8 @@ bool channelsAvg( } std::array pxCount = {}; // Per-channel sample counts - for (int c = spotPos.x - spotSize; c < spotPos.x + spotSize; ++c) { - for (int r = spotPos.y - spotSize; r < spotPos.y + spotSize; ++r) { + for (int c = x1; c < x2; ++c) { + for (int r = y1; r < y2; ++r) { const int ch = ri->getSensorType() == rtengine::ST_BAYER ? ri->FC(r,c) : ri->XTRANSFC(r,c); ++pxCount[ch]; @@ -98,7 +90,7 @@ bool channelsAvg( } -bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) +bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams ¤tParams, std::array& newExps) { newExps = { static_cast(currentParams.redRatio * currentParams.greenExp), diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc index 6a4da31b0..b31432a55 100644 --- a/rtengine/filmnegativethumb.cc +++ b/rtengine/filmnegativethumb.cc @@ -18,23 +18,17 @@ */ #include +#include "LUT.h" #include "rtengine.h" #include "rtthumbnail.h" #include "opthelper.h" +#include "sleef.h" #include "rt_algo.h" -#include "rtengine.h" #include "settings.h" #include "procparams.h" #define BENCHMARK #include "StopWatch.h" -namespace rtengine -{ - -extern const Settings* settings; - -} - void rtengine::Thumbnail::processFilmNegative( const procparams::ProcParams ¶ms, const Imagefloat* baseImg, diff --git a/rtgui/ilabel.h b/rtengine/flatcurvetypes.h similarity index 59% rename from rtgui/ilabel.h rename to rtengine/flatcurvetypes.h index 06da470b1..9efe0d259 100644 --- a/rtgui/ilabel.h +++ b/rtengine/flatcurvetypes.h @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2004-2019 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,23 +15,15 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ -#ifndef _ILABEL_ -#define _ILABEL_ +*/ +#pragma once -#include - -class ILabel : public Gtk::DrawingArea -{ - - Glib::ustring label; - -public: - explicit ILabel (const Glib::ustring &lab); - bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; - void on_realize() override; - void on_style_updated () override; +// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget +enum FlatCurveType { + FCT_Empty = -1, // Also used for identity curves + FCT_Linear, // 0 + FCT_MinMaxCPoints, // 1 + //FCT_Parametric, // 2 + // Insert new curve type above this line + FCT_Unchanged // Must remain the last of the enum }; - -#endif - diff --git a/rtengine/gamutwarning.cc b/rtengine/gamutwarning.cc index 3fc20d43a..569ea3066 100644 --- a/rtengine/gamutwarning.cc +++ b/rtengine/gamutwarning.cc @@ -23,10 +23,14 @@ * also distributed under the GPL V3+ */ -#include "gamutwarning.h" #include -namespace rtengine { +#include "gamutwarning.h" +#include "iccstore.h" +#include "image8.h" + +namespace rtengine +{ GamutWarning::GamutWarning(cmsHPROFILE iprof, cmsHPROFILE gamutprof, RenderingIntent intent, bool gamutbpc): lab2ref(nullptr), @@ -126,5 +130,4 @@ inline void GamutWarning::mark(Image8 *image, int y, int x) image->b(y, x) = 255; } - } // namespace rtengine diff --git a/rtengine/gamutwarning.h b/rtengine/gamutwarning.h index e0aaa98d9..b940b911f 100644 --- a/rtengine/gamutwarning.h +++ b/rtengine/gamutwarning.h @@ -25,11 +25,14 @@ #pragma once -#include "iccstore.h" -#include "noncopyable.h" -#include "image8.h" +#include -namespace rtengine { +#include "noncopyable.h" + +namespace rtengine +{ + +class Image8; enum RenderingIntent : int; diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index ca330f9b9..8d9e5de38 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -16,12 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "gauss.h" -#include "rt_math.h" #include #include -#include "opthelper.h" +#include + +#include "gauss.h" + #include "boxblur.h" +#include "opthelper.h" +#include "rt_math.h" + namespace { @@ -1349,7 +1353,7 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i } #endif -template void gaussianBlurImpl(T** src, T** dst, const int W, const int H, const double sigma, T *buffer = nullptr, eGaussType gausstype = GAUSS_STANDARD, T** buffer2 = nullptr) +template void gaussianBlurImpl(T** src, T** dst, const int W, const int H, const double sigma, bool useBoxBlur, eGaussType gausstype = GAUSS_STANDARD, T** buffer2 = nullptr) { static constexpr auto GAUSS_SKIP = 0.25; static constexpr auto GAUSS_3X3_LIMIT = 0.6; @@ -1357,7 +1361,7 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int static constexpr auto GAUSS_7X7_LIMIT = 1.15; static constexpr auto GAUSS_DOUBLE = 25.0; - if(buffer) { + if (useBoxBlur) { // special variant for very large sigma, currently only used by retinex algorithm // use iterated boxblur to approximate gaussian blur // Compute ideal averaging filter width and number of iterations @@ -1393,10 +1397,10 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int sizes[i] = ((i < m ? wl : wu) - 1) / 2; } - rtengine::boxblur(src, dst, buffer, sizes[0], sizes[0], W, H); + rtengine::boxblur(src, dst, sizes[0], W, H, true); for(int i = 1; i < n; i++) { - rtengine::boxblur(dst, dst, buffer, sizes[i], sizes[i], W, H); + rtengine::boxblur(dst, dst, sizes[i], W, H, true); } } else { if (sigma < GAUSS_SKIP) { @@ -1532,8 +1536,8 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int } } -void gaussianBlur(float** src, float** dst, const int W, const int H, const double sigma, float *buffer, eGaussType gausstype, float** buffer2) +void gaussianBlur(float** src, float** dst, const int W, const int H, const double sigma, bool useBoxBlur, eGaussType gausstype, float** buffer2) { - gaussianBlurImpl(src, dst, W, H, sigma, buffer, gausstype, buffer2); + gaussianBlurImpl(src, dst, W, H, sigma, useBoxBlur, gausstype, buffer2); } diff --git a/rtengine/gauss.h b/rtengine/gauss.h index b63301d2b..e226bbc13 100644 --- a/rtengine/gauss.h +++ b/rtengine/gauss.h @@ -16,11 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _GAUSS_H_ -#define _GAUSS_H_ +#pragma once enum eGaussType {GAUSS_STANDARD, GAUSS_MULT, GAUSS_DIV}; -void gaussianBlur(float** src, float** dst, const int W, const int H, const double sigma, float *buffer = nullptr, eGaussType gausstype = GAUSS_STANDARD, float** buffer2 = nullptr); - -#endif \ No newline at end of file +void gaussianBlur(float** src, float** dst, const int W, const int H, const double sigma, bool useBoxBlur = false, eGaussType gausstype = GAUSS_STANDARD, float** buffer2 = nullptr); diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index 0ebe6c172..6b2adb773 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -3,6 +3,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Alberto Griggio + * Optimized 2019 Ingo Weyrich * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +17,9 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ -/** +/* * This is a Fast Guided Filter implementation, derived directly from the * pseudo-code of the paper: * @@ -26,33 +27,21 @@ * by Kaiming He, Jian Sun * * available at https://arxiv.org/abs/1505.00996 - */ +*/ -#include "guidedfilter.h" #include "boxblur.h" -#include "rescale.h" +#include "guidedfilter.h" #include "imagefloat.h" +#include "rescale.h" -namespace rtengine { +#define BENCHMARK +#include "StopWatch.h" -#if 0 -# define DEBUG_DUMP(arr) \ - do { \ - Imagefloat im(arr.width(), arr.height()); \ - const char *out = "/tmp/" #arr ".tif"; \ - for (int y = 0; y < im.getHeight(); ++y) { \ - for (int x = 0; x < im.getWidth(); ++x) { \ - im.r(y, x) = im.g(y, x) = im.b(y, x) = arr[y][x] * 65535.f; \ - } \ - } \ - im.saveTIFF(out, 16); \ - } while (false) -#else -# define DEBUG_DUMP(arr) -#endif +namespace rtengine +{ - -namespace { +namespace +{ int calculate_subsampling(int w, int h, int r) { @@ -75,21 +64,17 @@ int calculate_subsampling(int w, int h, int r) } // namespace - void guidedFilter(const array2D &guide, const array2D &src, array2D &dst, int r, float epsilon, bool multithread, int subsampling) { - - const int W = src.width(); - const int H = src.height(); - - if (subsampling <= 0) { - subsampling = calculate_subsampling(W, H, r); - } - - enum Op { MUL, DIVEPSILON, ADD, SUB, ADDMUL, SUBMUL }; + enum Op {MUL, DIVEPSILON, SUBMUL}; const auto apply = - [=](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void +#ifdef _OPENMP + [multithread, epsilon](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void +#else + // removed multithread to fix clang warning on msys2 clang builds, which don't support OpenMp + [epsilon](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void +#endif { const int w = res.width(); const int h = res.height(); @@ -99,137 +84,109 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 #endif for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { - float r; - float aa = a[y][x]; - float bb = b[y][x]; switch (op) { - case MUL: - r = aa * bb; - break; - case DIVEPSILON: - r = aa / (bb + epsilon); - break; - case ADD: - r = aa + bb; - break; - case SUB: - r = aa - bb; - break; - case ADDMUL: - r = aa * bb + c[y][x]; - break; - case SUBMUL: - r = c[y][x] - (aa * bb); - break; - default: - assert(false); - r = 0; - break; + case MUL: + res[y][x] = a[y][x] * b[y][x]; + break; + case DIVEPSILON: + res[y][x] = a[y][x] / (b[y][x] + epsilon); // note: the value of epsilon intentionally has an impact on the result. It is not only to avoid divisions by zero + break; + case SUBMUL: + res[y][x] = c[y][x] - (a[y][x] * b[y][x]); + break; + default: + assert(false); + res[y][x] = 0; + break; } - res[y][x] = r; } } }; - // use the terminology of the paper (Algorithm 2) - const array2D &I = guide; - const array2D &p = src; - array2D &q = dst; - const auto f_subsample = - [=](array2D &d, const array2D &s) -> void + [multithread](array2D &d, const array2D &s) -> void { rescaleBilinear(s, d, multithread); }; - const auto f_upsample = f_subsample; - - const size_t w = W / subsampling; - const size_t h = H / subsampling; - - AlignedBuffer blur_buf(w * h); const auto f_mean = - [&](array2D &d, array2D &s, int rad) -> void + [multithread](array2D &d, array2D &s, int rad) -> void { rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); - float **src = s; - float **dst = d; -#ifdef _OPENMP - #pragma omp parallel if (multithread) -#endif - boxblur(src, dst, blur_buf.data, rad, rad, s.width(), s.height()); + boxblur(static_cast(s), static_cast(d), rad, s.width(), s.height(), multithread); }; + const int W = src.width(); + const int H = src.height(); + + if (subsampling <= 0) { + subsampling = calculate_subsampling(W, H, r); + } + + const size_t w = W / subsampling; + const size_t h = H / subsampling; + const float r1 = float(r) / subsampling; + array2D I1(w, h); array2D p1(w, h); - f_subsample(I1, I); - f_subsample(p1, p); + f_subsample(I1, guide); - DEBUG_DUMP(I); - DEBUG_DUMP(p); - DEBUG_DUMP(I1); - DEBUG_DUMP(p1); + if (&guide == &src) { + f_mean(p1, I1, r1); - float r1 = float(r) / subsampling; + apply(MUL, I1, I1, I1); // I1 = I1 * I1 - array2D meanI(w, h); - f_mean(meanI, I1, r1); - DEBUG_DUMP(meanI); + f_mean(I1, I1, r1); - array2D meanp(w, h); - f_mean(meanp, p1, r1); - DEBUG_DUMP(meanp); + apply(SUBMUL, I1, p1, p1, I1); // I1 = I1 - p1 * p1 + apply(DIVEPSILON, I1, I1, I1); // I1 = I1 / (I1 + epsilon) + apply(SUBMUL, p1, I1, p1, p1); // p1 = p1 - I1 * p1 - array2D &corrIp = p1; - apply(MUL, corrIp, I1, p1); - f_mean(corrIp, corrIp, r1); - DEBUG_DUMP(corrIp); + } else { + f_subsample(p1, src); - array2D &corrI = I1; - apply(MUL, corrI, I1, I1); - f_mean(corrI, corrI, r1); - DEBUG_DUMP(corrI); + array2D meanI(w, h); + f_mean(meanI, I1, r1); - array2D &varI = corrI; - apply(SUBMUL, varI, meanI, meanI, corrI); - DEBUG_DUMP(varI); + array2D meanp(w, h); + f_mean(meanp, p1, r1); - array2D &covIp = corrIp; - apply(SUBMUL, covIp, meanI, meanp, corrIp); - DEBUG_DUMP(covIp); + apply(MUL, p1, I1, p1); - array2D &a = varI; - apply(DIVEPSILON, a, covIp, varI); - DEBUG_DUMP(a); + f_mean(p1, p1, r1); - array2D &b = covIp; - apply(SUBMUL, b, a, meanI, meanp); - DEBUG_DUMP(b); + apply(MUL, I1, I1, I1); - meanI.free(); // frees w * h * 4 byte - meanp.free(); // frees w * h * 4 byte + f_mean(I1, I1, r1); - array2D &meana = a; - f_mean(meana, a, r1); - DEBUG_DUMP(meana); + apply(SUBMUL, I1, meanI, meanI, I1); + apply(SUBMUL, p1, meanI, meanp, p1); + apply(DIVEPSILON, I1, p1, I1); + apply(SUBMUL, p1, I1, meanI, meanp); + } - array2D &meanb = b; - f_mean(meanb, b, r1); - DEBUG_DUMP(meanb); + f_mean(I1, I1, r1); + f_mean(p1, p1, r1); - blur_buf.resize(0); // frees w * h * 4 byte + const int Ws = I1.width(); + const int Hs = I1.height(); + const int Wd = dst.width(); + const int Hd = dst.height(); - array2D meanA(W, H); - f_upsample(meanA, meana); - DEBUG_DUMP(meanA); + const float col_scale = static_cast(Ws) / static_cast(Wd); + const float row_scale = static_cast(Hs) / static_cast(Hd); - array2D &meanB = q; - f_upsample(meanB, meanb); - DEBUG_DUMP(meanB); +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif - apply(ADDMUL, q, meanA, I, meanB); - DEBUG_DUMP(q); + for (int y = 0; y < Hd; ++y) { + const float ymrs = y * row_scale; + for (int x = 0; x < Wd; ++x) { + dst[y][x] = getBilinearValue(I1, x * col_scale, ymrs) * guide[y][x] + getBilinearValue(p1, x * col_scale, ymrs); + } + } } } // namespace rtengine diff --git a/rtengine/guidedfilter.h b/rtengine/guidedfilter.h index af8ed0901..2d8b70369 100644 --- a/rtengine/guidedfilter.h +++ b/rtengine/guidedfilter.h @@ -20,9 +20,11 @@ #pragma once -#include "array2D.h" +template class array2D; + +namespace rtengine +{ -namespace rtengine { void guidedFilter(const array2D &guide, const array2D &src, array2D &dst, int r, float epsilon, bool multithread, int subsampling=0); diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 35dd74463..697a5e3d3 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -288,8 +288,6 @@ void boxblur_resamp(const float* const* src, float** dst, float** temp, int H, i namespace rtengine { -extern const Settings* settings; - void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue) { double progress = 0.0; diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 212b11d00..f5d16866e 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -18,23 +18,22 @@ * along with RawTherapee. If not, see . */ -#include "rawimagesource.h" -#include "rtthumbnail.h" -#include "curves.h" -#include "color.h" -#include "rt_math.h" -#include "iccstore.h" -#include "procparams.h" -#include "../rtgui/mydiagonalcurve.h" -#include "improcfun.h" -//#define BENCHMARK -#include "StopWatch.h" #include +#include "color.h" +#include "curves.h" +#include "improcfun.h" +#include "procparams.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "rtthumbnail.h" +#include "settings.h" -namespace rtengine { +//#define BENCHMARK +#include "StopWatch.h" -extern const Settings *settings; +namespace rtengine +{ namespace { diff --git a/rtengine/hphd_demosaic_RT.cc b/rtengine/hphd_demosaic_RT.cc index 0e56eae48..5e05b128e 100644 --- a/rtengine/hphd_demosaic_RT.cc +++ b/rtengine/hphd_demosaic_RT.cc @@ -18,12 +18,11 @@ */ #include +#include "rawimage.h" #include "rawimagesource.h" #include "rawimagesource_i.h" #include "jaggedarray.h" -#include "rawimage.h" #include "rt_math.h" -#include "procparams.h" #include "../rtgui/multilangmgr.h" #include "opthelper.h" //#define BENCHMARK @@ -353,7 +352,7 @@ void RawImageSource::hphd_demosaic () interpolate_row_rb_mul_pp(rawData, red[i], blue[i], green[i - 1], green[i], green[i + 1], i, 1.0, 1.0, 1.0, 0, W, 1); } - border_interpolate2(W, H, 4, rawData, red, green, blue); + border_interpolate(W, H, 4, rawData, red, green, blue); if (plistener) { plistener->setProgress(1.0); diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h index 3e0d0b5d6..5b9883421 100644 --- a/rtengine/iccmatrices.h +++ b/rtengine/iccmatrices.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ICCMATRICES_ -#define _ICCMATRICES_ +#pragma once // Bradford transform between illuminants constexpr double d65_d50[3][3] = { @@ -296,4 +295,3 @@ constexpr double d50_best[3][3] = { {-0.253000840399762, 0.0215532098817316,1.22569552576991} }; */ -#endif diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index a8d54b810..aea03664e 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -18,7 +18,9 @@ */ #include -#include +#include +#include +#include #include #ifdef WIN32 @@ -32,6 +34,7 @@ #include "iccstore.h" #include "iccmatrices.h" +#include "utils.h" #include "../rtgui/options.h" #include "../rtgui/threadutils.h" @@ -41,12 +44,6 @@ #include "cJSON.h" #define inkc_constant 0x696E6B43 -namespace rtengine -{ - -extern const Settings* settings; - -} namespace { diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 5c76660e5..731a155bb 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -19,15 +19,14 @@ #pragma once #include +#include #include #include -#include +#include #include -#include "color.h" - namespace rtengine { diff --git a/rtengine/iimage.cc b/rtengine/iimage.cc index a1ec979a1..7548fc8bf 100644 --- a/rtengine/iimage.cc +++ b/rtengine/iimage.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ +#include "color.h" #include "procparams.h" #include "rtengine.h" @@ -45,3 +46,7 @@ int rtengine::getCoarseBitMask( const procparams::CoarseTransformParams &coarse) return tr; } + +const LUTf& rtengine::getigammatab() { + return Color::igammatab_srgb; +} diff --git a/rtengine/iimage.h b/rtengine/iimage.h index 8f163d329..e600a34a6 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -16,17 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IIMAGE_ -#define _IIMAGE_ +#pragma once -#include #include -#include "rt_math.h" + +#include +#include + #include "alignedbuffer.h" +#include "coord2d.h" #include "imagedimensions.h" #include "LUT.h" -#include "coord2d.h" -#include "color.h" +#include "rt_math.h" + #include "../rtgui/threadutils.h" #define TR_NONE 0 @@ -57,6 +59,7 @@ extern const char sImage16[]; extern const char sImagefloat[]; int getCoarseBitMask(const procparams::CoarseTransformParams& coarse); +const LUTf& getigammatab(); enum TypeInterpolation { TI_Nearest, TI_Bilinear }; @@ -991,17 +994,35 @@ public: histogram(65536 >> histcompr); histogram.clear(); + const LUTf& igammatab = getigammatab(); - for (int i = 0; i < height; i++) - for (int j = 0; j < width; j++) { - float r_, g_, b_; - convertTo(r(i, j), r_); - convertTo(g(i, j), g_); - convertTo(b(i, j), b_); - histogram[(int)Color::igamma_srgb (r_) >> histcompr]++; - histogram[(int)Color::igamma_srgb (g_) >> histcompr]++; - histogram[(int)Color::igamma_srgb (b_) >> histcompr]++; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + LUTu histThr(histogram.getSize()); + histThr.clear(); +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) nowait +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + float r_, g_, b_; + convertTo(r(i, j), r_); + convertTo(g(i, j), g_); + convertTo(b(i, j), b_); + histThr[static_cast(igammatab[r_]) >> histcompr]++; + histThr[static_cast(igammatab[g_]) >> histcompr]++; + histThr[static_cast(igammatab[b_]) >> histcompr]++; + } } +#ifdef _OPENMP + #pragma omp critical +#endif + { + histogram += histThr; + } + } } void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const override @@ -1009,16 +1030,16 @@ public: histogram.clear(); avg_r = avg_g = avg_b = 0.; n = 0; - + const LUTf& igammatab = getigammatab(); for (unsigned int i = 0; i < (unsigned int)(height); i++) for (unsigned int j = 0; j < (unsigned int)(width); j++) { float r_, g_, b_; convertTo(r(i, j), r_); convertTo(g(i, j), g_); convertTo(b(i, j), b_); - int rtemp = Color::igamma_srgb (r_); - int gtemp = Color::igamma_srgb (g_); - int btemp = Color::igamma_srgb (b_); + int rtemp = igammatab[r_]; + int gtemp = igammatab[g_]; + int btemp = igammatab[b_]; histogram[rtemp >> compression]++; histogram[gtemp >> compression] += 2; @@ -1045,6 +1066,9 @@ public: int n = 0; //int p = 6; +#ifdef _OPENMP + #pragma omp parallel for reduction(+:avg_r,avg_g,avg_b,n) schedule(dynamic,16) +#endif for (unsigned int i = 0; i < (unsigned int)(height); i++) for (unsigned int j = 0; j < (unsigned int)(width); j++) { float r_, g_, b_; @@ -1617,17 +1641,35 @@ public: histogram(65536 >> histcompr); histogram.clear(); + const LUTf& igammatab = getigammatab(); - for (int i = 0; i < height; i++) - for (int j = 0; j < width; j++) { - float r_, g_, b_; - convertTo(r(i, j), r_); - convertTo(g(i, j), g_); - convertTo(b(i, j), b_); - histogram[(int)Color::igamma_srgb (r_) >> histcompr]++; - histogram[(int)Color::igamma_srgb (g_) >> histcompr]++; - histogram[(int)Color::igamma_srgb (b_) >> histcompr]++; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + LUTu histThr(histogram.getSize()); + histThr.clear(); +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) nowait +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + float r_, g_, b_; + convertTo(r(i, j), r_); + convertTo(g(i, j), g_); + convertTo(b(i, j), b_); + histThr[static_cast(igammatab[r_]) >> histcompr]++; + histThr[static_cast(igammatab[g_]) >> histcompr]++; + histThr[static_cast(igammatab[b_]) >> histcompr]++; + } } +#ifdef _OPENMP + #pragma omp critical +#endif + { + histogram += histThr; + } + } } void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const override @@ -1635,6 +1677,7 @@ public: histogram.clear(); avg_r = avg_g = avg_b = 0.; n = 0; + const LUTf& igammatab = getigammatab(); for (unsigned int i = 0; i < (unsigned int)(height); i++) for (unsigned int j = 0; j < (unsigned int)(width); j++) { @@ -1642,9 +1685,9 @@ public: convertTo(r(i, j), r_); convertTo(g(i, j), g_); convertTo(b(i, j), b_); - int rtemp = Color::igamma_srgb (r_); - int gtemp = Color::igamma_srgb (g_); - int btemp = Color::igamma_srgb (b_); + int rtemp = igammatab[r_]; + int gtemp = igammatab[g_]; + int btemp = igammatab[b_]; histogram[rtemp >> compression]++; histogram[gtemp >> compression] += 2; @@ -1671,6 +1714,9 @@ public: int n = 0; //int p = 6; +#ifdef _OPENMP + #pragma omp parallel for reduction(+:avg_r,avg_g,avg_b,n) schedule(dynamic,16) +#endif for (unsigned int i = 0; i < (unsigned int)(height); i++) for (unsigned int j = 0; j < (unsigned int)(width); j++) { float r_, g_, b_; @@ -1861,5 +1907,3 @@ public: }; } - -#endif diff --git a/rtengine/image16.cc b/rtengine/image16.cc index b0ac6c2af..22dd2f866 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -16,11 +16,13 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + +#include "colortemp.h" #include "image16.h" #include "imagefloat.h" #include "image8.h" -#include -#include "rtengine.h" +#include "rt_math.h" namespace { diff --git a/rtengine/image16.h b/rtengine/image16.h index 108fd0b5c..60bef4a95 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -19,17 +19,15 @@ // // A class representing a 16 bit rgb image with separate planes and 16 byte aligned data // -#ifndef _IMAGE16_ -#define _IMAGE16_ +#pragma once #include "imageio.h" -#include "rtengine.h" -#include "imagefloat.h" namespace rtengine { class Image8; +class Imagefloat; class Image16 : public IImage16, public ImageIO { @@ -110,4 +108,3 @@ public: }; } -#endif diff --git a/rtengine/image8.cc b/rtengine/image8.cc index 8bf3f564c..d5d0b58bf 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -18,7 +18,10 @@ */ #include #include + +#include "colortemp.h" #include "image8.h" +#include "imagefloat.h" #include "rtengine.h" using namespace rtengine; @@ -230,10 +233,10 @@ void Image8::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, c lineB[dst_x] = CLIP(bm * btot); } else { // computing a special factor for this incomplete sub-region - float area = src_sub_width * src_sub_height; - lineR[dst_x] = CLIP(rm2 * rtot / area); - lineG[dst_x] = CLIP(gm2 * gtot / area); - lineB[dst_x] = CLIP(bm2 * btot / area); + float larea = src_sub_width * src_sub_height; + lineR[dst_x] = CLIP(rm2 * rtot / larea); + lineG[dst_x] = CLIP(gm2 * gtot / larea); + lineB[dst_x] = CLIP(bm2 * btot / larea); } } } diff --git a/rtengine/image8.h b/rtengine/image8.h index d36001378..d0bdff108 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -19,15 +19,13 @@ // // A class representing a 8 bit rgb image without alpha channel // -#ifndef _IMAGE8_ -#define _IMAGE8_ +#pragma once #include "imageio.h" -#include "rtengine.h" -#include "imagefloat.h" namespace rtengine { +class Imagefloat; class Image8 : public IImage8, public ImageIO { @@ -104,4 +102,3 @@ public: }; } -#endif diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 403f4708c..24cfefde9 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -17,15 +17,22 @@ * along with RawTherapee. If not, see . */ #include + #include -#include + #include +#include + +#include + #include "imagedata.h" -#include "iptcpairs.h" #include "imagesource.h" -#include "rt_math.h" +#include "iptcpairs.h" #include "procparams.h" +#include "rt_math.h" +#include "utils.h" +#include "../rtexif/rtexif.h" #pragma GCC diagnostic warning "-Wextra" #define PRINT_HDR_PS_DETECTION 0 diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 99caaf361..ff8ed4b86 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -16,17 +16,24 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __IMAGEDATA_H__ -#define __IMAGEDATA_H__ +#pragma once #include #include -#include "rawimage.h" #include -#include -#include "../rtexif/rtexif.h" +#include + +#include + #include -#include "rtengine.h" + +#include "imageio.h" + +namespace rtexif +{ + +class TagDirectory; +} namespace rtengine { @@ -133,4 +140,3 @@ public: } -#endif diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 1e8cdce5c..3098c2ce4 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -17,12 +17,14 @@ * along with RawTherapee. If not, see . */ #include + +#include "colortemp.h" #include "imagefloat.h" #include "image16.h" #include "image8.h" +#include "labimage.h" #include #include "rtengine.h" -#include "mytime.h" #include "iccstore.h" #include "alignedbuffer.h" #include "rt_math.h" diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index 761fc485f..17c4076a1 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -19,11 +19,9 @@ // // A class representing a 16 bit rgb image with separate planes and 16 byte aligned data // -#ifndef _IMAGEFLOAT_ -#define _IMAGEFLOAT_ +#pragma once #include "imageio.h" -#include "rtengine.h" namespace rtengine { @@ -31,6 +29,7 @@ using namespace procparams; class Image8; class Image16; +class LabImage; /* * Image type used by most tools; expected range: [0.0 ; 65535.0] @@ -228,4 +227,3 @@ public: }; } -#endif diff --git a/rtengine/imageformat.h b/rtengine/imageformat.h index dc40cf147..f8fee4c59 100644 --- a/rtengine/imageformat.h +++ b/rtengine/imageformat.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGEFORMAT_ -#define _IMAGEFORMAT_ +#pragma once namespace rtengine { @@ -51,5 +50,3 @@ typedef enum SensorType { } eSensorType; } - -#endif diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index f335f5be8..fce181c3f 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -27,8 +27,10 @@ #include #include "rt_math.h" #include "procparams.h" +#include "utils.h" #include "../rtgui/options.h" #include "../rtgui/version.h" +#include "../rtexif/rtexif.h" #ifdef WIN32 #include @@ -810,7 +812,7 @@ int ImageIO::loadTIFF (const Glib::ustring &fname) * TIFFTAG_SMAXSAMPLEVALUE, but for now, we normalize the image to the * effective minimum and maximum values */ - if (options.rtSettings.verbose) { + if (settings->verbose) { printf("Information of \"%s\":\n", fname.c_str()); uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit; if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) { diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 86b718e35..140dc8c3f 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -16,35 +16,51 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGEIO_ -#define _IMAGEIO_ - -#define IMIO_SUCCESS 0 -#define IMIO_CANNOTREADFILE 1 -#define IMIO_INVALIDHEADER 2 -#define IMIO_HEADERERROR 3 -#define IMIO_READERROR 4 -#define IMIO_VARIANTNOTSUPPORTED 5 -#define IMIO_FILETYPENOTSUPPORTED 6 -#define IMIO_CANNOTWRITEFILE 7 +#pragma once #include -#include +#include + #include -#include "rtengine.h" -#include "imageformat.h" -#include "../rtexif/rtexif.h" -#include "imagedimensions.h" + #include "iimage.h" -#include "colortemp.h" +#include "imagedimensions.h" +#include "imageformat.h" +#include "rtengine.h" + +enum { + IMIO_SUCCESS, + IMIO_CANNOTREADFILE, + IMIO_INVALIDHEADER, + IMIO_HEADERERROR, + IMIO_READERROR, + IMIO_VARIANTNOTSUPPORTED, + IMIO_FILETYPENOTSUPPORTED, + IMIO_CANNOTWRITEFILE +}; + +namespace rtexif +{ + +class TagDirectory; + +} namespace rtengine { +class ColorTemp; class ProgressListener; class Imagefloat; +namespace procparams +{ + +class ExifPairs; + +} + class ImageIO : virtual public ImageDatas { @@ -111,4 +127,3 @@ public: }; } -#endif diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index edc1102c4..e0c26aa9f 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -21,21 +21,31 @@ #include #include -#include +#include -#include "colortemp.h" #include "coord2d.h" -#include "dcp.h" -#include "image16.h" -#include "image8.h" #include "imagedata.h" -#include "imagefloat.h" #include "LUT.h" #include "rtengine.h" +template +class LUT; + +using LUTf = LUT; + +template +class multi_array2D; + namespace rtengine { +class ColorTemp; +class DCPProfile; +class DCPProfileApplyState; +class Imagefloat; +class RetinexgaintransmissionCurve; +class RetinextransmissionCurve; + namespace procparams { @@ -47,7 +57,7 @@ struct RAWParams; struct RetinexParams; struct ToneCurveParams; struct CaptureSharpeningParams; -} +}; class ImageMatrices { @@ -82,7 +92,7 @@ public: virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; - virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array& newExps) { return false; }; + virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams& currentParams, std::array& newExps) { return false; }; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; @@ -101,13 +111,13 @@ public: // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* - virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const RAWParams &raw) = 0; + virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw) = 0; virtual eSensorType getSensorType () const = 0; virtual bool isMono () const = 0; // true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource virtual bool isWBProviderReady () = 0; - virtual void convertColorSpace (Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images + virtual void convertColorSpace (Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0; virtual ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) = 0; @@ -126,7 +136,7 @@ public: virtual ImageMatrices* getImageMatrices () = 0; virtual bool isRAW () const = 0; - virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &as) + virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) { return nullptr; }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ed2b506af..684d34e01 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -16,28 +16,38 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include +#include +#include +#include + #include "improccoordinator.h" -#include "curves.h" -#include "mytime.h" -#include "refreshmap.h" -#include "../rtgui/ppversion.h" + +#include "cieimage.h" +#include "color.h" #include "colortemp.h" -#include "improcfun.h" +#include "curves.h" +#include "dcp.h" #include "iccstore.h" +#include "image8.h" +#include "imagefloat.h" +#include "improcfun.h" +#include "labimage.h" +#include "lcp.h" #include "procparams.h" #include "tweakoperator.h" -#include -#include -#include -#include "color.h" +#include "refreshmap.h" + +#include "../rtgui/options.h" + #ifdef _OPENMP #include #endif + + namespace rtengine { -extern const Settings* settings; - ImProcCoordinator::ImProcCoordinator() : orig_prev(nullptr), oprevi(nullptr), @@ -246,9 +256,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) MyMutex::MyLock processingLock(mProcessing); - constexpr int numofphases = 15; - int readyphase = 0; - bool highDetailNeeded = options.prevdemo == PD_Sidecar ? true : (todo & M_HIGHQUAL); // Check if any detail crops need high detail. If not, take a fast path short cut @@ -289,8 +296,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //rp.deadPixelFilter = rp.hotPixelFilter = false; } - progress("Applying white balance, color correction & sRGB conversion...", 100 * readyphase / numofphases); - if (frameCountListener) { frameCountListener->FrameCountChanged(imgsrc->getFrameCount(), params->raw.bayersensor.imageNum); } @@ -549,12 +554,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.firstAnalysis(orig_prev, *params, vhist16); } - readyphase++; - oprevi = orig_prev; - progress ("Spot Removal...", 100 * readyphase / numofphases); - if (todo & M_SPOT) { if (params->spot.enabled && !params->spot.entries.empty()) { allocCache(spotprev); @@ -592,7 +593,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.ToneMapFattal02(oprevi); } - progress ("Rotate / Distortion...", 100 * readyphase / numofphases); // Remove transformation if unneeded bool needstransform = ipf.needsTransform(); @@ -619,11 +619,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.lab2rgb(labcbdl, *oprevi, params->icm.workingProfile); } - readyphase++; - progress("Preparing shadow/highlight map...", 100 * readyphase / numofphases); - - readyphase++; - if (todo & M_AUTOEXP) { if (params->toneCurve.autoexp) { LUTu aehist; @@ -660,8 +655,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } - progress("Exposure curve & CIELAB conversion...", 100 * readyphase / numofphases); - if (todo & (M_AUTOEXP | M_RGBCURVE)) { if (params->icm.workingTRC == "Custom") { //exec TRC IN free if (oprevi == orig_prev) { @@ -783,7 +776,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double ggm = 33.; double bbm = 33.; - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params->icm, as); ipf.rgbProc (oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation, @@ -809,8 +802,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); } - readyphase++; - if (todo & (M_LUMACURVE | M_CROP)) { LUTu lhist16(32768); lhist16.clear(); @@ -853,8 +844,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (todo & (M_LUMINANCE + M_COLOR)) { nprevl->CopyFrom(oprevl); - progress("Applying Color Boost...", 100 * readyphase / numofphases); - histCCurve.clear(); histLCurve.clear(); ipf.chromiLuminanceCurve(nullptr, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve); @@ -865,72 +854,22 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.EPDToneMap(nprevl, 0, scale); } - // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled - readyphase++; - - /* Issue 2785, disabled some 1:1 tools - if (scale==1) { - if((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled)){ - progress ("Denoising luminance impulse...",100*readyphase/numofphases); - ipf.impulsedenoise (nprevl); - readyphase++; - } - if((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled)){ - progress ("Defringing...",100*readyphase/numofphases); - ipf.defringe (nprevl); - readyphase++; - } - if (params->sharpenEdge.enabled) { - progress ("Edge sharpening...",100*readyphase/numofphases); - ipf.MLsharpen (nprevl); - readyphase++; - } - if (params->sharpenMicro.enabled) { - if(( params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled)){ - progress ("Microcontrast...",100*readyphase/numofphases); - ipf.MLmicrocontrast (nprevl); - readyphase++; - } - } - if(((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled)) && params->sharpening.enabled) { - progress ("Sharpening...",100*readyphase/numofphases); - - float **buffer = new float*[pH]; - for (int i=0; idirpyrequalizer.cbdlMethod == "aft") { if (((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled))) { - progress("Pyramid wavelet...", 100 * readyphase / numofphases); ipf.dirpyrequalizer(nprevl, scale); - //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); - readyphase++; } } wavcontlutili = false; - //CurveFactory::curveWavContL ( wavcontlutili,params->wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); CurveFactory::curveWavContL(wavcontlutili, params->wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16); if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; - // WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; - progress("Wavelet...", 100 * readyphase / numofphases); - // ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, scale); ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); } @@ -938,7 +877,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.softLight(nprevl); if (params->colorappearance.enabled) { - //L histo and Chroma histo for ciecam + // L histo and Chroma histo for ciecam // histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C int x1, y1, x2, y2; params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); @@ -1019,8 +958,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) { acListener->ybCamChanged((int) yb); //real value Yb scene } - - readyphase++; } else { // CIECAM is disabled, we free up its image buffer to save some space if (ncie) { @@ -1055,8 +992,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } if (panningRelatedChange || (todo & M_MONITOR)) { - progress("Conversion to RGB...", 100 * readyphase / numofphases); - if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); @@ -1068,7 +1003,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete workimg; workimg = ipf.lab2rgb(nprevl, 0, 0, pW, pH, params->icm); } catch (char * str) { - progress("Error converting file...", 0); return; } } @@ -1087,8 +1021,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imageListener->imageReady(params->crop); } - readyphase++; - if (hListener) { updateLRGBHistograms(); hListener->histogramChanged(histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma, histLRETI); @@ -1276,15 +1208,6 @@ void ImProcCoordinator::updateLRGBHistograms() } -void ImProcCoordinator::progress(Glib::ustring str, int pr) -{ - - /* if (plistener) { - plistener->setProgressStr (str); - plistener->setProgress ((double)pr / 100.0); - }*/ -} - bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, double tempBias) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index edd0353a0..a490b6660 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -16,21 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMPROCCOORDINATOR_H_ -#define _IMPROCCOORDINATOR_H_ +#pragma once #include -#include "rtengine.h" -#include "improcfun.h" -#include "image8.h" -#include "image16.h" -#include "imagesource.h" -#include "procevents.h" +#include "array2D.h" +#include "colortemp.h" +#include "curves.h" #include "dcrop.h" +#include "imagesource.h" +#include "improcfun.h" #include "LUT.h" +#include "procevents.h" +#include "rtengine.h" + #include "../rtgui/threadutils.h" +namespace Glib +{ +class Thread; +} + namespace rtengine { @@ -182,7 +188,6 @@ protected: MyMutex minit; // to gain mutually exclusive access to ... to what exactly? - void progress (Glib::ustring str, int pr); void backupParams(); void restoreParams(); void reallocAll (); @@ -417,5 +422,5 @@ public: } denoiseInfoStore; }; + } -#endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index db77e02fa..cb0834570 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -17,35 +17,43 @@ * along with RawTherapee. If not, see . */ #include + #include -#include +#include + #ifdef _OPENMP #include #endif #include "alignedbuffer.h" -#include "rtengine.h" -#include "improcfun.h" +#include "calc_distort.h" +#include "ciecam02.h" +#include "cieimage.h" +#include "clutstore.h" +#include "color.h" #include "curves.h" -#include "mytime.h" +#include "dcp.h" +#include "EdgePreservingDecomposition.h" +#include "iccmatrices.h" #include "iccstore.h" #include "imagesource.h" -#include "rtthumbnail.h" -#include "utils.h" -#include "iccmatrices.h" -#include "color.h" -#include "calc_distort.h" -#include "rt_math.h" -#include "EdgePreservingDecomposition.h" #include "improccoordinator.h" -#include "clutstore.h" -#include "ciecam02.h" -#include "StopWatch.h" +#include "improcfun.h" +#include "labimage.h" #include "procparams.h" -#include "../rtgui/ppversion.h" -#include "../rtgui/guiutils.h" +#include "rt_math.h" +#include "rtengine.h" +#include "rtthumbnail.h" +#include "satandvalueblendingcurve.h" +#include "StopWatch.h" +#include "utils.h" + #include "../rtgui/editcallbacks.h" +#ifdef _DEBUG +#include "mytime.h" +#endif + #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -265,8 +273,6 @@ namespace rtengine using namespace procparams; -extern const Settings* settings; - ImProcFunctions::~ImProcFunctions () { if (monitorTransform) { @@ -296,7 +302,7 @@ void ImProcFunctions::updateColorProfiles (const Glib::ustring& monitorProfile, #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB monitor = ICCStore::getInstance()->getProfile (monitorProfile); #else - monitor = ICCStore::getInstance()->getProfile (options.rtSettings.srgb); + monitor = ICCStore::getInstance()->getProfile (settings->srgb); #endif } @@ -866,7 +872,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw mean = (sum / ((height) * width)) / 327.68f; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone } } - +#ifdef _OPENMP + static_cast(numThreads); // to silence cppcheck warning +#endif //evaluate lightness, contrast } @@ -1466,8 +1474,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw if (ciedata) { //only with improccoordinator // Data for J Q M s and C histograms int posl, posc; - float brli = 327.f; - float chsacol = 327.f; + float brli; + float chsacol; float libr; float colch; @@ -2046,17 +2054,25 @@ filmlike_clip (float *r, float *g, float *b) } } -void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, - int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve, - const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure) +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, + const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, + const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, + LUTu& histToneCurve, size_t chunkSize, bool measure) { - rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve, chunkSize, measure); + rgbProc(working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, + clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, + params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve, chunkSize, measure); } // Process RGB image and convert to LAB space -void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, - int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve, - const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure) +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, + const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, + const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, + DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { std::unique_ptr stop; @@ -3755,10 +3771,9 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, float rlo; //0.4 0.5 float rlm; //1.1 float rlh; //1.1 - float rlob; //for BW old mode if (mode == 0) { //colour - rlo = rlob = strProtect; //0.5 ==> 0.75 + rlo = strProtect; //0.5 ==> 0.75 rlh = 2.2f * strProtect; rlm = 1.5f * strProtect; constexpr float v0 = 0.15f; @@ -3775,7 +3790,6 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, } } else { //bw coefficient to preserve same results as before for satlimtopacity = 0.5 (default) rlo = strProtect * 0.8f; //0.4 - rlob = strProtect; //0.5 rlm = strProtect * 2.2f; //1.1 rlh = strProtect * 2.4f; //1.2 if (v > 0.15f) { @@ -4077,7 +4091,7 @@ void ImProcFunctions::toning2col (float r, float g, float b, float &ro, float &g * @param iplow iphigh [0..1] luminance * @param wp wip 3x3 matrix and inverse conversion rgb XYZ **/ -void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, LUTf & clToningcurve, LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3] ) +void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3] ) { ro = CLIP(r); go = CLIP(g); @@ -4136,7 +4150,7 @@ void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go } -void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & curve) +void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, const LUTf& curve) { int W = lold->W; @@ -4156,7 +4170,7 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur -void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve, LUTf & lhskcurve, LUTf & clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve) +void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, const LUTf& acurve, const LUTf& bcurve, const LUTf& satcurve, const LUTf& lhskcurve, const LUTf& clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve) { int W = lold->W; @@ -4247,11 +4261,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { chCurve = new FlatCurve (params->labCurve.chcurve); - if (!chCurve || chCurve->isIdentity()) { - if (chCurve) { - delete chCurve; - chCurve = nullptr; - } + if (chCurve->isIdentity()) { + delete chCurve; + chCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { chutili = true; @@ -4264,11 +4276,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { lhCurve = new FlatCurve (params->labCurve.lhcurve); - if (!lhCurve || lhCurve->isIdentity()) { - if (lhCurve) { - delete lhCurve; - lhCurve = nullptr; - } + if (lhCurve->isIdentity()) { + delete lhCurve; + lhCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { lhutili = true; @@ -4281,11 +4291,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { hhCurve = new FlatCurve (params->labCurve.hhcurve); - if (!hhCurve || hhCurve->isIdentity()) { - if (hhCurve) { - delete hhCurve; - hhCurve = nullptr; - } + if (hhCurve->isIdentity()) { + delete hhCurve; + hhCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { hhutili = true; @@ -5356,7 +5364,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double int imax = 65536 >> histcompr; int overex = 0; float sum = 0.f, hisum = 0.f, losum = 0.f; - float ave = 0.f, hidev = 0.f, lodev = 0.f; + float ave = 0.f; //find average luminance histogram.getSumAndAverage (sum, ave); @@ -5384,36 +5392,32 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double float octile[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}, ospread = 0.f; count = 0; - int i = 0; + int j = 0; - for (; i < min ((int)ave, imax); i++) { + for (; j < min ((int)ave, imax); ++j) { if (count < 8) { - octile[count] += histogram[i]; + octile[count] += histogram[j]; if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { - octile[count] = xlog (1. + (float)i) / log (2.f); + octile[count] = xlog (1. + j) / log (2.f); count++;// = min(count+1,7); } } - //lodev += SQR(ave-i)*histogram[i]; - lodev += (xlog (ave + 1.f) - xlog ((float)i + 1.)) * histogram[i]; - losum += histogram[i]; + losum += histogram[j]; } - for (; i < imax; i++) { + for (; j < imax; ++j) { if (count < 8) { - octile[count] += histogram[i]; + octile[count] += histogram[j]; if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { - octile[count] = xlog (1. + (float)i) / log (2.f); + octile[count] = xlog (1. + j) / log (2.f); count++;// = min(count+1,7); } } - //hidev += SQR(i-ave)*histogram[i]; - hidev += (xlog ((float)i + 1.) - xlog (ave + 1.f)) * histogram[i]; - hisum += histogram[i]; + hisum += histogram[j]; } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 0f56dc556..995288e7a 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -16,34 +16,54 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMPROCFUN_H_ -#define _IMPROCFUN_H_ +#pragma once + +#include -#include "imagefloat.h" -#include "image16.h" -#include "image8.h" -#include "shmap.h" #include "coord2d.h" -#include "color.h" -#include "labimage.h" -#include "cieimage.h" -#include "LUT.h" -#include "lcp.h" -#include "dcp.h" -#include "curves.h" -#include "cplx_wavelet_dec.h" -#include "pipettebuffer.h" #include "gamutwarning.h" +#include "pipettebuffer.h" +template +class LUT; + +using LUTu = LUT; +using LUTf = LUT; + +template +class multi_array2D; namespace rtengine { +class ColorAppearance; +class ColorGradientCurve; +class DCPProfile; +class DCPProfileApplyState; +class FlatCurve; +class FramesMetaData; +class LensCorrection; +class NoiseCurve; +class OpacityCurve; +class ToneCurve; +class WavCurve; +class WavOpacityCurveBY; +class WavOpacityCurveRG; +class WavOpacityCurveW; +class WavOpacityCurveWL; + +class CieImage; +class Image8; +class Imagefloat; +class LabImage; +class wavelet_decomposition; + namespace procparams { class ProcParams; struct SpotEntry; +struct ColorManagementParams; struct DirPyrDenoiseParams; struct SharpeningParams; struct VignettingParams; @@ -58,7 +78,7 @@ class ImProcFunctions cmsHTRANSFORM monitorTransform; std::unique_ptr gamutWarning; - const ProcParams* params; + const procparams::ProcParams* params; double scale; bool multiThread; @@ -68,126 +88,16 @@ class ImProcFunctions 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); - bool needsCA(); - bool needsDistortion(); - bool needsRotation(); - bool needsPerspective(); - bool needsGradient(); - bool needsVignetting(); - bool needsLCP(); - bool needsLensfun(); + bool needsCA() const; + bool needsDistortion() const; + bool needsRotation() const; + bool needsPerspective() const; + bool needsGradient() const; + bool needsVignetting() const; + bool needsLCP() const; + bool needsLensfun() const; // static cmsUInt8Number* Mempro = NULL; - inline void interpolateTransformCubic(Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul) - { - const double A = -0.85; - - double w[4]; - - { - double t1, t2; - t1 = -A * (Dx - 1.0) * Dx; - t2 = (3.0 - 2.0 * Dx) * Dx * Dx; - w[3] = t1 * Dx; - w[2] = t1 * (Dx - 1.0) + t2; - w[1] = -t1 * Dx + 1.0 - t2; - w[0] = -t1 * (Dx - 1.0); - } - - double rd, gd, bd; - double yr[4] = {0.0}, yg[4] = {0.0}, yb[4] = {0.0}; - - for (int k = ys, kx = 0; k < ys + 4; k++, kx++) { - rd = gd = bd = 0.0; - - for (int i = xs, ix = 0; i < xs + 4; i++, ix++) { - rd += src->r(k, i) * w[ix]; - gd += src->g(k, i) * w[ix]; - bd += src->b(k, i) * w[ix]; - } - - yr[kx] = rd; - yg[kx] = gd; - yb[kx] = bd; - } - - - { - double t1, t2; - - t1 = -A * (Dy - 1.0) * Dy; - t2 = (3.0 - 2.0 * Dy) * Dy * Dy; - w[3] = t1 * Dy; - w[2] = t1 * (Dy - 1.0) + t2; - w[1] = -t1 * Dy + 1.0 - t2; - w[0] = -t1 * (Dy - 1.0); - } - - rd = gd = bd = 0.0; - - for (int i = 0; i < 4; i++) { - rd += yr[i] * w[i]; - gd += yg[i] * w[i]; - bd += yb[i] * w[i]; - } - - *r = rd * mul; - *g = gd * mul; - *b = bd * mul; - - // if (xs==100 && ys==100) - // printf ("r=%g, g=%g\n", *r, *g); - } - - inline void interpolateTransformChannelsCubic(float** src, int xs, int ys, double Dx, double Dy, float *r, double mul) - { - const double A = -0.85; - - double w[4]; - - { - double t1, t2; - t1 = -A * (Dx - 1.0) * Dx; - t2 = (3.0 - 2.0 * Dx) * Dx * Dx; - w[3] = t1 * Dx; - w[2] = t1 * (Dx - 1.0) + t2; - w[1] = -t1 * Dx + 1.0 - t2; - w[0] = -t1 * (Dx - 1.0); - } - - double rd; - double yr[4] = {0.0}; - - for (int k = ys, kx = 0; k < ys + 4; k++, kx++) { - rd = 0.0; - - for (int i = xs, ix = 0; i < xs + 4; i++, ix++) { - rd += src[k][i] * w[ix]; - } - - yr[kx] = rd; - } - - - { - double t1, t2; - t1 = -A * (Dy - 1.0) * Dy; - t2 = (3.0 - 2.0 * Dy) * Dy * Dy; - w[3] = t1 * Dy; - w[2] = t1 * (Dy - 1.0) + t2; - w[1] = -t1 * Dy + 1.0 - t2; - w[0] = -t1 * (Dy - 1.0); - } - - rd = 0.0; - - for (int i = 0; i < 4; i++) { - rd += yr[i] * w[i]; - } - - *r = rd * mul; - } - public: enum class Median { @@ -201,7 +111,7 @@ public: double lumimul[3]; - explicit ImProcFunctions(const ProcParams* iparams, bool imultiThread = true) + explicit ImProcFunctions(const procparams::ProcParams* iparams, bool imultiThread = true) : monitorTransform(nullptr), params(iparams), scale(1), multiThread(imultiThread), lumimul{} {} ~ImProcFunctions(); bool needsLuminanceOnly() @@ -210,19 +120,24 @@ public: } void setScale(double iscale); - bool needsTransform(); - bool needsPCVignetting(); + bool needsTransform() const; + bool needsPCVignetting() const; void firstAnalysis(const Imagefloat* const working, const procparams::ProcParams ¶ms, LUTu & vhist16); void updateColorProfiles(const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck); - void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, - int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, - const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false); - void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, - int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, - const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, - double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false); - void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, LUTf & clToningcurve, LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); + void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, + const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, + const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, + const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, + const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, + const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, + int hlcomprthresh, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); void toningsmh2(float r, float g, float b, float &ro, float &go, float &bo, float low[3], float satLow, float med[3], float satMed, float high[3], float satHigh, float reducac, int mode, int preser); @@ -232,18 +147,18 @@ public: void retreavergb(float &r, float &g, float &b); void moyeqt(Imagefloat* working, float &moyS, float &eqty); - void luminanceCurve(LabImage* lold, LabImage* lnew, LUTf &curve); - void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const ProcParams* params, + void luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf &curve); + void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const procparams::ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, float &d, float &dj, float &yb, int rtt, bool showSharpMask = false); - void chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLurve); + void chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, const LUTf& acurve, const LUTf& bcurve, const LUTf& satcurve, const LUTf& satclcurve, const LUTf& clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLurve); void vibrance(LabImage* lab); //Jacques' vibrance // 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); - float resizeScale(const ProcParams* params, int fw, int fh, int &imw, int &imh); + 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); void Lanczos(const LabImage* src, LabImage* dst, float scale); @@ -309,20 +224,20 @@ public: void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi); void RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope); - void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); - void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer); //for DCT + void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); + void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); - bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); - bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, + bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); + bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); + void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, + const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); - bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); - bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, + bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); + bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); - void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, + void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); + void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, @@ -361,13 +276,13 @@ public: // CieImage *ciec; void workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, const Glib::ustring &profile, double gampos, double slpos, cmsHTRANSFORM &transform, bool normalizeIn = true, bool normalizeOut = true, bool keepTransForm = false) const; - bool transCoord(int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr); - bool transCoord(int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr); + bool transCoord(int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr) const; + bool transCoord(int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr) const; static void getAutoExp(const LUTu & histogram, int histcompr, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static double getAutoDistor(const Glib::ustring& fname, int thumb_size); - double getTransformAutoFill(int oW, int oH, const LensCorrection *pLCPMap = nullptr); + double getTransformAutoFill(int oW, int oH, const LensCorrection *pLCPMap = nullptr) const; void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace); }; + } -#endif diff --git a/rtengine/impulse_denoise.cc b/rtengine/impulse_denoise.cc index c08f55700..20229e714 100644 --- a/rtengine/impulse_denoise.cc +++ b/rtengine/impulse_denoise.cc @@ -22,7 +22,7 @@ #include "labimage.h" #include "improcfun.h" #include "cieimage.h" -#include "sleef.c" +#include "sleef.h" #include "opthelper.h" #include "gauss.h" diff --git a/rtengine/init.cc b/rtengine/init.cc index 8d3ee96cb..1a00f7ff6 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -18,6 +18,7 @@ */ #include #include "../rtgui/profilestorecombobox.h" +#include "color.h" #include "rtengine.h" #include "iccstore.h" #include "dcp.h" @@ -42,7 +43,7 @@ const Settings* settings; MyMutex* lcmsMutex = nullptr; MyMutex *fftwMutex = nullptr; -int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir, bool loadAll) +int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir, bool loadAll) { settings = s; ProcParams::init(); diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 60d4cb9ff..28a0f2d57 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ /* * Haze removal using the algorithm described in the paper: @@ -26,41 +26,126 @@ * * using a guided filter for the "soft matting" of the transmission map * - */ +*/ +#include #include -#include +#include +#include "color.h" #include "guidedfilter.h" +#include "iccstore.h" +#include "imagefloat.h" #include "improcfun.h" #include "procparams.h" -#include "rt_algo.h" +#include "rescale.h" #include "rt_math.h" -extern Options options; +#include "../rtgui/options.h" -namespace rtengine { +namespace rtengine +{ -namespace { +namespace +{ -#if 0 -# define DEBUG_DUMP(arr) \ - do { \ - Imagefloat im(arr.width(), arr.height()); \ - const char *out = "/tmp/" #arr ".tif"; \ - for (int y = 0; y < im.getHeight(); ++y) { \ - for (int x = 0; x < im.getWidth(); ++x) { \ - im.r(y, x) = im.g(y, x) = im.b(y, x) = arr[y][x] * 65535.f; \ - } \ - } \ - im.saveTIFF(out, 16); \ - } while (false) -#else -# define DEBUG_DUMP(arr) +float normalize(Imagefloat *rgb, bool multithread) +{ + float maxval = 0.f; + const int W = rgb->getWidth(); + const int H = rgb->getHeight(); +#ifdef _OPENMP + #pragma omp parallel for reduction(max:maxval) schedule(dynamic, 16) if (multithread) #endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + maxval = max(maxval, rgb->r(y, x), rgb->g(y, x), rgb->b(y, x)); + } + } + maxval = max(maxval * 2.f, 65535.f); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + rgb->r(y, x) /= maxval; + rgb->g(y, x) /= maxval; + rgb->b(y, x) /= maxval; + } + } + return maxval; +} +void restore(Imagefloat *rgb, float maxval, bool multithread) +{ + const int W = rgb->getWidth(); + const int H = rgb->getHeight(); + if (maxval > 0.f && maxval != 1.f) { +#ifdef _OPENMP +# pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + rgb->r(y, x) *= maxval; + rgb->g(y, x) *= maxval; + rgb->b(y, x) *= maxval; + } + } + } +} -int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread) +int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, const array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) +{ + const int W = R.width(); + const int H = R.height(); + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; y += patchsize) { + const int pH = min(y + patchsize, H); + for (int x = 0; x < W; x += patchsize) { + float minR = RT_INFINITY_F; + float minG = RT_INFINITY_F; + float minB = RT_INFINITY_F; +#ifdef __SSE2__ + vfloat minRv = F2V(minR); + vfloat minGv = F2V(minG); + vfloat minBv = F2V(minB); +#endif + const int pW = min(x + patchsize, W); + for (int yy = y; yy < pH; ++yy) { + int xx = x; +#ifdef __SSE2__ + for (; xx < pW - 3; xx += 4) { + minRv = vminf(minRv, LVFU(R[yy][xx])); + minGv = vminf(minGv, LVFU(G[yy][xx])); + minBv = vminf(minBv, LVFU(B[yy][xx])); + } +#endif + for (; xx < pW; ++xx) { + minR = min(minR, R[yy][xx]); + minG = min(minG, G[yy][xx]); + minB = min(minB, B[yy][xx]); + } + } +#ifdef __SSE2__ + minR = min(minR, vhmin(minRv)); + minG = min(minG, vhmin(minGv)); + minB = min(minB, vhmin(minBv)); +#endif + float val = min(minR / ambient[0], minG / ambient[1], minB / ambient[2]); + val = 1.f - strength * LIM01(val); + for (int yy = y; yy < pH; ++yy) { + std::fill(dst[yy] + x, dst[yy] + pW, val); + } + } + } + + return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); +} + +int get_dark_channel_downsized(const array2D &R, const array2D &G, const array2D &B, const array2D &dst, int patchsize, bool multithread) { const int W = R.width(); const int H = R.height(); @@ -73,22 +158,11 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr for (int x = 0; x < W; x += patchsize) { float val = RT_INFINITY_F; const int pW = min(x + patchsize, W); - for (int yy = y; yy < pH; ++yy) { - for (int xx = x; xx < pW; ++xx) { - float r = R[yy][xx]; - float g = G[yy][xx]; - float b = B[yy][xx]; - if (ambient) { - r /= ambient[0]; - g /= ambient[1]; - b /= ambient[2]; - } - val = min(val, r, g, b); + for (int xx = x; xx < pW; ++xx) { + for (int yy = y; yy < pH; ++yy) { + val = min(val, R[yy][xx], G[yy][xx], B[yy][xx]); } } - if (clip) { - val = LIM01(val); - } for (int yy = y; yy < pH; ++yy) { std::fill(dst[yy] + x, dst[yy] + pW, val); } @@ -98,33 +172,24 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); } - float estimate_ambient_light(const array2D &R, const array2D &G, const array2D &B, const array2D &dark, int patchsize, int npatches, float ambient[3]) { const int W = R.width(); const int H = R.height(); - const auto get_percentile = - [](std::priority_queue &q, float prcnt) -> float - { - size_t n = LIM(q.size() * prcnt, 1, q.size()); - while (q.size() > n) { - q.pop(); - } - return q.top(); - }; - float darklim = RT_INFINITY_F; { - std::priority_queue p; + std::vector p; for (int y = 0; y < H; y += patchsize) { for (int x = 0; x < W; x += patchsize) { if (!OOG(dark[y][x], 1.f - 1e-5f)) { - p.push(dark[y][x]); + p.push_back(dark[y][x]); } } } - darklim = get_percentile(p, 0.95); + const int pos = p.size() * 0.95; + std::nth_element(p.begin(), p.begin() + pos, p.end()); + darklim = p[pos]; } std::vector> patches; @@ -138,14 +203,15 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c } } - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "dehaze: computing ambient light from " << patches.size() << " patches" << std::endl; } float bright_lim = RT_INFINITY_F; { - std::priority_queue l; + std::vector l; + l.reserve(patches.size() * patchsize * patchsize); for (auto &p : patches) { const int pW = min(p.first+patchsize, W); @@ -153,12 +219,13 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c for (int y = p.second; y < pH; ++y) { for (int x = p.first; x < pW; ++x) { - l.push(R[y][x] + G[y][x] + B[y][x]); + l.push_back(R[y][x] + G[y][x] + B[y][x]); } } } - - bright_lim = get_percentile(l, 0.95); + const int pos = l.size() * 0.95; + std::nth_element(l.begin(), l.begin() + pos, l.end()); + bright_lim = l[pos]; } double rr = 0, gg = 0, bb = 0; @@ -190,7 +257,6 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c return darklim > 0 ? -1.125f * std::log(darklim) : std::log(std::numeric_limits::max()) / 2; } - void extract_channels(Imagefloat *img, array2D &r, array2D &g, array2D &b, int radius, float epsilon, bool multithread) { const int W = img->getWidth(); @@ -208,20 +274,19 @@ void extract_channels(Imagefloat *img, array2D &r, array2D &g, arr } // namespace - void ImProcFunctions::dehaze(Imagefloat *img) { - if (!params->dehaze.enabled) { + if (!params->dehaze.enabled || params->dehaze.strength == 0.0) { return; } - img->normalizeFloatTo1(); - + const float maxChannel = normalize(img, multiThread); + const int W = img->getWidth(); const int H = img->getHeight(); const float strength = LIM01(float(params->dehaze.strength) / 100.f * 0.9f); - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "dehaze: strength = " << strength << std::endl; } @@ -229,101 +294,143 @@ void ImProcFunctions::dehaze(Imagefloat *img) int patchsize = max(int(5 / scale), 2); float ambient[3]; - array2D &t_tilde = dark; - float max_t = 0.f; + float maxDistance = 0.f; { - int npatches = 0; - array2D R(W, H); + array2D& R = dark; // R and dark can safely use the same buffer, which is faster and reduces memory allocations/deallocations array2D G(W, H); array2D B(W, H); extract_channels(img, R, G, B, patchsize, 1e-1, multiThread); - + + { + constexpr int sizecap = 200; + const float r = static_cast(W) / static_cast(H); + const int hh = r >= 1.f ? sizecap : sizecap / r; + const int ww = r >= 1.f ? sizecap * r : sizecap; + + if (W <= ww && H <= hh) { + // don't rescale small thumbs + array2D D(W, H); + const int npatches = get_dark_channel_downsized(R, G, B, D, 2, multiThread); + maxDistance = estimate_ambient_light(R, G, B, D, patchsize, npatches, ambient); + } else { + array2D RR(ww, hh); + array2D GG(ww, hh); + array2D BB(ww, hh); + rescaleNearest(R, RR, multiThread); + rescaleNearest(G, GG, multiThread); + rescaleNearest(B, BB, multiThread); + array2D D(ww, hh); + + const int npatches = get_dark_channel_downsized(RR, GG, BB, D, 2, multiThread); + maxDistance = estimate_ambient_light(RR, GG, BB, D, patchsize, npatches, ambient); + } + } + + if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { + if (settings->verbose) { + std::cout << "dehaze: no haze detected" << std::endl; + } + restore(img, maxChannel, multiThread); + return; // probably no haze at all + } patchsize = max(max(W, H) / 600, 2); - npatches = get_dark_channel(R, G, B, dark, patchsize, nullptr, false, multiThread); - DEBUG_DUMP(dark); - max_t = estimate_ambient_light(R, G, B, dark, patchsize, npatches, ambient); - - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "dehaze: ambient light is " << ambient[0] << ", " << ambient[1] << ", " << ambient[2] << std::endl; } - get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread); - } - - if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { - if (options.rtSettings.verbose) { - std::cout << "dehaze: no haze detected" << std::endl; - } - img->normalizeFloatTo65535(); - return; // probably no haze at all - } - - DEBUG_DUMP(t_tilde); - -#ifdef _OPENMP - #pragma omp parallel for if (multiThread) -#endif - for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { - dark[y][x] = 1.f - strength * dark[y][x]; - } + get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread, strength); } const int radius = patchsize * 4; - const float epsilon = 1e-5; - array2D &t = t_tilde; + constexpr float epsilon = 1e-5f; - { - array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); - guidedFilter(guideB, t_tilde, t, radius, epsilon, multiThread); - } + array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); + guidedFilter(guideB, dark, dark, radius, epsilon, multiThread); - DEBUG_DUMP(t); - - if (options.rtSettings.verbose) { - std::cout << "dehaze: max distance is " << max_t << std::endl; + if (settings->verbose) { + std::cout << "dehaze: max distance is " << maxDistance << std::endl; } - float depth = -float(params->dehaze.depth) / 100.f; - const float t0 = max(1e-3f, std::exp(depth * max_t)); + const float depth = -float(params->dehaze.depth) / 100.f; + const float t0 = max(1e-3f, std::exp(depth * maxDistance)); const float teps = 1e-3f; + + const bool luminance = params->dehaze.luminance; + const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); +#ifdef __SSE2__ + const vfloat wsv[3] = {F2V(ws[1][0]), F2V(ws[1][1]),F2V(ws[1][2])}; +#endif + const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws); #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { + int x = 0; +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat ambient0v = F2V(ambient[0]); + const vfloat ambient1v = F2V(ambient[1]); + const vfloat ambient2v = F2V(ambient[2]); + const vfloat ambientYv = F2V(ambientY); + const vfloat epsYv = F2V(1e-5f); + const vfloat t0v = F2V(t0); + const vfloat tepsv = F2V(teps); + const vfloat cmaxChannelv = F2V(maxChannel); + for (; x < W - 3; x += 4) { // ensure that the transmission is such that to avoid clipping... - float rgb[3] = { img->r(y, x), img->g(y, x), img->b(y, x) }; + const vfloat r = LVFU(img->r(y, x)); + const vfloat g = LVFU(img->g(y, x)); + const vfloat b = LVFU(img->b(y, x)); // ... t >= tl to avoid negative values - float tl = 1.f - min(rgb[0]/ambient[0], rgb[1]/ambient[1], rgb[2]/ambient[2]); - // ... t >= tu to avoid values > 1 - float tu = t0 - teps; - for (int c = 0; c < 3; ++c) { - if (ambient[c] < 1) { - tu = max(tu, (rgb[c] - ambient[c])/(1.f - ambient[c])); - } - } - float mt = max(t[y][x], t0, tl + teps, tu + teps); + const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); + const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv + tepsv, t0v)); if (params->dehaze.showDepthMap) { - img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt); + const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * cmaxChannelv; + STVFU(img->r(y, x), valv); + STVFU(img->g(y, x), valv); + STVFU(img->b(y, x), valv); + } else if (luminance) { + const vfloat Yv = Color::rgbLuminance(r, g, b, wsv); + const vfloat YYv = (Yv - ambientYv) / mtv + ambientYv; + const vfloat fv = vself(vmaskf_gt(Yv, epsYv), cmaxChannelv * YYv / Yv, cmaxChannelv); + STVFU(img->r(y, x), r * fv); + STVFU(img->g(y, x), g * fv); + STVFU(img->b(y, x), b * fv); } else { - float r = (rgb[0] - ambient[0]) / mt + ambient[0]; - float g = (rgb[1] - ambient[1]) / mt + ambient[1]; - float b = (rgb[2] - ambient[2]) / mt + ambient[2]; - - img->r(y, x) = r; - img->g(y, x) = g; - img->b(y, x) = b; + STVFU(img->r(y, x), ((r - ambient0v) / mtv + ambient0v) * cmaxChannelv); + STVFU(img->g(y, x), ((g - ambient1v) / mtv + ambient1v) * cmaxChannelv); + STVFU(img->b(y, x), ((b - ambient2v) / mtv + ambient2v) * cmaxChannelv); + } + } +#endif + for (; x < W; ++x) { + // ensure that the transmission is such that to avoid clipping... + const float r = img->r(y, x); + const float g = img->g(y, x); + const float b = img->b(y, x); + // ... t >= tl to avoid negative values + const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]); + const float mt = max(dark[y][x], t0, tl + teps); + if (params->dehaze.showDepthMap) { + img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel; + } else if (luminance) { + const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); + const float YY = (Y - ambientY) / mt + ambientY; + const float f = Y > 1e-5f ? maxChannel * YY / Y : maxChannel; + img->r(y, x) *= f; + img->g(y, x) *= f; + img->b(y, x) *= f; + } else { + img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * maxChannel; + img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * maxChannel; + img->b(y, x) = ((b - ambient[2]) / mt + ambient[2]) * maxChannel; } } } - - img->normalizeFloatTo65535(); } - } // namespace rtengine diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 14aeb4049..1d3f2f494 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -17,13 +17,14 @@ * along with RawTherapee. If not, see . */ #include "rtengine.h" +#include "image8.h" +#include "imagefloat.h" +#include "labimage.h" #include "improcfun.h" -#include +#include #include "iccstore.h" #include "iccmatrices.h" -#include "../rtgui/options.h" #include "settings.h" -#include "curves.h" #include "alignedbuffer.h" #include "color.h" #include "procparams.h" @@ -33,8 +34,6 @@ namespace rtengine extern void filmlike_clip(float *r, float *g, float *b); -extern const Settings* settings; - namespace { inline void copyAndClampLine(const float *src, unsigned char *dst, const int W) diff --git a/rtengine/iplabregions.cc b/rtengine/iplabregions.cc index af6567c3c..6526419f5 100644 --- a/rtengine/iplabregions.cc +++ b/rtengine/iplabregions.cc @@ -18,16 +18,18 @@ * along with RawTherapee. If not, see . */ -#ifdef _OPENMP -#include -#endif - -#include "improcfun.h" +#include "array2D.h" +#include "color.h" +#include "curves.h" #include "guidedfilter.h" +#include "iccstore.h" +#include "improcfun.h" +#include "labimage.h" #include "procparams.h" +#include "sleef.h" + //#define BENCHMARK #include "StopWatch.h" -#include "sleef.c" namespace { @@ -51,7 +53,8 @@ void fastlin2log(float *x, float factor, float base, int w) } -namespace rtengine { +namespace rtengine +{ void ImProcFunctions::labColorCorrectionRegions(LabImage *lab) { diff --git a/rtengine/iplocalcontrast.cc b/rtengine/iplocalcontrast.cc index 6143f48a3..daeb142dd 100644 --- a/rtengine/iplocalcontrast.cc +++ b/rtengine/iplocalcontrast.cc @@ -22,16 +22,14 @@ * along with RawTherapee. If not, see . */ -#ifdef _OPENMP -#include -#endif - #include "array2D.h" #include "gauss.h" +#include "labimage.h" #include "improcfun.h" #include "procparams.h" -namespace rtengine { +namespace rtengine +{ void ImProcFunctions::localContrast(LabImage *lab) { diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index 0c1fb1ad8..b9e234b63 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -20,10 +20,12 @@ #include "improcfun.h" #include "alignedbuffer.h" +#include "imagefloat.h" +#include "labimage.h" #include "opthelper.h" #include "rt_math.h" #include "procparams.h" -#include "sleef.c" +#include "sleef.h" //#define PROFILE diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 7117c9f2a..84f33482f 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -41,17 +41,19 @@ #include #include +#include "color.h" +#include "curves.h" #include "gauss.h" #include "improcfun.h" +#include "jaggedarray.h" #include "median.h" #include "opthelper.h" #include "procparams.h" #include "rawimagesource.h" #include "rtengine.h" +#include "shmap.h" #include "StopWatch.h" -#define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) - namespace { void retinex_scales( float* scales, int nscales, int mode, int s, float high) @@ -136,362 +138,422 @@ void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, floa namespace rtengine { -extern const Settings* settings; - -void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, const RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) +void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, const LUTf& mapcurve, bool mapcontlutili, int width, int height, const procparams::RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) { +BENCHFUN + if (!deh.enabled) { + return; + } - if (deh.enabled) {//enabled - float maxtr, mintr; - constexpr float eps = 2.f; - bool useHsl = deh.retinexcolorspace == "HSLLOG"; - bool useHslLin = deh.retinexcolorspace == "HSLLIN"; - float offse = (float) deh.offs; //def = 0 not use - int iter = deh.iter; - int gradient = deh.scal; - int scal = 3;//disabled scal - int nei = (int) (2.8f * deh.neigh); //def = 220 - float vart = (float)deh.vart / 100.f;//variance - float gradvart = (float)deh.grad; - float gradstr = (float)deh.grads; - float strength = (float) deh.str / 100.f; // Blend with original L channel data - float limD = (float) deh.limd; - limD = pow(limD, 1.7f);//about 2500 enough - limD *= useHslLin ? 10.f : 1.f; - float ilimD = 1.f / limD; - float hig = ((float) deh.highl) / 100.f; - scal = deh.skal; + constexpr float eps = 2.f; + const bool useHsl = deh.retinexcolorspace == "HSLLOG"; + const bool useHslLin = deh.retinexcolorspace == "HSLLIN"; + const float offse = deh.offs; //def = 0 not use + const int iter = deh.iter; + const int gradient = deh.scal; + int scal = deh.skal; + const int nei = 2.8f * deh.neigh; //def = 220 + const float vart = deh.vart / 100.f;//variance + const float gradvart = deh.grad; + const float gradstr = deh.grads; + const float strength = deh.str / 100.f; // Blend with original L channel data + float limD = deh.limd; + limD = pow(limD, 1.7f);//about 2500 enough + limD *= useHslLin ? 10.f : 1.f; + const float ilimD = 1.f / limD; + const float hig = deh.highl / 100.f; - int H_L = height; - int W_L = width; + const int H_L = height; + const int W_L = width; - float *tran[H_L] ALIGNED16; - float *tranBuffer = nullptr; + constexpr float elogt = 2.71828f; + bool lhutili = false; - constexpr float elogt = 2.71828f; - bool lhutili = false; + FlatCurve* shcurve = new FlatCurve(deh.lhcurve); //curve L=f(H) - FlatCurve* shcurve = new FlatCurve(deh.lhcurve); //curve L=f(H) - - if (!shcurve || shcurve->isIdentity()) { - if (shcurve) { - delete shcurve; - shcurve = nullptr; - } - } else { - lhutili = true; + if (!shcurve || shcurve->isIdentity()) { + if (shcurve) { + delete shcurve; + shcurve = nullptr; } + } else { + lhutili = true; + } - bool higplus = false ; - int moderetinex = 2; // default to 2 ( deh.retinexMethod == "high" ) + bool higplus = false ; + int moderetinex = 2; // default to 2 ( deh.retinexMethod == "high" ) - if(deh.retinexMethod == "highliplus") { - higplus = true; - moderetinex = 3; - } else if (deh.retinexMethod == "uni") { - moderetinex = 0; - } else if (deh.retinexMethod == "low") { - moderetinex = 1; - } else { /*if (deh.retinexMethod == "highli") */ - moderetinex = 3; - } + if(deh.retinexMethod == "highliplus") { + higplus = true; + moderetinex = 3; + } else if (deh.retinexMethod == "uni") { + moderetinex = 0; + } else if (deh.retinexMethod == "low") { + moderetinex = 1; + } else { /*if (deh.retinexMethod == "highli") */ + moderetinex = 3; + } - constexpr float aahi = 49.f / 99.f; ////reduce sensibility 50% - constexpr float bbhi = 1.f - aahi; + constexpr float aahi = 49.f / 99.f; ////reduce sensibility 50% + constexpr float bbhi = 1.f - aahi; + float high = bbhi + aahi * (float) deh.highl; - for(int it = 1; it < iter + 1; it++) { //iter nb max of iterations - float high = bbhi + aahi * (float) deh.highl; + for (int it = 1; it < iter + 1; it++) { //iter nb max of iterations + float grad = 1.f; + float sc = scal; - float grad = 1.f; - float sc = scal; - - if(gradient == 0) { - grad = 1.f; - sc = 3.f; - } else if(gradient == 1) { - grad = 0.25f * it + 0.75f; - sc = -0.5f * it + 4.5f; - } else if(gradient == 2) { - grad = 0.5f * it + 0.5f; - sc = -0.75f * it + 5.75f; - } else if(gradient == 3) { - grad = 0.666f * it + 0.333f; - sc = -0.75f * it + 5.75f; - } else if(gradient == 4) { - grad = 0.8f * it + 0.2f; - sc = -0.75f * it + 5.75f; - } else if(gradient == 5) { - if(moderetinex != 3) { - grad = 2.5f * it - 1.5f; - } else { - float aa = (11.f * high - 1.f) / 4.f; - float bb = 1.f - aa; - grad = aa * it + bb; - } - - sc = -0.75f * it + 5.75f; - } else if(gradient == 6) { - if(moderetinex != 3) { - grad = 5.f * it - 4.f; - } else { - float aa = (21.f * high - 1.f) / 4.f; - float bb = 1.f - aa; - grad = aa * it + bb; - } - - sc = -0.75f * it + 5.75f; - } - - else if(gradient == -1) { - grad = -0.125f * it + 1.125f; - sc = 3.f; - } - - if(iter == 1) { - sc = scal; + if (gradient == 0) { + grad = 1.f; + sc = 3.f; + } else if (gradient == 1) { + grad = 0.25f * it + 0.75f; + sc = -0.5f * it + 4.5f; + } else if (gradient == 2) { + grad = 0.5f * it + 0.5f; + sc = -0.75f * it + 5.75f; + } else if (gradient == 3) { + grad = 0.666f * it + 0.333f; + sc = -0.75f * it + 5.75f; + } else if (gradient == 4) { + grad = 0.8f * it + 0.2f; + sc = -0.75f * it + 5.75f; + } else if (gradient == 5) { + if (moderetinex != 3) { + grad = 2.5f * it - 1.5f; } else { - //adjust sc in function of choice of scale by user if iterations - if(scal < 3) { - sc -= 1; + float aa = (11.f * high - 1.f) / 4.f; + float bb = 1.f - aa; + grad = aa * it + bb; + } - if(sc < 1.f) {//avoid 0 - sc = 1.f; - } + sc = -0.75f * it + 5.75f; + } else if (gradient == 6) { + if (moderetinex != 3) { + grad = 5.f * it - 4.f; + } else { + float aa = (21.f * high - 1.f) / 4.f; + float bb = 1.f - aa; + grad = aa * it + bb; + } + + sc = -0.75f * it + 5.75f; + } else if (gradient == -1) { + grad = -0.125f * it + 1.125f; + sc = 3.f; + } + + if (iter == 1) { + sc = scal; + } else { + //adjust sc in function of choice of scale by user if iterations + if (scal < 3) { + sc -= 1; + if (sc < 1.f) {//avoid 0 + sc = 1.f; } + } else if (scal > 4) { + sc += 1; + } + } - if(scal > 4) { - sc += 1; + float varx = vart; + float limdx = limD; + float ilimdx = ilimD; + + if (gradvart != 0) { + if (gradvart == 1) { + varx = vart * (-0.125f * it + 1.125f); + limdx = limD * (-0.125f * it + 1.125f); + ilimdx = 1.f / limdx; + } else if (gradvart == 2) { + varx = vart * (-0.2f * it + 1.2f); + limdx = limD * (-0.2f * it + 1.2f); + ilimdx = 1.f / limdx; + } else if (gradvart == -1) { + varx = vart * (0.125f * it + 0.875f); + limdx = limD * (0.125f * it + 0.875f); + ilimdx = 1.f / limdx; + } else if (gradvart == -2) { + varx = vart * (0.4f * it + 0.6f); + limdx = limD * (0.4f * it + 0.6f); + ilimdx = 1.f / limdx; + } + } + + scal = round(sc); + float ks = 1.f; + + if (gradstr != 0) { + if (gradstr == 1) { + if (it <= 3) { + ks = -0.3f * it + 1.6f; + } else { + ks = 0.5f; + } + } else if (gradstr == 2) { + if (it <= 3) { + ks = -0.6f * it + 2.2f; + } else { + ks = 0.3f; + } + } else if (gradstr == -1) { + if (it <= 3) { + ks = 0.2f * it + 0.6f; + } else { + ks = 1.2f; + } + } else if (gradstr == -2) { + if (it <= 3) { + ks = 0.4f * it + 0.2f; + } else { + ks = 1.5f; } } + } - float varx = vart; - float limdx = limD; - float ilimdx = ilimD; + const float strengthx = ks * strength; - if(gradvart != 0) { - if(gradvart == 1) { - varx = vart * (-0.125f * it + 1.125f); - limdx = limD * (-0.125f * it + 1.125f); - ilimdx = 1.f / limdx; - } else if(gradvart == 2) { - varx = vart * (-0.2f * it + 1.2f); - limdx = limD * (-0.2f * it + 1.2f); - ilimdx = 1.f / limdx; - } else if(gradvart == -1) { - varx = vart * (0.125f * it + 0.875f); - limdx = limD * (0.125f * it + 0.875f); - ilimdx = 1.f / limdx; - } else if(gradvart == -2) { - varx = vart * (0.4f * it + 0.6f); - limdx = limD * (0.4f * it + 0.6f); - ilimdx = 1.f / limdx; - } - } + constexpr auto maxRetinexScales = 8; + float RetinexScales[maxRetinexScales]; - scal = round(sc); - float ks = 1.f; + retinex_scales(RetinexScales, scal, moderetinex, nei / grad, high); - if(gradstr != 0) { - if(gradstr == 1) { - if(it <= 3) { - ks = -0.3f * it + 1.6f; - } else { - ks = 0.5f; - } - } else if(gradstr == 2) { - if(it <= 3) { - ks = -0.6f * it + 2.2f; - } else { - ks = 0.3f; - } - } else if(gradstr == -1) { - if(it <= 3) { - ks = 0.2f * it + 0.6f; - } else { - ks = 1.2f; - } - } else if(gradstr == -2) { - if(it <= 3) { - ks = 0.4f * it + 0.2f; - } else { - ks = 1.5f; - } - } - } + const int shHighlights = deh.highlights; + const int shShadows = deh.shadows; - float strengthx = ks * strength; + int mapmet = 0; - constexpr auto maxRetinexScales = 8; - float RetinexScales[maxRetinexScales]; + if(deh.mapMethod == "map") { + mapmet = 2; + } else if(deh.mapMethod == "mapT") { + mapmet = 3; + } else if(deh.mapMethod == "gaus") { + mapmet = 4; + } - retinex_scales( RetinexScales, scal, moderetinex, nei / grad, high ); + const double shradius = mapmet == 4 ? (double) deh.radius : 40.; - float *src[H_L] ALIGNED16; - float *srcBuffer = new float[H_L * W_L]; + int viewmet = 0; - for (int i = 0; i < H_L; i++) { - src[i] = &srcBuffer[i * W_L]; - } + if(deh.viewMethod == "mask") { + viewmet = 1; + } else if(deh.viewMethod == "tran") { + viewmet = 2; + } else if(deh.viewMethod == "tran2") { + viewmet = 3; + } else if(deh.viewMethod == "unsharp") { + viewmet = 4; + } - int h_th = 0, s_th = 0; - - int shHighlights = deh.highlights; - int shShadows = deh.shadows; - - int mapmet = 0; - - if(deh.mapMethod == "map") { - mapmet = 2; - } else if(deh.mapMethod == "mapT") { - mapmet = 3; - } else if(deh.mapMethod == "gaus") { - mapmet = 4; - } - - const double shradius = mapmet == 4 ? (double) deh.radius : 40.; - - int viewmet = 0; - - if(deh.viewMethod == "mask") { - viewmet = 1; - } else if(deh.viewMethod == "tran") { - viewmet = 2; - } else if(deh.viewMethod == "tran2") { - viewmet = 3; - } else if(deh.viewMethod == "unsharp") { - viewmet = 4; - } + std::unique_ptr> srcBuffer(new JaggedArray(W_L, H_L)); + float** src = *(srcBuffer.get()); #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int i = 0; i < H_L; i++) - for (int j = 0; j < W_L; j++) { - src[i][j] = luminance[i][j] + eps; - luminance[i][j] = 0.f; - } - - float *out[H_L] ALIGNED16; - float *outBuffer = new float[H_L * W_L]; - - for (int i = 0; i < H_L; i++) { - out[i] = &outBuffer[i * W_L]; + for (int i = 0; i < H_L; i++) + for (int j = 0; j < W_L; j++) { + src[i][j] = luminance[i][j] + eps; + luminance[i][j] = 0.f; } - if(viewmet == 3 || viewmet == 2) { - tranBuffer = new float[H_L * W_L]; + JaggedArray out(W_L, H_L); + JaggedArray& tran = out; // tran and out can safely use the same buffer - for (int i = 0; i < H_L; i++) { - tran[i] = &tranBuffer[i * W_L]; - } - } + const float logBetaGain = xlogf(16384.f); + float pond = logBetaGain / (float) scal; - const float logBetaGain = xlogf(16384.f); - float pond = logBetaGain / (float) scal; + if(!useHslLin) { + pond /= log(elogt); + } - if(!useHslLin) { - pond /= log(elogt); - } + std::unique_ptr shmap; + if (((mapmet == 2 || mapmet == 3 || mapmet == 4) && it == 1)) { + shmap.reset(new SHMap(W_L, H_L)); + } - auto shmap = ((mapmet == 2 || mapmet == 3 || mapmet == 4) && it == 1) ? new SHMap (W_L, H_L) : nullptr; + std::unique_ptr buffer; + if (mapmet > 0) { + buffer.reset(new float[W_L * H_L]); + } - float *buffer = new float[W_L * H_L];; - - for ( int scale = scal - 1; scale >= 0; scale-- ) { -#ifdef _OPENMP - #pragma omp parallel -#endif - { - if(scale == scal - 1) - { - gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer); - } else { // reuse result of last iteration - // out was modified in last iteration => restore it - if((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1) - { -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H_L; i++) { - for (int j = 0; j < W_L; j++) { - out[i][j] = buffer[i * W_L + j]; - } - } - } - - gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); - } - if((((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1 && scale > 0) - { - // out will be modified => store it for use in next iteration. We even don't need a new buffer because 'buffer' is free after gaussianBlur :) -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H_L; i++) { - for (int j = 0; j < W_L; j++) { - buffer[i * W_L + j] = out[i][j]; - } - } - } - } - - if(((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) && it == 1) { - shmap->updateL (out, shradius, true, 1); - h_th = shmap->max_f - deh.htonalwidth * (shmap->max_f - shmap->avg) / 100; - s_th = deh.stonalwidth * (shmap->avg - shmap->min_f) / 100; - } - -#ifdef __SSE2__ - vfloat pondv = F2V(pond); - vfloat limMinv = F2V(ilimdx); - vfloat limMaxv = F2V(limdx); - -#endif - - if(mapmet > 0 && mapcontlutili && it == 1) { - // TODO: When rgbcurvespeedup branch is merged into master we can simplify the code by - // 1) in rawimagesource.retinexPrepareCurves() insert - // mapcurve *= 0.5f; - // after - // CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); - // 2) remove the division by 2.f from the code 7 lines below this line + for (int scale = scal - 1; scale >= 0; --scale) { + if (scale == scal - 1) { + gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], true); + } else { // reuse result of last iteration + // out was modified in last iteration => restore it + if((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1) { #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < H_L; i++) { for (int j = 0; j < W_L; j++) { - out[i][j] = mapcurve[2.f * out[i][j]] / 2.f; + out[i][j] = buffer[i * W_L + j]; } } - } - if(((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) && it == 1) { - float hWeight = (100.f - shHighlights) / 100.f; - float sWeight = (100.f - shShadows) / 100.f; + gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), true); + } + + if ((((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1 && scale > 0) { + // out will be modified => store it for use in next iteration. #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) + #pragma omp parallel for #endif - for (int i = 0; i < H_L; i++) { - for (int j = 0; j < W_L; j++) { - float mapval = 1.f + shmap->map[i][j]; - float factor = 1.f; + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + buffer[i * W_L + j] = out[i][j]; + } + } + } + int h_th = 0; + int s_th = 0; + if (((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) && it == 1) { + shmap->updateL(out, shradius, true, 1); + h_th = shmap->max_f - deh.htonalwidth * (shmap->max_f - shmap->avg) / 100; + s_th = deh.stonalwidth * (shmap->avg - shmap->min_f) / 100; + } - if (mapval > h_th) { - factor = (h_th + hWeight * (mapval - h_th)) / mapval; - } else if (mapval < s_th) { - factor = (s_th - sWeight * (s_th - mapval)) / mapval; - } + if (mapmet > 0 && mapcontlutili && it == 1) { +#ifdef _OPENMP + #pragma omp parallel for +#endif - out[i][j] *= factor; + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + out[i][j] = mapcurve[2.f * out[i][j]]; + } + } + } + + if (((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) && it == 1) { + const float hWeight = (100.f - shHighlights) / 100.f; + const float sWeight = (100.f - shShadows) / 100.f; +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + const float mapval = 1.f + shmap->map[i][j]; + float factor; + + if (mapval > h_th) { + factor = (h_th + hWeight * (mapval - h_th)) / mapval; + } else if (mapval < s_th) { + factor = (s_th - sWeight * (s_th - mapval)) / mapval; + } else { + factor = 1.f; } + + out[i][j] *= factor; + } + } + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i++) { + int j = 0; + +#ifdef __SSE2__ + const vfloat pondv = F2V(pond); + const vfloat limMinv = F2V(ilimdx); + const vfloat limMaxv = F2V(limdx); + if( useHslLin) { + for (; j < W_L - 3; j += 4) { + STVFU(luminance[i][j], LVFU(luminance[i][j]) + pondv * vclampf(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv)); + } + } else { + for (; j < W_L - 3; j += 4) { + STVFU(luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(vclampf(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv))); + } + } + +#endif + + if(useHslLin) { + for (; j < W_L; j++) { + luminance[i][j] += pond * LIM(src[i][j] / out[i][j], ilimdx, limdx); + } + } else { + for (; j < W_L; j++) { + luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ? + } + } + } + } + + srcBuffer.reset(); + + float mean = 0.f; + float stddv = 0.f; + // I call mean_stddv2 instead of mean_stddv ==> logBetaGain + + float maxtr, mintr; + mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr); + //printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); + + //mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr); + if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve + float asig = 0.166666f / stddv; + float bsig = 0.5f - asig * mean; + float amax = 0.333333f / (maxtr - mean - stddv); + float bmax = 1.f - amax * maxtr; + float amin = 0.333333f / (mean - stddv - mintr); + float bmin = -amin * mintr; + + asig *= 500.f; + bsig *= 500.f; + amax *= 500.f; + bmax *= 500.f; + amin *= 500.f; + bmin *= 500.f; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int i = 0; i < H_L; i++ ) { + for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission + float absciss; + if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { + absciss = asig * luminance[i][j] + bsig; + } else if (luminance[i][j] >= mean) { + absciss = amax * luminance[i][j] + bmax; + } else { /*if(luminance[i][j] <= mean - stddv)*/ + absciss = amin * luminance[i][j] + bmin; + } + + //TODO : move multiplication by 4.f and subtraction of 1.f inside the curve + luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission + + if(viewmet == 3 || viewmet == 2) { + tran[i][j] = luminance[i][j]; + } + } + } + + // median filter on transmission ==> reduce artifacts + if (deh.medianmap && it == 1) { //only one time + JaggedArray tmL(W_L, H_L); + constexpr int borderL = 1; + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = borderL; i < H_L - borderL; i++) { + for (int j = borderL; j < W_L - borderL; j++) { + tmL[i][j] = median(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3 } } @@ -499,307 +561,164 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e #pragma omp parallel for #endif - for (int i = 0; i < H_L; i++) { - int j = 0; - -#ifdef __SSE2__ - - if(useHslLin) { - for (; j < W_L - 3; j += 4) { - _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (vclampf(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); - } - } else { - for (; j < W_L - 3; j += 4) { - _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(vclampf(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); - } - } - -#endif - - if(useHslLin) { - for (; j < W_L; j++) { - luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimdx, limdx)); - } - } else { - for (; j < W_L; j++) { - luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ? - } + for (int i = borderL; i < H_L - borderL; i++ ) { + for (int j = borderL; j < W_L - borderL; j++) { + luminance[i][j] = tmL[i][j]; } } } - if(mapmet > 1) { - if(shmap) { - delete shmap; - } - } - - shmap = nullptr; - - delete [] buffer; - delete [] srcBuffer; - - float mean = 0.f; - float stddv = 0.f; // I call mean_stddv2 instead of mean_stddv ==> logBetaGain + //mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr); + mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr); + } - mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); - //printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); + constexpr float epsil = 0.1f; - //mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr); - if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve - float asig = 0.166666f / stddv; - float bsig = 0.5f - asig * mean; - float amax = 0.333333f / (maxtr - mean - stddv); - float bmax = 1.f - amax * maxtr; - float amin = 0.333333f / (mean - stddv - mintr); - float bmin = -amin * mintr; + mini = mean - varx * stddv; - asig *= 500.f; - bsig *= 500.f; - amax *= 500.f; - bmax *= 500.f; - amin *= 500.f; - bmin *= 500.f; + if (mini < mintr) { + mini = mintr + epsil; + } -#ifdef _OPENMP - #pragma omp parallel -#endif - { - float absciss; -#ifdef _OPENMP - #pragma omp for schedule(dynamic,16) -#endif + maxi = mean + varx * stddv; - for (int i = 0; i < H_L; i++ ) - for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission - if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { - absciss = asig * luminance[i][j] + bsig; - } else if (luminance[i][j] >= mean) { - absciss = amax * luminance[i][j] + bmax; - } else { /*if(luminance[i][j] <= mean - stddv)*/ - absciss = amin * luminance[i][j] + bmin; - } + if (maxi > maxtr) { + maxi = maxtr - epsil; + } - //TODO : move multiplication by 4.f and subtraction of 1.f inside the curve - luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission + float delta = maxi - mini; + //printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); - if(viewmet == 3 || viewmet == 2) { - tran[i][j] = luminance[i][j]; - } - } - } + if ( !delta ) { + delta = 1.0f; + } - // median filter on transmission ==> reduce artifacts - if (deh.medianmap && it == 1) { //only one time - int wid = W_L; - int hei = H_L; - float *tmL[hei] ALIGNED16; - float *tmLBuffer = new float[wid * hei]; - int borderL = 1; - - for (int i = 0; i < hei; i++) { - tmL[i] = &tmLBuffer[i * wid]; - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = borderL; i < hei - borderL; i++) { - for (int j = borderL; j < wid - borderL; j++) { - tmL[i][j] = median(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3 - } - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = borderL; i < hei - borderL; i++ ) { - for (int j = borderL; j < wid - borderL; j++) { - luminance[i][j] = tmL[i][j]; - } - } - - delete [] tmLBuffer; - - } - - // I call mean_stddv2 instead of mean_stddv ==> logBetaGain - //mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr); - mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); - - } - - float epsil = 0.1f; - - mini = mean - varx * stddv; - - if (mini < mintr) { - mini = mintr + epsil; - } - - maxi = mean + varx * stddv; - - if (maxi > maxtr) { - maxi = maxtr - epsil; - } - - float delta = maxi - mini; - //printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); - - if ( !delta ) { - delta = 1.0f; - } - - float cdfactor = 32768.f / delta; - maxCD = -9999999.f; - minCD = 9999999.f; - // coeff for auto "transmission" with 2 sigma #95% data - float aza = 16300.f / (2.f * stddv); - float azb = -aza * (mean - 2.f * stddv); - float bza = 16300.f / (2.f * stddv); - float bzb = 16300.f - bza * (mean); + // coeff for auto "transmission" with 2 sigma #95% data + const float aza = 16300.f / (2.f * stddv); + const float azb = -aza * (mean - 2.f * stddv); + const float bza = 16300.f / (2.f * stddv); + const float bzb = 16300.f - bza * (mean); //prepare work for curve gain #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int i = 0; i < H_L; i++) { - for (int j = 0; j < W_L; j++) { - luminance[i][j] = luminance[i][j] - mini; - } + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + luminance[i][j] = luminance[i][j] - mini; } + } - mean = 0.f; - stddv = 0.f; - // I call mean_stddv2 instead of mean_stddv ==> logBetaGain + mean = 0.f; + stddv = 0.f; + // I call mean_stddv2 instead of mean_stddv ==> logBetaGain - mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); - float asig = 0.f, bsig = 0.f, amax = 0.f, bmax = 0.f, amin = 0.f, bmin = 0.f; + mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr); + float asig = 0.f, bsig = 0.f, amax = 0.f, bmax = 0.f, amin = 0.f, bmin = 0.f; - if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve - asig = 0.166666f / stddv; - bsig = 0.5f - asig * mean; - amax = 0.333333f / (maxtr - mean - stddv); - bmax = 1.f - amax * maxtr; - amin = 0.333333f / (mean - stddv - mintr); - bmin = -amin * mintr; + if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve + asig = 0.166666f / stddv; + bsig = 0.5f - asig * mean; + amax = 0.333333f / (maxtr - mean - stddv); + bmax = 1.f - amax * maxtr; + amin = 0.333333f / (mean - stddv - mintr); + bmin = -amin * mintr; - asig *= 500.f; - bsig *= 500.f; - amax *= 500.f; - bmax *= 500.f; - amin *= 500.f; - bmin *= 500.f; - } + asig *= 500.f; + bsig *= 500.f; + amax *= 500.f; + bmax *= 500.f; + amin *= 500.f; + bmin *= 500.f; + } + + const float cdfactor = 32768.f / delta; + maxCD = -9999999.f; + minCD = 9999999.f; #ifdef _OPENMP - #pragma omp parallel -#endif - { - float cdmax = -999999.f, cdmin = 999999.f; -#ifdef _OPENMP - #pragma omp for schedule(dynamic,16) nowait + #pragma omp parallel for reduction(max:maxCD) reduction(min:minCD) schedule(dynamic, 16) #endif - for ( int i = 0; i < H_L; i ++ ) - for (int j = 0; j < W_L; j++) { - float gan; + for ( int i = 0; i < H_L; i ++ ) { + for (int j = 0; j < W_L; j++) { + float gan; - if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { - float absciss; - - if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { - absciss = asig * luminance[i][j] + bsig; - } else if (luminance[i][j] >= mean) { - absciss = amax * luminance[i][j] + bmax; - } else { /*if(luminance[i][j] <= mean - stddv)*/ - absciss = amin * luminance[i][j] + bmin; - } - - - // float cd = cdfactor * ( luminance[i][j] - mini ) + offse; - // TODO : move multiplication by 2.f inside the curve - gan = 2.f * (dehagaintransmissionCurve[absciss]); //new gain function transmission - } else { - gan = 0.5f; - } - - float cd = gan * cdfactor * ( luminance[i][j] ) + offse; - - cdmax = cd > cdmax ? cd : cdmax; - cdmin = cd < cdmin ? cd : cdmin; - - float str = strengthx; - - if(lhutili && it == 1) { // S=f(H) - { - float HH = exLuminance[i][j]; - float valparam; - - if(useHsl || useHslLin) { - valparam = float((shcurve->getVal(HH) - 0.5f)); - } else { - valparam = float((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); - } - - str *= (1.f + 2.f * valparam); - } - } - - if(higplus && exLuminance[i][j] > 65535.f * hig) { - str *= hig; - } - - if(viewmet == 0) { - luminance[i][j] = intp(str, clipretinex( cd, 0.f, 32768.f ), originalLuminance[i][j]); - } else if(viewmet == 1) { - luminance[i][j] = out[i][j]; - } else if(viewmet == 4) { - luminance[i][j] = originalLuminance[i][j] + str * (originalLuminance[i][j] - out[i][j]);//unsharp - } else if(viewmet == 2) { - if(tran[i][j] <= mean) { - luminance[i][j] = azb + aza * tran[i][j]; //auto values - } else { - luminance[i][j] = bzb + bza * tran[i][j]; - } - } else { /*if(viewmet == 3) */ - luminance[i][j] = 1000.f + tran[i][j] * 700.f; //arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5 - } + if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { + float absciss; + if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { + absciss = asig * luminance[i][j] + bsig; + } else if (luminance[i][j] >= mean) { + absciss = amax * luminance[i][j] + bmax; + } else { /*if(luminance[i][j] <= mean - stddv)*/ + absciss = amin * luminance[i][j] + bmin; } -#ifdef _OPENMP - #pragma omp critical -#endif - { - maxCD = maxCD > cdmax ? maxCD : cdmax; - minCD = minCD < cdmin ? minCD : cdmin; + + // float cd = cdfactor * ( luminance[i][j] - mini ) + offse; + // TODO : move multiplication by 2.f inside the curve + gan = 2.f * dehagaintransmissionCurve[absciss]; //new gain function transmission + } else { + gan = 0.5f; + } + + const float cd = gan * cdfactor * luminance[i][j] + offse; + + maxCD = cd > maxCD ? cd : maxCD; + minCD = cd < minCD ? cd : minCD; + + float str = strengthx; + + if (lhutili && it == 1) { // S=f(H) + { + const float HH = exLuminance[i][j]; + float valparam; + + if(useHsl || useHslLin) { + valparam = shcurve->getVal(HH) - 0.5f; + } else { + valparam = shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f; + } + + str *= (1.f + 2.f * valparam); + } + } + + if (higplus && exLuminance[i][j] > 65535.f * hig) { + str *= hig; + } + + if (viewmet == 0) { + luminance[i][j] = intp(str, LIM(cd, 0.f, 32768.f), originalLuminance[i][j]); + } else if (viewmet == 1) { + luminance[i][j] = out[i][j]; + } else if (viewmet == 4) { + luminance[i][j] = originalLuminance[i][j] + str * (originalLuminance[i][j] - out[i][j]);//unsharp + } else if (viewmet == 2) { + if(tran[i][j] <= mean) { + luminance[i][j] = azb + aza * tran[i][j]; //auto values + } else { + luminance[i][j] = bzb + bza * tran[i][j]; + } + } else { /*if (viewmet == 3) */ + luminance[i][j] = 1000.f + tran[i][j] * 700.f; //arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5 } } - - delete [] outBuffer; - outBuffer = nullptr; - //printf("cdmin=%f cdmax=%f\n",minCD, maxCD); - Tmean = mean; - Tsigma = stddv; - Tmin = mintr; - Tmax = maxtr; - - if (shcurve) { - delete shcurve; - shcurve = nullptr; - } } - if(tranBuffer) { - delete [] tranBuffer; - } + Tmean = mean; + Tsigma = stddv; + Tmin = mintr; + Tmax = maxtr; + if (shcurve) { + delete shcurve; + shcurve = nullptr; + } } } diff --git a/rtengine/ipshadowshighlights.cc b/rtengine/ipshadowshighlights.cc index cddc8734b..5c5b6b324 100644 --- a/rtengine/ipshadowshighlights.cc +++ b/rtengine/ipshadowshighlights.cc @@ -20,13 +20,19 @@ #include "improcfun.h" +#include "array2D.h" +#include "color.h" +#include "curves.h" #include "gauss.h" #include "guidedfilter.h" +#include "iccstore.h" +#include "labimage.h" #include "opthelper.h" #include "procparams.h" -#include "sleef.c" +#include "sleef.h" -namespace rtengine { +namespace rtengine +{ void ImProcFunctions::shadowsHighlights(LabImage *lab) { diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index bbd1de155..a35476d3a 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -17,22 +17,27 @@ * along with RawTherapee. If not, see . */ -#include "improcfun.h" -#include "gauss.h" #include "bilateral2.h" +#include "cieimage.h" +#include "gauss.h" +#include "improcfun.h" #include "jaggedarray.h" -#include "rt_math.h" -#include "procparams.h" -#include "sleef.c" +#include "labimage.h" #include "opthelper.h" +#include "procparams.h" +#include "rt_algo.h" +#include "rt_math.h" +#include "settings.h" +#include "sleef.h" + //#define BENCHMARK #include "StopWatch.h" -#include "rt_algo.h" + using namespace std; namespace { -void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, float** blend, int W, int H, const SharpeningParams &sharpenParam) +void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, float** blend, int W, int H, const procparams::SharpeningParams &sharpenParam) { const float scale = (100.f - sharpenParam.halocontrol_amount) * 0.01f; @@ -156,9 +161,7 @@ void dcdamping (float** aI, float** aO, float damping, int W, int H) namespace rtengine { -extern const Settings* settings; - -void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, const SharpeningParams &sharpenParam, double Scale) +void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale) { if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { return; @@ -207,13 +210,13 @@ BENCHFUN for (int k = 0; k < sharpenParam.deconviter; k++) { if (!needdamp) { // apply gaussian blur and divide luminance by result of gaussian blur - gaussianBlur(tmpI, tmp, W, H, sigma, nullptr, GAUSS_DIV, luminance); + gaussianBlur(tmpI, tmp, W, H, sigma, false, GAUSS_DIV, luminance); } else { // apply gaussian blur + damping gaussianBlur(tmpI, tmp, W, H, sigma); dcdamping(tmp, luminance, damping, W, H); } - gaussianBlur(tmp, tmpI, W, H, sigma, nullptr, GAUSS_MULT); + gaussianBlur(tmp, tmpI, W, H, sigma, false, GAUSS_MULT); } // end for #ifdef _OPENMP @@ -241,7 +244,7 @@ BENCHFUN delete blurbuffer; } -void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpenParam, bool showMask) +void ImProcFunctions::sharpening (LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask) { if ((!sharpenParam.enabled) || sharpenParam.amount < 1 || lab->W < 8 || lab->H < 8) { diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc index c7a4d1af7..41d0d48bf 100644 --- a/rtengine/ipsoftlight.cc +++ b/rtengine/ipsoftlight.cc @@ -3,6 +3,7 @@ * This file is part of RawTherapee. * * Copyright 2018 Alberto Griggio + * Optimized 2019 Ingo Weyrich * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,59 +19,116 @@ * along with RawTherapee. If not, see . */ -#ifdef _OPENMP -#include -#endif - +#include "color.h" +#include "iccstore.h" #include "improcfun.h" +#include "labimage.h" #include "procparams.h" -namespace rtengine { - namespace { inline float sl(float blend, float x) { - if (!OOG(x)) { - const float orig = 1.f - blend; - float v = Color::gamma_srgb(x) / MAXVALF; - // Pegtop's formula from + if (!rtengine::OOG(x)) { + float v = rtengine::Color::gamma_srgb(x) / rtengine::MAXVALF; + // using Pegtop's formula from // https://en.wikipedia.org/wiki/Blend_modes#Soft_Light - float v2 = v * v; - float v22 = v2 * 2.f; - v = v2 + v22 - v22 * v; - x = blend * Color::igamma_srgb(v * MAXVALF) + orig * x; + // const float orig = 1.f - blend; + // float v2 = v * v; + // float v22 = v2 * 2.f; + // v = v2 + v22 - v22 * v; + // return blend * Color::igamma_srgb(v * MAXVALF) + orig * x; + + // using optimized formula (heckflosse67@gmx.de) + return rtengine::intp(blend, rtengine::Color::igamma_srgb(v * v * (3.f - 2.f * v) * rtengine::MAXVALF), x); } return x; } +#ifdef __SSE2__ +inline vfloat sl(vfloat blend, vfloat x) +{ + const vfloat v = rtengine::Color::gammatab_srgb[x] / F2V(rtengine::MAXVALF); + return vself(vmaskf_gt(x, F2V(rtengine::MAXVALF)), x, vself(vmaskf_lt(x, ZEROV), x, vintpf(blend, rtengine::Color::igammatab_srgb[v * v * (F2V(3.f) - (v + v)) * rtengine::MAXVALF], x))); +} +#endif + } // namespace - -void ImProcFunctions::softLight(LabImage *lab) +void rtengine::ImProcFunctions::softLight(LabImage *lab) { if (!params->softlight.enabled || !params->softlight.strength) { return; } - Imagefloat working(lab->W, lab->H); - lab2rgb(*lab, working, params->icm.workingProfile); + const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; - const float blend = params->softlight.strength / 100.f; + const TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; + +#ifdef __SSE2__ + const vfloat wpv[3][3] = { + {F2V(wprof[0][0]), F2V(wprof[0][1]), F2V(wprof[0][2])}, + {F2V(wprof[1][0]), F2V(wprof[1][1]), F2V(wprof[1][2])}, + {F2V(wprof[2][0]), F2V(wprof[2][1]), F2V(wprof[2][2])} + }; + + const vfloat wipv[3][3] = { + {F2V(wiprof[0][0]), F2V(wiprof[0][1]), F2V(wiprof[0][2])}, + {F2V(wiprof[1][0]), F2V(wiprof[1][1]), F2V(wiprof[1][2])}, + {F2V(wiprof[2][0]), F2V(wiprof[2][1]), F2V(wiprof[2][2])} + }; +#endif #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel #endif - for (int y = 0; y < working.getHeight(); ++y) { - for (int x = 0; x < working.getWidth(); ++x) { - working.r(y, x) = sl(blend, working.r(y, x)); - working.g(y, x) = sl(blend, working.g(y, x)); - working.b(y, x) = sl(blend, working.b(y, x)); + { + const float blend = params->softlight.strength / 100.f; +#ifdef __SSE2__ + const vfloat blendv = F2V(blend); +#endif +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + for (int i = 0; i < lab->H; ++i) { + int j = 0; +#ifdef __SSE2__ + for (; j < lab->W - 3; j += 4) { + vfloat Xv, Yv, Zv; + vfloat Rv, Gv, Bv; + Color::Lab2XYZ(LVFU(lab->L[i][j]),LVFU (lab->a[i][j]),LVFU (lab->b[i][j]), Xv, Yv, Zv); + Color::xyz2rgb(Xv, Yv, Zv, Rv, Gv, Bv, wipv); + Rv = sl(blendv, Rv); + Gv = sl(blendv, Gv); + Bv = sl(blendv, Bv); + Color::rgbxyz(Rv, Gv, Bv, Xv, Yv, Zv, wpv); + for (int k = 0; k < 4; ++k) { + Color::XYZ2Lab(Xv[k], Yv[k], Zv[k], lab->L[i][j + k], lab->a[i][j + k], lab->b[i][j+ k]); + } + } +#endif + for (; j < lab->W; j++) { + float X, Y, Z; + float R, G, B; + Color::Lab2XYZ(lab->L[i][j], lab->a[i][j], lab->b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, R, G, B, wip); + R = sl(blend, R); + G = sl(blend, G); + B = sl(blend, B); + Color::rgbxyz(R, G, B, X, Y, Z, wp); + Color::XYZ2Lab(X, Y, Z, lab->L[i][j], lab->a[i][j], lab->b[i][j]); + } } } - - rgb2lab(working, *lab, params->icm.workingProfile); } - -} // namespace rtengine diff --git a/rtengine/iptcpairs.h b/rtengine/iptcpairs.h index 21099735a..af45d7d38 100644 --- a/rtengine/iptcpairs.h +++ b/rtengine/iptcpairs.h @@ -16,9 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IPTCPAIRS_ -#define _IPTCPAIRS_ - +#pragma once struct IptcPair { IptcTag tag; @@ -44,6 +42,3 @@ const IptcPair strTags[] = { {IPTC_TAG_ORIG_TRANS_REF, 32, "TransReference"}, {IPTC_TAG_DATE_CREATED, 8, "DateCreated"} }; - -#endif - diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 8dee92479..af513536e 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -16,17 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "rtengine.h" -#include "improcfun.h" -#include "procparams.h" -#ifdef _OPENMP -#include -#endif -#include "mytime.h" -#include "rt_math.h" -#include "sleef.c" -#include "rtlensfun.h" +#include +#include "imagefloat.h" +#include "improcfun.h" + +#include "procparams.h" +#include "rt_math.h" +#include "rtengine.h" +#include "rtlensfun.h" +#include "sleef.h" using namespace std; @@ -87,6 +86,114 @@ float normn (float a, float b, int n) } } +#ifdef __SSE2__ +inline void interpolateTransformCubic(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)) * F2V(mul); + r = vhadd(weight * rv); + g = vhadd(weight * gv); + b = vhadd(weight * bv); +} +#else +inline void interpolateTransformCubic(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 * (rv[0] * w0Hor + rv[1] * w1Hor + rv[2] * w2Hor + rv[3] * w3Hor); + 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); +} +#endif +#ifdef __SSE2__ +inline void interpolateTransformChannelsCubic(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 * vhadd(weight * cv); +} +#else +inline void interpolateTransformChannelsCubic(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 * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor); +} +#endif } @@ -97,7 +204,7 @@ namespace rtengine #define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b))) bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef, - const LensCorrection *pLCPMap) + const LensCorrection *pLCPMap) const { bool clipped = false; @@ -113,7 +220,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, blue.push_back (Coord2D (src[i].x, src[i].y)); } - return clipped; + return false; } double oW = W, oH = H; @@ -199,7 +306,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, } // Transform all corners and critical sidelines of an image -bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef, const LensCorrection *pLCPMap) +bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef, const LensCorrection *pLCPMap) const { const int DivisionsPerBorder = 32; @@ -308,7 +415,7 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, std::unique_ptr pLCPMap; if (needsLensfun()) { - pLCPMap = LFDatabase::findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); + pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); } else if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile (params->lensProf.lcpFile); @@ -741,87 +848,92 @@ 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) { // set up stuff, depending on the mode we are - bool enableLCPDist = pLCPMap && params->lensProf.useDist; - bool enableCA = highQuality && needsCA(); - bool enableGradient = needsGradient(); - bool enablePCVignetting = needsPCVignetting(); - bool enableVignetting = needsVignetting(); - bool enablePerspective = needsPerspective(); - bool enableDistortion = needsDistortion(); + const bool enableLCPDist = pLCPMap && params->lensProf.useDist; + const bool enableCA = highQuality && needsCA(); + const bool enableGradient = needsGradient(); + const bool enablePCVignetting = needsPCVignetting(); + const bool enableVignetting = needsVignetting(); + const bool enablePerspective = needsPerspective(); + const bool enableDistortion = needsDistortion(); - double w2 = (double) oW / 2.0 - 0.5; - double h2 = (double) oH / 2.0 - 0.5; + const double w2 = static_cast(oW) / 2.0 - 0.5; + const double h2 = static_cast(oH) / 2.0 - 0.5; double vig_w2, vig_h2, maxRadius, v, b, mul; - calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); - struct grad_params gp; + grad_params gp; if (enableGradient) { - calcGradientParams (oW, oH, params->gradient, gp); + calcGradientParams(oW, oH, params->gradient, gp); } - struct pcv_params pcv; + pcv_params pcv; if (enablePCVignetting) { - calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv); + calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv); } - float** chOrig[3]; - chOrig[0] = original->r.ptrs; - chOrig[1] = original->g.ptrs; - chOrig[2] = original->b.ptrs; - - float** chTrans[3]; - chTrans[0] = transformed->r.ptrs; - chTrans[1] = transformed->g.ptrs; - chTrans[2] = transformed->b.ptrs; + const std::array chOrig = { + original->r.ptrs, + original->g.ptrs, + original->b.ptrs + }; + const std::array chTrans = { + transformed->r.ptrs, + transformed->g.ptrs, + transformed->b.ptrs + }; // auxiliary variables for c/a correction - double chDist[3]; - chDist[0] = enableCA ? params->cacorrection.red : 0.0; - chDist[1] = 0.0; - chDist[2] = enableCA ? params->cacorrection.blue : 0.0; + const std::array chDist = { + enableCA + ? params->cacorrection.red + : 0.0, + 0.0, + enableCA + ? params->cacorrection.blue + : 0.0 + }; // auxiliary variables for distortion correction - double distAmount = params->distortion.amount; + const double distAmount = params->distortion.amount; // auxiliary variables for rotation - double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); - double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); + const double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0); + const double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0); // auxiliary variables for vertical perspective correction - double vpdeg = params->perspective.vertical / 100.0 * 45.0; - double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI; - double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oW * tan (vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * - oW * tan (vpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oW * tan (vpalpha)))) / (SQR (maxRadius) * 8))); - double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); + const double vpdeg = params->perspective.vertical / 100.0 * 45.0; + const double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI; + const double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * + oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8))); + const double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos(vpteta); + const double vptanpt = tan(vpteta); // auxiliary variables for horizontal perspective correction - double hpdeg = params->perspective.horizontal / 100.0 * 45.0; - double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI; - double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oH * tan (hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * - oH * tan (hpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oH * tan (hpalpha)))) / (SQR (maxRadius) * 8))); - double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); + const double hpdeg = params->perspective.horizontal / 100.0 * 45.0; + const double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI; + const double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * + oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8))); + const double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos(hpteta); + const double hptanpt = tan(hpteta); - double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.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; -#if defined( __GNUC__ ) && __GNUC__ >= 7// silence warning -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif -#if defined( __GNUC__ ) && __GNUC__ >= 7 -#pragma GCC diagnostic pop -#endif // main cycle - bool darkening = (params->vignetting.amount <= 0.0); #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for schedule(dynamic, 16) if(multiThread) #endif - for (int y = 0; y < transformed->getHeight(); y++) { - for (int x = 0; x < transformed->getWidth(); x++) { - double x_d = x, y_d = y; + for (int y = 0; y < transformed->getHeight(); ++y) { + for (int x = 0; x < transformed->getWidth(); ++x) { + double x_d = x; + double y_d = y; if (enableLCPDist) { pLCPMap->correctDistortion(x_d, y_d, cx, cy, ascale); // must be first transform @@ -830,15 +942,8 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I y_d *= ascale; } - x_d += ascale * (cx - w2); // centering x coord & scale - y_d += ascale * (cy - h2); // centering y coord & scale - - double vig_x_d = 0., vig_y_d = 0.; - - if (enableVignetting) { - vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale - vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale - } + x_d += ascale * centerFactorx; // centering x coord & scale + y_d += ascale * centerFactory; // centering y coord & scale if (enablePerspective) { // horizontal perspective transformation @@ -851,26 +956,18 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } // rotate - double Dxc = x_d * cost - y_d * sint; - double Dyc = x_d * sint + y_d * cost; + const double Dxc = x_d * cost - y_d * sint; + const double Dyc = x_d * sint + y_d * cost; // distortion correction - double s = 1; + double s = 1.0; if (enableDistortion) { - double r = sqrt (Dxc * Dxc + Dyc * Dyc) / maxRadius; // sqrt is slow - s = 1.0 - distAmount + distAmount * r ; + const double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; + s = 1.0 - distAmount + distAmount * r; } - double r2 = 0.; - - if (enableVignetting) { - double vig_Dx = vig_x_d * cost - vig_y_d * sint; - double vig_Dy = vig_x_d * sint + vig_y_d * cost; - r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); - } - - for (int c = 0; c < (enableCA ? 3 : 1); c++) { + for (int c = 0; c < (enableCA ? 3 : 1); ++c) { double Dx = Dxc * (s + chDist[c]); double Dy = Dyc * (s + chDist[c]); @@ -879,59 +976,63 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I Dy += h2; // Extract integer and fractions of source screen coordinates - int xc = (int)Dx; - Dx -= (double)xc; + int xc = Dx; + Dx -= xc; xc -= sx; - int yc = (int)Dy; - Dy -= (double)yc; + int yc = Dy; + Dy -= yc; yc -= sy; // Convert only valid pixels if (yc >= 0 && yc < original->getHeight() && xc >= 0 && xc < original->getWidth()) { - // multiplier for vignetting correction double vignmul = 1.0; if (enableVignetting) { + const double vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale + const double vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale + const double vig_Dx = vig_x_d * cost - vig_y_d * sint; + const double vig_Dy = vig_x_d * sint + vig_y_d * cost; + const double r2 = sqrt(vig_Dx * vig_Dx + vig_Dy * vig_Dy); if (darkening) { - vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001); + vignmul /= std::max(v + mul * tanh(b * (maxRadius - s * r2) / maxRadius), 0.001); } else { - vignmul *= (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius)); + vignmul *= (v + mul * tanh(b * (maxRadius - s * r2) / maxRadius)); } } if (enableGradient) { - vignmul *= calcGradientFactor (gp, cx + x, cy + y); + vignmul *= calcGradientFactor(gp, cx + x, cy + y); } if (enablePCVignetting) { - vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y); + vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y); } 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); + interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul); } else 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); + 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 { - interpolateTransformCubic (original, xc - 1, yc - 1, Dx, Dy, & (transformed->r (y, x)), & (transformed->g (y, x)), & (transformed->b (y, x)), vignmul); + interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul); } } 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); + const int y1 = LIM(yc, 0, original->getHeight() - 1); + const int y2 = LIM(yc + 1, 0, original->getHeight() - 1); + 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); } 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); + 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 { @@ -939,9 +1040,9 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I // not valid (source pixel x,y not inside source image, etc.) chTrans[c][y][x] = 0; } else { - transformed->r (y, x) = 0; - transformed->g (y, x) = 0; - transformed->b (y, x) = 0; + transformed->r(y, x) = 0; + transformed->g(y, x) = 0; + transformed->b(y, x) = 0; } } } @@ -988,7 +1089,7 @@ 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); + interpolateTransformChannelsCubic (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); @@ -1008,7 +1109,7 @@ void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *trans } -double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LensCorrection *pLCPMap) +double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LensCorrection *pLCPMap) const { if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap == nullptr)) { return 1; @@ -1032,52 +1133,52 @@ double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LensCorrecti return scaleL; } -bool ImProcFunctions::needsCA () +bool ImProcFunctions::needsCA () const { return fabs (params->cacorrection.red) > 1e-15 || fabs (params->cacorrection.blue) > 1e-15; } -bool ImProcFunctions::needsDistortion () +bool ImProcFunctions::needsDistortion () const { return fabs (params->distortion.amount) > 1e-15; } -bool ImProcFunctions::needsRotation () +bool ImProcFunctions::needsRotation () const { return fabs (params->rotate.degree) > 1e-15; } -bool ImProcFunctions::needsPerspective () +bool ImProcFunctions::needsPerspective () const { return params->perspective.horizontal || params->perspective.vertical; } -bool ImProcFunctions::needsGradient () +bool ImProcFunctions::needsGradient () const { return params->gradient.enabled && fabs (params->gradient.strength) > 1e-15; } -bool ImProcFunctions::needsPCVignetting () +bool ImProcFunctions::needsPCVignetting () const { return params->pcvignette.enabled && fabs (params->pcvignette.strength) > 1e-15; } -bool ImProcFunctions::needsVignetting () +bool ImProcFunctions::needsVignetting () const { return params->vignetting.amount; } -bool ImProcFunctions::needsLCP () +bool ImProcFunctions::needsLCP () const { return params->lensProf.useLcp(); } -bool ImProcFunctions::needsLensfun() +bool ImProcFunctions::needsLensfun() const { return params->lensProf.useLensfun(); } -bool ImProcFunctions::needsTransform () +bool ImProcFunctions::needsTransform () const { return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLensfun(); } diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index a7199064a..14e5f3c44 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -23,16 +23,11 @@ #include "rtengine.h" #include "improcfun.h" #include "iccstore.h" -#include "mytime.h" -#include "../rtgui/thresholdselector.h" +#include "labimage.h" #include "curves.h" #include "color.h" #include "procparams.h" #include "StopWatch.h" -#ifdef _OPENMP -#include -#endif - using namespace std; diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 07e9da85b..7c0dc368b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -28,19 +28,21 @@ #include "../rtgui/threadutils.h" -#include "rtengine.h" -#include "improcfun.h" -#include "LUT.h" #include "array2D.h" -#include "boxblur.h" -#include "rt_math.h" -#include "mytime.h" -#include "sleef.c" -#include "opthelper.h" -#include "median.h" +#include "color.h" +#include "curves.h" #include "EdgePreservingDecomposition.h" #include "iccstore.h" +#include "improcfun.h" +#include "labimage.h" +#include "LUT.h" +#include "median.h" +#include "opthelper.h" #include "procparams.h" +#include "rt_math.h" +#include "rtengine.h" +#include "sleef.h" +#include "../rtgui/options.h" #ifdef _OPENMP #include @@ -55,12 +57,9 @@ #define epsilon 0.001f/(TS*TS) //tolerance - namespace rtengine { -extern const Settings* settings; - struct cont_params { float mul[10]; int chrom; @@ -1196,7 +1195,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const b = 327.68f * Chprov * sincosv.x; //aply Munsell } else {//general case L = labco->L[i1][j1]; - const float Lin = labco->L[i1][j1]; + const float Lin = std::max(0.f, L); if(wavclCurve && cp.finena) { labco->L[i1][j1] = (0.5f * Lin + 1.5f * wavclCurve[Lin]) / 2.f; //apply contrast curve diff --git a/rtengine/jpeg.h b/rtengine/jpeg.h index 99baecc5a..9b1f45f1d 100644 --- a/rtengine/jpeg.h +++ b/rtengine/jpeg.h @@ -1,5 +1,4 @@ -#ifndef _RT_JPEG_H -#define _RT_JPEG_H +#pragma once #include @@ -29,6 +28,3 @@ typedef struct { #ifdef __cplusplus } #endif - - -#endif diff --git a/rtengine/labimage.cc b/rtengine/labimage.cc index b31bc89a1..153af4c75 100644 --- a/rtengine/labimage.cc +++ b/rtengine/labimage.cc @@ -17,7 +17,6 @@ * along with RawTherapee. If not, see . */ -#include #include #include "labimage.h" diff --git a/rtengine/labimage.h b/rtengine/labimage.h index bcc2484ab..79f003b07 100644 --- a/rtengine/labimage.h +++ b/rtengine/labimage.h @@ -16,8 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LABIMAGE_H_ -#define _LABIMAGE_H_ +#pragma once + +#include namespace rtengine { @@ -45,4 +46,3 @@ public: }; } -#endif diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index b456fc478..c80a126f5 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -18,26 +18,24 @@ */ #include +#include #include +#include +#include #include #ifdef WIN32 #include -#include #endif #include "lcp.h" +#include "opthelper.h" #include "procparams.h" +#include "rt_math.h" #include "settings.h" - -namespace rtengine -{ - -extern const Settings* settings; - -} +#include "utils.h" class rtengine::LCPProfile::LCPPersModel { @@ -984,7 +982,7 @@ rtengine::LCPMapper::LCPMapper( bool useCADistP, int fullWidth, int fullHeight, - const CoarseTransformParams& coarse, + const procparams::CoarseTransformParams& coarse, int rawRotationDeg ) : enableCA(false), @@ -1137,6 +1135,17 @@ void rtengine::LCPMapper::correctCA(double& x, double& y, int cx, int cy, int ch y -= cy; } +void rtengine::LCPMapper::processVignette(int width, int height, float** rawData) const +{ +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < height; ++y) { + processVignetteLine(width, y, rawData[y]); + } +} + void rtengine::LCPMapper::processVignetteLine(int width, int y, float* line) const { // No need for swapXY, since vignette is in RAW and always before rotation @@ -1175,6 +1184,17 @@ void rtengine::LCPMapper::processVignetteLine(int width, int y, float* line) con } } +void rtengine::LCPMapper::processVignette3Channels(int width, int height, float** rawData) const +{ +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < height; ++y) { + processVignetteLine3Channels(width, y, rawData[y]); + } +} + void rtengine::LCPMapper::processVignetteLine3Channels(int width, int y, float* line) const { // No need for swapXY, since vignette is in RAW and always before rotation diff --git a/rtengine/lcp.h b/rtengine/lcp.h index 30b7e5191..2e36fe113 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -20,21 +20,27 @@ #pragma once #include -#include #include #include #include -#include +#include #include #include "cache.h" -#include "imagefloat.h" -#include "opthelper.h" namespace rtengine { +namespace procparams +{ + +class ProcParams; + +struct CoarseTransformParams; + +} + enum class LCPCorrectionMode { VIGNETTE, DISTORTION, @@ -165,8 +171,8 @@ public: virtual void correctDistortion(double &x, double &y, int cx, int cy, double scale) const = 0; virtual bool isCACorrectionAvailable() const = 0; virtual void correctCA(double &x, double &y, int cx, int cy, int channel) const = 0; - virtual void processVignetteLine(int width, int y, float *line) const = 0; - virtual void processVignetteLine3Channels(int width, int y, float *line) const = 0; + virtual void processVignette(int width, int height, float** rawData) const = 0; + virtual void processVignette3Channels(int width, int height, float** rawData) const = 0; }; @@ -185,7 +191,7 @@ public: bool useCADistP, int fullWidth, int fullHeight, - const CoarseTransformParams& coarse, + const procparams::CoarseTransformParams& coarse, int rawRotationDeg ); @@ -193,8 +199,8 @@ public: void correctDistortion(double &x, double &y, int cx, int cy, double scale) const override; // MUST be the first stage bool isCACorrectionAvailable() const override; void correctCA(double& x, double& y, int cx, int cy, int channel) const override; - void processVignetteLine(int width, int y, float* line) const override; - void processVignetteLine3Channels(int width, int y, float* line) const override; + void processVignette(int width, int height, float** rawData) const override; + void processVignette3Channels(int width, int height, float** rawData) const override; private: bool enableCA; // is the mapper capable if CA correction? @@ -203,6 +209,9 @@ private: LCPModelCommon mc; LCPModelCommon chrom[3]; // in order RedGreen/Green/BlueGreen bool isFisheye; + + void processVignetteLine(int width, int y, float* line) const; + void processVignetteLine3Channels(int width, int y, float* line) const; }; } diff --git a/rtengine/lmmse_demosaic.cc b/rtengine/lmmse_demosaic.cc new file mode 100644 index 000000000..6191ca36c --- /dev/null +++ b/rtengine/lmmse_demosaic.cc @@ -0,0 +1,824 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2019 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include + +#include "rawimagesource.h" +#include "rt_math.h" +#include "color.h" +#include "../rtgui/multilangmgr.h" +#include "sleef.h" +#include "opthelper.h" +#include "median.h" + +using namespace std; + +namespace rtengine +{ + +// LSMME demosaicing algorithm +// L. Zhang and X. Wu, +// Color demozaicing via directional Linear Minimum Mean Square-error Estimation, +// IEEE Trans. on Image Processing, vol. 14, pp. 2167-2178, +// Dec. 2005. +// Adapted to RawTherapee by Jacques Desmis 3/2013 +// Improved speed and reduced memory consumption by Ingo Weyrich 2/2015 +// TODO Tiles to reduce memory consumption +void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations) +{ + const int width = winw, height = winh; + const int ba = 10; + const int rr1 = height + 2 * ba; + const int cc1 = width + 2 * ba; + const int w1 = cc1; + const int w2 = 2 * w1; + const int w3 = 3 * w1; + const int w4 = 4 * w1; + float h0, h1, h2, h3, h4, hs; + h0 = 1.0f; + h1 = exp( -1.0f / 8.0f); + h2 = exp( -4.0f / 8.0f); + h3 = exp( -9.0f / 8.0f); + h4 = exp(-16.0f / 8.0f); + hs = h0 + 2.0f * (h1 + h2 + h3 + h4); + h0 /= hs; + h1 /= hs; + h2 /= hs; + h3 /= hs; + h4 /= hs; + int passref = 0; + int iter = 0; + + if (iterations <= 4) { + iter = iterations - 1; + passref = 0; + } else if (iterations <= 6) { + iter = 3; + passref = iterations - 4; + } else if (iterations <= 8) { + iter = 3; + passref = iterations - 6; + } + + bool applyGamma = true; + + if (iterations == 0) { + applyGamma = false; + iter = 0; + } else { + applyGamma = true; + } + + float *rix[5]; + float *qix[5]; + float *buffer = (float *)calloc(static_cast(rr1) * cc1 * 5 * sizeof(float), 1); + + if (buffer == nullptr) { // allocation of big block of memory failed, try to get 5 smaller ones + printf("lmmse_interpolate_omp: allocation of big memory block failed, try to get 5 smaller ones now...\n"); + bool allocationFailed = false; + + for (int i = 0; i < 5; i++) { + qix[i] = (float *)calloc(static_cast(rr1) * cc1 * sizeof(float), 1); + + if (!qix[i]) { // allocation of at least one small block failed + allocationFailed = true; + } + } + + if (allocationFailed) { // fall back to igv_interpolate + printf("lmmse_interpolate_omp: allocation of 5 small memory blocks failed, falling back to igv_interpolate...\n"); + + for (int i = 0; i < 5; i++) { // free the already allocated buffers + if (qix[i]) { + free(qix[i]); + } + } + + igv_interpolate(winw, winh); + return; + } + } else { + qix[0] = buffer; + + for (int i = 1; i < 5; i++) { + qix[i] = qix[i - 1] + rr1 * cc1; + } + } + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_LMMSE"))); + plistener->setProgress (0.0); + } + + + LUTf *gamtab; + + if (applyGamma) { + gamtab = &(Color::gammatab_24_17a); + } else { + gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); + gamtab->makeIdentity(65535.f); + } + + +#ifdef _OPENMP + #pragma omp parallel private(rix) +#endif + { +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rrr = ba; rrr < rr1 - ba; rrr++) { + for (int ccc = ba, row = rrr - ba; ccc < cc1 - ba; ccc++) { + int col = ccc - ba; + float *rix = qix[4] + rrr * cc1 + ccc; + rix[0] = (*gamtab)[rawData[row][col]]; + } + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.1); + } + } + + // G-R(B) +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + + for (int rr = 2; rr < rr1 - 2; rr++) { + // G-R(B) at R(B) location + for (int cc = 2 + (FC(rr, 2) & 1); cc < cc1 - 2; cc += 2) { + rix[4] = qix[4] + rr * cc1 + cc; + float v0 = 0.0625f * (rix[4][-w1 - 1] + rix[4][-w1 + 1] + rix[4][w1 - 1] + rix[4][w1 + 1]) + 0.25f * (rix[4][0]); + // horizontal + rix[0] = qix[0] + rr * cc1 + cc; + rix[0][0] = -0.25f * (rix[4][ -2] + rix[4][ 2]) + xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); + float Y = v0 + xdiv2f(rix[0][0]); + + if (rix[4][0] > 1.75f * Y) { + rix[0][0] = median(rix[0][0], rix[4][ -1], rix[4][ 1]); + } else { + rix[0][0] = LIM(rix[0][0], 0.0f, 1.0f); + } + + rix[0][0] -= rix[4][0]; + // vertical + rix[1] = qix[1] + rr * cc1 + cc; + rix[1][0] = -0.25f * (rix[4][-w2] + rix[4][w2]) + xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); + Y = v0 + xdiv2f(rix[1][0]); + + if (rix[4][0] > 1.75f * Y) { + rix[1][0] = median(rix[1][0], rix[4][-w1], rix[4][w1]); + } else { + rix[1][0] = LIM(rix[1][0], 0.0f, 1.0f); + } + + rix[1][0] -= rix[4][0]; + } + + // G-R(B) at G location + for (int ccc = 2 + (FC(rr, 3) & 1); ccc < cc1 - 2; ccc += 2) { + rix[0] = qix[0] + rr * cc1 + ccc; + rix[1] = qix[1] + rr * cc1 + ccc; + rix[4] = qix[4] + rr * cc1 + ccc; + rix[0][0] = 0.25f * (rix[4][ -2] + rix[4][ 2]) - xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); + rix[1][0] = 0.25f * (rix[4][-w2] + rix[4][w2]) - xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); + rix[0][0] = LIM(rix[0][0], -1.0f, 0.0f) + rix[4][0]; + rix[1][0] = LIM(rix[1][0], -1.0f, 0.0f) + rix[4][0]; + } + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.2); + } + } + + + // apply low pass filter on differential colors +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rr = 4; rr < rr1 - 4; rr++) + for (int cc = 4; cc < cc1 - 4; cc++) { + rix[0] = qix[0] + rr * cc1 + cc; + rix[2] = qix[2] + rr * cc1 + cc; + rix[2][0] = h0 * rix[0][0] + h1 * (rix[0][ -1] + rix[0][ 1]) + h2 * (rix[0][ -2] + rix[0][ 2]) + h3 * (rix[0][ -3] + rix[0][ 3]) + h4 * (rix[0][ -4] + rix[0][ 4]); + rix[1] = qix[1] + rr * cc1 + cc; + rix[3] = qix[3] + rr * cc1 + cc; + rix[3][0] = h0 * rix[1][0] + h1 * (rix[1][-w1] + rix[1][w1]) + h2 * (rix[1][-w2] + rix[1][w2]) + h3 * (rix[1][-w3] + rix[1][w3]) + h4 * (rix[1][-w4] + rix[1][w4]); + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.3); + } + } + + // interpolate G-R(B) at R(B) +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rr = 4; rr < rr1 - 4; rr++) { + int cc = 4 + (FC(rr, 4) & 1); +#ifdef __SSE2__ + vfloat p1v, p2v, p3v, p4v, p5v, p6v, p7v, p8v, p9v, muv, vxv, vnv, xhv, vhv, xvv, vvv; + vfloat epsv = F2V(1e-7); + vfloat ninev = F2V(9.f); + + for (; cc < cc1 - 10; cc += 8) { + rix[0] = qix[0] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + rix[2] = qix[2] + rr * cc1 + cc; + rix[3] = qix[3] + rr * cc1 + cc; + rix[4] = qix[4] + rr * cc1 + cc; + // horizontal + p1v = LC2VFU(rix[2][-4]); + p2v = LC2VFU(rix[2][-3]); + p3v = LC2VFU(rix[2][-2]); + p4v = LC2VFU(rix[2][-1]); + p5v = LC2VFU(rix[2][ 0]); + p6v = LC2VFU(rix[2][ 1]); + p7v = LC2VFU(rix[2][ 2]); + p8v = LC2VFU(rix[2][ 3]); + p9v = LC2VFU(rix[2][ 4]); + muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; + vxv = epsv + SQRV(p1v - muv) + SQRV(p2v - muv) + SQRV(p3v - muv) + SQRV(p4v - muv) + SQRV(p5v - muv) + SQRV(p6v - muv) + SQRV(p7v - muv) + SQRV(p8v - muv) + SQRV(p9v - muv); + p1v -= LC2VFU(rix[0][-4]); + p2v -= LC2VFU(rix[0][-3]); + p3v -= LC2VFU(rix[0][-2]); + p4v -= LC2VFU(rix[0][-1]); + p5v -= LC2VFU(rix[0][ 0]); + p6v -= LC2VFU(rix[0][ 1]); + p7v -= LC2VFU(rix[0][ 2]); + p8v -= LC2VFU(rix[0][ 3]); + p9v -= LC2VFU(rix[0][ 4]); + vnv = epsv + SQRV(p1v) + SQRV(p2v) + SQRV(p3v) + SQRV(p4v) + SQRV(p5v) + SQRV(p6v) + SQRV(p7v) + SQRV(p8v) + SQRV(p9v); + xhv = (LC2VFU(rix[0][0]) * vxv + LC2VFU(rix[2][0]) * vnv) / (vxv + vnv); + vhv = vxv * vnv / (vxv + vnv); + + // vertical + p1v = LC2VFU(rix[3][-w4]); + p2v = LC2VFU(rix[3][-w3]); + p3v = LC2VFU(rix[3][-w2]); + p4v = LC2VFU(rix[3][-w1]); + p5v = LC2VFU(rix[3][ 0]); + p6v = LC2VFU(rix[3][ w1]); + p7v = LC2VFU(rix[3][ w2]); + p8v = LC2VFU(rix[3][ w3]); + p9v = LC2VFU(rix[3][ w4]); + muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; + vxv = epsv + SQRV(p1v - muv) + SQRV(p2v - muv) + SQRV(p3v - muv) + SQRV(p4v - muv) + SQRV(p5v - muv) + SQRV(p6v - muv) + SQRV(p7v - muv) + SQRV(p8v - muv) + SQRV(p9v - muv); + p1v -= LC2VFU(rix[1][-w4]); + p2v -= LC2VFU(rix[1][-w3]); + p3v -= LC2VFU(rix[1][-w2]); + p4v -= LC2VFU(rix[1][-w1]); + p5v -= LC2VFU(rix[1][ 0]); + p6v -= LC2VFU(rix[1][ w1]); + p7v -= LC2VFU(rix[1][ w2]); + p8v -= LC2VFU(rix[1][ w3]); + p9v -= LC2VFU(rix[1][ w4]); + vnv = epsv + SQRV(p1v) + SQRV(p2v) + SQRV(p3v) + SQRV(p4v) + SQRV(p5v) + SQRV(p6v) + SQRV(p7v) + SQRV(p8v) + SQRV(p9v); + xvv = (LC2VFU(rix[1][0]) * vxv + LC2VFU(rix[3][0]) * vnv) / (vxv + vnv); + vvv = vxv * vnv / (vxv + vnv); + // interpolated G-R(B) + muv = (xhv * vvv + xvv * vhv) / (vhv + vvv); + STC2VFU(rix[4][0], muv); + } + +#endif + + for (; cc < cc1 - 4; cc += 2) { + rix[0] = qix[0] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + rix[2] = qix[2] + rr * cc1 + cc; + rix[3] = qix[3] + rr * cc1 + cc; + rix[4] = qix[4] + rr * cc1 + cc; + // horizontal + float p1 = rix[2][-4]; + float p2 = rix[2][-3]; + float p3 = rix[2][-2]; + float p4 = rix[2][-1]; + float p5 = rix[2][ 0]; + float p6 = rix[2][ 1]; + float p7 = rix[2][ 2]; + float p8 = rix[2][ 3]; + float p9 = rix[2][ 4]; + float mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; + float vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu); + p1 -= rix[0][-4]; + p2 -= rix[0][-3]; + p3 -= rix[0][-2]; + p4 -= rix[0][-1]; + p5 -= rix[0][ 0]; + p6 -= rix[0][ 1]; + p7 -= rix[0][ 2]; + p8 -= rix[0][ 3]; + p9 -= rix[0][ 4]; + float vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9); + float xh = (rix[0][0] * vx + rix[2][0] * vn) / (vx + vn); + float vh = vx * vn / (vx + vn); + + // vertical + p1 = rix[3][-w4]; + p2 = rix[3][-w3]; + p3 = rix[3][-w2]; + p4 = rix[3][-w1]; + p5 = rix[3][ 0]; + p6 = rix[3][ w1]; + p7 = rix[3][ w2]; + p8 = rix[3][ w3]; + p9 = rix[3][ w4]; + mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; + vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu); + p1 -= rix[1][-w4]; + p2 -= rix[1][-w3]; + p3 -= rix[1][-w2]; + p4 -= rix[1][-w1]; + p5 -= rix[1][ 0]; + p6 -= rix[1][ w1]; + p7 -= rix[1][ w2]; + p8 -= rix[1][ w3]; + p9 -= rix[1][ w4]; + vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9); + float xv = (rix[1][0] * vx + rix[3][0] * vn) / (vx + vn); + float vv = vx * vn / (vx + vn); + // interpolated G-R(B) + rix[4][0] = (xh * vv + xv * vh) / (vh + vv); + } + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.4); + } + } + + // copy CFA values +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rr = 0; rr < rr1; rr++) + for (int cc = 0, row = rr - ba; cc < cc1; cc++) { + int col = cc - ba; + int c = FC(rr, cc); + rix[c] = qix[c] + rr * cc1 + cc; + + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + rix[c][0] = (*gamtab)[rawData[row][col]]; + } else { + rix[c][0] = 0.f; + } + + if (c != 1) { + rix[1] = qix[1] + rr * cc1 + cc; + rix[4] = qix[4] + rr * cc1 + cc; + rix[1][0] = rix[c][0] + rix[4][0]; + } + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.5); + } + } + + // bilinear interpolation for R/B + // interpolate R/B at G location +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rr = 1; rr < rr1 - 1; rr++) + for (int cc = 1 + (FC(rr, 2) & 1), c = FC(rr, cc + 1); cc < cc1 - 1; cc += 2) { + rix[c] = qix[c] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + rix[c][0] = rix[1][0] + xdiv2f(rix[c][ -1] - rix[1][ -1] + rix[c][ 1] - rix[1][ 1]); + c = 2 - c; + rix[c] = qix[c] + rr * cc1 + cc; + rix[c][0] = rix[1][0] + xdiv2f(rix[c][-w1] - rix[1][-w1] + rix[c][w1] - rix[1][w1]); + c = 2 - c; + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.6); + } + } + + // interpolate R/B at B/R location +#ifdef _OPENMP + #pragma omp for +#endif + + for (int rr = 1; rr < rr1 - 1; rr++) + for (int cc = 1 + (FC(rr, 1) & 1), c = 2 - FC(rr, cc); cc < cc1 - 1; cc += 2) { + rix[c] = qix[c] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + rix[c][0] = rix[1][0] + 0.25f * (rix[c][-w1] - rix[1][-w1] + rix[c][ -1] - rix[1][ -1] + rix[c][ 1] - rix[1][ 1] + rix[c][ w1] - rix[1][ w1]); + } + +#ifdef _OPENMP + #pragma omp single +#endif + { + if (plistener) { + plistener->setProgress (0.7); + } + } + + }// End of parallelization 1 + + // median filter/ + for (int pass = 0; pass < iter; pass++) { + // Apply 3x3 median filter + // Compute median(R-G) and median(B-G) + +#ifdef _OPENMP + #pragma omp parallel for private(rix) +#endif + + for (int rr = 1; rr < rr1 - 1; rr++) { + for (int c = 0; c < 3; c += 2) { + int d = c + 3 - (c == 0 ? 0 : 1); + int cc = 1; +#ifdef __SSE2__ + + for (; cc < cc1 - 4; cc += 4) { + rix[d] = qix[d] + rr * cc1 + cc; + rix[c] = qix[c] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + // Assign 3x3 differential color values + const std::array p = { + LVFU(rix[c][-w1 - 1]) - LVFU(rix[1][-w1 - 1]), + LVFU(rix[c][-w1]) - LVFU(rix[1][-w1]), + LVFU(rix[c][-w1 + 1]) - LVFU(rix[1][-w1 + 1]), + LVFU(rix[c][ -1]) - LVFU(rix[1][ -1]), + LVFU(rix[c][ 0]) - LVFU(rix[1][ 0]), + LVFU(rix[c][ 1]) - LVFU(rix[1][ 1]), + LVFU(rix[c][ w1 - 1]) - LVFU(rix[1][ w1 - 1]), + LVFU(rix[c][ w1]) - LVFU(rix[1][ w1]), + LVFU(rix[c][ w1 + 1]) - LVFU(rix[1][ w1 + 1]) + }; + _mm_storeu_ps(&rix[d][0], median(p)); + } + +#endif + + for (; cc < cc1 - 1; cc++) { + rix[d] = qix[d] + rr * cc1 + cc; + rix[c] = qix[c] + rr * cc1 + cc; + rix[1] = qix[1] + rr * cc1 + cc; + // Assign 3x3 differential color values + const std::array p = { + rix[c][-w1 - 1] - rix[1][-w1 - 1], + rix[c][-w1] - rix[1][-w1], + rix[c][-w1 + 1] - rix[1][-w1 + 1], + rix[c][ -1] - rix[1][ -1], + rix[c][ 0] - rix[1][ 0], + rix[c][ 1] - rix[1][ 1], + rix[c][ w1 - 1] - rix[1][ w1 - 1], + rix[c][ w1] - rix[1][ w1], + rix[c][ w1 + 1] - rix[1][ w1 + 1] + }; + rix[d][0] = median(p); + } + } + } + + // red/blue at GREEN pixel locations & red/blue and green at BLUE/RED pixel locations +#ifdef _OPENMP + #pragma omp parallel for private (rix) +#endif + + for (int rr = 0; rr < rr1; rr++) { + rix[0] = qix[0] + rr * cc1; + rix[1] = qix[1] + rr * cc1; + rix[2] = qix[2] + rr * cc1; + rix[3] = qix[3] + rr * cc1; + rix[4] = qix[4] + rr * cc1; + int c0 = FC(rr, 0); + int c1 = FC(rr, 1); + + if (c0 == 1) { + c1 = 2 - c1; + int d = c1 + 3 - (c1 == 0 ? 0 : 1); + int cc; + + for (cc = 0; cc < cc1 - 1; cc += 2) { + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + rix[0]++; + rix[1]++; + rix[2]++; + rix[3]++; + rix[4]++; + rix[c1][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + rix[0]++; + rix[1]++; + rix[2]++; + rix[3]++; + rix[4]++; + } + + if (cc < cc1) { // remaining pixel, only if width is odd + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + } + } else { + c0 = 2 - c0; + int d = c0 + 3 - (c0 == 0 ? 0 : 1); + int cc; + + for (cc = 0; cc < cc1 - 1; cc += 2) { + rix[c0][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + rix[0]++; + rix[1]++; + rix[2]++; + rix[3]++; + rix[4]++; + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + rix[0]++; + rix[1]++; + rix[2]++; + rix[3]++; + rix[4]++; + } + + if (cc < cc1) { // remaining pixel, only if width is odd + rix[c0][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + } + } + } + } + + if (plistener) { + plistener->setProgress (0.8); + } + + if (applyGamma) { + gamtab = &(Color::igammatab_24_17); + } else { + gamtab->makeIdentity(); + } + + array2D* rgb[3]; + rgb[0] = &red; + rgb[1] = &green; + rgb[2] = &blue; + + // copy result back to image matrix +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int row = 0; row < height; row++) { + for (int col = 0, rr = row + ba; col < width; col++) { + int cc = col + ba; + int c = FC(row, col); + + for (int ii = 0; ii < 3; ii++) + if (ii != c) { + float *rix = qix[ii] + rr * cc1 + cc; + (*(rgb[ii]))[row][col] = (*gamtab)[65535.f * rix[0]]; + } else { + (*(rgb[ii]))[row][col] = CLIP(rawData[row][col]); + } + } + } + + if (plistener) { + plistener->setProgress (1.0); + } + + if (buffer) { + free(buffer); + } else + for (int i = 0; i < 5; i++) { + free(qix[i]); + } + + if (!applyGamma) { + delete gamtab; + } + + if (iterations > 4) { + refinement(passref); + } + +} + +#ifdef __SSE2__ +#define CLIPV(a) vclampf(a,ZEROV,c65535v) +#endif +void RawImageSource::refinement(int PassCount) +{ + int width = W; + int height = H; + int w1 = width; + int w2 = 2 * w1; + + if (plistener) { + plistener->setProgressStr(M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); + } + + array2D *rgb[3]; + rgb[0] = &red; + rgb[1] = &green; + rgb[2] = &blue; + + for (int b = 0; b < PassCount; b++) { + if (plistener) { + plistener->setProgress((float)b / PassCount); + } + + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + float *pix[3]; + + /* Reinforce interpolated green pixels on RED/BLUE pixel locations */ +#ifdef _OPENMP + #pragma omp for +#endif + + for (int row = 2; row < height - 2; row++) { + int col = 2 + (FC(row, 2) & 1); + int c = FC(row, col); +#ifdef __SSE2__ + vfloat dLv, dRv, dUv, dDv, v0v; + vfloat onev = F2V(1.f); + vfloat zd5v = F2V(0.5f); + vfloat c65535v = F2V(65535.f); + + for (; col < width - 8; col += 8) { + int indx = row * width + col; + pix[c] = (float*)(*rgb[c]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + dLv = onev / (onev + vabsf(LC2VFU(pix[c][ -2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); + dRv = onev / (onev + vabsf(LC2VFU(pix[c][ 2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); + dUv = onev / (onev + vabsf(LC2VFU(pix[c][-w2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); + dDv = onev / (onev + vabsf(LC2VFU(pix[c][ w2]) - LC2VFU(pix[c][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); + v0v = CLIPV(LC2VFU(pix[c][0]) + zd5v + ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); + STC2VFU(pix[1][0], v0v); + } + +#endif + + for (; col < width - 2; col += 2) { + int indx = row * width + col; + pix[c] = (float*)(*rgb[c]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + float dL = 1.f / (1.f + fabsf(pix[c][ -2] - pix[c][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); + float dR = 1.f / (1.f + fabsf(pix[c][ 2] - pix[c][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); + float dU = 1.f / (1.f + fabsf(pix[c][-w2] - pix[c][0]) + fabsf(pix[1][w1] - pix[1][-w1])); + float dD = 1.f / (1.f + fabsf(pix[c][ w2] - pix[c][0]) + fabsf(pix[1][w1] - pix[1][-w1])); + float v0 = (pix[c][0] + 0.5f + ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); + pix[1][0] = CLIP(v0); + } + } + + /* Reinforce interpolated red/blue pixels on GREEN pixel locations */ +#ifdef _OPENMP + #pragma omp for +#endif + + for (int row = 2; row < height - 2; row++) { + int col = 2 + (FC(row, 3) & 1); + int c = FC(row, col + 1); +#ifdef __SSE2__ + vfloat dLv, dRv, dUv, dDv, v0v; + vfloat onev = F2V(1.f); + vfloat zd5v = F2V(0.5f); + vfloat c65535v = F2V(65535.f); + + for (; col < width - 8; col += 8) { + int indx = row * width + col; + pix[1] = (float*)(*rgb[1]) + indx; + + for (int i = 0; i < 2; c = 2 - c, i++) { + pix[c] = (float*)(*rgb[c]) + indx; + dLv = onev / (onev + vabsf(LC2VFU(pix[1][ -2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][ 1]) - LC2VFU(pix[c][ -1]))); + dRv = onev / (onev + vabsf(LC2VFU(pix[1][ 2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][ 1]) - LC2VFU(pix[c][ -1]))); + dUv = onev / (onev + vabsf(LC2VFU(pix[1][-w2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][w1]) - LC2VFU(pix[c][-w1]))); + dDv = onev / (onev + vabsf(LC2VFU(pix[1][ w2]) - LC2VFU(pix[1][0])) + vabsf(LC2VFU(pix[c][w1]) - LC2VFU(pix[c][-w1]))); + v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v - ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); + STC2VFU(pix[c][0], v0v); + } + } + +#endif + + for (; col < width - 2; col += 2) { + int indx = row * width + col; + pix[1] = (float*)(*rgb[1]) + indx; + + for (int i = 0; i < 2; c = 2 - c, i++) { + pix[c] = (float*)(*rgb[c]) + indx; + float dL = 1.f / (1.f + fabsf(pix[1][ -2] - pix[1][0]) + fabsf(pix[c][ 1] - pix[c][ -1])); + float dR = 1.f / (1.f + fabsf(pix[1][ 2] - pix[1][0]) + fabsf(pix[c][ 1] - pix[c][ -1])); + float dU = 1.f / (1.f + fabsf(pix[1][-w2] - pix[1][0]) + fabsf(pix[c][w1] - pix[c][-w1])); + float dD = 1.f / (1.f + fabsf(pix[1][ w2] - pix[1][0]) + fabsf(pix[c][w1] - pix[c][-w1])); + float v0 = (pix[1][0] + 0.5f - ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); + pix[c][0] = CLIP(v0); + } + } + } + + /* Reinforce integrated red/blue pixels on BLUE/RED pixel locations */ +#ifdef _OPENMP + #pragma omp for +#endif + + for (int row = 2; row < height - 2; row++) { + int col = 2 + (FC(row, 2) & 1); + int c = 2 - FC(row, col); +#ifdef __SSE2__ + vfloat dLv, dRv, dUv, dDv, v0v; + vfloat onev = F2V(1.f); + vfloat zd5v = F2V(0.5f); + vfloat c65535v = F2V(65535.f); + + for (; col < width - 8; col += 8) { + int indx = row * width + col; + pix[0] = (float*)(*rgb[0]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + pix[2] = (float*)(*rgb[2]) + indx; + int d = 2 - c; + dLv = onev / (onev + vabsf(LC2VFU(pix[d][ -2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); + dRv = onev / (onev + vabsf(LC2VFU(pix[d][ 2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][ 1]) - LC2VFU(pix[1][ -1]))); + dUv = onev / (onev + vabsf(LC2VFU(pix[d][-w2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); + dDv = onev / (onev + vabsf(LC2VFU(pix[d][ w2]) - LC2VFU(pix[d][0])) + vabsf(LC2VFU(pix[1][w1]) - LC2VFU(pix[1][-w1]))); + v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v - ((LC2VFU(pix[1][-1]) - LC2VFU(pix[c][-1])) * dLv + (LC2VFU(pix[1][1]) - LC2VFU(pix[c][1])) * dRv + (LC2VFU(pix[1][-w1]) - LC2VFU(pix[c][-w1])) * dUv + (LC2VFU(pix[1][w1]) - LC2VFU(pix[c][w1])) * dDv ) / (dLv + dRv + dUv + dDv)); + STC2VFU(pix[c][0], v0v); + } + +#endif + + for (; col < width - 2; col += 2) { + int indx = row * width + col; + pix[0] = (float*)(*rgb[0]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + pix[2] = (float*)(*rgb[2]) + indx; + int d = 2 - c; + float dL = 1.f / (1.f + fabsf(pix[d][ -2] - pix[d][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); + float dR = 1.f / (1.f + fabsf(pix[d][ 2] - pix[d][0]) + fabsf(pix[1][ 1] - pix[1][ -1])); + float dU = 1.f / (1.f + fabsf(pix[d][-w2] - pix[d][0]) + fabsf(pix[1][w1] - pix[1][-w1])); + float dD = 1.f / (1.f + fabsf(pix[d][ w2] - pix[d][0]) + fabsf(pix[1][w1] - pix[1][-w1])); + float v0 = (pix[1][0] + 0.5f - ((pix[1][ -1] - pix[c][ -1]) * dL + (pix[1][ 1] - pix[c][ 1]) * dR + (pix[1][-w1] - pix[c][-w1]) * dU + (pix[1][ w1] - pix[c][ w1]) * dD ) / (dL + dR + dU + dD)); + pix[c][0] = CLIP(v0); + } + } + } // end parallel + } +} +#ifdef __SSE2__ +#undef CLIPV +#endif + +} /* namespace */ diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc index 259e08565..842766dcf 100644 --- a/rtengine/myfile.cc +++ b/rtengine/myfile.cc @@ -18,8 +18,7 @@ */ #include "myfile.h" #include -#include - +#include "rtengine.h" // get mmap() sorted out #ifdef MYFILE_MMAP diff --git a/rtengine/myfile.h b/rtengine/myfile.h index f2ed4150c..423edea9a 100644 --- a/rtengine/myfile.h +++ b/rtengine/myfile.h @@ -16,13 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYFILE_ -#define _MYFILE_ +#pragma once -#include #include #include -#include "rtengine.h" + +#include + +#include "opthelper.h" + +namespace rtengine +{ + +class ProgressListener; + +} + struct IMFILE { int fd; ssize_t pos; @@ -47,28 +56,26 @@ IMFILE* fopen (const char* fname); IMFILE* gfopen (const char* fname); IMFILE* fopen (unsigned* buf, int size); void fclose (IMFILE* f); -inline int ftell (IMFILE* f) +inline long ftell (IMFILE* f) { - return f->pos; } inline int feof (IMFILE* f) { - return f->eof; } -inline void fseek (IMFILE* f, int p, int how) +inline void fseek (IMFILE* f, long p, int how) { - int fpos = f->pos; + ssize_t fpos = f->pos; if (how == SEEK_SET) { f->pos = p; } else if (how == SEEK_CUR) { f->pos += p; } else if (how == SEEK_END) { - if(p <= 0 && -p <= f->size) { + if (p <= 0 && -p <= f->size) { f->pos = f->size + p; } return; @@ -134,6 +141,3 @@ inline unsigned char* fdata(int offset, IMFILE* f) int fscanf (IMFILE* f, const char* s ...); char* fgets (char* s, int n, IMFILE* f); - -#endif - diff --git a/rtengine/mytime.h b/rtengine/mytime.h index 80fb0899a..787fefcc3 100644 --- a/rtengine/mytime.h +++ b/rtengine/mytime.h @@ -19,7 +19,7 @@ #pragma once #ifdef WIN32 -#include +#include #elif defined __APPLE__ #include #else diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc new file mode 100644 index 000000000..bbbfb7c20 --- /dev/null +++ b/rtengine/panasonic_decoders.cc @@ -0,0 +1,278 @@ +/* + * This file is part of RawTherapee. + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ + +#include +#include "dcraw.h" + +// Code adapted from libraw +/* -*- C++ -*- + * Copyright 2019 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +*/ + +unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) +{ + int byte; + + if (!nbits && !bytes) { + return vbits=0; + } + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + if (encoding == 5) { + for (byte = 0; byte < 16; byte++) + { + bytes[byte] = buf[vbits++]; + vbits &= 0x3FFF; + } + return 0; + } else { + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); + } +} + +class pana_cs6_page_decoder +{ + unsigned int pixelbuffer[14], lastoffset, maxoffset; + unsigned char current, *buffer; +public: + pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) + : pixelbuffer{}, lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) + { + } + void read_page(); // will throw IO error if not enough space in buffer + unsigned int nextpixel() + { + return current < 14 ? pixelbuffer[current++] : 0; + } +}; + +#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) + +void pana_cs6_page_decoder::read_page() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + ; + pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit + pixelbuffer[1] = (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & 0x3fff; + pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; + pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); + pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); + pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); + pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; + pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); + pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); + pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; + pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; + pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); + pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; + pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; + current = 0; + lastoffset += 16; +} +#undef wbuffer + +void DCraw::panasonic_load_raw() +{ + int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; + if (RT_pana_info.encoding == 5) { + pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding); + pana_bits(0, 0); + unsigned bytes[16] = {}; + for (int row = 0; row < raw_height; ++row) { + ushort* raw_block_data = raw_image + row * raw_width; + + for (int col = 0; col < raw_width; col += enc_blck_size) { + pana_bits(0, bytes); + + if (RT_pana_info.bpp == 12) { + raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + else if (RT_pana_info.bpp == 14) { + raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + } + } + } else if (RT_pana_info.encoding == 6) { + panasonicC6_load_raw(); + } else if (RT_pana_info.encoding == 7) { + panasonicC7_load_raw(); + } else { + pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding); + pana_bits(0, 0); + int sh = 0, pred[2], nonz[2]; + for (int row = 0; row < height; ++row) { + for (int col = 0; col < raw_width; ++col) { + int i; + if ((i = col % 14) == 0) { + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + } + if (i % 3 == 2) { + sh = 4 >> (3 - pana_bits(2)); + } + if (nonz[i & 1]) { + int j; + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) { + pred[i & 1] &= ~(-1 << sh); + } + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) { + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + } + if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) { + derror(); + } + } + } + } +} + +void DCraw::panasonicC6_load_raw() +{ + constexpr int rowstep = 16; + const int blocksperrow = raw_width / 11; + const int rowbytes = blocksperrow * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC6_load_raw()"); + + for (int row = 0; row < raw_height - rowstep + 1; row += rowstep) { + const int rowstoread = MIN(rowstep, raw_height - row); + fread(iobuf, rowbytes, rowstoread, ifp); + pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); + for (int crow = 0, col = 0; crow < rowstoread; ++crow, col = 0) { + unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; + for (int rblock = 0; rblock < blocksperrow; rblock++) { + page.read_page(); + unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; + unsigned pmul = 0, pixel_base = 0; + for (int pix = 0; pix < 11; ++pix) { + if (pix % 3 == 2) { + unsigned base = page.nextpixel(); + if (base > 3) { + derror(); + } + if (base == 3) { + base = 4; + } + pixel_base = 0x200 << base; + pmul = 1 << base; + } + unsigned epixel = page.nextpixel(); + if (oddeven[pix % 2]) { + epixel *= pmul; + if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) { + epixel += nonzero[pix % 2] - pixel_base; + } + nonzero[pix % 2] = epixel; + } else { + oddeven[pix % 2] = epixel; + if (epixel) { + nonzero[pix % 2] = epixel; + } else { + epixel = nonzero[pix % 2]; + } + } + const unsigned spix = epixel - 0xf; + if (spix <= 0xffff) { + rowptr[col++] = spix & 0xffff; + } else { + epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); + rowptr[col++] = epixel & 0x3fff; + } + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} + +void DCraw::panasonicC7_load_raw() +{ + constexpr int rowstep = 16; + const int pixperblock = RT_pana_info.bpp == 14 ? 9 : 10; + const int rowbytes = raw_width / pixperblock * 16; + + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC7_load_raw()"); + for (int row = 0; row < raw_height - rowstep + 1; row += rowstep) { + const int rowstoread = MIN(rowstep, raw_height - row); + fread (iobuf, rowbytes, rowstoread, ifp); + unsigned char *bytes = iobuf; + for (int crow = 0; crow < rowstoread; crow++) { + ushort *rowptr = &raw_image[(row + crow) * raw_width]; + for (int col = 0; col < raw_width - pixperblock + 1; col += pixperblock, bytes += 16) { + if (RT_pana_info.bpp == 14) { + rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + rowptr[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + rowptr[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + rowptr[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + rowptr[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } else if (RT_pana_info.bpp == 12) { // have not seen in the wild yet + rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} diff --git a/rtengine/pdaflinesfilter.cc b/rtengine/pdaflinesfilter.cc index d0694fd11..1eddbc1ea 100644 --- a/rtengine/pdaflinesfilter.cc +++ b/rtengine/pdaflinesfilter.cc @@ -18,17 +18,19 @@ * along with RawTherapee. If not, see . */ -#include "pdaflinesfilter.h" -#include "settings.h" #include + #include "camconst.h" +#include "pdaflinesfilter.h" +#include "pixelsmap.h" +#include "rawimage.h" +#include "settings.h" -namespace rtengine { +namespace rtengine +{ -extern const Settings *settings; - - -namespace { +namespace +{ class PDAFGreenEqulibrateThreshold: public RawImageSource::GreenEqulibrateThreshold { static constexpr float BASE_THRESHOLD = 0.5f; @@ -166,8 +168,6 @@ private: } // namespace - - PDAFLinesFilter::PDAFLinesFilter(RawImage *ri): ri_(ri), W_(ri->get_width()), @@ -206,7 +206,7 @@ std::unique_ptr PDAFLinesFilter::lineD } -int PDAFLinesFilter::markLine(array2D &rawData, PixelsMap &bpMap, int y) +int PDAFLinesFilter::markLine(const array2D &rawData, PixelsMap &bpMap, int y) { rowmap_.clear(); rowmap_.resize((W_+1)/2, false); @@ -258,7 +258,7 @@ int PDAFLinesFilter::markLine(array2D &rawData, PixelsMap &bpMap, int y) } -int PDAFLinesFilter::mark(array2D &rawData, PixelsMap &bpMap) +int PDAFLinesFilter::mark(const array2D &rawData, PixelsMap &bpMap) { if (pattern_.empty()) { diff --git a/rtengine/pdaflinesfilter.h b/rtengine/pdaflinesfilter.h index 7f4c7985b..707eb9371 100644 --- a/rtengine/pdaflinesfilter.h +++ b/rtengine/pdaflinesfilter.h @@ -21,10 +21,14 @@ #pragma once #include -#include "rawimagesource.h" -#include "noncopyable.h" -namespace rtengine { +#include "noncopyable.h" +#include "rawimagesource.h" + +namespace rtengine +{ + +class RawImage; class PDAFLinesFilter: public rtengine::NonCopyable { @@ -32,12 +36,12 @@ public: explicit PDAFLinesFilter(RawImage *ri); ~PDAFLinesFilter(); - int mark(array2D &rawData, PixelsMap &bpMap); + int mark(const array2D &rawData, PixelsMap &bpMap); RawImageSource::GreenEqulibrateThreshold &greenEqThreshold(); std::unique_ptr lineDenoiseRowBlender(); private: - int markLine(array2D &rawData, PixelsMap &bpMap, int y); + int markLine(const array2D& rawData, PixelsMap &bpMap, int y); RawImage *ri_; int W_; diff --git a/rtengine/pipettebuffer.cc b/rtengine/pipettebuffer.cc index d915381ef..11cf50ae9 100644 --- a/rtengine/pipettebuffer.cc +++ b/rtengine/pipettebuffer.cc @@ -20,6 +20,7 @@ #include "pipettebuffer.h" #include "imagefloat.h" +#include "labimage.h" #include "../rtgui/editcallbacks.h" diff --git a/rtengine/pipettebuffer.h b/rtengine/pipettebuffer.h index 01b24720c..6f017a196 100644 --- a/rtengine/pipettebuffer.h +++ b/rtengine/pipettebuffer.h @@ -18,8 +18,6 @@ */ #pragma once -#include "array2D.h" -#include "coord.h" #include "iimage.h" class EditDataProvider; @@ -31,6 +29,7 @@ namespace rtengine { class Imagefloat; +class LabImage; /// @brief Structure that contains information about and pointers to the Edit buffer class PipetteBuffer diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 4b93f3f61..2e98b7b22 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -21,16 +21,27 @@ //////////////////////////////////////////////////////////////// #include -#include "rawimagesource.h" -#include "../rtgui/multilangmgr.h" -#include "procparams.h" +#include + +#include "array2D.h" #include "gauss.h" #include "median.h" +#include "procparams.h" +#include "rawimagesource.h" +#include "sleef.h" +#include "../rtgui/multilangmgr.h" +#include "../rtgui/options.h" + //#define BENCHMARK #include "StopWatch.h" + namespace { +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} + float greenDiff(float a, float b, float stddevFactor, float eperIso, float nreadIso, float prnu) { // calculate the difference between two green samples @@ -107,9 +118,9 @@ void xorMasks(int xStart, int xEnd, int yStart, int yEnd, const array2D } } -void floodFill4Impl(int y, int x, int xStart, int xEnd, int yStart, int yEnd, array2D &mask, std::stack, std::vector>> &coordStack) +void floodFill4Impl(int yin, int xin, int xStart, int xEnd, int yStart, int yEnd, array2D &mask, std::stack, std::vector>> &coordStack) { - coordStack.emplace(x, y); + coordStack.emplace(xin, yin); while(!coordStack.empty()) { auto coord = coordStack.top(); @@ -295,7 +306,7 @@ void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUTu *histo using namespace std; using namespace rtengine; -void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RAWParams &rawParamsIn, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection) +void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const procparams::RAWParams &rawParamsIn, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection) { BENCHFUN if(numFrames != 4) { // fallback for non pixelshift files @@ -303,19 +314,20 @@ BENCHFUN return; } - RAWParams::BayerSensor bayerParams = rawParamsIn.bayersensor; + procparams::RAWParams::BayerSensor bayerParams = rawParamsIn.bayersensor; bool motionDetection = true; - if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO) { + if(bayerParams.pixelShiftMotionCorrectionMethod == procparams::RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO) { bool pixelShiftEqualBright = bayerParams.pixelShiftEqualBright; bayerParams.setPixelShiftDefaults(); bayerParams.pixelShiftEqualBright = pixelShiftEqualBright; - } else if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::OFF) { + } else if(bayerParams.pixelShiftMotionCorrectionMethod == procparams::RAWParams::BayerSensor::PSMotionCorrectionMethod::OFF) { motionDetection = false; bayerParams.pixelShiftShowMotion = false; } + const unsigned int cfarray[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; const bool showMotion = bayerParams.pixelShiftShowMotion; const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; @@ -323,9 +335,11 @@ BENCHFUN if(motionDetection) { if(!showOnlyMask) { if(bayerParams.pixelShiftMedian) { // We need the demosaiced frames for motion correction - if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { + if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { lmmse_interpolate_omp(winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.lmmse_iterations); - } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { + dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.dualDemosaicContrast, true); + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::RCDVNG4)) { dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.dualDemosaicContrast, true); } else { amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[0]), red, green, blue, options.chunkSizeAMAZE, options.measure); @@ -335,9 +349,11 @@ BENCHFUN multi_array2D blueTmp(winw, winh); for(int i = 0; i < 3; i++) { - if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { + if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { lmmse_interpolate_omp(winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], bayerParams.lmmse_iterations); - } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { + dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], bayerParams.dualDemosaicContrast, true); + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::RCDVNG4)) { dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], bayerParams.dualDemosaicContrast, true); } else { amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], options.chunkSizeAMAZE, options.measure); @@ -362,11 +378,15 @@ BENCHFUN } } } else { - if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { + if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::LMMSE)) { lmmse_interpolate_omp(winw, winh, rawData, red, green, blue, bayerParams.lmmse_iterations); - } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { - RAWParams rawParamsTmp = rawParamsIn; - rawParamsTmp.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4); + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { + procparams::RAWParams rawParamsTmp = rawParamsIn; + rawParamsTmp.bayersensor.method = procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4); + dual_demosaic_RT (true, rawParamsTmp, winw, winh, rawData, red, green, blue, bayerParams.dualDemosaicContrast, true); + } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(procparams::RAWParams::BayerSensor::PSDemosaicMethod::RCDVNG4)) { + procparams::RAWParams rawParamsTmp = rawParamsIn; + rawParamsTmp.bayersensor.method = procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4); dual_demosaic_RT (true, rawParamsTmp, winw, winh, rawData, red, green, blue, bayerParams.dualDemosaicContrast, true); } else { amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); @@ -634,11 +654,11 @@ BENCHFUN for(int i = winy + 1; i < winh - 1; ++i) { int j = winx + 1; - int c = FC(i, j); + int c = fc(cfarray, i, j); - bool bluerow = (c + FC(i, j + 1)) == 3; + bool bluerow = (c + fc(cfarray, i, j + 1)) == 3; - for(int j = winx + 1, offset = FC(i, j) & 1; j < winw - 1; ++j, offset ^= 1) { + for(int j = winx + 1, offset = fc(cfarray, i, j) & 1; j < winw - 1; ++j, offset ^= 1) { (*histogreenThr[1 - offset])[(*rawDataFrames[1 - offset])[i - offset + 1][j]]++; (*histogreenThr[3 - offset])[(*rawDataFrames[3 - offset])[i + offset][j + 1]]++; @@ -719,9 +739,9 @@ BENCHFUN }; int ng = 0; int j = winx + 1; - int c = FC(i, j); + int c = fc(cfarray, i, j); - if((c + FC(i, j + 1)) == 3) { + if((c + fc(cfarray, i, j + 1)) == 3) { // row with blue pixels => swap destination pointers for non green pixels std::swap(nonGreenDest0, nonGreenDest1); ng ^= 1; @@ -776,7 +796,7 @@ BENCHFUN for(int i = winy + border - offsY; i < winh - (border + offsY); ++i) { // offset to keep the code short. It changes its value between 0 and 1 for each iteration of the loop - unsigned int offset = FC(i, winx + border - offsX) & 1; + unsigned int offset = fc(cfarray, i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { psMask[i][j] = noMotion; @@ -912,7 +932,7 @@ BENCHFUN float *blueDest = blue[i + offsY]; // offset to keep the code short. It changes its value between 0 and 1 for each iteration of the loop - unsigned int offset = FC(i, winx + border - offsX) & 1; + unsigned int offset = fc(cfarray, i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { if(showOnlyMask) { @@ -962,9 +982,9 @@ BENCHFUN float *nonGreenDest1 = blue[i]; int ng = 0; int j = winx + 1; - int c = FC(i, j); + int c = fc(cfarray, i, j); - if((c + FC(i, j + 1)) == 3) { + if((c + fc(cfarray, i, j + 1)) == 3) { // row with blue pixels => swap destination pointers for non green pixels std::swap(nonGreenDest0, nonGreenDest1); ng ^= 1; diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index 7216e6a34..de1603f1c 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -19,6 +19,7 @@ #include "previewimage.h" +#include "color.h" #include "iimage.h" #include "iimage.h" #include "procparams.h" diff --git a/rtengine/previewimage.h b/rtengine/previewimage.h index 71ddefe8a..e6c3ea070 100644 --- a/rtengine/previewimage.h +++ b/rtengine/previewimage.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREVIEWIMAGE_ -#define _PREVIEWIMAGE_ +#pragma once + +#include -#include #include namespace rtengine @@ -52,5 +52,3 @@ public: }; } - -#endif diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h index 004eb006f..6cdc6bd7c 100644 --- a/rtengine/processingjob.h +++ b/rtengine/processingjob.h @@ -16,11 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROCESSINGJOB_ -#define _PROCESSINGJOB_ +#pragma once -#include "rtengine.h" #include "procparams.h" +#include "rtengine.h" namespace rtengine { @@ -55,5 +54,3 @@ public: }; } - -#endif diff --git a/rtengine/procevents.h b/rtengine/procevents.h index ca098f216..1b00d4218 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -16,15 +16,11 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __PROCEVENT__ -#define __PROCEVENT__ +#pragma once namespace rtengine { - - - // Aligned so the first entry starts on line 30 enum ProcEventCode { EvPhotoLoaded = 0, @@ -540,13 +536,11 @@ private: }; -inline bool operator==(ProcEvent a, ProcEvent b) { return int(a) == int(b); } -inline bool operator==(ProcEvent a, ProcEventCode b) { return int(a) == int(b); } -inline bool operator==(ProcEventCode a, ProcEvent b) { return int(a) == int(b); } -inline bool operator!=(ProcEvent a, ProcEvent b) { return int(a) != int(b); } -inline bool operator!=(ProcEvent a, ProcEventCode b) { return int(a) != int(b); } -inline bool operator!=(ProcEventCode a, ProcEvent b) { return int(a) != int(b); } +inline bool operator ==(ProcEvent a, ProcEvent b) { return int(a) == int(b); } +inline bool operator ==(ProcEvent a, ProcEventCode b) { return int(a) == int(b); } +inline bool operator ==(ProcEventCode a, ProcEvent b) { return int(a) == int(b); } +inline bool operator !=(ProcEvent a, ProcEvent b) { return int(a) != int(b); } +inline bool operator !=(ProcEvent a, ProcEventCode b) { return int(a) != int(b); } +inline bool operator !=(ProcEventCode a, ProcEvent b) { return int(a) != int(b); } } -#endif - diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index cacf5672b..27e9066dc 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -22,9 +22,14 @@ #include #include +#include +#include +#include +#include "color.h" #include "curves.h" #include "procparams.h" +#include "utils.h" #include "../rtgui/multilangmgr.h" #include "../rtgui/options.h" @@ -1158,9 +1163,10 @@ CaptureSharpeningParams::CaptureSharpeningParams() : autoContrast(true), autoRadius(true), contrast(10.0), - gamma(1.00), deconvradius(0.75), - deconviter(20) + deconvradiusOffset(0.0), + deconviter(20), + deconvitercheck(true) { } @@ -1169,10 +1175,11 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) return enabled == other.enabled && contrast == other.contrast - && gamma == other.gamma && autoContrast == other.autoContrast && autoRadius == other.autoRadius && deconvradius == other.deconvradius + && deconvitercheck == other.deconvitercheck + && deconvradiusOffset == other.deconvradiusOffset && deconviter == other.deconviter; } @@ -2572,7 +2579,8 @@ DehazeParams::DehazeParams() : enabled(false), strength(50), showDepthMap(false), - depth(25) + depth(25), + luminance(false) { } @@ -2582,7 +2590,8 @@ bool DehazeParams::operator ==(const DehazeParams& other) const enabled == other.enabled && strength == other.strength && showDepthMap == other.showDepthMap - && depth == other.depth; + && depth == other.depth + && luminance == other.luminance; } bool DehazeParams::operator !=(const DehazeParams& other) const @@ -2718,6 +2727,7 @@ const std::vector& RAWParams::BayerSensor::getPSDemosaicMethodStrin static const std::vector method_strings { "amaze", "amazevng4", + "rcdvng4", "lmmse" }; return method_strings; @@ -3293,6 +3303,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Luminance", dehaze.luminance, keyFile); // Directional pyramid denoising saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile); @@ -3428,8 +3439,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.autoContrast, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile); - saveToKeyfile(!pedited || pedited->pdsharpening.gamma, "PostDemosaicSharpening", "DeconvGamma", pdsharpening.gamma, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.deconvitercheck, "PostDemosaicSharpening", "DeconvIterCheck", pdsharpening.deconvitercheck, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); // Post resize sharpening @@ -4564,9 +4576,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); - - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterCheck", pedited, pdsharpening.deconvitercheck, pedited->pdsharpening.deconvitercheck); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); } @@ -4980,6 +4992,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Dehaze", "Strength", pedited, dehaze.strength, pedited->dehaze.strength); assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap); assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth); + assignFromKeyfile(keyFile, "Dehaze", "Luminance", pedited, dehaze.luminance, pedited->dehaze.luminance); } if (keyFile.has_group("Film Simulation")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 14a104c0a..e934f9ed9 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -20,10 +20,11 @@ #include #include +#include #include #include -#include +#include #include #include "coord.h" @@ -548,9 +549,10 @@ struct CaptureSharpeningParams { bool autoContrast; bool autoRadius; double contrast; - double gamma; double deconvradius; + double deconvradiusOffset; int deconviter; + bool deconvitercheck; CaptureSharpeningParams(); @@ -1378,6 +1380,7 @@ struct DehazeParams { int strength; bool showDepthMap; int depth; + bool luminance; DehazeParams(); @@ -1421,6 +1424,7 @@ struct RAWParams { enum class PSDemosaicMethod { AMAZE, AMAZEVNG4, + RCDVNG4, LMMSE }; diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 5c38cf705..7d937e736 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -16,6 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include +#include + #include "profilestore.h" #include "dynamicprofile.h" @@ -156,7 +160,7 @@ void ProfileStore::_parseProfiles () if (findEntryFromFullPathU (options.defProfRaw) == nullptr) { options.setDefProfRawMissing (true); - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("WARNING: Default profile \"%s\" for raw images not found!\n", options.defProfRaw.c_str()); } } @@ -164,7 +168,7 @@ void ProfileStore::_parseProfiles () if (findEntryFromFullPathU (options.defProfImg) == nullptr) { options.setDefProfImgMissing (true); - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("WARNING: Default profile \"%s\" for standard images not found!\n", options.defProfImg.c_str()); } } @@ -216,7 +220,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath if (lastdot != Glib::ustring::npos && lastdot == currDir.length() - 4 && currDir.substr (lastdot).casefold() == paramFileExtension) { // file found - if ( options.rtSettings.verbose ) { + if (settings->verbose) { printf ("Processing file %s...", fname.c_str()); } @@ -229,7 +233,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath if (!res && pProf->pparams->ppVersion >= 220) { fileFound = true; - if ( options.rtSettings.verbose ) { + if (settings->verbose) { printf ("OK\n"); } @@ -240,7 +244,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath // map the partial profile partProfiles[filePSE] = pProf; //partProfiles.insert( std::pair (filePSE, pProf) ); - } else if ( options.rtSettings.verbose ) { + } else if (settings->verbose) { printf ("failed!\n"); } } @@ -518,7 +522,7 @@ PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) for (auto rule : dynamicRules) { if (rule.matches (im)) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("found matching profile %s\n", rule.profilepath.c_str()); } diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 384aa2a46..460facb72 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -16,16 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROFILESTORE_ -#define _PROFILESTORE_ +#pragma once #include #include -#include -#include "rtengine.h" -#include "noncopyable.h" +#include + #include "dynamicprofile.h" +#include "noncopyable.h" +#include "../rtgui/threadutils.h" // forward decl namespace rtengine @@ -34,6 +34,8 @@ namespace rtengine namespace procparams { +class ProcParams; + class AutoPartialProfile; class PartialProfile; @@ -211,5 +213,3 @@ public: void dumpFolderList(); }; - -#endif diff --git a/rtengine/rawflatfield.cc b/rtengine/rawflatfield.cc new file mode 100644 index 000000000..05b3be408 --- /dev/null +++ b/rtengine/rawflatfield.cc @@ -0,0 +1,537 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2019 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ + +#include +#include +#include + +#include "rawimagesource.h" +#include "procparams.h" +#include "rawimage.h" +//#define BENCHMARK +//#include "StopWatch.h" +#include "opthelper.h" + +namespace { + +void cfaboxblur(const float* const * riFlatFile, float* cfablur, int boxH, int boxW, int H, int W) +{ + if (boxW < 0 || boxH < 0 || (boxW == 0 && boxH == 0)) { // nothing to blur or negative values + memcpy(cfablur, riFlatFile[0], static_cast(W) * H * sizeof(float)); + return; + } + + std::unique_ptr tmpBuffer; + float *cfatmp = cfablur; + + + if (boxH > 0 && boxW > 0) { + // we need a temporary buffer if we have to blur both directions + tmpBuffer.reset(new float [H * W]); + cfatmp = tmpBuffer.get(); + } + + // if boxW == 0 we can skip the horizontal blur and process the vertical blur from riFlatFile to cfablur without using a temporary buffer + const float* srcVertical = boxW == 0 ? riFlatFile[0] : cfatmp; + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + + if (boxW > 0) { + //box blur cfa image; box size = BS + //horizontal blur +#ifdef _OPENMP + #pragma omp for +#endif + + for (int row = 0; row < H; ++row) { + int len = boxW / 2 + 1; + cfatmp[row * W] = riFlatFile[row][0] / len; + cfatmp[row * W + 1] = riFlatFile[row][1] / len; + + for (int j = 2; j <= boxW; j += 2) { + cfatmp[row * W] += riFlatFile[row][j] / len; + cfatmp[row * W + 1] += riFlatFile[row][j + 1] / len; + } + + for (int col = 2; col <= boxW; col += 2) { + cfatmp[row * W + col] = (cfatmp[row * W + col - 2] * len + riFlatFile[row][boxW + col]) / (len + 1); + cfatmp[row * W + col + 1] = (cfatmp[row * W + col - 1] * len + riFlatFile[row][boxW + col + 1]) / (len + 1); + len ++; + } + + const float rlen = 1.f / len; + for (int col = boxW + 2; col < W - boxW; col++) { + cfatmp[row * W + col] = cfatmp[row * W + col - 2] + (riFlatFile[row][boxW + col] - cfatmp[row * W + col - boxW - 2]) * rlen; + } + + for (int col = W - boxW; col < W; col += 2) { + cfatmp[row * W + col] = (cfatmp[row * W + col - 2] * len - cfatmp[row * W + col - boxW - 2]) / (len - 1); + + if (col + 1 < W) { + cfatmp[row * W + col + 1] = (cfatmp[row * W + col - 1] * len - cfatmp[row * W + col - boxW - 1]) / (len - 1); + } + + len --; + } + } + } + + if (boxH > 0) { + //vertical blur +#ifdef __SSE2__ + const vfloat leninitv = F2V(boxH / 2 + 1); + const vfloat onev = F2V(1.f); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int col = 0; col < W - 7; col += 8) { + vfloat lenv = leninitv; + vfloat temp1v = LVFU(srcVertical[col]) / lenv; + vfloat temp2v = LVFU(srcVertical[W + col]) / lenv; + vfloat temp3v = LVFU(srcVertical[col + 4]) / lenv; + vfloat temp4v = LVFU(srcVertical[W + col + 4]) / lenv; + + for (int i = 2; i < boxH + 2; i += 2) { + temp1v += LVFU(srcVertical[i * W + col]) / lenv; + temp2v += LVFU(srcVertical[(i + 1) * W + col]) / lenv; + temp3v += LVFU(srcVertical[i * W + col + 4]) / lenv; + temp4v += LVFU(srcVertical[(i + 1) * W + col + 4]) / lenv; + } + + STVFU(cfablur[col], temp1v); + STVFU(cfablur[W + col], temp2v); + STVFU(cfablur[col + 4], temp3v); + STVFU(cfablur[W + col + 4], temp4v); + + int row; + for (row = 2; row < boxH + 2; row += 2) { + const vfloat lenp1v = lenv + onev; + temp1v = (temp1v * lenv + LVFU(srcVertical[(row + boxH) * W + col])) / lenp1v; + temp2v = (temp2v * lenv + LVFU(srcVertical[(row + boxH + 1) * W + col])) / lenp1v; + temp3v = (temp3v * lenv + LVFU(srcVertical[(row + boxH) * W + col + 4])) / lenp1v; + temp4v = (temp4v * lenv + LVFU(srcVertical[(row + boxH + 1) * W + col + 4])) / lenp1v; + STVFU(cfablur[row * W + col], temp1v); + STVFU(cfablur[(row + 1) * W + col], temp2v); + STVFU(cfablur[row * W + col + 4], temp3v); + STVFU(cfablur[(row + 1) * W + col + 4], temp4v); + lenv = lenp1v; + } + + for (; row < H - boxH - 1; row += 2) { + temp1v = temp1v + (LVFU(srcVertical[(row + boxH) * W + col]) - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenv; + temp2v = temp2v + (LVFU(srcVertical[(row + 1 + boxH) * W + col]) - LVFU(srcVertical[(row + 1 - boxH - 2) * W + col])) / lenv; + temp3v = temp3v + (LVFU(srcVertical[(row + boxH) * W + col + 4]) - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenv; + temp4v = temp4v + (LVFU(srcVertical[(row + 1 + boxH) * W + col + 4]) - LVFU(srcVertical[(row + 1 - boxH - 2) * W + col + 4])) / lenv; + STVFU(cfablur[row * W + col], temp1v); + STVFU(cfablur[(row + 1) * W + col], temp2v); + STVFU(cfablur[row * W + col + 4], temp3v); + STVFU(cfablur[(row + 1) * W + col + 4], temp4v); + } + + if (row < H - boxH) { + temp1v = temp1v + (LVFU(srcVertical[(row + boxH) * W + col]) - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenv; + temp3v = temp3v + (LVFU(srcVertical[(row + boxH) * W + col + 4]) - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenv; + STVFU(cfablur[row * W + col], temp1v); + STVFU(cfablur[row * W + col + 4], temp3v); + vfloat swapv = temp1v; + temp1v = temp2v; + temp2v = swapv; + swapv = temp3v; + temp3v = temp4v; + temp4v = swapv; + ++row; + } + + for (; row < H - 1; row += 2) { + const vfloat lenm1v = lenv - onev; + temp1v = (temp1v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenm1v; + temp2v = (temp2v * lenv - LVFU(srcVertical[(row - boxH - 1) * W + col])) / lenm1v; + temp3v = (temp3v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenm1v; + temp4v = (temp4v * lenv - LVFU(srcVertical[(row - boxH - 1) * W + col + 4])) / lenm1v; + STVFU(cfablur[row * W + col], temp1v); + STVFU(cfablur[(row + 1) * W + col], temp2v); + STVFU(cfablur[row * W + col + 4], temp3v); + STVFU(cfablur[(row + 1) * W + col + 4], temp4v); + lenv = lenm1v; + } + + if (row < H) { + vfloat lenm1v = lenv - onev; + temp1v = (temp1v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenm1v; + temp3v = (temp3v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenm1v; + STVFU(cfablur[row * W + col], temp1v); + STVFU(cfablur[row * W + col + 4], temp3v); + } + + } + +#ifdef _OPENMP + #pragma omp single +#endif + + for (int col = W - (W % 8); col < W; ++col) { + int len = boxH / 2 + 1; + cfablur[col] = srcVertical[col] / len; + cfablur[W + col] = srcVertical[W + col] / len; + + for (int i = 2; i < boxH + 2; i += 2) { + cfablur[col] += srcVertical[i * W + col] / len; + cfablur[W + col] += srcVertical[(i + 1) * W + col] / len; + } + + for (int row = 2; row < boxH + 2; row += 2) { + cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + srcVertical[(row + boxH) * W + col]) / (len + 1); + cfablur[(row + 1) * W + col] = (cfablur[(row - 1) * W + col] * len + srcVertical[(row + boxH + 1) * W + col]) / (len + 1); + ++len; + } + + for (int row = boxH + 2; row < H - boxH; ++row) { + cfablur[row * W + col] = cfablur[(row - 2) * W + col] + (srcVertical[(row + boxH) * W + col] - srcVertical[(row - boxH - 2) * W + col]) / len; + } + + for (int row = H - boxH; row < H; row += 2) { + cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len - srcVertical[(row - boxH - 2) * W + col]) / (len - 1); + + if (row + 1 < H) { + cfablur[(row + 1) * W + col] = (cfablur[(row - 1) * W + col] * len - srcVertical[(row - boxH - 1) * W + col]) / (len - 1); + } + --len; + } + } + +#else +#ifdef _OPENMP + #pragma omp for +#endif + + for (int col = 0; col < W; ++col) { + int len = boxH / 2 + 1; + cfablur[col] = srcVertical[col] / len; + cfablur[W + col] = srcVertical[W + col] / len; + + for (int i = 2; i < boxH + 2; i += 2) { + cfablur[col] += srcVertical[i * W + col] / len; + cfablur[W + col] += srcVertical[(i + 1) * W + col] / len; + } + + for (int row = 2; row < boxH + 2; row += 2) { + cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + srcVertical[(row + boxH) * W + col]) / (len + 1); + cfablur[(row + 1) * W + col] = (cfablur[(row - 1) * W + col] * len + srcVertical[(row + boxH + 1) * W + col]) / (len + 1); + ++len; + } + + for (int row = boxH + 2; row < H - boxH; ++row) { + cfablur[row * W + col] = cfablur[(row - 2) * W + col] + (srcVertical[(row + boxH) * W + col] - srcVertical[(row - boxH - 2) * W + col]) / len; + } + + for (int row = H - boxH; row < H; row += 2) { + cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len - srcVertical[(row - boxH - 2) * W + col]) / (len - 1); + + if (row + 1 < H) { + cfablur[(row + 1) * W + col] = (cfablur[(row - 1) * W + col] * len - srcVertical[(row - boxH - 1) * W + col]) / (len - 1); + } + --len; + } + } +#endif + } + } +} + +} + +namespace rtengine +{ + +void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const unsigned short black[4]) +{ +// BENCHFUN + const float fblack[4] = {static_cast(black[0]), static_cast(black[1]), static_cast(black[2]), static_cast(black[3])}; + std::unique_ptr cfablur(new float[H * W]); + + const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1); + + if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::V)) { + cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W); + } else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::H)) { + cfaboxblur(riFlatFile->data, cfablur.get(), 0, 2 * BS, H, W); + } else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::VH)) { + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile->data, cfablur.get(), BS, BS, H, W); //first do area blur to correct vignette + } else { //(raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::area_ff)) + cfaboxblur(riFlatFile->data, cfablur.get(), BS, BS, H, W); + } + + if (ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) { + float refcolor[2][2]; + + // find center values by channel + for (int m = 0; m < 2; ++m) + for (int n = 0; n < 2; ++n) { + const int row = 2 * (H >> 2) + m; + 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]); + } + + float limitFactor = 1.f; + + if (raw.ff_AutoClipControl) { + bool clippedBefore = false; + for (int m = 0; m < 2 && !clippedBefore; ++m) { + for (int n = 0; n < 2 && !clippedBefore; ++n) { + float maxval = 0.f; + const int c = ri->get_colors() != 1 ? FC(m, n) : 0; + const int c4 = ri->get_colors() != 1 ? ((c == 1 && !(m & 1)) ? 3 : c) : 0; + const float clipVal = ri->get_white(c4); +#ifdef _OPENMP + #pragma omp parallel for reduction(max:maxval) schedule(dynamic, 16) +#endif + for (int row = 0; row < H - m; row += 2) { + for (int col = 0; col < W - n && !clippedBefore; col += 2) { + const float rawVal = rawData[row + m][col + n]; + if (rawVal >= clipVal) { + clippedBefore = true; + break; + } + const float tempval = (rawVal - fblack[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - fblack[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 (!clippedBefore) { + limitFactor = std::min(limitFactor, ri->get_white(c4) / (maxval + fblack[c4])); + } else { + limitFactor = 1.f; + } + } + } + } + flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui + } else { + limitFactor = std::max((100 - raw.ff_clipControl) / 100.f, 0.01f); + } + + for (int m = 0; m < 2; ++m) + for (int n = 0; n < 2; ++n) { + refcolor[m][n] *= limitFactor; + } + + unsigned int c[2][2] {}; + unsigned int c4[2][2] {}; + if (ri->get_colors() != 1) { + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 2; ++j) { + c[i][j] = FC(i, j); + } + } + c4[0][0] = (c[0][0] == 1) ? 3 : c[0][0]; + c4[0][1] = (c[0][1] == 1) ? 3 : c[0][1]; + c4[1][0] = c[1][0]; + c4[1][1] = c[1][1]; + } + + constexpr float minValue = 1.f; // if the pixel value in the flat field is less or equal this value, no correction will be applied. + +#ifdef __SSE2__ + 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 onev = F2V(1.f); + const vfloat minValuev = F2V(minValue); +#endif +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int row = 0; row < H; ++row) { + int col = 0; +#ifdef __SSE2__ + const vfloat rowBlackv = blackv[row & 1]; + const vfloat rowRefcolorv = refcolorv[row & 1]; + + for (; col < W - 3; col += 4) { + const vfloat blurv = LVFU(cfablur[row * W + col]) - rowBlackv; + vfloat vignettecorrv = rowRefcolorv / blurv; + vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv); + const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; + STVFU(rawData[row][col], valv * vignettecorrv + rowBlackv); + } + +#endif + + for (; col < W; ++col) { + const float blur = cfablur[row * W + col] - fblack[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]]; + } + } + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { + float refcolor[3] = {0.f}; + int cCount[3] = {0}; + + // find center average values by channel + for (int m = -3; m < 3; ++m) + for (int n = -3; n < 3; ++n) { + 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]); + cCount[c] ++; + } + + for (int c = 0; c < 3; ++c) { + refcolor[c] = refcolor[c] / cCount[c]; + } + + float limitFactor = 1.f; + + if (raw.ff_AutoClipControl) { + // determine maximum calculated value to avoid clipping + bool clippedBefore = false; + const float clipVal = ri->get_white(0); + float maxval = 0.f; + // xtrans files have only one black level actually, so we can simplify the code a bit +#ifdef _OPENMP + #pragma omp parallel for reduction(max:maxval) schedule(dynamic,16) +#endif + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W && !clippedBefore; ++col) { + const float rawVal = rawData[row][col]; + if (rawVal >= clipVal) { + clippedBefore = true; + break; + } + const float tempval = (rawVal - fblack[0]) * (refcolor[ri->XTRANSFC(row, col)] / std::max(1e-5f, cfablur[(row) * W + col] - fblack[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]); + flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui + } + } else { + limitFactor = std::max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f); + } + + + for (int c = 0; c < 3; ++c) { + refcolor[c] *= limitFactor; + } + + constexpr float minValue = 1.f; // if the pixel value in the flat field is less or equal this value, no correction will be applied. + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + 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 vignettecorr = blur <= minValue ? 1.f : refcolor[c] / blur; + rawData[row][col] = (rawData[row][col] - fblack[c]) * vignettecorr + fblack[c]; + } + } + } + + if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::VH)) { + std::unique_ptr cfablur1(new float[H * W]); + std::unique_ptr cfablur2(new float[H * W]); + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile->data, cfablur1.get(), 0, 2 * BS, H, W); //now do horizontal blur + cfaboxblur(riFlatFile->data, cfablur2.get(), 2 * BS, 0, H, W); //now do vertical blur + + if (ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) { + unsigned int c[2][2] {}; + unsigned int c4[2][2] {}; + if (ri->get_colors() != 1) { + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 2; ++j) { + c[i][j] = FC(i, j); + } + } + c4[0][0] = (c[0][0] == 1) ? 3 : c[0][0]; + c4[0][1] = (c[0][1] == 1) ? 3 : c[0][1]; + c4[1][0] = c[1][0]; + c4[1][1] = c[1][1]; + } + +#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 epsv = F2V(1e-5f); +#endif +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int row = 0; row < H; ++row) { + int col = 0; +#ifdef __SSE2__ + const vfloat rowBlackv = blackv[row & 1]; + + for (; col < W - 3; col += 4) { + const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) / + (vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, epsv)); + const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; + STVFU(rawData[row][col], valv * linecorrv + rowBlackv); + } + +#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]]; + } + } + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + + 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]; + } + } + } + } +} +} /* namespace */ diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 0134d4d16..4421e4af4 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -15,12 +15,11 @@ #include "settings.h" #include "camconst.h" #include "utils.h" +#include "rtengine.h" namespace rtengine { -extern const Settings* settings; - RawImage::RawImage( const Glib::ustring &name ) : data(nullptr) , prefilters(0) diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 9c6d42969..09aaed7ad 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -16,12 +16,12 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __RAWIMAGE_H -#define __RAWIMAGE_H +#pragma once #include #include #include +#include #include "dcraw.h" #include "imageformat.h" @@ -307,5 +307,3 @@ public: }; } - -#endif // __RAWIMAGE_H diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 5f1d13c79..ea3152918 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -19,32 +19,38 @@ #include #include -#include "rtengine.h" -#include "rawimagesource.h" -#include "rawimagesource_i.h" -#include "jaggedarray.h" -#include "median.h" -#include "rawimage.h" -#include "mytime.h" -#include "iccstore.h" +#include "camconst.h" +#include "color.h" #include "curves.h" +#include "dcp.h" #include "dfmanager.h" #include "ffmanager.h" -#include "dcp.h" -#include "rt_math.h" +#include "iccstore.h" +#include "imagefloat.h" #include "improcfun.h" -#include "rtlensfun.h" +#include "jaggedarray.h" +#include "median.h" +#include "mytime.h" #include "pdaflinesfilter.h" -#include "camconst.h" #include "procparams.h" -#include "color.h" +#include "rawimage.h" +#include "rawimagesource_i.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "rtengine.h" +#include "rtlensfun.h" +#include "../rtgui/options.h" + //#define BENCHMARK //#include "StopWatch.h" + #ifdef _OPENMP #include #endif + #include "opthelper.h" #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) + #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -419,7 +425,6 @@ void transLineD1x (const float* const red, const float* const green, const float namespace rtengine { -extern const Settings* settings; #undef ABS #undef DIST @@ -500,6 +505,26 @@ RawImageSource::~RawImageSource () } } +unsigned RawImageSource::FC(int row, int col) const +{ + return ri->FC(row, col); +} + +eSensorType RawImageSource::getSensorType () const +{ + return ri != nullptr ? ri->getSensorType() : ST_NONE; +} + +bool RawImageSource::isMono() const +{ + return ri->get_colors() == 1; +} + +int RawImageSource::getRotateDegree() const +{ + return ri->get_rotateDegree(); +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void RawImageSource::transformRect (const PreviewProps &pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) @@ -913,7 +938,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima } } -DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as) +DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileApplyState &as) { if (cmp.inputProfile == "(camera)" || cmp.inputProfile == "(none)") { return nullptr; @@ -1360,7 +1385,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (!hasFlatField && lensProf.useVign && lensProf.lcMode != LensProfParams::LcMode::NONE) { std::unique_ptr pmap; if (lensProf.useLensfun()) { - pmap = LFDatabase::findModifier(lensProf, idata, W, H, coarse, -1); + pmap = LFDatabase::getInstance()->findModifier(lensProf, idata, W, H, coarse, -1); } else { const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile(lensProf.lcpFile); @@ -1374,32 +1399,13 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) { if(numFrames == 4) { for(int i = 0; i < 4; ++i) { -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int y = 0; y < H; y++) { - map.processVignetteLine(W, y, (*rawDataFrames[i])[y]); - } + map.processVignette(W, H, *rawDataFrames[i]); } } else { - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int y = 0; y < H; y++) { - map.processVignetteLine(W, y, rawData[y]); - } + map.processVignette(W, H, rawData); } } else if(ri->get_colors() == 3) { -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int y = 0; y < H; y++) { - map.processVignetteLine3Channels(W, y, rawData[y]); - } + map.processVignette3Channels(W, H, rawData); } } } @@ -1950,8 +1956,8 @@ void RawImageSource::retinexPrepareCurves(const RetinexParams &retinexParams, LU CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI); } - CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); - + CurveFactory::mapcurve(mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); + mapcurve *= 0.5f; retinexParams.getCurves(retinextransmissionCurve, retinexgaintransmissionCurve); } @@ -2386,311 +2392,6 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) } - -void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]) -{ -// BENCHFUN - float *cfablur = (float (*)) malloc (H * W * sizeof * cfablur); - int BS = raw.ff_BlurRadius; - BS += BS & 1; - - //function call to cfabloxblur - if (raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::FlatFieldBlurType::V)) { - cfaboxblur(riFlatFile, cfablur, 2 * BS, 0); - } else if (raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::FlatFieldBlurType::H)) { - cfaboxblur(riFlatFile, cfablur, 0, 2 * BS); - } else if (raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::FlatFieldBlurType::VH)) { - //slightly more complicated blur if trying to correct both vertical and horizontal anomalies - cfaboxblur(riFlatFile, cfablur, BS, BS); //first do area blur to correct vignette - } else { //(raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::area_ff)) - cfaboxblur(riFlatFile, cfablur, BS, BS); - } - - if(ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) { - float refcolor[2][2]; - - //find centre average values by channel - for (int m = 0; m < 2; m++) - for (int n = 0; n < 2; n++) { - int row = 2 * (H >> 2) + m; - int col = 2 * (W >> 2) + n; - int c = ri->get_colors() != 1 ? FC(row, col) : 0; - int c4 = ri->get_colors() != 1 ? (( c == 1 && !(row & 1) ) ? 3 : c) : 0; - refcolor[m][n] = max(0.0f, cfablur[row * W + col] - black[c4]); - } - - float limitFactor = 1.f; - - if(raw.ff_AutoClipControl) { - for (int m = 0; m < 2; m++) - for (int n = 0; n < 2; n++) { - float maxval = 0.f; - int c = ri->get_colors() != 1 ? FC(m, n) : 0; - int c4 = ri->get_colors() != 1 ? (( c == 1 && !(m & 1) ) ? 3 : c) : 0; -#ifdef _OPENMP - #pragma omp parallel -#endif - { - float maxvalthr = 0.f; -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 0; row < H - m; row += 2) { - for (int col = 0; col < W - n; col += 2) { - float tempval = (rawData[row + m][col + n] - black[c4]) * ( refcolor[m][n] / max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]) ); - - if(tempval > maxvalthr) { - maxvalthr = tempval; - } - } - } - -#ifdef _OPENMP - #pragma omp critical -#endif - { - - if(maxvalthr > maxval) { - maxval = maxvalthr; - } - - } - } - - // now we have the max value for the channel - // if it clips, calculate factor to avoid clipping - if(maxval + black[c4] >= ri->get_white(c4)) { - limitFactor = min(limitFactor, ri->get_white(c4) / (maxval + black[c4])); - } - } - - flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui - } else { - limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f); - } - - for (int m = 0; m < 2; m++) - for (int n = 0; n < 2; n++) { - refcolor[m][n] *= limitFactor; - } - - unsigned int c[2][2] {}; - unsigned int c4[2][2] {}; - if(ri->get_colors() != 1) { - for (int i = 0; i < 2; ++i) { - for(int j = 0; j < 2; ++j) { - c[i][j] = FC(i, j); - } - } - c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0]; - c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1]; - c4[1][0] = c[1][0]; - c4[1][1] = c[1][1]; - } - - constexpr float minValue = 1.f; // if the pixel value in the flat field is less or equal this value, no correction will be applied. - -#ifdef __SSE2__ - 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]) - }; - 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]]) - }; - - vfloat onev = F2V(1.f); - vfloat minValuev = F2V(minValue); -#endif -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int row = 0; row < H; row ++) { - int col = 0; -#ifdef __SSE2__ - vfloat rowBlackv = blackv[row & 1]; - vfloat rowRefcolorv = refcolorv[row & 1]; - - for (; col < W - 3; col += 4) { - vfloat blurv = LVFU(cfablur[(row) * W + col]) - rowBlackv; - vfloat vignettecorrv = rowRefcolorv / blurv; - vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv); - vfloat valv = LVFU(rawData[row][col]); - valv -= rowBlackv; - STVFU(rawData[row][col], valv * vignettecorrv + rowBlackv); - } - -#endif - - for (; col < W; col ++) { - float blur = cfablur[(row) * W + col] - black[c4[row & 1][col & 1]]; - float vignettecorr = blur <= minValue ? 1.f : refcolor[row & 1][col & 1] / blur; - 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) { - float refcolor[3] = {0.f}; - int cCount[3] = {0}; - - //find center ave values by channel - for (int m = -3; m < 3; m++) - for (int n = -3; n < 3; n++) { - int row = 2 * (H >> 2) + m; - int col = 2 * (W >> 2) + n; - int c = riFlatFile->XTRANSFC(row, col); - refcolor[c] += max(0.0f, cfablur[row * W + col] - black[c]); - cCount[c] ++; - } - - for(int c = 0; c < 3; c++) { - refcolor[c] = refcolor[c] / cCount[c]; - } - - float limitFactor = 1.f; - - if(raw.ff_AutoClipControl) { - // determine maximum calculated value to avoid clipping - float maxval = 0.f; - // xtrans files have only one black level actually, so we can simplify the code a bit -#ifdef _OPENMP - #pragma omp parallel -#endif - { - float maxvalthr = 0.f; -#ifdef _OPENMP - #pragma omp for schedule(dynamic,16) nowait -#endif - - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - float tempval = (rawData[row][col] - black[0]) * ( refcolor[ri->XTRANSFC(row, col)] / max(1e-5f, cfablur[(row) * W + col] - black[0]) ); - - if(tempval > maxvalthr) { - maxvalthr = tempval; - } - } - } - -#ifdef _OPENMP - #pragma omp critical -#endif - { - if(maxvalthr > maxval) { - maxval = maxvalthr; - } - } - } - - // there's only one white level for xtrans - if(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 { - limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f); - } - - - for(int c = 0; c < 3; c++) { - refcolor[c] *= limitFactor; - } - - constexpr float minValue = 1.f; // if the pixel value in the flat field is less or equal this value, no correction will be applied. - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - int c = ri->XTRANSFC(row, col); - float blur = cfablur[(row) * W + col] - black[c]; - float vignettecorr = blur <= minValue ? 1.f : refcolor[c] / blur; - rawData[row][col] = (rawData[row][col] - black[c]) * vignettecorr + black[c]; - } - } - } - - if (raw.ff_BlurType == RAWParams::getFlatFieldBlurTypeString(RAWParams::FlatFieldBlurType::VH)) { - float *cfablur1 = (float (*)) malloc (H * W * sizeof * cfablur1); - float *cfablur2 = (float (*)) malloc (H * W * sizeof * cfablur2); - //slightly more complicated blur if trying to correct both vertical and horizontal anomalies - cfaboxblur(riFlatFile, cfablur1, 0, 2 * BS); //now do horizontal blur - cfaboxblur(riFlatFile, cfablur2, 2 * BS, 0); //now do vertical blur - - if(ri->getSensorType() == ST_BAYER || ri->get_colors() == 1) { - unsigned int c[2][2] {}; - unsigned int c4[2][2] {}; - if(ri->get_colors() != 1) { - for (int i = 0; i < 2; ++i) { - for(int j = 0; j < 2; ++j) { - c[i][j] = FC(i, j); - } - } - c4[0][0] = ( c[0][0] == 1) ? 3 : c[0][0]; - c4[0][1] = ( c[0][1] == 1) ? 3 : c[0][1]; - c4[1][0] = c[1][0]; - c4[1][1] = c[1][1]; - } - -#ifdef __SSE2__ - 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]]) - }; - - vfloat epsv = F2V(1e-5f); -#endif -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int row = 0; row < H; row ++) { - int col = 0; -#ifdef __SSE2__ - vfloat rowBlackv = blackv[row & 1]; - - for (; col < W - 3; col += 4) { - vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) / - (vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, epsv)); - vfloat valv = LVFU(rawData[row][col]); - valv -= rowBlackv; - STVFU(rawData[row][col], valv * linecorrv + rowBlackv); - } - -#endif - - for (; col < W; col ++) { - float linecorr = SQR(max(1e-5f, cfablur[row * W + col] - black[c4[row & 1][col & 1]])) / - (max(1e-5f, cfablur1[row * W + col] - black[c4[row & 1][col & 1]]) * 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) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - int c = ri->XTRANSFC(row, col); - float hlinecorr = (max(1e-5f, cfablur[(row) * W + col] - black[c]) / max(1e-5f, cfablur1[(row) * W + col] - black[c]) ); - float vlinecorr = (max(1e-5f, cfablur[(row) * W + col] - black[c]) / max(1e-5f, cfablur2[(row) * W + col] - black[c]) ); - rawData[row][col] = ((rawData[row][col] - black[c]) * hlinecorr * vlinecorr + black[c]); - } - } - - } - - free (cfablur1); - free (cfablur2); - } - - free (cfablur); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - /* Copy original pixel data and * subtract dark frame (if present) from current image and apply flat field correction (if present) */ @@ -2782,253 +2483,6 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw } } -void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH, int boxW) -{ - - if (boxW < 0 || boxH < 0 || (boxW == 0 && boxH == 0)) { // nothing to blur or negative values - memcpy(cfablur, riFlatFile->data[0], W * H * sizeof(float)); - return; - } - - float *tmpBuffer = nullptr; - float *cfatmp = nullptr; - float *srcVertical = nullptr; - - - if(boxH > 0 && boxW > 0) { - // we need a temporary buffer if we have to blur both directions - tmpBuffer = (float (*)) calloc (H * W, sizeof * tmpBuffer); - } - - if(boxH == 0) { - // if boxH == 0 we can skip the vertical blur and process the horizontal blur from riFlatFile to cfablur without using a temporary buffer - cfatmp = cfablur; - } else { - cfatmp = tmpBuffer; - } - - if(boxW == 0) { - // if boxW == 0 we can skip the horizontal blur and process the vertical blur from riFlatFile to cfablur without using a temporary buffer - srcVertical = riFlatFile->data[0]; - } else { - srcVertical = cfatmp; - } - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - - if(boxW > 0) { - //box blur cfa image; box size = BS - //horizontal blur -#ifdef _OPENMP - #pragma omp for -#endif - - for (int row = 0; row < H; row++) { - int len = boxW / 2 + 1; - cfatmp[row * W + 0] = riFlatFile->data[row][0] / len; - cfatmp[row * W + 1] = riFlatFile->data[row][1] / len; - - for (int j = 2; j <= boxW; j += 2) { - cfatmp[row * W + 0] += riFlatFile->data[row][j] / len; - cfatmp[row * W + 1] += riFlatFile->data[row][j + 1] / len; - } - - for (int col = 2; col <= boxW; col += 2) { - cfatmp[row * W + col] = (cfatmp[row * W + col - 2] * len + riFlatFile->data[row][boxW + col]) / (len + 1); - cfatmp[row * W + col + 1] = (cfatmp[row * W + col - 1] * len + riFlatFile->data[row][boxW + col + 1]) / (len + 1); - len ++; - } - - for (int col = boxW + 2; col < W - boxW; col++) { - cfatmp[row * W + col] = cfatmp[row * W + col - 2] + (riFlatFile->data[row][boxW + col] - cfatmp[row * W + col - boxW - 2]) / len; - } - - for (int col = W - boxW; col < W; col += 2) { - cfatmp[row * W + col] = (cfatmp[row * W + col - 2] * len - cfatmp[row * W + col - boxW - 2]) / (len - 1); - - if (col + 1 < W) { - cfatmp[row * W + col + 1] = (cfatmp[row * W + col - 1] * len - cfatmp[row * W + col - boxW - 1]) / (len - 1); - } - - len --; - } - } - } - - if(boxH > 0) { - //vertical blur -#ifdef __SSE2__ - vfloat leninitv = F2V(boxH / 2 + 1); - vfloat onev = F2V( 1.0f ); - vfloat temp1v, temp2v, temp3v, temp4v, lenv, lenp1v, lenm1v; - int row; -#ifdef _OPENMP - #pragma omp for nowait -#endif - - for (int col = 0; col < W - 7; col += 8) { - lenv = leninitv; - temp1v = LVFU(srcVertical[0 * W + col]) / lenv; - temp2v = LVFU(srcVertical[1 * W + col]) / lenv; - temp3v = LVFU(srcVertical[0 * W + col + 4]) / lenv; - temp4v = LVFU(srcVertical[1 * W + col + 4]) / lenv; - - for (int i = 2; i < boxH + 2; i += 2) { - temp1v += LVFU(srcVertical[i * W + col]) / lenv; - temp2v += LVFU(srcVertical[(i + 1) * W + col]) / lenv; - temp3v += LVFU(srcVertical[i * W + col + 4]) / lenv; - temp4v += LVFU(srcVertical[(i + 1) * W + col + 4]) / lenv; - } - - STVFU(cfablur[0 * W + col], temp1v); - STVFU(cfablur[1 * W + col], temp2v); - STVFU(cfablur[0 * W + col + 4], temp3v); - STVFU(cfablur[1 * W + col + 4], temp4v); - - for (row = 2; row < boxH + 2; row += 2) { - lenp1v = lenv + onev; - temp1v = (temp1v * lenv + LVFU(srcVertical[(row + boxH) * W + col])) / lenp1v; - temp2v = (temp2v * lenv + LVFU(srcVertical[(row + boxH + 1) * W + col])) / lenp1v; - temp3v = (temp3v * lenv + LVFU(srcVertical[(row + boxH) * W + col + 4])) / lenp1v; - temp4v = (temp4v * lenv + LVFU(srcVertical[(row + boxH + 1) * W + col + 4])) / lenp1v; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - STVFU(cfablur[row * W + col + 4], temp3v); - STVFU(cfablur[(row + 1)*W + col + 4], temp4v); - lenv = lenp1v; - } - - for (; row < H - boxH - 1; row += 2) { - temp1v = temp1v + (LVFU(srcVertical[(row + boxH) * W + col]) - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenv; - temp2v = temp2v + (LVFU(srcVertical[(row + 1 + boxH) * W + col]) - LVFU(srcVertical[(row + 1 - boxH - 2) * W + col])) / lenv; - temp3v = temp3v + (LVFU(srcVertical[(row + boxH) * W + col + 4]) - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenv; - temp4v = temp4v + (LVFU(srcVertical[(row + 1 + boxH) * W + col + 4]) - LVFU(srcVertical[(row + 1 - boxH - 2) * W + col + 4])) / lenv; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - STVFU(cfablur[row * W + col + 4], temp3v); - STVFU(cfablur[(row + 1)*W + col + 4], temp4v); - } - - for(; row < H - boxH; row++) { - temp1v = temp1v + (LVFU(srcVertical[(row + boxH) * W + col]) - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenv; - temp3v = temp3v + (LVFU(srcVertical[(row + boxH) * W + col + 4]) - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenv; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[row * W + col + 4], temp3v); - vfloat swapv = temp1v; - temp1v = temp2v; - temp2v = swapv; - swapv = temp3v; - temp3v = temp4v; - temp4v = swapv; - } - - for (; row < H - 1; row += 2) { - lenm1v = lenv - onev; - temp1v = (temp1v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenm1v; - temp2v = (temp2v * lenv - LVFU(srcVertical[(row - boxH - 1) * W + col])) / lenm1v; - temp3v = (temp3v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenm1v; - temp4v = (temp4v * lenv - LVFU(srcVertical[(row - boxH - 1) * W + col + 4])) / lenm1v; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - STVFU(cfablur[row * W + col + 4], temp3v); - STVFU(cfablur[(row + 1)*W + col + 4], temp4v); - lenv = lenm1v; - } - - for(; row < H; row++) { - lenm1v = lenv - onev; - temp1v = (temp1v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col])) / lenm1v; - temp3v = (temp3v * lenv - LVFU(srcVertical[(row - boxH - 2) * W + col + 4])) / lenm1v; - STVFU(cfablur[(row)*W + col], temp1v); - STVFU(cfablur[(row)*W + col + 4], temp3v); - } - - } - -#ifdef _OPENMP - #pragma omp single -#endif - - for (int col = W - (W % 8); col < W; col++) { - int len = boxH / 2 + 1; - cfablur[0 * W + col] = srcVertical[0 * W + col] / len; - cfablur[1 * W + col] = srcVertical[1 * W + col] / len; - - for (int i = 2; i < boxH + 2; i += 2) { - cfablur[0 * W + col] += srcVertical[i * W + col] / len; - cfablur[1 * W + col] += srcVertical[(i + 1) * W + col] / len; - } - - for (int row = 2; row < boxH + 2; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + srcVertical[(row + boxH) * W + col]) / (len + 1); - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len + srcVertical[(row + boxH + 1) * W + col]) / (len + 1); - len ++; - } - - for (int row = boxH + 2; row < H - boxH; row++) { - cfablur[row * W + col] = cfablur[(row - 2) * W + col] + (srcVertical[(row + boxH) * W + col] - srcVertical[(row - boxH - 2) * W + col]) / len; - } - - for (int row = H - boxH; row < H; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len - srcVertical[(row - boxH - 2) * W + col]) / (len - 1); - - if (row + 1 < H) { - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len - srcVertical[(row - boxH - 1) * W + col]) / (len - 1); - } - - len --; - } - } - -#else -#ifdef _OPENMP - #pragma omp for -#endif - - for (int col = 0; col < W; col++) { - int len = boxH / 2 + 1; - cfablur[0 * W + col] = srcVertical[0 * W + col] / len; - cfablur[1 * W + col] = srcVertical[1 * W + col] / len; - - for (int i = 2; i < boxH + 2; i += 2) { - cfablur[0 * W + col] += srcVertical[i * W + col] / len; - cfablur[1 * W + col] += srcVertical[(i + 1) * W + col] / len; - } - - for (int row = 2; row < boxH + 2; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + srcVertical[(row + boxH) * W + col]) / (len + 1); - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len + srcVertical[(row + boxH + 1) * W + col]) / (len + 1); - len ++; - } - - for (int row = boxH + 2; row < H - boxH; row++) { - cfablur[row * W + col] = cfablur[(row - 2) * W + col] + (srcVertical[(row + boxH) * W + col] - srcVertical[(row - boxH - 2) * W + col]) / len; - } - - for (int row = H - boxH; row < H; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len - srcVertical[(row - boxH - 2) * W + col]) / (len - 1); - - if (row + 1 < H) { - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len - srcVertical[(row - boxH - 1) * W + col]) / (len - 1); - } - - len --; - } - } - -#endif - } - } - - if(tmpBuffer) { - free (tmpBuffer); - } -} - - // Scale original pixels into the range 0 65535 using black offsets and multipliers void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const RAWParams &raw, array2D &rawData) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e52adea18..28cf30010 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -23,17 +23,19 @@ #include #include "array2D.h" -#include "color.h" -#include "curves.h" -#include "dcp.h" +#include "colortemp.h" #include "iimage.h" #include "imagesource.h" -#include "pixelsmap.h" #define HR_SCALE 2 namespace rtengine { +class PixelsMap; +class RawImage; +class DiagonalCurve; +class RetinextransmissionCurve; +class RetinexgaintransmissionCurve; class RawImageSource : public ImageSource { @@ -107,10 +109,7 @@ protected: void transformRect (const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw); void transformPosition (int x, int y, int tran, int& tx, int& ty); - unsigned FC(int row, int col) const - { - return ri->FC(row, col); - } + unsigned FC(int row, int col) const; inline void getRowStartEnd (int x, int &start, int &end); static void getProfilePreprocParams(cmsHPROFILE in, float& gammafac, float& lineFac, float& lineSum); @@ -122,7 +121,7 @@ public: int load(const Glib::ustring &fname, bool firstFrameOnly); void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; - bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) override; + bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams ¤tParams, std::array& newExps) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; @@ -130,7 +129,6 @@ public: void flushRawData () override; void flushRGB () override; void HLRecovery_Global (const procparams::ToneCurveParams &hrp) override; - void refinement_lassus (int PassCount); void refinement(int PassCount); void setBorder(unsigned int rawBorder) override {border = rawBorder;} bool isRGBSourceModified() const override @@ -138,21 +136,14 @@ public: return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified } - void processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]); - void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); - void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW); - void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw, array2D &rawData); // raw for cblack + void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const unsigned short black[4]); + void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); + void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D &rawData); // raw for cblack void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; - eSensorType getSensorType () const override - { - return ri != nullptr ? ri->getSensorType() : ST_NONE; - } - bool isMono () const override - { - return ri->get_colors() == 1; - } - ColorTemp getWB () const override + eSensorType getSensorType () const override; + bool isMono () const override; + ColorTemp getWB () const override { return camera_wb; } @@ -170,10 +161,7 @@ public: void getFullSize (int& w, int& h, int tr = TR_NONE) override; void getSize (const PreviewProps &pp, int& w, int& h) override; - int getRotateDegree() const override - { - return ri->get_rotateDegree(); - } + int getRotateDegree() const override; ImageMatrices* getImageMatrices () override { @@ -191,17 +179,17 @@ public: void getAutoExpHistogram (LUTu & histogram, int& histcompr) override; void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override; void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, std::vector &outCurve) override; - DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &as) override; + DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override; void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override; static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in); - static void colorSpaceConversion (Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName) + static void colorSpaceConversion (Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName) { colorSpaceConversion_ (im, cmp, wb, pre_mul, embedded, camprofile, cam, camName); } static void inverse33 (const double (*coeff)[3], double (*icoeff)[3]); - void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, const RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); + void MSR(float** luminance, float **originalLuminance, float **exLuminance, const LUTf& mapcurve, bool mapcontlutili, int width, int height, const procparams::RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); void HLRecovery_inpaint (float** red, float** green, float** blue) override; static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]); @@ -277,18 +265,15 @@ protected: void eahd_demosaic(); void hphd_demosaic(); void vng4_demosaic(const array2D &rawData, array2D &red, array2D &green, array2D &blue); - void ppg_demosaic(); - void jdl_interpolate_omp(); void igv_interpolate(int winw, int winh); - void lmmse_interpolate_omp(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations); + void lmmse_interpolate_omp(int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations); void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, size_t chunkSize = 1, bool measure = false);//Emil's code for AMaZE - void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, double &contrast, bool autoContrast = false); + void dual_demosaic_RT(bool isBayer, const procparams::RAWParams &raw, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, double &contrast, bool autoContrast = false); void fast_demosaic();//Emil's code for fast demosaicing void dcb_demosaic(int iterations, bool dcb_enhance); void ahd_demosaic(); void rcd_demosaic(size_t chunkSize = 1, bool measure = false); - void border_interpolate(unsigned int border, float (*image)[4], unsigned int start = 0, unsigned int end = 0); - void border_interpolate2(int winw, int winh, int lborders, const array2D &rawData, array2D &red, array2D &green, array2D &blue); + void border_interpolate(int winw, int winh, int lborders, const array2D &rawData, array2D &red, array2D &green, array2D &blue); void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border); void fill_raw( float (*cache )[3], int x0, int y0, float** rawData); void fill_border( float (*cache )[3], int border, int x0, int y0); @@ -307,7 +292,7 @@ protected: void xtransborder_interpolate (int border, array2D &red, array2D &green, array2D &blue); void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false); void fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue); - void pixelshift(int winx, int winy, int winw, int winh, const RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection); + void pixelshift(int winx, int winy, int winw, int winh, const procparams::RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection); void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; diff --git a/rtengine/rawimagesource_i.h b/rtengine/rawimagesource_i.h index 485205d9d..47c6b5bab 100644 --- a/rtengine/rawimagesource_i.h +++ b/rtengine/rawimagesource_i.h @@ -16,9 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ - -#ifndef RAWIMAGESOURCE_I_H_INCLUDED -#define RAWIMAGESOURCE_I_H_INCLUDED +#pragma once #include "rawimagesource.h" @@ -184,5 +182,3 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (const array2D &raw } } - -#endif diff --git a/rtengine/rawmetadatalocation.h b/rtengine/rawmetadatalocation.h index 559815a4f..894bc6bd2 100644 --- a/rtengine/rawmetadatalocation.h +++ b/rtengine/rawmetadatalocation.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RAWMETADATALOCATION_ -#define _RAWMETADATALOCATION_ +#pragma once namespace rtengine { @@ -36,6 +35,3 @@ public: }; } - -#endif - diff --git a/rtengine/rcd_demosaic.cc b/rtengine/rcd_demosaic.cc index 48c3ad334..4ceb92b26 100644 --- a/rtengine/rcd_demosaic.cc +++ b/rtengine/rcd_demosaic.cc @@ -20,13 +20,19 @@ #include "rawimagesource.h" #include "rt_math.h" -#include "procparams.h" #include "../rtgui/multilangmgr.h" #include "opthelper.h" #include "StopWatch.h" using namespace std; +namespace +{ +unsigned fc(const unsigned int cfa[2][2], int r, int c) { + return cfa[r & 1][c & 1]; +} +} + namespace rtengine { @@ -56,6 +62,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) plistener->setProgress(progress); } + const unsigned int cfarray[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; constexpr int rcdBorder = 9; constexpr int tileSize = 214; constexpr int tileSizeN = tileSize - 2 * rcdBorder; @@ -98,8 +105,8 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) for (int row = rowStart; row < rowEnd; row++) { int indx = (row - rowStart) * tileSize; - int c0 = FC(row, colStart); - int c1 = FC(row, colStart + 1); + int c0 = fc(cfarray, row, colStart); + int c1 = fc(cfarray, row, colStart + 1); int col = colStart; for (; col < colEnd - 1; col+=2, indx+=2) { @@ -132,7 +139,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) // Step 2.1: Low pass filter incorporating green, red and blue local samples from the raw data for (int row = 2; row < tileRows - 2; row++) { - for (int col = 2 + (FC(row, 0) & 1), indx = row * tileSize + col; col < tilecols - 2; col += 2, indx += 2) { + for (int col = 2 + (fc(cfarray, row, 0) & 1), indx = row * tileSize + col; col < tilecols - 2; col += 2, indx += 2) { lpf[indx>>1] = 0.25f * cfa[indx] + 0.125f * (cfa[indx - w1] + cfa[indx + w1] + cfa[indx - 1] + cfa[indx + 1]) + 0.0625f * (cfa[indx - w1 - 1] + cfa[indx - w1 + 1] + cfa[indx + w1 - 1] + cfa[indx + w1 + 1]); } } @@ -142,7 +149,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) */ // Step 3.1: Populate the green channel at blue and red CFA positions for (int row = 4; row < tileRows - 4; row++) { - for (int col = 4 + (FC(row, 0) & 1), indx = row * tileSize + col; col < tilecols - 4; col += 2, indx += 2) { + for (int col = 4 + (fc(cfarray, row, 0) & 1), indx = row * tileSize + col; col < tilecols - 4; col += 2, indx += 2) { // Refined vertical and horizontal local discrimination float VH_Central_Value = VH_Dir[indx]; @@ -177,7 +184,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) // Step 4.1: Calculate P/Q diagonal local discrimination for (int row = rcdBorder - 4; row < tileRows - rcdBorder + 4; row++) { - for (int col = rcdBorder - 4 + (FC(row, rcdBorder) & 1), indx = row * tileSize + col; col < tilecols - rcdBorder + 4; col += 2, indx += 2) { + for (int col = rcdBorder - 4 + (fc(cfarray, row, rcdBorder) & 1), indx = row * tileSize + col; col < tilecols - rcdBorder + 4; col += 2, indx += 2) { const float cfai = cfa[indx]; float P_Stat = max(epssq, - 18.f * cfai * (cfa[indx - w1 - 1] + cfa[indx + w1 + 1] + 2.f * (cfa[indx - w2 - 2] + cfa[indx + w2 + 2]) - cfa[indx - w3 - 3] - cfa[indx + w3 + 3]) - 2.f * cfai * (cfa[indx - w4 - 4] + cfa[indx + w4 + 4] - 19.f * cfai) - cfa[indx - w1 - 1] * (70.f * cfa[indx + w1 + 1] - 12.f * cfa[indx - w2 - 2] + 24.f * cfa[indx + w2 + 2] - 38.f * cfa[indx - w3 - 3] + 16.f * cfa[indx + w3 + 3] + 12.f * cfa[indx - w4 - 4] - 6.f * cfa[indx + w4 + 4] + 46.f * cfa[indx - w1 - 1]) + cfa[indx + w1 + 1] * (24.f * cfa[indx - w2 - 2] - 12.f * cfa[indx + w2 + 2] + 16.f * cfa[indx - w3 - 3] - 38.f * cfa[indx + w3 + 3] - 6.f * cfa[indx - w4 - 4] + 12.f * cfa[indx + w4 + 4] + 46.f * cfa[indx + w1 + 1]) + cfa[indx - w2 - 2] * (14.f * cfa[indx + w2 + 2] - 12.f * cfa[indx + w3 + 3] - 2.f * (cfa[indx - w4 - 4] - cfa[indx + w4 + 4]) + 11.f * cfa[indx - w2 - 2]) - cfa[indx + w2 + 2] * (12.f * cfa[indx - w3 - 3] + 2.f * (cfa[indx - w4 - 4] - cfa[indx + w4 + 4]) + 11.f * cfa[indx + w2 + 2]) + cfa[indx - w3 - 3] * (2.f * cfa[indx + w3 + 3] - 6.f * cfa[indx - w4 - 4] + 10.f * cfa[indx - w3 - 3]) - cfa[indx + w3 + 3] * (6.f * cfa[indx + w4 + 4] + 10.f * cfa[indx + w3 + 3]) + cfa[indx - w4 - 4] * cfa[indx - w4 - 4] + cfa[indx + w4 + 4] * cfa[indx + w4 + 4]); @@ -190,7 +197,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) // Step 4.2: Populate the red and blue channels at blue and red CFA positions for (int row = rcdBorder - 3; row < tileRows - rcdBorder + 3; row++) { - for (int col = rcdBorder - 3 + (FC(row, rcdBorder - 1) & 1), indx = row * tileSize + col, c = 2 - FC(row, col); col < tilecols - rcdBorder + 3; col += 2, indx += 2) { + for (int col = rcdBorder - 3 + (fc(cfarray, row, rcdBorder - 1) & 1), indx = row * tileSize + col, c = 2 - fc(cfarray, row, col); col < tilecols - rcdBorder + 3; col += 2, indx += 2) { // Refined P/Q diagonal local discrimination float PQ_Central_Value = PQ_Dir[indx]; @@ -222,7 +229,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) // Step 4.3: Populate the red and blue channels at green CFA positions for (int row = rcdBorder; row < tileRows - rcdBorder; row++) { - for (int col = rcdBorder + (FC(row, rcdBorder - 1) & 1), indx = row * tileSize + col; col < tilecols - rcdBorder; col += 2, indx += 2) { + for (int col = rcdBorder + (fc(cfarray, row, rcdBorder - 1) & 1), indx = row * tileSize + col; col < tilecols - rcdBorder; col += 2, indx += 2) { // Refined vertical and horizontal local discrimination float VH_Central_Value = VH_Dir[indx]; @@ -297,7 +304,7 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) free(PQ_Dir); } - border_interpolate2(W, H, rcdBorder, rawData, red, green, blue); + border_interpolate(W, H, rcdBorder, rawData, red, green, blue); if (plistener) { plistener->setProgress(1); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 6917d856e..b77eac29c 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -526,7 +526,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { }; -namespace rtengine { +namespace rtengine +{ RefreshMapper::RefreshMapper(): next_event_(rtengine::NUMOFEVENTS) diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index b41a571b1..39c80feef 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __REFRESHMAP__ -#define __REFRESHMAP__ +#pragma once #include + #include "procevents.h" // Use M_VOID if you wish to update the proc params without updating the preview at all ! @@ -82,7 +82,8 @@ extern int refreshmap[]; -namespace rtengine { +namespace rtengine +{ class RefreshMapper { public: @@ -99,5 +100,3 @@ private: }; } // namespace rtengine - -#endif diff --git a/rtengine/rescale.h b/rtengine/rescale.h index e9d476fea..70974aa48 100644 --- a/rtengine/rescale.h +++ b/rtengine/rescale.h @@ -21,8 +21,10 @@ #pragma once #include "array2D.h" +#include "rt_math.h" -namespace rtengine { +namespace rtengine +{ inline float getBilinearValue(const array2D &src, float x, float y) { @@ -95,5 +97,4 @@ inline void rescaleNearest(const array2D &src, array2D &dst, bool } } - } // namespace rtengine diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index dd7783c1d..b02e75461 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -31,7 +31,7 @@ #include "opthelper.h" #include "rt_algo.h" #include "rt_math.h" -#include "sleef.c" +#include "sleef.h" namespace { float calcBlendFactor(float val, float threshold) { @@ -352,7 +352,7 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H, contrastThreshold = calcContrastThreshold(luminance, minY, minX, tilesize); break; } else { - // in second pass we allow a variance of 4 + // in second pass we allow a variance of 8 // we additionally scan the tiles +-skip pixels around the best tile from pass 2 // Means we scan (2 * skip + 1)^2 tiles in this step to get a better hit rate // fortunately the scan is quite fast, so we use only one core and don't parallelize diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6353fe68b..4efffa63a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -21,21 +21,18 @@ #include #include #include +#include -#include +#include #include #include "iimage.h" #include "imageformat.h" -#include "LUT.h" #include "procevents.h" #include "rawmetadatalocation.h" #include "rt_math.h" #include "settings.h" -#include "utils.h" - -#include "../rtexif/rtexif.h" #include "../rtgui/threadutils.h" @@ -45,7 +42,18 @@ * */ +template +class LUT; + +using LUTu = LUT; + class EditDataProvider; +namespace rtexif +{ + +class TagDirectory; + +} namespace rtengine { @@ -574,7 +582,7 @@ public: * @param baseDir base directory of RT's installation dir * @param userSettingsDir RT's base directory in the user's settings dir * @param loadAll if false, don't load the various dependencies (profiles, HALDClut files, ...), they'll be loaded from disk each time they'll be used (launching time improvement) */ -int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir, bool loadAll = true); +int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir, bool loadAll = true); /** Cleanup the RT engine (static variables) */ void cleanup (); diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 8c634eaa8..7ffb9ad33 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -18,14 +18,15 @@ * along with RawTherapee. If not, see . */ -#include "rtlensfun.h" -#include "procparams.h" -#include "settings.h" #include -namespace rtengine { +#include "imagedata.h" +#include "procparams.h" +#include "rtlensfun.h" +#include "settings.h" -extern const Settings *settings; +namespace rtengine +{ //----------------------------------------------------------------------------- // LFModifier @@ -34,7 +35,6 @@ extern const Settings *settings; LFModifier::~LFModifier() { if (data_) { - MyMutex::MyLock lock(lfModifierMutex); data_->Destroy(); } } @@ -77,11 +77,6 @@ bool LFModifier::isCACorrectionAvailable() const return (flags_ & LF_MODIFY_TCA); } -#ifdef __GNUC__ // silence warning, can be removed when function is implemented -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) const { assert(channel >= 0 && channel <= 2); @@ -107,25 +102,39 @@ void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) co y -= cy; } -#ifdef __GNUC__ -#pragma GCC diagnostic pop +#ifdef _OPENMP +void LFModifier::processVignette(int width, int height, float** rawData) const +{ + #pragma omp parallel for schedule(dynamic,16) + + for (int y = 0; y < height; ++y) { + data_->ApplyColorModification(rawData[y], 0, y, width, 1, LF_CR_1(INTENSITY), 0); + } +} +#else +void LFModifier::processVignette(int width, int height, float** rawData) const +{ + data_->ApplyColorModification(rawData[0], 0, 0, width, height, LF_CR_1(INTENSITY), width * sizeof(float)); +} + #endif - -void LFModifier::processVignetteLine(int width, int y, float *line) const +#ifdef _OPENMP +void LFModifier::processVignette3Channels(int width, int height, float** rawData) const { - MyMutex::MyLock lock(lfModifierMutex); - data_->ApplyColorModification(line, 0, y, width, 1, LF_CR_1(INTENSITY), 0); + #pragma omp parallel for schedule(dynamic,16) + + for (int y = 0; y < height; ++y) { + data_->ApplyColorModification(rawData[y], 0, y, width, 1, LF_CR_3(RED, GREEN, BLUE), 0); + } +} +#else +void LFModifier::processVignette3Channels(int width, int height, float** rawData) const +{ + data_->ApplyColorModification(rawData[0], 0, 0, width, height, LF_CR_3(RED, GREEN, BLUE), width * 3 * sizeof(float)); } - -void LFModifier::processVignetteLine3Channels(int width, int y, float *line) const -{ - MyMutex::MyLock lock(lfModifierMutex); - data_->ApplyColorModification(line, 0, y, width, 1, LF_CR_3(RED, GREEN, BLUE), 0); -} - - +#endif Glib::ustring LFModifier::getDisplayString() const { if (!data_) { @@ -499,13 +508,20 @@ std::unique_ptr LFDatabase::getModifier(const LFCamera &camera, cons return ret; } - -std::unique_ptr LFDatabase::findModifier(const LensProfParams &lensProf, const FramesMetaData *idata, int width, int height, const CoarseTransformParams &coarse, int rawRotationDeg) +std::unique_ptr LFDatabase::findModifier( + const procparams::LensProfParams &lensProf, + const FramesMetaData *idata, + int width, + int height, + const procparams::CoarseTransformParams &coarse, + int rawRotationDeg +) const { + const float focallen = idata->getFocalLen(); + Glib::ustring make, model, lens; - float focallen = idata->getFocalLen(); if (lensProf.lfAutoMatch()) { - if (focallen <= 0) { + if (focallen <= 0.f) { return nullptr; } make = idata->getMake(); @@ -516,19 +532,25 @@ std::unique_ptr LFDatabase::findModifier(const LensProfParams &lensP model = lensProf.lfCameraModel; lens = lensProf.lfLens; } + if (make.empty() || model.empty() || lens.empty()) { return nullptr; } - const LFDatabase *db = getInstance(); - LFCamera c = db->findCamera(make, model); - LFLens l = db->findLens(lensProf.lfAutoMatch() ? c : LFCamera(), lens); - if (focallen <= 0 && l.data_ && l.data_->MinFocal == l.data_->MaxFocal) { - focallen = l.data_->MinFocal; - } - if (focallen <= 0) { + const std::string key = (make + model + lens).collate_key(); + if (notFound.find(key) != notFound.end()) { + // This combination was not found => do not search again return nullptr; } + + const LFCamera c = findCamera(make, model); + const LFLens l = findLens( + lensProf.lfAutoMatch() + ? c + : LFCamera(), + lens + ); + bool swap_xy = false; if (rawRotationDeg >= 0) { int rot = (coarse.rotate + rawRotationDeg) % 360; @@ -538,14 +560,28 @@ std::unique_ptr LFDatabase::findModifier(const LensProfParams &lensP } } - std::unique_ptr ret = db->getModifier(c, l, idata->getFocalLen(), idata->getFNumber(), idata->getFocusDist(), width, height, swap_xy); + std::unique_ptr ret = getModifier( + c, + l, + idata->getFocalLen(), + idata->getFNumber(), + idata->getFocusDist(), + width, + height, + swap_xy + ); if (settings->verbose) { std::cout << "LENSFUN:\n" << " camera: " << c.getDisplayString() << "\n" << " lens: " << l.getDisplayString() << "\n" << " correction: " - << (ret ? ret->getDisplayString() : "NONE") << std::endl; + << (ret ? ret->getDisplayString() : "NONE") + << std::endl; + } + + if (!ret) { + notFound.insert(key); } return ret; diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 092e2bf01..2f3e4677d 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -21,20 +21,25 @@ #pragma once #include +#include #include -#include +#include #include #include "lcp.h" #include "noncopyable.h" -namespace rtengine { +namespace rtengine +{ + +class FramesMetaData; namespace procparams { +struct CoarseTransformParams; struct LensProfParams; } @@ -51,8 +56,8 @@ public: void correctDistortion(double &x, double &y, int cx, int cy, double scale) const override; bool isCACorrectionAvailable() const override; void correctCA(double &x, double &y, int cx, int cy, int channel) const override; - void processVignetteLine(int width, int y, float *line) const override; - void processVignetteLine3Channels(int width, int y, float *line) const override; + void processVignette(int width, int height, float** rawData) const override; + void processVignette3Channels(int width, int height, float** rawData) const override; Glib::ustring getDisplayString() const; @@ -63,7 +68,6 @@ private: lfModifier *data_; bool swap_xy_; int flags_; - mutable MyMutex lfModifierMutex; }; class LFCamera final @@ -119,7 +123,13 @@ public: LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model) const; LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const; - static std::unique_ptr findModifier(const procparams::LensProfParams &lensProf, const FramesMetaData *idata, int width, int height, const CoarseTransformParams &coarse, int rawRotationDeg); + std::unique_ptr findModifier( + const procparams::LensProfParams &lensProf, + const FramesMetaData *idata, + int width, int height, + const procparams::CoarseTransformParams &coarse, + int rawRotationDeg + ) const; private: std::unique_ptr getModifier(const LFCamera &camera, const LFLens &lens, @@ -131,6 +141,7 @@ private: mutable MyMutex lfDBMutex; static LFDatabase instance_; lfDatabase *data_; + mutable std::set notFound; }; } // namespace rtengine diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 25f50980d..0cdcbf6ed 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -16,31 +16,36 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + +#include + +#include + +#include +#include +#include + +#include "cieimage.h" +#include "color.h" +#include "colortemp.h" +#include "curves.h" +#include "dcp.h" +#include "iccstore.h" +#include "image8.h" +#include "improcfun.h" +#include "jpeg.h" +#include "labimage.h" +#include "median.h" +#include "procparams.h" +#include "rawimage.h" +#include "rawimagesource.h" #include "rtengine.h" #include "rtthumbnail.h" -#include "../rtgui/options.h" -#include "image8.h" -#include -#include "curves.h" -#include -#include "improcfun.h" -#include "colortemp.h" -#include "mytime.h" -#include "utils.h" -#include "iccstore.h" -#include "iccmatrices.h" -#include "rawimagesource.h" -#include "stdimagesource.h" -#include -#include "rawimage.h" -#include "jpeg.h" -#include "../rtgui/ppversion.h" -#include "improccoordinator.h" #include "settings.h" -#include "procparams.h" -#include +#include "stdimagesource.h" #include "StopWatch.h" -#include "median.h" +#include "utils.h" namespace { @@ -183,13 +188,9 @@ void scale_colors (rtengine::RawImage *ri, float scale_mul[4], float cblack[4], } -extern Options options; - namespace rtengine { -extern const Settings *settings; - using namespace procparams; Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode) @@ -329,7 +330,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); neutral.icm.inputProfile = "(camera)"; - neutral.icm.workingProfile = options.rtSettings.srgb; + neutral.icm.workingProfile = settings->srgb; src.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false); double thresholdDummy = 0.f; @@ -428,7 +429,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL // did we succeed? if ( err ) { - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "Could not extract thumb from " << fname.c_str() << std::endl; } delete tpp; @@ -1236,7 +1237,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ImProcFunctions ipf (¶ms, forHistogramMatching); // enable multithreading when forHistogramMatching is true ipf.setScale (sqrt (double (fw * fw + fh * fh)) / sqrt (double (thumbImg->getWidth() * thumbImg->getWidth() + thumbImg->getHeight() * thumbImg->getHeight()))*scale); - ipf.updateColorProfiles (ICCStore::getInstance()->getDefaultMonitorProfileName(), RenderingIntent(options.rtSettings.monitorIntent), false, false); + ipf.updateColorProfiles (ICCStore::getInstance()->getDefaultMonitorProfileName(), RenderingIntent(settings->monitorIntent), false, false); LUTu hist16 (65536); @@ -1363,7 +1364,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT LabImage* labView = new LabImage (fw, fh); DCPProfile *dcpProf = nullptr; - DCPProfile::ApplyState as; + DCPProfileApplyState as; if (isRaw) { cmsHPROFILE dummy; @@ -2126,11 +2127,11 @@ bool Thumbnail::readData (const Glib::ustring& fname) return true; } catch (Glib::Error &err) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("Thumbnail::readData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } } catch (...) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("Thumbnail::readData / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); } } @@ -2177,11 +2178,11 @@ bool Thumbnail::writeData (const Glib::ustring& fname) keyData = keyFile.to_data (); } catch (Glib::Error& err) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("Thumbnail::writeData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } } catch (...) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("Thumbnail::writeData / Unknown exception while trying to save \"%s\"!\n", fname.c_str()); } } @@ -2193,7 +2194,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname) FILE *f = g_fopen (fname.c_str (), "wt"); if (!f) { - if (options.rtSettings.verbose) { + if (settings->verbose) { printf ("Thumbnail::writeData / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); } diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 8b3f27a8b..dcc9596f6 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -16,15 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBPROCESSINGPARAMETERS_ -#define _THUMBPROCESSINGPARAMETERS_ +#pragma once + +#include -#include "rawmetadatalocation.h" -#include #include -#include "image8.h" + #include "image16.h" +#include "image8.h" #include "imagefloat.h" +#include "LUT.h" +#include "rawmetadatalocation.h" + #include "../rtgui/threadutils.h" namespace rtengine @@ -160,6 +163,3 @@ public: } }; } - -#endif - diff --git a/rtengine/satandvalueblendingcurve.h b/rtengine/satandvalueblendingcurve.h new file mode 100644 index 000000000..c610652b4 --- /dev/null +++ b/rtengine/satandvalueblendingcurve.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include "color.h" +#include "curves.h" + +namespace rtengine +{ + +class SatAndValueBlendingToneCurve : public ToneCurve +{ +public: + void Apply(float& r, float& g, float& b) const; +}; + +// Tone curve modifying the value channel only, preserving hue and saturation +// values in 0xffff space +inline void SatAndValueBlendingToneCurve::Apply (float& ir, float& ig, float& ib) const +{ + + assert (lutToneCurve); + + float r = CLIP(ir); + float g = CLIP(ig); + float b = CLIP(ib); + + const float lum = (r + g + b) / 3.f; + const float newLum = lutToneCurve[lum]; + + if (newLum == lum) { + return; + } + + float h, s, v; + Color::rgb2hsvtc(r, g, b, h, s, v); + + float dV; + if (newLum > lum) { + // Linearly targeting Value = 1 and Saturation = 0 + const float coef = (newLum - lum) / (65535.f - lum); + dV = (1.f - v) * coef; + s *= 1.f - coef; + } else { + // Linearly targeting Value = 0 + const float coef = (newLum - lum) / lum ; + dV = v * coef; + } + Color::hsv2rgbdcp(h, s, v + dV, r, g, b); + + setUnlessOOG(ir, ig, ib, r, g, b); +} + +} diff --git a/rtengine/settings.h b/rtengine/settings.h index 8852c05c8..f261444c8 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -16,9 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RTSETTINGS_ -#define _RTSETTINGS_ +#pragma once +#include namespace rtengine { @@ -96,7 +96,5 @@ public: * @param s a pointer to the Settings instance to destroy. */ static void destroy(Settings* s); }; +extern const Settings* settings; } - -#endif - diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index 6b59c4b40..abdcc42a4 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -18,9 +18,11 @@ */ #include "shmap.h" #include "gauss.h" +#include "imagefloat.h" #include "rtengine.h" #include "rt_math.h" #include "rawimagesource.h" +#include "sleef.h" #include "jaggedarray.h" #undef THREAD_PRIORITY_NORMAL #include "opthelper.h" @@ -28,8 +30,6 @@ namespace rtengine { -extern const Settings* settings; - SHMap::SHMap (int w, int h) : max_f(0.f), min_f(0.f), avg(0.f), W(w), H(h) { @@ -85,21 +85,14 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int if (!hq) { fillLuminance( img, map, lumi); - float *buffer = nullptr; - - if(radius > 40.) { - // When we pass another buffer to gaussianBlur, it will use iterated boxblur which is less prone to artifacts - buffer = new float[W * H]; - } + const bool useBoxBlur = radius > 40.0; // boxblur is less prone to artifacts for large radi #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel if (!useBoxBlur) #endif { - gaussianBlur (map, map, W, H, radius, buffer); + gaussianBlur (map, map, W, H, radius, useBoxBlur); } - - delete [] buffer; } else { @@ -358,7 +351,7 @@ void SHMap::forceStat (float max_, float min_, float avg_) avg = avg_; } -void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale) +void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, const LUTf& rangefn, int level, int scale) { //scale is spacing of directional averaging weights diff --git a/rtengine/shmap.h b/rtengine/shmap.h index 539ef99ff..68e352b23 100644 --- a/rtengine/shmap.h +++ b/rtengine/shmap.h @@ -16,16 +16,20 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __SHMAP__ -#define __SHMAP__ +#pragma once -#include "imagefloat.h" -#include "image16.h" #include "noncopyable.h" +template +class LUT; + +using LUTf = LUT; + namespace rtengine { +class Imagefloat; + class SHMap : public NonCopyable { @@ -46,8 +50,8 @@ private: void fillLuminance( Imagefloat * img, float **luminance, double lumi[3] ); void fillLuminanceL( float ** L, float **luminance ); - void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale); + void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, const LUTf& rangefn, int level, int scale); }; + } -#endif diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index a1ace521c..fac207016 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -16,6 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include "cieimage.h" +#include "dcp.h" +#include "imagefloat.h" +#include "labimage.h" #include "rtengine.h" #include "colortemp.h" #include "imagesource.h" @@ -25,7 +29,8 @@ #include "clutstore.h" #include "processingjob.h" #include "procparams.h" -#include +#include +#include #include "../rtgui/options.h" #include "rawimagesource.h" #include "../rtgui/multilangmgr.h" @@ -34,7 +39,6 @@ namespace rtengine { -extern const Settings* settings; namespace { @@ -240,7 +244,6 @@ private: bool dehacontlutili = false; bool mapcontlutili = false; bool useHsl = false; -// multi_array2D conversionBuffer(1, 1); multi_array2D conversionBuffer (1, 1); imgsrc->retinexPrepareBuffers (params.icm, params.retinex, conversionBuffer, dummy); imgsrc->retinexPrepareCurves (params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); @@ -804,17 +807,7 @@ private: void stage_denoise() { - procparams::ProcParams& params = job->pparams; - //ImProcFunctions ipf (¶ms, true); - ImProcFunctions &ipf = * (ipf_p.get()); - - // perform luma/chroma denoise -// CieImage *cieView; -// NoisCurve noiseLCurve; -// bool lldenoiseutili=false; -// Imagefloat *calclum ; -// params.dirpyrDenoise.getCurves(noiseLCurve, lldenoiseutili); -// if (params.dirpyrDenoise.enabled && lldenoiseutili) { + const procparams::ProcParams& params = job->pparams; DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; // make a copy because we cheat here @@ -847,9 +840,7 @@ private: } if (denoiseParams.enabled) { - // CurveFactory::denoiseLL(lldenoiseutili, denoiseParams.lcurve, Noisecurve,1); - //denoiseParams.getCurves(noiseLCurve); -// ipf.RGB_denoise(baseImg, baseImg, calclum, imgsrc->isRAW(), denoiseParams, params.defringe, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, lldenoiseutili); + ImProcFunctions &ipf = * (ipf_p.get()); float nresi, highresi; int kall = 2; ipf.RGB_denoise (kall, baseImg, baseImg, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); @@ -871,7 +862,7 @@ private: void stage_transform() { - procparams::ProcParams& params = job->pparams; + const procparams::ProcParams& params = job->pparams; //ImProcFunctions ipf (¶ms, true); ImProcFunctions &ipf = * (ipf_p.get()); @@ -1000,7 +991,7 @@ private: } autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = imgsrc->getDCP (params.icm, as); LUTu histToneCurve; @@ -1086,13 +1077,10 @@ private: ipf.vibrance (labView); ipf.labColorCorrectionRegions(labView); - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - ipf.impulsedenoise (labView); - } - // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + ipf.impulsedenoise (labView); ipf.defringe (labView); } diff --git a/rtengine/simpleprocess.h b/rtengine/simpleprocess.h index d6efe802d..9b41b4643 100644 --- a/rtengine/simpleprocess.h +++ b/rtengine/simpleprocess.h @@ -4,24 +4,11 @@ * * Created on September 18, 2010, 8:31 PM */ +#pragma once -#ifndef SIMPLEPROCESS_H -#define SIMPLEPROCESS_H - -#ifdef __cplusplus -extern "C" { -#endif - - - - -#ifdef __cplusplus -} -#endif namespace rtengine { extern Glib::Thread *batchThread; -} -#endif /* SIMPLEPROCESS_H */ +} diff --git a/rtengine/sleef.c b/rtengine/sleef.c deleted file mode 100644 index cc92be108..000000000 --- a/rtengine/sleef.c +++ /dev/null @@ -1,1279 +0,0 @@ -//////////////////////////////////////////////////////////////// -// -// this code was taken from http://shibatch.sourceforge.net/ -// Many thanks to the author of original version: Naoki Shibata -// -// This version contains modifications made by Ingo Weyrich -// -//////////////////////////////////////////////////////////////// - -#ifndef _SLEEFC_ -#define _SLEEFC_ - -#include -#include -#include "rt_math.h" -#include "opthelper.h" - -#define PI4_A .7853981554508209228515625 -#define PI4_B .794662735614792836713604629039764404296875e-8 -#define PI4_C .306161699786838294306516483068750264552437361480769e-16 -#define M_4_PI 1.273239544735162542821171882678754627704620361328125 - -#define L2U .69314718055966295651160180568695068359375 -#define L2L .28235290563031577122588448175013436025525412068e-12 -#define R_LN2 1.442695040888963407359924681001892137426645954152985934135449406931 -#define pow_F(a,b) (xexpf(b*xlogf(a))) - -__inline int64_t doubleToRawLongBits(double d) { - union { - double f; - int64_t i; - } tmp; - tmp.f = d; - return tmp.i; -} - -__inline double longBitsToDouble(int64_t i) { - union { - double f; - int64_t i; - } tmp; - tmp.i = i; - return tmp.f; -} - -__inline double xfabs(double x) { - return longBitsToDouble(0x7fffffffffffffffLL & doubleToRawLongBits(x)); -} - -__inline double mulsign(double x, double y) { - return longBitsToDouble(doubleToRawLongBits(x) ^ (doubleToRawLongBits(y) & (1LL << 63))); -} - -__inline double sign(double d) { return mulsign(1, d); } -__inline double mla(double x, double y, double z) { return x * y + z; } -__inline double xrint(double x) { return x < 0 ? (int)(x - 0.5) : (int)(x + 0.5); } - -__inline int xisnan(double x) { return x != x; } -__inline int xisinf(double x) { return x == rtengine::RT_INFINITY || x == -rtengine::RT_INFINITY; } -__inline int xisminf(double x) { return x == -rtengine::RT_INFINITY; } -__inline int xispinf(double x) { return x == rtengine::RT_INFINITY; } - -__inline double ldexpk(double x, int q) { - double u; - int m; - m = q >> 31; - m = (((m + q) >> 9) - m) << 7; - q = q - (m << 2); - u = longBitsToDouble(((int64_t)(m + 0x3ff)) << 52); - double u2 = u*u; - u2 = u2 * u2; - x = x * u2; - u = longBitsToDouble(((int64_t)(q + 0x3ff)) << 52); - return x * u; -} - -__inline double xldexp(double x, int q) { return ldexpk(x, q); } - -__inline int ilogbp1(double d) { - int m = d < 4.9090934652977266E-91; - d = m ? 2.037035976334486E90 * d : d; - int q = (doubleToRawLongBits(d) >> 52) & 0x7ff; - q = m ? q - (300 + 0x03fe) : q - 0x03fe; - return q; -} - -__inline int xilogb(double d) { - int e = ilogbp1(xfabs(d)) - 1; - e = d == 0 ? (-2147483647 - 1) : e; - e = d == rtengine::RT_INFINITY || d == -rtengine::RT_INFINITY ? 2147483647 : e; - return e; -} - -__inline double upper(double d) { - return longBitsToDouble(doubleToRawLongBits(d) & 0xfffffffff8000000LL); -} - -typedef struct { - double x, y; -} double2; - -typedef struct { - float x, y; -} float2; - -__inline double2 dd(double h, double l) { - double2 ret; - ret.x = h; ret.y = l; - return ret; -} - -__inline double2 normalize_d(double2 t) { - double2 s; - - s.x = t.x + t.y; - s.y = t.x - s.x + t.y; - - return s; -} - -__inline double2 scale_d(double2 d, double s) { - double2 r; - - r.x = d.x * s; - r.y = d.y * s; - - return r; -} - -__inline double2 add2_ss(double x, double y) { - double2 r; - - r.x = x + y; - double v = r.x - x; - r.y = (x - (r.x - v)) + (y - v); - - return r; -} - -__inline double2 add_ds(double2 x, double y) { - // |x| >= |y| - - double2 r; - - assert(xisnan(x.x) || xisnan(y) || xfabs(x.x) >= xfabs(y)); - - r.x = x.x + y; - r.y = x.x - r.x + y + x.y; - - return r; -} - -__inline double2 add2_ds(double2 x, double y) { - // |x| >= |y| - - double2 r; - - r.x = x.x + y; - double v = r.x - x.x; - r.y = (x.x - (r.x - v)) + (y - v); - r.y += x.y; - - return r; -} - -__inline double2 add_sd(double x, double2 y) { - // |x| >= |y| - - double2 r; - - assert(xisnan(x) || xisnan(y.x) || xfabs(x) >= xfabs(y.x)); - - r.x = x + y.x; - r.y = x - r.x + y.x + y.y; - - return r; -} - -__inline double2 add_dd(double2 x, double2 y) { - // |x| >= |y| - - double2 r; - - assert(xisnan(x.x) || xisnan(y.x) || xfabs(x.x) >= xfabs(y.x)); - - r.x = x.x + y.x; - r.y = x.x - r.x + y.x + x.y + y.y; - - return r; -} - -__inline double2 add2_dd(double2 x, double2 y) { - double2 r; - - r.x = x.x + y.x; - double v = r.x - x.x; - r.y = (x.x - (r.x - v)) + (y.x - v); - r.y += x.y + y.y; - - return r; -} - -__inline double2 div_dd(double2 n, double2 d) { - double t = 1.0 / d.x; - double dh = upper(d.x), dl = d.x - dh; - double th = upper(t ), tl = t - th; - double nhh = upper(n.x), nhl = n.x - nhh; - - double2 q; - - q.x = n.x * t; - - double u = -q.x + nhh * th + nhh * tl + nhl * th + nhl * tl + - q.x * (1 - dh * th - dh * tl - dl * th - dl * tl); - - q.y = t * (n.y - q.x * d.y) + u; - - return q; -} - -__inline double2 mul_ss(double x, double y) { - double xh = upper(x), xl = x - xh; - double yh = upper(y), yl = y - yh; - double2 r; - - r.x = x * y; - r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl; - - return r; -} - -__inline double2 mul_ds(double2 x, double y) { - double xh = upper(x.x), xl = x.x - xh; - double yh = upper(y ), yl = y - yh; - double2 r; - - r.x = x.x * y; - r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.y * y; - - return r; -} - -__inline double2 mul_dd(double2 x, double2 y) { - double xh = upper(x.x), xl = x.x - xh; - double yh = upper(y.x), yl = y.x - yh; - double2 r; - - r.x = x.x * y.x; - r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.x * y.y + x.y * y.x; - - return r; -} - -__inline double2 squ_d(double2 x) { - double xh = upper(x.x), xl = x.x - xh; - double2 r; - - r.x = x.x * x.x; - r.y = xh * xh - r.x + (xh + xh) * xl + xl * xl + x.x * (x.y + x.y); - - return r; -} - -__inline double2 rec_s(double d) { - double t = 1.0 / d; - double dh = upper(d), dl = d - dh; - double th = upper(t), tl = t - th; - double2 q; - - q.x = t; - q.y = t * (1 - dh * th - dh * tl - dl * th - dl * tl); - - return q; -} - -__inline double2 sqrt_d(double2 d) { - double t = sqrt(d.x + d.y); - return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), 0.5); -} - -__inline double atan2k(double y, double x) { - double s, t, u; - int q = 0; - - if (x < 0) { x = -x; q = -2; } - if (y > x) { t = x; x = y; y = -t; q += 1; } - - s = y / x; - t = s * s; - - u = -1.88796008463073496563746e-05; - u = u * t + (0.000209850076645816976906797); - u = u * t + (-0.00110611831486672482563471); - u = u * t + (0.00370026744188713119232403); - u = u * t + (-0.00889896195887655491740809); - u = u * t + (0.016599329773529201970117); - u = u * t + (-0.0254517624932312641616861); - u = u * t + (0.0337852580001353069993897); - u = u * t + (-0.0407629191276836500001934); - u = u * t + (0.0466667150077840625632675); - u = u * t + (-0.0523674852303482457616113); - u = u * t + (0.0587666392926673580854313); - u = u * t + (-0.0666573579361080525984562); - u = u * t + (0.0769219538311769618355029); - u = u * t + (-0.090908995008245008229153); - u = u * t + (0.111111105648261418443745); - u = u * t + (-0.14285714266771329383765); - u = u * t + (0.199999999996591265594148); - u = u * t + (-0.333333333333311110369124); - - t = u * t * s + s; - t = q * (rtengine::RT_PI_2) + t; - - return t; -} - -__inline double xatan2(double y, double x) { - double r = atan2k(xfabs(y), x); - - r = mulsign(r, x); - if (xisinf(x) || x == 0) r = rtengine::RT_PI_2 - (xisinf(x) ? (sign(x) * (rtengine::RT_PI_2)) : 0); - if (xisinf(y) ) r = rtengine::RT_PI_2 - (xisinf(x) ? (sign(x) * (rtengine::RT_PI*1/4)) : 0); - if ( y == 0) r = (sign(x) == -1 ? rtengine::RT_PI : 0); - - return xisnan(x) || xisnan(y) ? rtengine::RT_NAN : mulsign(r, y); -} - -__inline double xasin(double d) { - return mulsign(atan2k(xfabs(d), sqrt((1+d)*(1-d))), d); -} - -__inline double xacos(double d) { - return mulsign(atan2k(sqrt((1+d)*(1-d)), xfabs(d)), d) + (d < 0 ? rtengine::RT_PI : 0); -} - -__inline double xatan(double s) { - double t, u; - int q = 0; - - if (s < 0) { s = -s; q = 2; } - if (s > 1) { s = 1.0 / s; q |= 1; } - - t = s * s; - - u = -1.88796008463073496563746e-05; - u = u * t + (0.000209850076645816976906797); - u = u * t + (-0.00110611831486672482563471); - u = u * t + (0.00370026744188713119232403); - u = u * t + (-0.00889896195887655491740809); - u = u * t + (0.016599329773529201970117); - u = u * t + (-0.0254517624932312641616861); - u = u * t + (0.0337852580001353069993897); - u = u * t + (-0.0407629191276836500001934); - u = u * t + (0.0466667150077840625632675); - u = u * t + (-0.0523674852303482457616113); - u = u * t + (0.0587666392926673580854313); - u = u * t + (-0.0666573579361080525984562); - u = u * t + (0.0769219538311769618355029); - u = u * t + (-0.090908995008245008229153); - u = u * t + (0.111111105648261418443745); - u = u * t + (-0.14285714266771329383765); - u = u * t + (0.199999999996591265594148); - u = u * t + (-0.333333333333311110369124); - - t = s + s * (t * u); - - if ((q & 1) != 0) t = 1.570796326794896557998982 - t; - if ((q & 2) != 0) t = -t; - - return t; -} - -__inline double xsin(double d) { - int q; - double u, s; - - q = (int)xrint(d * rtengine::RT_1_PI); - - d = mla(q, -PI4_A*4, d); - d = mla(q, -PI4_B*4, d); - d = mla(q, -PI4_C*4, d); - - s = d * d; - - if ((q & 1) != 0) d = -d; - - u = -7.97255955009037868891952e-18; - u = mla(u, s, 2.81009972710863200091251e-15); - u = mla(u, s, -7.64712219118158833288484e-13); - u = mla(u, s, 1.60590430605664501629054e-10); - u = mla(u, s, -2.50521083763502045810755e-08); - u = mla(u, s, 2.75573192239198747630416e-06); - u = mla(u, s, -0.000198412698412696162806809); - u = mla(u, s, 0.00833333333333332974823815); - u = mla(u, s, -0.166666666666666657414808); - - u = mla(s, u * d, d); - - return u; -} - -__inline double xcos(double d) { - int q; - double u, s; - - q = 1 + 2*(int)xrint(d * rtengine::RT_1_PI - 0.5); - - d = mla(q, -PI4_A*2, d); - d = mla(q, -PI4_B*2, d); - d = mla(q, -PI4_C*2, d); - - s = d * d; - - if ((q & 2) == 0) d = -d; - - u = -7.97255955009037868891952e-18; - u = mla(u, s, 2.81009972710863200091251e-15); - u = mla(u, s, -7.64712219118158833288484e-13); - u = mla(u, s, 1.60590430605664501629054e-10); - u = mla(u, s, -2.50521083763502045810755e-08); - u = mla(u, s, 2.75573192239198747630416e-06); - u = mla(u, s, -0.000198412698412696162806809); - u = mla(u, s, 0.00833333333333332974823815); - u = mla(u, s, -0.166666666666666657414808); - - u = mla(s, u * d, d); - - return u; -} - -__inline double2 xsincos(double d) { - int q; - double u, s, t; - double2 r; - - q = (int)xrint(d * (2 * rtengine::RT_1_PI)); - - s = d; - - s = mla(-q, PI4_A*2, s); - s = mla(-q, PI4_B*2, s); - s = mla(-q, PI4_C*2, s); - - t = s; - - s = s * s; - - u = 1.58938307283228937328511e-10; - u = mla(u, s, -2.50506943502539773349318e-08); - u = mla(u, s, 2.75573131776846360512547e-06); - u = mla(u, s, -0.000198412698278911770864914); - u = mla(u, s, 0.0083333333333191845961746); - u = mla(u, s, -0.166666666666666130709393); - u = u * s * t; - - r.x = t + u; - - u = -1.13615350239097429531523e-11; - u = mla(u, s, 2.08757471207040055479366e-09); - u = mla(u, s, -2.75573144028847567498567e-07); - u = mla(u, s, 2.48015872890001867311915e-05); - u = mla(u, s, -0.00138888888888714019282329); - u = mla(u, s, 0.0416666666666665519592062); - u = mla(u, s, -0.5); - - r.y = u * s + 1; - - if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } - if ((q & 2) != 0) { r.x = -r.x; } - if (((q+1) & 2) != 0) { r.y = -r.y; } - - if (xisinf(d)) { r.x = r.y = rtengine::RT_NAN; } - - return r; -} - -__inline double xtan(double d) { - int q; - double u, s, x; - - q = (int)xrint(d * (2 * rtengine::RT_1_PI)); - - x = mla(q, -PI4_A*2, d); - x = mla(q, -PI4_B*2, x); - x = mla(q, -PI4_C*2, x); - - s = x * x; - - if ((q & 1) != 0) x = -x; - - u = 1.01419718511083373224408e-05; - u = mla(u, s, -2.59519791585924697698614e-05); - u = mla(u, s, 5.23388081915899855325186e-05); - u = mla(u, s, -3.05033014433946488225616e-05); - u = mla(u, s, 7.14707504084242744267497e-05); - u = mla(u, s, 8.09674518280159187045078e-05); - u = mla(u, s, 0.000244884931879331847054404); - u = mla(u, s, 0.000588505168743587154904506); - u = mla(u, s, 0.00145612788922812427978848); - u = mla(u, s, 0.00359208743836906619142924); - u = mla(u, s, 0.00886323944362401618113356); - u = mla(u, s, 0.0218694882853846389592078); - u = mla(u, s, 0.0539682539781298417636002); - u = mla(u, s, 0.133333333333125941821962); - u = mla(u, s, 0.333333333333334980164153); - - u = mla(s, u * x, x); - - if ((q & 1) != 0) u = 1.0 / u; - - if (xisinf(d)) u = rtengine::RT_NAN; - - return u; -} - -__inline double xlog(double d) { - double x, x2, t, m; - int e; - - e = ilogbp1(d * 0.7071); - m = ldexpk(d, -e); - - x = (m-1) / (m+1); - x2 = x * x; - - t = 0.148197055177935105296783; - t = mla(t, x2, 0.153108178020442575739679); - t = mla(t, x2, 0.181837339521549679055568); - t = mla(t, x2, 0.22222194152736701733275); - t = mla(t, x2, 0.285714288030134544449368); - t = mla(t, x2, 0.399999999989941956712869); - t = mla(t, x2, 0.666666666666685503450651); - t = mla(t, x2, 2); - - x = x * t + 0.693147180559945286226764 * e; - - if (xisinf(d)) x = rtengine::RT_INFINITY; - if (d < 0) x = rtengine::RT_NAN; - if (d == 0) x = -rtengine::RT_INFINITY; - - return x; -} - -__inline double xexp(double d) { - int q = (int)xrint(d * R_LN2); - double s, u; - - s = mla(q, -L2U, d); - s = mla(q, -L2L, s); - - u = 2.08860621107283687536341e-09; - u = mla(u, s, 2.51112930892876518610661e-08); - u = mla(u, s, 2.75573911234900471893338e-07); - u = mla(u, s, 2.75572362911928827629423e-06); - u = mla(u, s, 2.4801587159235472998791e-05); - u = mla(u, s, 0.000198412698960509205564975); - u = mla(u, s, 0.00138888888889774492207962); - u = mla(u, s, 0.00833333333331652721664984); - u = mla(u, s, 0.0416666666666665047591422); - u = mla(u, s, 0.166666666666666851703837); - u = mla(u, s, 0.5); - - u = s * s * u + s + 1; - u = ldexpk(u, q); - - if (xisminf(d)) u = 0; - - return u; -} - -__inline double2 logk(double d) { - double2 x, x2; - double m, t; - int e; - - e = ilogbp1(d * 0.7071); - m = ldexpk(d, -e); - - x = div_dd(add2_ss(-1, m), add2_ss(1, m)); - x2 = squ_d(x); - - t = 0.134601987501262130076155; - t = mla(t, x2.x, 0.132248509032032670243288); - t = mla(t, x2.x, 0.153883458318096079652524); - t = mla(t, x2.x, 0.181817427573705403298686); - t = mla(t, x2.x, 0.222222231326187414840781); - t = mla(t, x2.x, 0.285714285651261412873718); - t = mla(t, x2.x, 0.400000000000222439910458); - t = mla(t, x2.x, 0.666666666666666371239645); - - return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), - add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); -} - -__inline double expk(double2 d) { - int q = (int)rint((d.x + d.y) * R_LN2); - double2 s, t; - double u; - - s = add2_ds(d, q * -L2U); - s = add2_ds(s, q * -L2L); - - s = normalize_d(s); - - u = 2.51069683420950419527139e-08; - u = mla(u, s.x, 2.76286166770270649116855e-07); - u = mla(u, s.x, 2.75572496725023574143864e-06); - u = mla(u, s.x, 2.48014973989819794114153e-05); - u = mla(u, s.x, 0.000198412698809069797676111); - u = mla(u, s.x, 0.0013888888939977128960529); - u = mla(u, s.x, 0.00833333333332371417601081); - u = mla(u, s.x, 0.0416666666665409524128449); - u = mla(u, s.x, 0.166666666666666740681535); - u = mla(u, s.x, 0.500000000000000999200722); - - t = add_dd(s, mul_ds(squ_d(s), u)); - - t = add_sd(1, t); - return ldexpk(t.x + t.y, q); -} - -__inline double xpow(double x, double y) { - int yisint = (int)y == y; - int yisodd = (1 & (int)y) != 0 && yisint; - - double result = expk(mul_ds(logk(xfabs(x)), y)); - - result = xisnan(result) ? rtengine::RT_INFINITY : result; - result *= (x >= 0 ? 1 : (!yisint ? rtengine::RT_NAN : (yisodd ? -1 : 1))); - - double efx = mulsign(xfabs(x) - 1, y); - if (xisinf(y)) result = efx < 0 ? 0.0 : (efx == 0 ? 1.0 : rtengine::RT_INFINITY); - if (xisinf(x) || x == 0) result = (yisodd ? sign(x) : 1) * ((x == 0 ? -y : y) < 0 ? 0 : rtengine::RT_INFINITY); - if (xisnan(x) || xisnan(y)) result = rtengine::RT_NAN; - if (y == 0 || x == 1) result = 1; - - return result; -} - -__inline double2 expk2(double2 d) { - int q = (int)rint((d.x + d.y) * R_LN2); - double2 s, t; - double u; - - s = add2_ds(d, q * -L2U); - s = add2_ds(s, q * -L2L); - - s = normalize_d(s); - - u = 2.51069683420950419527139e-08; - u = mla(u, s.x, 2.76286166770270649116855e-07); - u = mla(u, s.x, 2.75572496725023574143864e-06); - u = mla(u, s.x, 2.48014973989819794114153e-05); - u = mla(u, s.x, 0.000198412698809069797676111); - u = mla(u, s.x, 0.0013888888939977128960529); - u = mla(u, s.x, 0.00833333333332371417601081); - u = mla(u, s.x, 0.0416666666665409524128449); - u = mla(u, s.x, 0.166666666666666740681535); - u = mla(u, s.x, 0.500000000000000999200722); - - t = add_dd(s, mul_ds(squ_d(s), u)); - - t = add_sd(1, t); - return dd(ldexpk(t.x, q), ldexpk(t.y, q)); -} - -__inline double xsinh(double x) { - double y = xfabs(x); - double2 d = expk2(dd(y, 0)); - d = add2_dd(d, div_dd(dd(-1, 0), d)); - y = (d.x + d.y) * 0.5; - - y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; - y = mulsign(y, x); - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -__inline double xcosh(double x) { - double2 d = expk2(dd(x, 0)); - d = add2_dd(d, div_dd(dd(1, 0), d)); - double y = (d.x + d.y) * 0.5; - - y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -__inline double xtanh(double x) { - double y = xfabs(x); - double2 d = expk2(dd(y, 0)); - double2 e = div_dd(dd(1, 0), d); - d = div_dd(add2_dd(d, scale_d(e, -1)), add2_dd(d, e)); - y = d.x + d.y; - - y = xisinf(x) || xisnan(y) ? 1.0 : y; - y = mulsign(y, x); - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -__inline double2 logk2(double2 d) { - double2 x, x2, m; - double t; - int e; - - d = normalize_d(d); - e = ilogbp1(d.x * 0.7071); - m = scale_d(d, ldexpk(1, -e)); - - x = div_dd(add2_ds(m, -1), add2_ds(m, 1)); - x2 = squ_d(x); - - t = 0.134601987501262130076155; - t = mla(t, x2.x, 0.132248509032032670243288); - t = mla(t, x2.x, 0.153883458318096079652524); - t = mla(t, x2.x, 0.181817427573705403298686); - t = mla(t, x2.x, 0.222222231326187414840781); - t = mla(t, x2.x, 0.285714285651261412873718); - t = mla(t, x2.x, 0.400000000000222439910458); - t = mla(t, x2.x, 0.666666666666666371239645); - - return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), - add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); -} - -__inline double xasinh(double x) { - double y = xfabs(x); - double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), 1)), y)); - y = d.x + d.y; - - y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; - y = mulsign(y, x); - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -__inline double xacosh(double x) { - double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), -1)), x)); - double y = d.x + d.y; - - y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; - y = x == 1.0 ? 0.0 : y; - y = x < 1.0 ? rtengine::RT_NAN : y; - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -__inline double xatanh(double x) { - double y = xfabs(x); - double2 d = logk2(div_dd(add2_ss(1, y), add2_ss(1, -y))); - y = y > 1.0 ? rtengine::RT_NAN : (y == 1.0 ? rtengine::RT_INFINITY : (d.x + d.y) * 0.5); - - y = xisinf(x) || xisnan(y) ? rtengine::RT_NAN : y; - y = mulsign(y, x); - y = xisnan(x) ? rtengine::RT_NAN : y; - - return y; -} - -// - -__inline double xfma(double x, double y, double z) { - union { - double f; - long long int i; - } tmp; - - tmp.f = x; - tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; - double xh = tmp.f, xl = x - xh; - - tmp.f = y; - tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; - double yh = tmp.f, yl = y - yh; - - double h = x * y; - double l = xh * yh - h + xl * yh + xh * yl + xl * yl; - - double h2, l2, v; - - h2 = h + z; - v = h2 - h; - l2 = (h - (h2 - v)) + (z - v) + l; - - return h2 + l2; -} - -__inline double xsqrt(double d) { // max error : 0.5 ulp - double q = 1; - - if (d < 8.636168555094445E-78) { - d *= 1.157920892373162E77; - q = 2.9387358770557188E-39; - } - - // http://en.wikipedia.org/wiki/Fast_inverse_square_root - double x = longBitsToDouble(0x5fe6ec85e7de30da - (doubleToRawLongBits(d + 1e-320) >> 1)); - - x = x * (1.5 - 0.5 * d * x * x); - x = x * (1.5 - 0.5 * d * x * x); - x = x * (1.5 - 0.5 * d * x * x); - - // You can change xfma to fma if fma is correctly implemented - x = xfma(d * x, d * x, -d) * (x * -0.5) + d * x; - - return d == rtengine::RT_INFINITY ? rtengine::RT_INFINITY : x * q; -} - -__inline double xcbrt(double d) { // max error : 2 ulps - double x, y, q = 1.0; - int e, r; - - e = ilogbp1(d); - d = ldexpk(d, -e); - r = (e + 6144) % 3; - q = (r == 1) ? 1.2599210498948731647672106 : q; - q = (r == 2) ? 1.5874010519681994747517056 : q; - q = ldexpk(q, (e + 6144) / 3 - 2048); - - q = mulsign(q, d); - d = xfabs(d); - - x = -0.640245898480692909870982; - x = x * d + 2.96155103020039511818595; - x = x * d + -5.73353060922947843636166; - x = x * d + 6.03990368989458747961407; - x = x * d + -3.85841935510444988821632; - x = x * d + 2.2307275302496609725722; - - y = x * x; y = y * y; x -= (d * y - x) * (1.0 / 3.0); - y = d * x * x; - y = (y - (2.0 / 3.0) * y * (y * x - 1)) * q; - - return y; -} - -__inline double xexp2(double a) { - double u = expk(mul_ds(dd(0.69314718055994528623, 2.3190468138462995584e-17), a)); - if (xispinf(a)) u = rtengine::RT_INFINITY; - if (xisminf(a)) u = 0; - return u; -} - -__inline double xexp10(double a) { - double u = expk(mul_ds(dd(2.3025850929940459011, -2.1707562233822493508e-16), a)); - if (xispinf(a)) u = rtengine::RT_INFINITY; - if (xisminf(a)) u = 0; - return u; -} - -__inline double xexpm1(double a) { - double2 d = add2_ds(expk2(dd(a, 0)), -1.0); - double x = d.x + d.y; - if (xispinf(a)) x = rtengine::RT_INFINITY; - if (xisminf(a)) x = -1; - return x; -} - -__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 (a < 0) x = rtengine::RT_NAN; - if (a == 0) x = -rtengine::RT_INFINITY; - - return x; -} - -__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 (a < -1) x = rtengine::RT_NAN; - if (a == -1) x = -rtengine::RT_INFINITY; - - return x; -} - -/////////////////////////////////////////// - -#define PI4_Af 0.78515625f -#define PI4_Bf 0.00024127960205078125f -#define PI4_Cf 6.3329935073852539062e-07f -#define PI4_Df 4.9604681473525147339e-10f - -#define L2Uf 0.693145751953125f -#define L2Lf 1.428606765330187045e-06f - -#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f - -__inline int32_t floatToRawIntBits(float d) { - union { - float f; - int32_t i; - } tmp; - tmp.f = d; - return tmp.i; -} - -__inline float intBitsToFloat(int32_t i) { - union { - float f; - int32_t i; - } tmp; - tmp.i = i; - return tmp.f; -} - -__inline float xfabsf(float x) { - return intBitsToFloat(0x7fffffffL & floatToRawIntBits(x)); -} - -__inline float mulsignf(float x, float y) { - return intBitsToFloat(floatToRawIntBits(x) ^ (floatToRawIntBits(y) & (1 << 31))); -} - -__inline float signf(float d) { return copysign(1, d); } -__inline float mlaf(float x, float y, float z) { return x * y + z; } - -__inline int xisnanf(float x) { return x != x; } -__inline int xisinff(float x) { return x == rtengine::RT_INFINITY_F || x == -rtengine::RT_INFINITY_F; } -__inline int xisminff(float x) { return x == -rtengine::RT_INFINITY_F; } -__inline int xispinff(float x) { return x == rtengine::RT_INFINITY_F; } - -__inline int ilogbp1f(float d) { - int m = d < 5.421010862427522E-20f; - d = m ? 1.8446744073709552E19f * d : d; - int q = (floatToRawIntBits(d) >> 23) & 0xff; - q = m ? q - (64 + 0x7e) : q - 0x7e; - return q; -} - -__inline float ldexpkf(float x, int q) { - float u; - int m; - m = q >> 31; - m = (((m + q) >> 6) - m) << 4; - q = q - (m << 2); - u = intBitsToFloat(((int32_t)(m + 0x7f)) << 23); - u = u * u; - x = x * u * u; - u = intBitsToFloat(((int32_t)(q + 0x7f)) << 23); - return x * u; -} - -__inline float xcbrtf(float d) { // max error : 2 ulps - float x, y, q = 1.0f; - int e, r; - - e = ilogbp1f(d); - d = ldexpkf(d, -e); - r = (e + 6144) % 3; - q = (r == 1) ? 1.2599210498948731647672106f : q; - q = (r == 2) ? 1.5874010519681994747517056f : q; - q = ldexpkf(q, (e + 6144) / 3 - 2048); - - q = mulsignf(q, d); - d = xfabsf(d); - - x = -0.601564466953277587890625f; - x = mlaf(x, d, 2.8208892345428466796875f); - x = mlaf(x, d, -5.532182216644287109375f); - x = mlaf(x, d, 5.898262500762939453125f); - x = mlaf(x, d, -3.8095417022705078125f); - x = mlaf(x, d, 2.2241256237030029296875f); - - y = d * x * x; - y = (y - (2.0f / 3.0f) * y * (y * x - 1.0f)) * q; - - return y; -} - -__inline float xsinf(float d) { - int q; - float u, s; - - q = rint(d * rtengine::RT_1_PI_F); - - d = mlaf(q, -PI4_Af*4, d); - d = mlaf(q, -PI4_Bf*4, d); - d = mlaf(q, -PI4_Cf*4, d); - d = mlaf(q, -PI4_Df*4, d); - - s = d * d; - - if ((q & 1) != 0) d = -d; - - u = 2.6083159809786593541503e-06f; - u = mlaf(u, s, -0.0001981069071916863322258f); - u = mlaf(u, s, 0.00833307858556509017944336f); - u = mlaf(u, s, -0.166666597127914428710938f); - - u = mlaf(s, u * d, d); - - return u; -} - -__inline float xcosf(float d) { -#ifdef __SSE2__ - // faster than scalar version - return xcosf(_mm_set_ss(d))[0]; -#else - int q; - float u, s; - - q = 1 + 2*rint(d * rtengine::RT_1_PI_F - 0.5f); - - d = mlaf(q, -PI4_Af*2, d); - d = mlaf(q, -PI4_Bf*2, d); - d = mlaf(q, -PI4_Cf*2, d); - d = mlaf(q, -PI4_Df*2, d); - - s = d * d; - - if ((q & 2) == 0) d = -d; - - u = 2.6083159809786593541503e-06f; - u = mlaf(u, s, -0.0001981069071916863322258f); - u = mlaf(u, s, 0.00833307858556509017944336f); - u = mlaf(u, s, -0.166666597127914428710938f); - - u = mlaf(s, u * d, d); - - return u; -#endif -} - -__inline float2 xsincosf(float d) { -#ifdef __SSE2__ - // faster than scalar version - vfloat2 res = xsincosf(_mm_set_ss(d)); - return {res.x[0], res.y[0]}; -#else - int q; - float u, s, t; - float2 r; - - q = rint(d * rtengine::RT_2_PI_F); - - s = d; - - s = mlaf(q, -PI4_Af*2, s); - s = mlaf(q, -PI4_Bf*2, s); - s = mlaf(q, -PI4_Cf*2, s); - s = mlaf(q, -PI4_Df*2, s); - - t = s; - - s = s * s; - - u = -0.000195169282960705459117889f; - u = mlaf(u, s, 0.00833215750753879547119141f); - u = mlaf(u, s, -0.166666537523269653320312f); - u = u * s * t; - - r.x = t + u; - - u = -2.71811842367242206819355e-07f; - u = mlaf(u, s, 2.47990446951007470488548e-05f); - u = mlaf(u, s, -0.00138888787478208541870117f); - u = mlaf(u, s, 0.0416666641831398010253906f); - u = mlaf(u, s, -0.5f); - - r.y = u * s + 1; - - if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } - if ((q & 2) != 0) { r.x = -r.x; } - if (((q+1) & 2) != 0) { r.y = -r.y; } - - if (xisinff(d)) { r.x = r.y = rtengine::RT_NAN_F; } - - return r; -#endif -} - -__inline float xtanf(float d) { - int q; - float u, s, x; - - q = rint(d * (float)(2 * rtengine::RT_1_PI)); - - x = d; - - x = mlaf(q, -PI4_Af*2, x); - x = mlaf(q, -PI4_Bf*2, x); - x = mlaf(q, -PI4_Cf*2, x); - x = mlaf(q, -PI4_Df*2, x); - - s = x * x; - - if ((q & 1) != 0) x = -x; - - u = 0.00927245803177356719970703f; - u = mlaf(u, s, 0.00331984995864331722259521f); - u = mlaf(u, s, 0.0242998078465461730957031f); - u = mlaf(u, s, 0.0534495301544666290283203f); - u = mlaf(u, s, 0.133383005857467651367188f); - u = mlaf(u, s, 0.333331853151321411132812f); - - u = mlaf(s, u * x, x); - - if ((q & 1) != 0) u = 1.0f / u; - - if (xisinff(d)) u = rtengine::RT_NAN_F; - - return u; -} - -__inline float xatanf(float s) { - float t, u; - int q = 0; - - if (s < 0) { s = -s; q = 2; } - if (s > 1) { s = 1.0f / s; q |= 1; } - - t = s * s; - - u = 0.00282363896258175373077393f; - u = mlaf(u, t, -0.0159569028764963150024414f); - u = mlaf(u, t, 0.0425049886107444763183594f); - u = mlaf(u, t, -0.0748900920152664184570312f); - u = mlaf(u, t, 0.106347933411598205566406f); - u = mlaf(u, t, -0.142027363181114196777344f); - u = mlaf(u, t, 0.199926957488059997558594f); - u = mlaf(u, t, -0.333331018686294555664062f); - - t = s + s * (t * u); - - if ((q & 1) != 0) t = 1.570796326794896557998982f - t; - if ((q & 2) != 0) t = -t; - - return t; -} - -__inline float atan2kf(float y, float x) { - float s, t, u; - float q = 0.f; - - if (x < 0) { x = -x; q = -2.f; } - if (y > x) { t = x; x = y; y = -t; q += 1.f; } - - s = y / x; - t = s * s; - - u = 0.00282363896258175373077393f; - u = mlaf(u, t, -0.0159569028764963150024414f); - u = mlaf(u, t, 0.0425049886107444763183594f); - u = mlaf(u, t, -0.0748900920152664184570312f); - u = mlaf(u, t, 0.106347933411598205566406f); - u = mlaf(u, t, -0.142027363181114196777344f); - u = mlaf(u, t, 0.199926957488059997558594f); - u = mlaf(u, t, -0.333331018686294555664062f); - - t = u * t; - t = mlaf(t,s,s); - return mlaf(q,(float)(rtengine::RT_PI_F_2),t); -} - -__inline float xatan2f(float y, float x) { - float r = atan2kf(xfabsf(y), x); - - r = mulsignf(r, x); - if (xisinff(x) || x == 0) r = rtengine::RT_PI_F/2 - (xisinff(x) ? (signf(x) * (float)(rtengine::RT_PI_F*.5f)) : 0); - if (xisinff(y) ) r = rtengine::RT_PI_F/2 - (xisinff(x) ? (signf(x) * (float)(rtengine::RT_PI_F*.25f)) : 0); - if ( y == 0) r = (signf(x) == -1 ? rtengine::RT_PI_F : 0); - - return xisnanf(x) || xisnanf(y) ? rtengine::RT_NAN_F : mulsignf(r, y); -} - -__inline float xasinf(float d) { - return mulsignf(atan2kf(fabsf(d), sqrtf((1.0f+d)*(1.0f-d))), d); -} - -__inline float xacosf(float d) { - return mulsignf(atan2kf(sqrtf((1.0f+d)*(1.0f-d)), fabsf(d)), d) + (d < 0 ? (float)rtengine::RT_PI : 0.0f); -} - -__inline float xlogf(float d) { - 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 (xisinff(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 xexpf(float d) { - if(d<=-104.0f) return 0.0f; - - int q = rint(d * R_LN2f); - float s, u; - - s = mlaf(q, -L2Uf, d); - s = mlaf(q, -L2Lf, s); - - u = 0.00136324646882712841033936f; - u = mlaf(u, s, 0.00836596917361021041870117f); - u = mlaf(u, s, 0.0416710823774337768554688f); - u = mlaf(u, s, 0.166665524244308471679688f); - u = mlaf(u, s, 0.499999850988388061523438f); - - u = mlaf( s, mlaf(s,u,1.f),1.f); - return ldexpkf(u, q); - -} - -__inline float xmul2f(float d) { - union { - float floatval; - int intval; - } uflint; - uflint.floatval = d; - if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing - uflint.intval += 1 << 23; // add 1 to the exponent - } - return uflint.floatval; -} - -__inline float xdiv2f(float d) { - union { - float floatval; - int intval; - } uflint; - uflint.floatval = d; - if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing - uflint.intval -= 1 << 23; // sub 1 from the exponent - } - return uflint.floatval; -} - -__inline float xdivf( float d, int n){ - union { - float floatval; - int intval; - } uflint; - uflint.floatval = d; - if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing - uflint.intval -= n << 23; // add n to the exponent - } - return uflint.floatval; -} - -__inline float xlin2log(float x, float base) -{ - constexpr float one(1); - return xlogf(x * (base - one) + one) / xlogf(base); -} - -__inline float xlog2lin(float x, float base) -{ - constexpr float one(1); - return (pow_F(base, x) - one) / (base - one); -} - -#endif diff --git a/rtengine/sleef.h b/rtengine/sleef.h new file mode 100644 index 000000000..30c059010 --- /dev/null +++ b/rtengine/sleef.h @@ -0,0 +1,1275 @@ +//////////////////////////////////////////////////////////////// +// +// this code was taken from http://shibatch.sourceforge.net/ +// Many thanks to the author of original version: Naoki Shibata +// +// This version contains modifications made by Ingo Weyrich +// +//////////////////////////////////////////////////////////////// +#pragma once + +#include +#include +#include "rt_math.h" +#include "opthelper.h" + +#define PI4_A .7853981554508209228515625 +#define PI4_B .794662735614792836713604629039764404296875e-8 +#define PI4_C .306161699786838294306516483068750264552437361480769e-16 +#define M_4_PI 1.273239544735162542821171882678754627704620361328125 + +#define L2U .69314718055966295651160180568695068359375 +#define L2L .28235290563031577122588448175013436025525412068e-12 +#define R_LN2 1.442695040888963407359924681001892137426645954152985934135449406931 +#define pow_F(a,b) (xexpf(b*xlogf(a))) + +__inline int64_t doubleToRawLongBits(double d) { + union { + double f; + int64_t i; + } tmp; + tmp.f = d; + return tmp.i; +} + +__inline double longBitsToDouble(int64_t i) { + union { + double f; + int64_t i; + } tmp; + tmp.i = i; + return tmp.f; +} + +__inline double xfabs(double x) { + return longBitsToDouble(0x7fffffffffffffffLL & doubleToRawLongBits(x)); +} + +__inline double mulsign(double x, double y) { + return longBitsToDouble(doubleToRawLongBits(x) ^ (doubleToRawLongBits(y) & (1LL << 63))); +} + +__inline double sign(double d) { return mulsign(1, d); } +__inline double mla(double x, double y, double z) { return x * y + z; } +__inline double xrint(double x) { return x < 0 ? (int)(x - 0.5) : (int)(x + 0.5); } + +__inline int xisnan(double x) { return x != x; } +__inline int xisinf(double x) { return x == rtengine::RT_INFINITY || x == -rtengine::RT_INFINITY; } +__inline int xisminf(double x) { return x == -rtengine::RT_INFINITY; } +__inline int xispinf(double x) { return x == rtengine::RT_INFINITY; } + +__inline double ldexpk(double x, int q) { + double u; + int m; + m = q >> 31; + m = (((m + q) >> 9) - m) << 7; + q = q - (m << 2); + u = longBitsToDouble(((int64_t)(m + 0x3ff)) << 52); + double u2 = u*u; + u2 = u2 * u2; + x = x * u2; + u = longBitsToDouble(((int64_t)(q + 0x3ff)) << 52); + return x * u; +} + +__inline double xldexp(double x, int q) { return ldexpk(x, q); } + +__inline int ilogbp1(double d) { + int m = d < 4.9090934652977266E-91; + d = m ? 2.037035976334486E90 * d : d; + int q = (doubleToRawLongBits(d) >> 52) & 0x7ff; + q = m ? q - (300 + 0x03fe) : q - 0x03fe; + return q; +} + +__inline int xilogb(double d) { + int e = ilogbp1(xfabs(d)) - 1; + e = d == 0 ? (-2147483647 - 1) : e; + e = d == rtengine::RT_INFINITY || d == -rtengine::RT_INFINITY ? 2147483647 : e; + return e; +} + +__inline double upper(double d) { + return longBitsToDouble(doubleToRawLongBits(d) & 0xfffffffff8000000LL); +} + +typedef struct { + double x, y; +} double2; + +typedef struct { + float x, y; +} float2; + +__inline double2 dd(double h, double l) { + double2 ret; + ret.x = h; ret.y = l; + return ret; +} + +__inline double2 normalize_d(double2 t) { + double2 s; + + s.x = t.x + t.y; + s.y = t.x - s.x + t.y; + + return s; +} + +__inline double2 scale_d(double2 d, double s) { + double2 r; + + r.x = d.x * s; + r.y = d.y * s; + + return r; +} + +__inline double2 add2_ss(double x, double y) { + double2 r; + + r.x = x + y; + double v = r.x - x; + r.y = (x - (r.x - v)) + (y - v); + + return r; +} + +__inline double2 add_ds(double2 x, double y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x.x) || xisnan(y) || xfabs(x.x) >= xfabs(y)); + + r.x = x.x + y; + r.y = x.x - r.x + y + x.y; + + return r; +} + +__inline double2 add2_ds(double2 x, double y) { + // |x| >= |y| + + double2 r; + + r.x = x.x + y; + double v = r.x - x.x; + r.y = (x.x - (r.x - v)) + (y - v); + r.y += x.y; + + return r; +} + +__inline double2 add_sd(double x, double2 y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x) || xisnan(y.x) || xfabs(x) >= xfabs(y.x)); + + r.x = x + y.x; + r.y = x - r.x + y.x + y.y; + + return r; +} + +__inline double2 add_dd(double2 x, double2 y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x.x) || xisnan(y.x) || xfabs(x.x) >= xfabs(y.x)); + + r.x = x.x + y.x; + r.y = x.x - r.x + y.x + x.y + y.y; + + return r; +} + +__inline double2 add2_dd(double2 x, double2 y) { + double2 r; + + r.x = x.x + y.x; + double v = r.x - x.x; + r.y = (x.x - (r.x - v)) + (y.x - v); + r.y += x.y + y.y; + + return r; +} + +__inline double2 div_dd(double2 n, double2 d) { + double t = 1.0 / d.x; + double dh = upper(d.x), dl = d.x - dh; + double th = upper(t ), tl = t - th; + double nhh = upper(n.x), nhl = n.x - nhh; + + double2 q; + + q.x = n.x * t; + + double u = -q.x + nhh * th + nhh * tl + nhl * th + nhl * tl + + q.x * (1 - dh * th - dh * tl - dl * th - dl * tl); + + q.y = t * (n.y - q.x * d.y) + u; + + return q; +} + +__inline double2 mul_ss(double x, double y) { + double xh = upper(x), xl = x - xh; + double yh = upper(y), yl = y - yh; + double2 r; + + r.x = x * y; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl; + + return r; +} + +__inline double2 mul_ds(double2 x, double y) { + double xh = upper(x.x), xl = x.x - xh; + double yh = upper(y ), yl = y - yh; + double2 r; + + r.x = x.x * y; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.y * y; + + return r; +} + +__inline double2 mul_dd(double2 x, double2 y) { + double xh = upper(x.x), xl = x.x - xh; + double yh = upper(y.x), yl = y.x - yh; + double2 r; + + r.x = x.x * y.x; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.x * y.y + x.y * y.x; + + return r; +} + +__inline double2 squ_d(double2 x) { + double xh = upper(x.x), xl = x.x - xh; + double2 r; + + r.x = x.x * x.x; + r.y = xh * xh - r.x + (xh + xh) * xl + xl * xl + x.x * (x.y + x.y); + + return r; +} + +__inline double2 rec_s(double d) { + double t = 1.0 / d; + double dh = upper(d), dl = d - dh; + double th = upper(t), tl = t - th; + double2 q; + + q.x = t; + q.y = t * (1 - dh * th - dh * tl - dl * th - dl * tl); + + return q; +} + +__inline double2 sqrt_d(double2 d) { + double t = sqrt(d.x + d.y); + return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), 0.5); +} + +__inline double atan2k(double y, double x) { + double s, t, u; + int q = 0; + + if (x < 0) { x = -x; q = -2; } + if (y > x) { t = x; x = y; y = -t; q += 1; } + + s = y / x; + t = s * s; + + u = -1.88796008463073496563746e-05; + u = u * t + (0.000209850076645816976906797); + u = u * t + (-0.00110611831486672482563471); + u = u * t + (0.00370026744188713119232403); + u = u * t + (-0.00889896195887655491740809); + u = u * t + (0.016599329773529201970117); + u = u * t + (-0.0254517624932312641616861); + u = u * t + (0.0337852580001353069993897); + u = u * t + (-0.0407629191276836500001934); + u = u * t + (0.0466667150077840625632675); + u = u * t + (-0.0523674852303482457616113); + u = u * t + (0.0587666392926673580854313); + u = u * t + (-0.0666573579361080525984562); + u = u * t + (0.0769219538311769618355029); + u = u * t + (-0.090908995008245008229153); + u = u * t + (0.111111105648261418443745); + u = u * t + (-0.14285714266771329383765); + u = u * t + (0.199999999996591265594148); + u = u * t + (-0.333333333333311110369124); + + t = u * t * s + s; + t = q * (rtengine::RT_PI_2) + t; + + return t; +} + +__inline double xatan2(double y, double x) { + double r = atan2k(xfabs(y), x); + + r = mulsign(r, x); + if (xisinf(x) || x == 0) r = rtengine::RT_PI_2 - (xisinf(x) ? (sign(x) * (rtengine::RT_PI_2)) : 0); + if (xisinf(y) ) r = rtengine::RT_PI_2 - (xisinf(x) ? (sign(x) * (rtengine::RT_PI*1/4)) : 0); + if ( y == 0) r = (sign(x) == -1 ? rtengine::RT_PI : 0); + + return xisnan(x) || xisnan(y) ? rtengine::RT_NAN : mulsign(r, y); +} + +__inline double xasin(double d) { + return mulsign(atan2k(xfabs(d), sqrt((1+d)*(1-d))), d); +} + +__inline double xacos(double d) { + return mulsign(atan2k(sqrt((1+d)*(1-d)), xfabs(d)), d) + (d < 0 ? rtengine::RT_PI : 0); +} + +__inline double xatan(double s) { + double t, u; + int q = 0; + + if (s < 0) { s = -s; q = 2; } + if (s > 1) { s = 1.0 / s; q |= 1; } + + t = s * s; + + u = -1.88796008463073496563746e-05; + u = u * t + (0.000209850076645816976906797); + u = u * t + (-0.00110611831486672482563471); + u = u * t + (0.00370026744188713119232403); + u = u * t + (-0.00889896195887655491740809); + u = u * t + (0.016599329773529201970117); + u = u * t + (-0.0254517624932312641616861); + u = u * t + (0.0337852580001353069993897); + u = u * t + (-0.0407629191276836500001934); + u = u * t + (0.0466667150077840625632675); + u = u * t + (-0.0523674852303482457616113); + u = u * t + (0.0587666392926673580854313); + u = u * t + (-0.0666573579361080525984562); + u = u * t + (0.0769219538311769618355029); + u = u * t + (-0.090908995008245008229153); + u = u * t + (0.111111105648261418443745); + u = u * t + (-0.14285714266771329383765); + u = u * t + (0.199999999996591265594148); + u = u * t + (-0.333333333333311110369124); + + t = s + s * (t * u); + + if ((q & 1) != 0) t = 1.570796326794896557998982 - t; + if ((q & 2) != 0) t = -t; + + return t; +} + +__inline double xsin(double d) { + int q; + double u, s; + + q = (int)xrint(d * rtengine::RT_1_PI); + + d = mla(q, -PI4_A*4, d); + d = mla(q, -PI4_B*4, d); + d = mla(q, -PI4_C*4, d); + + s = d * d; + + if ((q & 1) != 0) d = -d; + + u = -7.97255955009037868891952e-18; + u = mla(u, s, 2.81009972710863200091251e-15); + u = mla(u, s, -7.64712219118158833288484e-13); + u = mla(u, s, 1.60590430605664501629054e-10); + u = mla(u, s, -2.50521083763502045810755e-08); + u = mla(u, s, 2.75573192239198747630416e-06); + u = mla(u, s, -0.000198412698412696162806809); + u = mla(u, s, 0.00833333333333332974823815); + u = mla(u, s, -0.166666666666666657414808); + + u = mla(s, u * d, d); + + return u; +} + +__inline double xcos(double d) { + int q; + double u, s; + + q = 1 + 2*(int)xrint(d * rtengine::RT_1_PI - 0.5); + + d = mla(q, -PI4_A*2, d); + d = mla(q, -PI4_B*2, d); + d = mla(q, -PI4_C*2, d); + + s = d * d; + + if ((q & 2) == 0) d = -d; + + u = -7.97255955009037868891952e-18; + u = mla(u, s, 2.81009972710863200091251e-15); + u = mla(u, s, -7.64712219118158833288484e-13); + u = mla(u, s, 1.60590430605664501629054e-10); + u = mla(u, s, -2.50521083763502045810755e-08); + u = mla(u, s, 2.75573192239198747630416e-06); + u = mla(u, s, -0.000198412698412696162806809); + u = mla(u, s, 0.00833333333333332974823815); + u = mla(u, s, -0.166666666666666657414808); + + u = mla(s, u * d, d); + + return u; +} + +__inline double2 xsincos(double d) { + int q; + double u, s, t; + double2 r; + + q = (int)xrint(d * (2 * rtengine::RT_1_PI)); + + s = d; + + s = mla(-q, PI4_A*2, s); + s = mla(-q, PI4_B*2, s); + s = mla(-q, PI4_C*2, s); + + t = s; + + s = s * s; + + u = 1.58938307283228937328511e-10; + u = mla(u, s, -2.50506943502539773349318e-08); + u = mla(u, s, 2.75573131776846360512547e-06); + u = mla(u, s, -0.000198412698278911770864914); + u = mla(u, s, 0.0083333333333191845961746); + u = mla(u, s, -0.166666666666666130709393); + u = u * s * t; + + r.x = t + u; + + u = -1.13615350239097429531523e-11; + u = mla(u, s, 2.08757471207040055479366e-09); + u = mla(u, s, -2.75573144028847567498567e-07); + u = mla(u, s, 2.48015872890001867311915e-05); + u = mla(u, s, -0.00138888888888714019282329); + u = mla(u, s, 0.0416666666666665519592062); + u = mla(u, s, -0.5); + + r.y = u * s + 1; + + if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } + if ((q & 2) != 0) { r.x = -r.x; } + if (((q+1) & 2) != 0) { r.y = -r.y; } + + if (xisinf(d)) { r.x = r.y = rtengine::RT_NAN; } + + return r; +} + +__inline double xtan(double d) { + int q; + double u, s, x; + + q = (int)xrint(d * (2 * rtengine::RT_1_PI)); + + x = mla(q, -PI4_A*2, d); + x = mla(q, -PI4_B*2, x); + x = mla(q, -PI4_C*2, x); + + s = x * x; + + if ((q & 1) != 0) x = -x; + + u = 1.01419718511083373224408e-05; + u = mla(u, s, -2.59519791585924697698614e-05); + u = mla(u, s, 5.23388081915899855325186e-05); + u = mla(u, s, -3.05033014433946488225616e-05); + u = mla(u, s, 7.14707504084242744267497e-05); + u = mla(u, s, 8.09674518280159187045078e-05); + u = mla(u, s, 0.000244884931879331847054404); + u = mla(u, s, 0.000588505168743587154904506); + u = mla(u, s, 0.00145612788922812427978848); + u = mla(u, s, 0.00359208743836906619142924); + u = mla(u, s, 0.00886323944362401618113356); + u = mla(u, s, 0.0218694882853846389592078); + u = mla(u, s, 0.0539682539781298417636002); + u = mla(u, s, 0.133333333333125941821962); + u = mla(u, s, 0.333333333333334980164153); + + u = mla(s, u * x, x); + + if ((q & 1) != 0) u = 1.0 / u; + + if (xisinf(d)) u = rtengine::RT_NAN; + + return u; +} + +__inline double xlog(double d) { + double x, x2, t, m; + int e; + + e = ilogbp1(d * 0.7071); + m = ldexpk(d, -e); + + x = (m-1) / (m+1); + x2 = x * x; + + t = 0.148197055177935105296783; + t = mla(t, x2, 0.153108178020442575739679); + t = mla(t, x2, 0.181837339521549679055568); + t = mla(t, x2, 0.22222194152736701733275); + t = mla(t, x2, 0.285714288030134544449368); + t = mla(t, x2, 0.399999999989941956712869); + t = mla(t, x2, 0.666666666666685503450651); + t = mla(t, x2, 2); + + x = x * t + 0.693147180559945286226764 * e; + + if (xisinf(d)) x = rtengine::RT_INFINITY; + if (d < 0) x = rtengine::RT_NAN; + if (d == 0) x = -rtengine::RT_INFINITY; + + return x; +} + +__inline double xexp(double d) { + int q = (int)xrint(d * R_LN2); + double s, u; + + s = mla(q, -L2U, d); + s = mla(q, -L2L, s); + + u = 2.08860621107283687536341e-09; + u = mla(u, s, 2.51112930892876518610661e-08); + u = mla(u, s, 2.75573911234900471893338e-07); + u = mla(u, s, 2.75572362911928827629423e-06); + u = mla(u, s, 2.4801587159235472998791e-05); + u = mla(u, s, 0.000198412698960509205564975); + u = mla(u, s, 0.00138888888889774492207962); + u = mla(u, s, 0.00833333333331652721664984); + u = mla(u, s, 0.0416666666666665047591422); + u = mla(u, s, 0.166666666666666851703837); + u = mla(u, s, 0.5); + + u = s * s * u + s + 1; + u = ldexpk(u, q); + + if (xisminf(d)) u = 0; + + return u; +} + +__inline double2 logk(double d) { + double2 x, x2; + double m, t; + int e; + + e = ilogbp1(d * 0.7071); + m = ldexpk(d, -e); + + x = div_dd(add2_ss(-1, m), add2_ss(1, m)); + x2 = squ_d(x); + + t = 0.134601987501262130076155; + t = mla(t, x2.x, 0.132248509032032670243288); + t = mla(t, x2.x, 0.153883458318096079652524); + t = mla(t, x2.x, 0.181817427573705403298686); + t = mla(t, x2.x, 0.222222231326187414840781); + t = mla(t, x2.x, 0.285714285651261412873718); + t = mla(t, x2.x, 0.400000000000222439910458); + t = mla(t, x2.x, 0.666666666666666371239645); + + return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), + add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); +} + +__inline double expk(double2 d) { + int q = (int)rint((d.x + d.y) * R_LN2); + double2 s, t; + double u; + + s = add2_ds(d, q * -L2U); + s = add2_ds(s, q * -L2L); + + s = normalize_d(s); + + u = 2.51069683420950419527139e-08; + u = mla(u, s.x, 2.76286166770270649116855e-07); + u = mla(u, s.x, 2.75572496725023574143864e-06); + u = mla(u, s.x, 2.48014973989819794114153e-05); + u = mla(u, s.x, 0.000198412698809069797676111); + u = mla(u, s.x, 0.0013888888939977128960529); + u = mla(u, s.x, 0.00833333333332371417601081); + u = mla(u, s.x, 0.0416666666665409524128449); + u = mla(u, s.x, 0.166666666666666740681535); + u = mla(u, s.x, 0.500000000000000999200722); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(1, t); + return ldexpk(t.x + t.y, q); +} + +__inline double xpow(double x, double y) { + int yisint = (int)y == y; + int yisodd = (1 & (int)y) != 0 && yisint; + + double result = expk(mul_ds(logk(xfabs(x)), y)); + + result = xisnan(result) ? rtengine::RT_INFINITY : result; + result *= (x >= 0 ? 1 : (!yisint ? rtengine::RT_NAN : (yisodd ? -1 : 1))); + + double efx = mulsign(xfabs(x) - 1, y); + if (xisinf(y)) result = efx < 0 ? 0.0 : (efx == 0 ? 1.0 : rtengine::RT_INFINITY); + if (xisinf(x) || x == 0) result = (yisodd ? sign(x) : 1) * ((x == 0 ? -y : y) < 0 ? 0 : rtengine::RT_INFINITY); + if (xisnan(x) || xisnan(y)) result = rtengine::RT_NAN; + if (y == 0 || x == 1) result = 1; + + return result; +} + +__inline double2 expk2(double2 d) { + int q = (int)rint((d.x + d.y) * R_LN2); + double2 s, t; + double u; + + s = add2_ds(d, q * -L2U); + s = add2_ds(s, q * -L2L); + + s = normalize_d(s); + + u = 2.51069683420950419527139e-08; + u = mla(u, s.x, 2.76286166770270649116855e-07); + u = mla(u, s.x, 2.75572496725023574143864e-06); + u = mla(u, s.x, 2.48014973989819794114153e-05); + u = mla(u, s.x, 0.000198412698809069797676111); + u = mla(u, s.x, 0.0013888888939977128960529); + u = mla(u, s.x, 0.00833333333332371417601081); + u = mla(u, s.x, 0.0416666666665409524128449); + u = mla(u, s.x, 0.166666666666666740681535); + u = mla(u, s.x, 0.500000000000000999200722); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(1, t); + return dd(ldexpk(t.x, q), ldexpk(t.y, q)); +} + +__inline double xsinh(double x) { + double y = xfabs(x); + double2 d = expk2(dd(y, 0)); + d = add2_dd(d, div_dd(dd(-1, 0), d)); + y = (d.x + d.y) * 0.5; + + y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; + y = mulsign(y, x); + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +__inline double xcosh(double x) { + double2 d = expk2(dd(x, 0)); + d = add2_dd(d, div_dd(dd(1, 0), d)); + double y = (d.x + d.y) * 0.5; + + y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +__inline double xtanh(double x) { + double y = xfabs(x); + double2 d = expk2(dd(y, 0)); + double2 e = div_dd(dd(1, 0), d); + d = div_dd(add2_dd(d, scale_d(e, -1)), add2_dd(d, e)); + y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? 1.0 : y; + y = mulsign(y, x); + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +__inline double2 logk2(double2 d) { + double2 x, x2, m; + double t; + int e; + + d = normalize_d(d); + e = ilogbp1(d.x * 0.7071); + m = scale_d(d, ldexpk(1, -e)); + + x = div_dd(add2_ds(m, -1), add2_ds(m, 1)); + x2 = squ_d(x); + + t = 0.134601987501262130076155; + t = mla(t, x2.x, 0.132248509032032670243288); + t = mla(t, x2.x, 0.153883458318096079652524); + t = mla(t, x2.x, 0.181817427573705403298686); + t = mla(t, x2.x, 0.222222231326187414840781); + t = mla(t, x2.x, 0.285714285651261412873718); + t = mla(t, x2.x, 0.400000000000222439910458); + t = mla(t, x2.x, 0.666666666666666371239645); + + return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), + add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); +} + +__inline double xasinh(double x) { + double y = xfabs(x); + double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), 1)), y)); + y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; + y = mulsign(y, x); + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +__inline double xacosh(double x) { + double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), -1)), x)); + double y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? rtengine::RT_INFINITY : y; + y = x == 1.0 ? 0.0 : y; + y = x < 1.0 ? rtengine::RT_NAN : y; + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +__inline double xatanh(double x) { + double y = xfabs(x); + double2 d = logk2(div_dd(add2_ss(1, y), add2_ss(1, -y))); + y = y > 1.0 ? rtengine::RT_NAN : (y == 1.0 ? rtengine::RT_INFINITY : (d.x + d.y) * 0.5); + + y = xisinf(x) || xisnan(y) ? rtengine::RT_NAN : y; + y = mulsign(y, x); + y = xisnan(x) ? rtengine::RT_NAN : y; + + return y; +} + +// + +__inline double xfma(double x, double y, double z) { + union { + double f; + long long int i; + } tmp; + + tmp.f = x; + tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; + double xh = tmp.f, xl = x - xh; + + tmp.f = y; + tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; + double yh = tmp.f, yl = y - yh; + + double h = x * y; + double l = xh * yh - h + xl * yh + xh * yl + xl * yl; + + double h2, l2, v; + + h2 = h + z; + v = h2 - h; + l2 = (h - (h2 - v)) + (z - v) + l; + + return h2 + l2; +} + +__inline double xsqrt(double d) { // max error : 0.5 ulp + double q = 1; + + if (d < 8.636168555094445E-78) { + d *= 1.157920892373162E77; + q = 2.9387358770557188E-39; + } + + // http://en.wikipedia.org/wiki/Fast_inverse_square_root + double x = longBitsToDouble(0x5fe6ec85e7de30da - (doubleToRawLongBits(d + 1e-320) >> 1)); + + x = x * (1.5 - 0.5 * d * x * x); + x = x * (1.5 - 0.5 * d * x * x); + x = x * (1.5 - 0.5 * d * x * x); + + // You can change xfma to fma if fma is correctly implemented + x = xfma(d * x, d * x, -d) * (x * -0.5) + d * x; + + return d == rtengine::RT_INFINITY ? rtengine::RT_INFINITY : x * q; +} + +__inline double xcbrt(double d) { // max error : 2 ulps + double x, y, q = 1.0; + int e, r; + + e = ilogbp1(d); + d = ldexpk(d, -e); + r = (e + 6144) % 3; + q = (r == 1) ? 1.2599210498948731647672106 : q; + q = (r == 2) ? 1.5874010519681994747517056 : q; + q = ldexpk(q, (e + 6144) / 3 - 2048); + + q = mulsign(q, d); + d = xfabs(d); + + x = -0.640245898480692909870982; + x = x * d + 2.96155103020039511818595; + x = x * d + -5.73353060922947843636166; + x = x * d + 6.03990368989458747961407; + x = x * d + -3.85841935510444988821632; + x = x * d + 2.2307275302496609725722; + + y = x * x; y = y * y; x -= (d * y - x) * (1.0 / 3.0); + y = d * x * x; + y = (y - (2.0 / 3.0) * y * (y * x - 1)) * q; + + return y; +} + +__inline double xexp2(double a) { + double u = expk(mul_ds(dd(0.69314718055994528623, 2.3190468138462995584e-17), a)); + if (xispinf(a)) u = rtengine::RT_INFINITY; + if (xisminf(a)) u = 0; + return u; +} + +__inline double xexp10(double a) { + double u = expk(mul_ds(dd(2.3025850929940459011, -2.1707562233822493508e-16), a)); + if (xispinf(a)) u = rtengine::RT_INFINITY; + if (xisminf(a)) u = 0; + return u; +} + +__inline double xexpm1(double a) { + double2 d = add2_ds(expk2(dd(a, 0)), -1.0); + double x = d.x + d.y; + if (xispinf(a)) x = rtengine::RT_INFINITY; + if (xisminf(a)) x = -1; + return x; +} + +__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 (a < 0) x = rtengine::RT_NAN; + if (a == 0) x = -rtengine::RT_INFINITY; + + return x; +} + +__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 (a < -1) x = rtengine::RT_NAN; + if (a == -1) x = -rtengine::RT_INFINITY; + + return x; +} + +/////////////////////////////////////////// + +#define PI4_Af 0.78515625f +#define PI4_Bf 0.00024127960205078125f +#define PI4_Cf 6.3329935073852539062e-07f +#define PI4_Df 4.9604681473525147339e-10f + +#define L2Uf 0.693145751953125f +#define L2Lf 1.428606765330187045e-06f + +#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f + +__inline int32_t floatToRawIntBits(float d) { + union { + float f; + int32_t i; + } tmp; + tmp.f = d; + return tmp.i; +} + +__inline float intBitsToFloat(int32_t i) { + union { + float f; + int32_t i; + } tmp; + tmp.i = i; + return tmp.f; +} + +__inline float xfabsf(float x) { + return intBitsToFloat(0x7fffffffL & floatToRawIntBits(x)); +} + +__inline float mulsignf(float x, float y) { + return intBitsToFloat(floatToRawIntBits(x) ^ (floatToRawIntBits(y) & (1 << 31))); +} + +__inline float signf(float d) { return copysign(1, d); } +__inline float mlaf(float x, float y, float z) { return x * y + z; } + +__inline int xisnanf(float x) { return x != x; } +__inline int xisinff(float x) { return x == rtengine::RT_INFINITY_F || x == -rtengine::RT_INFINITY_F; } +__inline int xisminff(float x) { return x == -rtengine::RT_INFINITY_F; } +__inline int xispinff(float x) { return x == rtengine::RT_INFINITY_F; } + +__inline int ilogbp1f(float d) { + int m = d < 5.421010862427522E-20f; + d = m ? 1.8446744073709552E19f * d : d; + int q = (floatToRawIntBits(d) >> 23) & 0xff; + q = m ? q - (64 + 0x7e) : q - 0x7e; + return q; +} + +__inline float ldexpkf(float x, int q) { + float u; + int m; + m = q >> 31; + m = (((m + q) >> 6) - m) << 4; + q = q - (m << 2); + u = intBitsToFloat(((int32_t)(m + 0x7f)) << 23); + u = u * u; + x = x * u * u; + u = intBitsToFloat(((int32_t)(q + 0x7f)) << 23); + return x * u; +} + +__inline float xcbrtf(float d) { // max error : 2 ulps + float x, y, q = 1.0f; + int e, r; + + e = ilogbp1f(d); + d = ldexpkf(d, -e); + r = (e + 6144) % 3; + q = (r == 1) ? 1.2599210498948731647672106f : q; + q = (r == 2) ? 1.5874010519681994747517056f : q; + q = ldexpkf(q, (e + 6144) / 3 - 2048); + + q = mulsignf(q, d); + d = xfabsf(d); + + x = -0.601564466953277587890625f; + x = mlaf(x, d, 2.8208892345428466796875f); + x = mlaf(x, d, -5.532182216644287109375f); + x = mlaf(x, d, 5.898262500762939453125f); + x = mlaf(x, d, -3.8095417022705078125f); + x = mlaf(x, d, 2.2241256237030029296875f); + + y = d * x * x; + y = (y - (2.0f / 3.0f) * y * (y * x - 1.0f)) * q; + + return y; +} + +__inline float xsinf(float d) { + int q; + float u, s; + + q = rint(d * rtengine::RT_1_PI_F); + + d = mlaf(q, -PI4_Af*4, d); + d = mlaf(q, -PI4_Bf*4, d); + d = mlaf(q, -PI4_Cf*4, d); + d = mlaf(q, -PI4_Df*4, d); + + s = d * d; + + if ((q & 1) != 0) d = -d; + + u = 2.6083159809786593541503e-06f; + u = mlaf(u, s, -0.0001981069071916863322258f); + u = mlaf(u, s, 0.00833307858556509017944336f); + u = mlaf(u, s, -0.166666597127914428710938f); + + u = mlaf(s, u * d, d); + + return u; +} + +__inline float xcosf(float d) { +#ifdef __SSE2__ + // faster than scalar version + return xcosf(_mm_set_ss(d))[0]; +#else + int q; + float u, s; + + q = 1 + 2*rint(d * rtengine::RT_1_PI_F - 0.5f); + + d = mlaf(q, -PI4_Af*2, d); + d = mlaf(q, -PI4_Bf*2, d); + d = mlaf(q, -PI4_Cf*2, d); + d = mlaf(q, -PI4_Df*2, d); + + s = d * d; + + if ((q & 2) == 0) d = -d; + + u = 2.6083159809786593541503e-06f; + u = mlaf(u, s, -0.0001981069071916863322258f); + u = mlaf(u, s, 0.00833307858556509017944336f); + u = mlaf(u, s, -0.166666597127914428710938f); + + u = mlaf(s, u * d, d); + + return u; +#endif +} + +__inline float2 xsincosf(float d) { +#ifdef __SSE2__ + // faster than scalar version + vfloat2 res = xsincosf(_mm_set_ss(d)); + return {res.x[0], res.y[0]}; +#else + int q; + float u, s, t; + float2 r; + + q = rint(d * rtengine::RT_2_PI_F); + + s = d; + + s = mlaf(q, -PI4_Af*2, s); + s = mlaf(q, -PI4_Bf*2, s); + s = mlaf(q, -PI4_Cf*2, s); + s = mlaf(q, -PI4_Df*2, s); + + t = s; + + s = s * s; + + u = -0.000195169282960705459117889f; + u = mlaf(u, s, 0.00833215750753879547119141f); + u = mlaf(u, s, -0.166666537523269653320312f); + u = u * s * t; + + r.x = t + u; + + u = -2.71811842367242206819355e-07f; + u = mlaf(u, s, 2.47990446951007470488548e-05f); + u = mlaf(u, s, -0.00138888787478208541870117f); + u = mlaf(u, s, 0.0416666641831398010253906f); + u = mlaf(u, s, -0.5f); + + r.y = u * s + 1; + + if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } + if ((q & 2) != 0) { r.x = -r.x; } + if (((q+1) & 2) != 0) { r.y = -r.y; } + + if (xisinff(d)) { r.x = r.y = rtengine::RT_NAN_F; } + + return r; +#endif +} + +__inline float xtanf(float d) { + int q; + float u, s, x; + + q = rint(d * (float)(2 * rtengine::RT_1_PI)); + + x = d; + + x = mlaf(q, -PI4_Af*2, x); + x = mlaf(q, -PI4_Bf*2, x); + x = mlaf(q, -PI4_Cf*2, x); + x = mlaf(q, -PI4_Df*2, x); + + s = x * x; + + if ((q & 1) != 0) x = -x; + + u = 0.00927245803177356719970703f; + u = mlaf(u, s, 0.00331984995864331722259521f); + u = mlaf(u, s, 0.0242998078465461730957031f); + u = mlaf(u, s, 0.0534495301544666290283203f); + u = mlaf(u, s, 0.133383005857467651367188f); + u = mlaf(u, s, 0.333331853151321411132812f); + + u = mlaf(s, u * x, x); + + if ((q & 1) != 0) u = 1.0f / u; + + if (xisinff(d)) u = rtengine::RT_NAN_F; + + return u; +} + +__inline float xatanf(float s) { + float t, u; + int q = 0; + + if (s < 0) { s = -s; q = 2; } + if (s > 1) { s = 1.0f / s; q |= 1; } + + t = s * s; + + u = 0.00282363896258175373077393f; + u = mlaf(u, t, -0.0159569028764963150024414f); + u = mlaf(u, t, 0.0425049886107444763183594f); + u = mlaf(u, t, -0.0748900920152664184570312f); + u = mlaf(u, t, 0.106347933411598205566406f); + u = mlaf(u, t, -0.142027363181114196777344f); + u = mlaf(u, t, 0.199926957488059997558594f); + u = mlaf(u, t, -0.333331018686294555664062f); + + t = s + s * (t * u); + + if ((q & 1) != 0) t = 1.570796326794896557998982f - t; + if ((q & 2) != 0) t = -t; + + return t; +} + +__inline float atan2kf(float y, float x) { + float s, t, u; + float q = 0.f; + + if (x < 0) { x = -x; q = -2.f; } + if (y > x) { t = x; x = y; y = -t; q += 1.f; } + + s = y / x; + t = s * s; + + u = 0.00282363896258175373077393f; + u = mlaf(u, t, -0.0159569028764963150024414f); + u = mlaf(u, t, 0.0425049886107444763183594f); + u = mlaf(u, t, -0.0748900920152664184570312f); + u = mlaf(u, t, 0.106347933411598205566406f); + u = mlaf(u, t, -0.142027363181114196777344f); + u = mlaf(u, t, 0.199926957488059997558594f); + u = mlaf(u, t, -0.333331018686294555664062f); + + t = u * t; + t = mlaf(t,s,s); + return mlaf(q,(float)(rtengine::RT_PI_F_2),t); +} + +__inline float xatan2f(float y, float x) { + float r = atan2kf(xfabsf(y), x); + + r = mulsignf(r, x); + if (xisinff(x) || x == 0) r = rtengine::RT_PI_F/2 - (xisinff(x) ? (signf(x) * (float)(rtengine::RT_PI_F*.5f)) : 0); + if (xisinff(y) ) r = rtengine::RT_PI_F/2 - (xisinff(x) ? (signf(x) * (float)(rtengine::RT_PI_F*.25f)) : 0); + if ( y == 0) r = (signf(x) == -1 ? rtengine::RT_PI_F : 0); + + return xisnanf(x) || xisnanf(y) ? rtengine::RT_NAN_F : mulsignf(r, y); +} + +__inline float xasinf(float d) { + return mulsignf(atan2kf(fabsf(d), sqrtf((1.0f+d)*(1.0f-d))), d); +} + +__inline float xacosf(float d) { + return mulsignf(atan2kf(sqrtf((1.0f+d)*(1.0f-d)), fabsf(d)), d) + (d < 0 ? (float)rtengine::RT_PI : 0.0f); +} + +__inline float xlogf(float d) { + 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 (xisinff(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 xexpf(float d) { + if(d<=-104.0f) return 0.0f; + + int q = rint(d * R_LN2f); + float s, u; + + s = mlaf(q, -L2Uf, d); + s = mlaf(q, -L2Lf, s); + + u = 0.00136324646882712841033936f; + u = mlaf(u, s, 0.00836596917361021041870117f); + u = mlaf(u, s, 0.0416710823774337768554688f); + u = mlaf(u, s, 0.166665524244308471679688f); + u = mlaf(u, s, 0.499999850988388061523438f); + + u = mlaf( s, mlaf(s,u,1.f),1.f); + return ldexpkf(u, q); + +} + +__inline float xmul2f(float d) { + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval += 1 << 23; // add 1 to the exponent + } + return uflint.floatval; +} + +__inline float xdiv2f(float d) { + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval -= 1 << 23; // sub 1 from the exponent + } + return uflint.floatval; +} + +__inline float xdivf( float d, int n){ + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval -= n << 23; // add n to the exponent + } + return uflint.floatval; +} + +__inline float xlin2log(float x, float base) +{ + constexpr float one(1); + return xlogf(x * (base - one) + one) / xlogf(base); +} + +__inline float xlog2lin(float x, float base) +{ + constexpr float one(1); + return (pow_F(base, x) - one) / (base - one); +} diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c index 3000c1c10..1982c7c4c 100644 --- a/rtengine/sleefsseavx.c +++ b/rtengine/sleefsseavx.c @@ -48,199 +48,199 @@ #define NANf ((float)rtengine::RT_NAN) static INLINE vdouble vadd3(vdouble v0, vdouble v1, vdouble v2) { - return vadd(vadd(v0, v1), v2); + return vadd(vadd(v0, v1), v2); } static INLINE vdouble vadd4(vdouble v0, vdouble v1, vdouble v2, vdouble v3) { - return vadd3(vadd(v0, v1), v2, v3); + return vadd3(vadd(v0, v1), v2, v3); } static INLINE vdouble vadd5(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4) { - return vadd4(vadd(v0, v1), v2, v3, v4); + return vadd4(vadd(v0, v1), v2, v3, v4); } static INLINE vdouble vadd6(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4, vdouble v5) { - return vadd5(vadd(v0, v1), v2, v3, v4, v5); + return vadd5(vadd(v0, v1), v2, v3, v4, v5); } static INLINE vdouble vadd7(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4, vdouble v5, vdouble v6) { - return vadd6(vadd(v0, v1), v2, v3, v4, v5, v6); + return vadd6(vadd(v0, v1), v2, v3, v4, v5, v6); } static INLINE vdouble vsub3(vdouble v0, vdouble v1, vdouble v2) { - return vsub(vsub(v0, v1), v2); + return vsub(vsub(v0, v1), v2); } static INLINE vdouble vsub4(vdouble v0, vdouble v1, vdouble v2, vdouble v3) { - return vsub3(vsub(v0, v1), v2, v3); + return vsub3(vsub(v0, v1), v2, v3); } static INLINE vdouble vsub5(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4) { - return vsub4(vsub(v0, v1), v2, v3, v4); + return vsub4(vsub(v0, v1), v2, v3, v4); } // static INLINE vdouble2 normalize_d(vdouble2 t) { - vdouble2 s; + vdouble2 s; - s.x = vadd(t.x, t.y); - s.y = vadd(vsub(t.x, s.x), t.y); + s.x = vadd(t.x, t.y); + s.y = vadd(vsub(t.x, s.x), t.y); - return s; + return s; } static INLINE vdouble2 scale_d(vdouble2 d, vdouble s) { - vdouble2 r = {vmul(d.x, s), vmul(d.y, s)}; - return r; + vdouble2 r = {vmul(d.x, s), vmul(d.y, s)}; + return r; } static INLINE vdouble2 add_ss(vdouble x, vdouble y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x, y); - r.y = vadd(vsub(x, r.x), y); + r.x = vadd(x, y); + r.y = vadd(vsub(x, r.x), y); - return r; + return r; } static INLINE vdouble2 add2_ss(vdouble x, vdouble y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x, y); - vdouble v = vsub(r.x, x); - r.y = vadd(vsub(x, vsub(r.x, v)), vsub(y, v)); + r.x = vadd(x, y); + vdouble v = vsub(r.x, x); + r.y = vadd(vsub(x, vsub(r.x, v)), vsub(y, v)); - return r; + return r; } static INLINE vdouble2 add_ds(vdouble2 x, vdouble y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x.x, y); - r.y = vadd3(vsub(x.x, r.x), y, x.y); + r.x = vadd(x.x, y); + r.y = vadd3(vsub(x.x, r.x), y, x.y); - return r; + return r; } static INLINE vdouble2 add2_ds(vdouble2 x, vdouble y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x.x, y); - vdouble v = vsub(r.x, x.x); - r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y, v)); - r.y = vadd(r.y, x.y); + r.x = vadd(x.x, y); + vdouble v = vsub(r.x, x.x); + r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y, v)); + r.y = vadd(r.y, x.y); - return r; + return r; } static INLINE vdouble2 add_sd(vdouble x, vdouble2 y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x, y.x); - r.y = vadd3(vsub(x, r.x), y.x, y.y); + r.x = vadd(x, y.x); + r.y = vadd3(vsub(x, r.x), y.x, y.y); - return r; + return r; } static INLINE vdouble2 add_dd(vdouble2 x, vdouble2 y) { - // |x| >= |y| + // |x| >= |y| - vdouble2 r; + vdouble2 r; - r.x = vadd(x.x, y.x); - r.y = vadd4(vsub(x.x, r.x), y.x, x.y, y.y); + r.x = vadd(x.x, y.x); + r.y = vadd4(vsub(x.x, r.x), y.x, x.y, y.y); - return r; + return r; } static INLINE vdouble2 add2_dd(vdouble2 x, vdouble2 y) { - vdouble2 r; + vdouble2 r; - r.x = vadd(x.x, y.x); - vdouble v = vsub(r.x, x.x); - r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y.x, v)); - r.y = vadd(r.y, vadd(x.y, y.y)); + r.x = vadd(x.x, y.x); + vdouble v = vsub(r.x, x.x); + r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y.x, v)); + r.y = vadd(r.y, vadd(x.y, y.y)); - return r; + return r; } static INLINE vdouble2 div_dd(vdouble2 n, vdouble2 d) { - vdouble t = vrec(d.x); - vdouble dh = vupper(d.x), dl = vsub(d.x, dh); - vdouble th = vupper(t ), tl = vsub(t , th); - vdouble nhh = vupper(n.x), nhl = vsub(n.x, nhh); + vdouble t = vrec(d.x); + vdouble dh = vupper(d.x), dl = vsub(d.x, dh); + vdouble th = vupper(t ), tl = vsub(t , th); + vdouble nhh = vupper(n.x), nhl = vsub(n.x, nhh); - vdouble2 q; + vdouble2 q; - q.x = vmul(n.x, t); + q.x = vmul(n.x, t); - vdouble u = vadd5(vsub(vmul(nhh, th), q.x), vmul(nhh, tl), vmul(nhl, th), vmul(nhl, tl), - vmul(q.x, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl)))); + vdouble u = vadd5(vsub(vmul(nhh, th), q.x), vmul(nhh, tl), vmul(nhl, th), vmul(nhl, tl), + vmul(q.x, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl)))); - q.y = vadd(vmul(t, vsub(n.y, vmul(q.x, d.y))), u); + q.y = vadd(vmul(t, vsub(n.y, vmul(q.x, d.y))), u); - return q; + return q; } static INLINE vdouble2 mul_ss(vdouble x, vdouble y) { - vdouble xh = vupper(x), xl = vsub(x, xh); - vdouble yh = vupper(y), yl = vsub(y, yh); - vdouble2 r; + vdouble xh = vupper(x), xl = vsub(x, xh); + vdouble yh = vupper(y), yl = vsub(y, yh); + vdouble2 r; - r.x = vmul(x, y); - r.y = vadd5(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl)); + r.x = vmul(x, y); + r.y = vadd5(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl)); - return r; + return r; } static INLINE vdouble2 mul_ds(vdouble2 x, vdouble y) { - vdouble xh = vupper(x.x), xl = vsub(x.x, xh); - vdouble yh = vupper(y ), yl = vsub(y , yh); - vdouble2 r; + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble yh = vupper(y ), yl = vsub(y , yh); + vdouble2 r; - r.x = vmul(x.x, y); - r.y = vadd6(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.y, y)); + r.x = vmul(x.x, y); + r.y = vadd6(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.y, y)); - return r; + return r; } static INLINE vdouble2 mul_dd(vdouble2 x, vdouble2 y) { - vdouble xh = vupper(x.x), xl = vsub(x.x, xh); - vdouble yh = vupper(y.x), yl = vsub(y.x, yh); - vdouble2 r; + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble yh = vupper(y.x), yl = vsub(y.x, yh); + vdouble2 r; - r.x = vmul(x.x, y.x); - r.y = vadd7(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.x, y.y), vmul(x.y, y.x)); + r.x = vmul(x.x, y.x); + r.y = vadd7(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.x, y.y), vmul(x.y, y.x)); - return r; + return r; } static INLINE vdouble2 squ_d(vdouble2 x) { - vdouble xh = vupper(x.x), xl = vsub(x.x, xh); - vdouble2 r; + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble2 r; - r.x = vmul(x.x, x.x); - r.y = vadd5(vmul(xh, xh), vneg(r.x), vmul(vadd(xh, xh), xl), vmul(xl, xl), vmul(x.x, vadd(x.y, x.y))); + r.x = vmul(x.x, x.x); + r.y = vadd5(vmul(xh, xh), vneg(r.x), vmul(vadd(xh, xh), xl), vmul(xl, xl), vmul(x.x, vadd(x.y, x.y))); - return r; + return r; } static INLINE vdouble2 rec_s(vdouble d) { - vdouble t = vrec(d); - vdouble dh = vupper(d), dl = vsub(d, dh); - vdouble th = vupper(t), tl = vsub(t, th); - vdouble2 q; + vdouble t = vrec(d); + vdouble dh = vupper(d), dl = vsub(d, dh); + vdouble th = vupper(t), tl = vsub(t, th); + vdouble2 q; - q.x = t; - q.y = vmul(t, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl))); + q.x = t; + q.y = vmul(t, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl))); - return q; + return q; } static INLINE vdouble2 sqrt_d(vdouble2 d) { - vdouble t = vsqrt(vadd(d.x, d.y)); - return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), vcast_vd_d(0.5)); + vdouble t = vsqrt(vadd(d.x, d.y)); + return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), vcast_vd_d(0.5)); } // @@ -248,688 +248,688 @@ static INLINE vdouble2 sqrt_d(vdouble2 d) { static INLINE vdouble xldexp(vdouble x, vint q) { return vldexp(x, q); } static INLINE vint xilogb(vdouble d) { - vdouble e = vcast_vd_vi(vsubi(vilogbp1(vabs(d)), vcast_vi_i(1))); - e = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-2147483648.0), e); - e = vsel(vmask_eq(vabs(d), vcast_vd_d(rtengine::RT_INFINITY)), vcast_vd_d(2147483647), e); - return vrint_vi_vd(e); + vdouble e = vcast_vd_vi(vsubi(vilogbp1(vabs(d)), vcast_vi_i(1))); + e = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-2147483648.0), e); + e = vsel(vmask_eq(vabs(d), vcast_vd_d(rtengine::RT_INFINITY)), vcast_vd_d(2147483647), e); + return vrint_vi_vd(e); } static INLINE vdouble xsin(vdouble d) { - vint q; - vdouble u, s; + vint q; + vdouble u, s; - q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_1_PI))); + q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_1_PI))); - u = vcast_vd_vi(q); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*4))); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*4))); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*4))); + u = vcast_vd_vi(q); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*4))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*4))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*4))); - s = vmul(d, d); + s = vmul(d, d); - d = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vneg(d), d); + d = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vneg(d), d); - u = vcast_vd_d(-7.97255955009037868891952e-18); - u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); - u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); - u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); - u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); - u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); - u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); - u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); - u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); + u = vcast_vd_d(-7.97255955009037868891952e-18); + u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); + u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); + u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); + u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); + u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); + u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); - u = vmla(s, vmul(u, d), d); + u = vmla(s, vmul(u, d), d); - return u; + return u; } static INLINE vdouble xcos(vdouble d) { - vint q; - vdouble u, s; + vint q; + vdouble u, s; - q = vrint_vi_vd(vsub(vmul(d, vcast_vd_d(rtengine::RT_1_PI)), vcast_vd_d(0.5))); - q = vaddi(vaddi(q, q), vcast_vi_i(1)); + q = vrint_vi_vd(vsub(vmul(d, vcast_vd_d(rtengine::RT_1_PI)), vcast_vd_d(0.5))); + q = vaddi(vaddi(q, q), vcast_vi_i(1)); - u = vcast_vd_vi(q); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*2))); - d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*2))); + u = vcast_vd_vi(q); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*2))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*2))); - s = vmul(d, d); + s = vmul(d, d); - d = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(0)), vneg(d), d); + d = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(0)), vneg(d), d); - u = vcast_vd_d(-7.97255955009037868891952e-18); - u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); - u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); - u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); - u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); - u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); - u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); - u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); - u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); + u = vcast_vd_d(-7.97255955009037868891952e-18); + u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); + u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); + u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); + u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); + u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); + u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); - u = vmla(s, vmul(u, d), d); + u = vmla(s, vmul(u, d), d); - return u; + return u; } static INLINE vdouble2 xsincos(vdouble d) { - vint q; - vmask m; - vdouble u, s, t, rx, ry; - vdouble2 r; + vint q; + vmask m; + vdouble u, s, t, rx, ry; + vdouble2 r; - q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_2_PI))); + q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_2_PI))); - s = d; + s = d; - u = vcast_vd_vi(q); - s = vmla(u, vcast_vd_d(-PI4_A*2), s); - s = vmla(u, vcast_vd_d(-PI4_B*2), s); - s = vmla(u, vcast_vd_d(-PI4_C*2), s); + u = vcast_vd_vi(q); + s = vmla(u, vcast_vd_d(-PI4_A*2), s); + s = vmla(u, vcast_vd_d(-PI4_B*2), s); + s = vmla(u, vcast_vd_d(-PI4_C*2), s); - t = s; + t = s; - s = vmul(s, s); + s = vmul(s, s); - u = vcast_vd_d(1.58938307283228937328511e-10); - u = vmla(u, s, vcast_vd_d(-2.50506943502539773349318e-08)); - u = vmla(u, s, vcast_vd_d(2.75573131776846360512547e-06)); - u = vmla(u, s, vcast_vd_d(-0.000198412698278911770864914)); - u = vmla(u, s, vcast_vd_d(0.0083333333333191845961746)); - u = vmla(u, s, vcast_vd_d(-0.166666666666666130709393)); - u = vmul(vmul(u, s), t); + u = vcast_vd_d(1.58938307283228937328511e-10); + u = vmla(u, s, vcast_vd_d(-2.50506943502539773349318e-08)); + u = vmla(u, s, vcast_vd_d(2.75573131776846360512547e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698278911770864914)); + u = vmla(u, s, vcast_vd_d(0.0083333333333191845961746)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666130709393)); + u = vmul(vmul(u, s), t); - rx = vadd(t, u); + rx = vadd(t, u); - u = vcast_vd_d(-1.13615350239097429531523e-11); - u = vmla(u, s, vcast_vd_d(2.08757471207040055479366e-09)); - u = vmla(u, s, vcast_vd_d(-2.75573144028847567498567e-07)); - u = vmla(u, s, vcast_vd_d(2.48015872890001867311915e-05)); - u = vmla(u, s, vcast_vd_d(-0.00138888888888714019282329)); - u = vmla(u, s, vcast_vd_d(0.0416666666666665519592062)); - u = vmla(u, s, vcast_vd_d(-0.5)); + u = vcast_vd_d(-1.13615350239097429531523e-11); + u = vmla(u, s, vcast_vd_d(2.08757471207040055479366e-09)); + u = vmla(u, s, vcast_vd_d(-2.75573144028847567498567e-07)); + u = vmla(u, s, vcast_vd_d(2.48015872890001867311915e-05)); + u = vmla(u, s, vcast_vd_d(-0.00138888888888714019282329)); + u = vmla(u, s, vcast_vd_d(0.0416666666666665519592062)); + u = vmla(u, s, vcast_vd_d(-0.5)); - ry = vadd(vcast_vd_d(1), vmul(s, u)); + ry = vadd(vcast_vd_d(1), vmul(s, u)); - m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(0)); - r.x = vsel(m, rx, ry); - r.y = vsel(m, ry, rx); + m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(0)); + r.x = vsel(m, rx, ry); + r.y = vsel(m, ry, rx); - m = vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)); - r.x = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.x))); + m = vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)); + r.x = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.x))); - m = vmaski_eq(vandi(vaddi(q, vcast_vi_i(1)), vcast_vi_i(2)), vcast_vi_i(2)); - r.y = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.y))); + m = vmaski_eq(vandi(vaddi(q, vcast_vi_i(1)), vcast_vi_i(2)), vcast_vi_i(2)); + r.y = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.y))); - m = vmask_isinf(d); - r.x = vsel(m, vcast_vd_d(rtengine::RT_NAN), r.x); - r.y = vsel(m, vcast_vd_d(rtengine::RT_NAN), r.y); + m = vmask_isinf(d); + r.x = vsel(m, vcast_vd_d(rtengine::RT_NAN), r.x); + r.y = vsel(m, vcast_vd_d(rtengine::RT_NAN), r.y); - return r; + return r; } static INLINE vdouble xtan(vdouble d) { - vint q; - vdouble u, s, x; - vmask m; + vint q; + vdouble u, s, x; + vmask m; - q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_2_PI))); + q = vrint_vi_vd(vmul(d, vcast_vd_d(rtengine::RT_2_PI))); - u = vcast_vd_vi(q); - x = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); - x = vadd(x, vmul(u, vcast_vd_d(-PI4_B*2))); - x = vadd(x, vmul(u, vcast_vd_d(-PI4_C*2))); + u = vcast_vd_vi(q); + x = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); + x = vadd(x, vmul(u, vcast_vd_d(-PI4_B*2))); + x = vadd(x, vmul(u, vcast_vd_d(-PI4_C*2))); - s = vmul(x, x); + s = vmul(x, x); - m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)); - x = vsel(m, vneg(x), x); + m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)); + x = vsel(m, vneg(x), x); - u = vcast_vd_d(1.01419718511083373224408e-05); - u = vmla(u, s, vcast_vd_d(-2.59519791585924697698614e-05)); - u = vmla(u, s, vcast_vd_d(5.23388081915899855325186e-05)); - u = vmla(u, s, vcast_vd_d(-3.05033014433946488225616e-05)); - u = vmla(u, s, vcast_vd_d(7.14707504084242744267497e-05)); - u = vmla(u, s, vcast_vd_d(8.09674518280159187045078e-05)); - u = vmla(u, s, vcast_vd_d(0.000244884931879331847054404)); - u = vmla(u, s, vcast_vd_d(0.000588505168743587154904506)); - u = vmla(u, s, vcast_vd_d(0.00145612788922812427978848)); - u = vmla(u, s, vcast_vd_d(0.00359208743836906619142924)); - u = vmla(u, s, vcast_vd_d(0.00886323944362401618113356)); - u = vmla(u, s, vcast_vd_d(0.0218694882853846389592078)); - u = vmla(u, s, vcast_vd_d(0.0539682539781298417636002)); - u = vmla(u, s, vcast_vd_d(0.133333333333125941821962)); - u = vmla(u, s, vcast_vd_d(0.333333333333334980164153)); + u = vcast_vd_d(1.01419718511083373224408e-05); + u = vmla(u, s, vcast_vd_d(-2.59519791585924697698614e-05)); + u = vmla(u, s, vcast_vd_d(5.23388081915899855325186e-05)); + u = vmla(u, s, vcast_vd_d(-3.05033014433946488225616e-05)); + u = vmla(u, s, vcast_vd_d(7.14707504084242744267497e-05)); + u = vmla(u, s, vcast_vd_d(8.09674518280159187045078e-05)); + u = vmla(u, s, vcast_vd_d(0.000244884931879331847054404)); + u = vmla(u, s, vcast_vd_d(0.000588505168743587154904506)); + u = vmla(u, s, vcast_vd_d(0.00145612788922812427978848)); + u = vmla(u, s, vcast_vd_d(0.00359208743836906619142924)); + u = vmla(u, s, vcast_vd_d(0.00886323944362401618113356)); + u = vmla(u, s, vcast_vd_d(0.0218694882853846389592078)); + u = vmla(u, s, vcast_vd_d(0.0539682539781298417636002)); + u = vmla(u, s, vcast_vd_d(0.133333333333125941821962)); + u = vmla(u, s, vcast_vd_d(0.333333333333334980164153)); - u = vmla(s, vmul(u, x), x); + u = vmla(s, vmul(u, x), x); - u = vsel(m, vrec(u), u); + u = vsel(m, vrec(u), u); - u = vsel(vmask_isinf(d), vcast_vd_d(rtengine::RT_NAN), u); + u = vsel(vmask_isinf(d), vcast_vd_d(rtengine::RT_NAN), u); - return u; + return u; } static INLINE vdouble atan2k(vdouble y, vdouble x) { - vdouble s, t, u; - vint q; - vmask p; + vdouble s, t, u; + vint q; + vmask p; - q = vseli_lt(x, vcast_vd_d(0), vcast_vi_i(-2), vcast_vi_i(0)); - x = vabs(x); + q = vseli_lt(x, vcast_vd_d(0), vcast_vi_i(-2), vcast_vi_i(0)); + x = vabs(x); - q = vseli_lt(x, y, vaddi(q, vcast_vi_i(1)), q); - p = vmask_lt(x, y); - s = vsel (p, vneg(x), y); - t = vmax (x, y); + q = vseli_lt(x, y, vaddi(q, vcast_vi_i(1)), q); + p = vmask_lt(x, y); + s = vsel (p, vneg(x), y); + t = vmax (x, y); - s = vdiv(s, t); - t = vmul(s, s); + s = vdiv(s, t); + t = vmul(s, s); - u = vcast_vd_d(-1.88796008463073496563746e-05); - u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); - u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); - u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); - u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); - u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); - u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); - u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); - u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); - u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); - u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); - u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); - u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); - u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); - u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); - u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); - u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); - u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); - u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); + u = vcast_vd_d(-1.88796008463073496563746e-05); + u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); + u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); + u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); + u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); + u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); + u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); + u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); + u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); + u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); + u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); + u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); + u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); + u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); + u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); + u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); + u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); + u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); + u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); - t = vadd(s, vmul(s, vmul(t, u))); - t = vadd(t, vmul(vcast_vd_vi(q), vcast_vd_d(rtengine::RT_PI/2))); + t = vadd(s, vmul(s, vmul(t, u))); + t = vadd(t, vmul(vcast_vd_vi(q), vcast_vd_d(rtengine::RT_PI/2))); - return t; + return t; } static INLINE vdouble xatan2(vdouble y, vdouble x) { - vdouble r = atan2k(vabs(y), x); + vdouble r = atan2k(vabs(y), x); - r = vmulsign(r, x); - r = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), vsub(vcast_vd_d(rtengine::RT_PI/2), visinf2(x, vmulsign(vcast_vd_d(rtengine::RT_PI/2), x))), r); - r = vsel(vmask_isinf(y), vsub(vcast_vd_d(rtengine::RT_PI/2), visinf2(x, vmulsign(vcast_vd_d(rtengine::RT_PI/4), x))), r); - r = vsel(vmask_eq(y, vcast_vd_d(0)), vsel(vmask_eq(vsign(x), vcast_vd_d(-1.0)), vcast_vd_d(rtengine::RT_PI), vcast_vd_d(0)), r); + r = vmulsign(r, x); + r = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), vsub(vcast_vd_d(rtengine::RT_PI/2), visinf2(x, vmulsign(vcast_vd_d(rtengine::RT_PI/2), x))), r); + r = vsel(vmask_isinf(y), vsub(vcast_vd_d(rtengine::RT_PI/2), visinf2(x, vmulsign(vcast_vd_d(rtengine::RT_PI/4), x))), r); + r = vsel(vmask_eq(y, vcast_vd_d(0)), vsel(vmask_eq(vsign(x), vcast_vd_d(-1.0)), vcast_vd_d(rtengine::RT_PI), vcast_vd_d(0)), r); - return vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), vmulsign(r, y)); + return vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), vmulsign(r, y)); } static INLINE vdouble xasin(vdouble d) { - vdouble x, y; - x = vadd(vcast_vd_d(1), d); - y = vsub(vcast_vd_d(1), d); - x = vmul(x, y); - x = vsqrt(x); - x = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), atan2k(vabs(d), x)); - return vmulsign(x, d); + vdouble x, y; + x = vadd(vcast_vd_d(1), d); + y = vsub(vcast_vd_d(1), d); + x = vmul(x, y); + x = vsqrt(x); + x = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), atan2k(vabs(d), x)); + return vmulsign(x, d); } static INLINE vdouble xacos(vdouble d) { - vdouble x, y; - x = vadd(vcast_vd_d(1), d); - y = vsub(vcast_vd_d(1), d); - x = vmul(x, y); - x = vsqrt(x); - x = vmulsign(atan2k(x, vabs(d)), d); - y = (vdouble)vandm(vmask_lt(d, vcast_vd_d(0)), (vmask)vcast_vd_d(rtengine::RT_PI)); - x = vadd(x, y); - return x; + vdouble x, y; + x = vadd(vcast_vd_d(1), d); + y = vsub(vcast_vd_d(1), d); + x = vmul(x, y); + x = vsqrt(x); + x = vmulsign(atan2k(x, vabs(d)), d); + y = (vdouble)vandm(vmask_lt(d, vcast_vd_d(0)), (vmask)vcast_vd_d(rtengine::RT_PI)); + x = vadd(x, y); + return x; } static INLINE vdouble xatan(vdouble s) { - vdouble t, u; - vint q; + vdouble t, u; + vint q; - q = vseli_lt(s, vcast_vd_d(0), vcast_vi_i(2), vcast_vi_i(0)); - s = vabs(s); + q = vseli_lt(s, vcast_vd_d(0), vcast_vi_i(2), vcast_vi_i(0)); + s = vabs(s); - q = vseli_lt(vcast_vd_d(1), s, vaddi(q, vcast_vi_i(1)), q); - s = vsel(vmask_lt(vcast_vd_d(1), s), vdiv(vcast_vd_d(1), s), s); + q = vseli_lt(vcast_vd_d(1), s, vaddi(q, vcast_vi_i(1)), q); + s = vsel(vmask_lt(vcast_vd_d(1), s), vdiv(vcast_vd_d(1), s), s); - t = vmul(s, s); + t = vmul(s, s); - u = vcast_vd_d(-1.88796008463073496563746e-05); - u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); - u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); - u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); - u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); - u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); - u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); - u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); - u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); - u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); - u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); - u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); - u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); - u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); - u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); - u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); - u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); - u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); - u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); + u = vcast_vd_d(-1.88796008463073496563746e-05); + u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); + u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); + u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); + u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); + u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); + u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); + u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); + u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); + u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); + u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); + u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); + u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); + u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); + u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); + u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); + u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); + u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); + u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); - t = vadd(s, vmul(s, vmul(t, u))); + t = vadd(s, vmul(s, vmul(t, u))); - t = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vsub(vcast_vd_d(rtengine::RT_PI/2), t), t); - t = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)), vneg(t), t); + t = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vsub(vcast_vd_d(rtengine::RT_PI/2), t), t); + t = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)), vneg(t), t); - return t; + return t; } static INLINE vdouble xlog(vdouble d) { - vdouble x, x2; - vdouble t, m; - vint e; + vdouble x, x2; + vdouble t, m; + vint e; - e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); - m = vldexp(d, vsubi(vcast_vi_i(0), e)); + e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); + m = vldexp(d, vsubi(vcast_vi_i(0), e)); - x = vdiv(vadd(vcast_vd_d(-1), m), vadd(vcast_vd_d(1), m)); - x2 = vmul(x, x); + x = vdiv(vadd(vcast_vd_d(-1), m), vadd(vcast_vd_d(1), m)); + x2 = vmul(x, x); - t = vcast_vd_d(0.148197055177935105296783); - t = vmla(t, x2, vcast_vd_d(0.153108178020442575739679)); - t = vmla(t, x2, vcast_vd_d(0.181837339521549679055568)); - t = vmla(t, x2, vcast_vd_d(0.22222194152736701733275)); - t = vmla(t, x2, vcast_vd_d(0.285714288030134544449368)); - t = vmla(t, x2, vcast_vd_d(0.399999999989941956712869)); - t = vmla(t, x2, vcast_vd_d(0.666666666666685503450651)); - t = vmla(t, x2, vcast_vd_d(2)); + t = vcast_vd_d(0.148197055177935105296783); + t = vmla(t, x2, vcast_vd_d(0.153108178020442575739679)); + t = vmla(t, x2, vcast_vd_d(0.181837339521549679055568)); + t = vmla(t, x2, vcast_vd_d(0.22222194152736701733275)); + t = vmla(t, x2, vcast_vd_d(0.285714288030134544449368)); + t = vmla(t, x2, vcast_vd_d(0.399999999989941956712869)); + t = vmla(t, x2, vcast_vd_d(0.666666666666685503450651)); + t = vmla(t, x2, vcast_vd_d(2)); - x = vadd(vmul(x, t), vmul(vcast_vd_d(0.693147180559945286226764), vcast_vd_vi(e))); + x = vadd(vmul(x, t), vmul(vcast_vd_d(0.693147180559945286226764), vcast_vd_vi(e))); - x = vsel(vmask_ispinf(d), vcast_vd_d(rtengine::RT_INFINITY), x); - x = vsel(vmask_gt(vcast_vd_d(0), d), vcast_vd_d(rtengine::RT_NAN), x); - x = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-rtengine::RT_INFINITY), x); + x = vsel(vmask_ispinf(d), vcast_vd_d(rtengine::RT_INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(0), d), vcast_vd_d(rtengine::RT_NAN), x); + x = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-rtengine::RT_INFINITY), x); - return x; + return x; } static INLINE vdouble xexp(vdouble d) { - vint q = vrint_vi_vd(vmul(d, vcast_vd_d(R_LN2))); - vdouble s, u; + vint q = vrint_vi_vd(vmul(d, vcast_vd_d(R_LN2))); + vdouble s, u; - s = vadd(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); - s = vadd(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + s = vadd(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = vadd(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); - u = vcast_vd_d(2.08860621107283687536341e-09); - u = vmla(u, s, vcast_vd_d(2.51112930892876518610661e-08)); - u = vmla(u, s, vcast_vd_d(2.75573911234900471893338e-07)); - u = vmla(u, s, vcast_vd_d(2.75572362911928827629423e-06)); - u = vmla(u, s, vcast_vd_d(2.4801587159235472998791e-05)); - u = vmla(u, s, vcast_vd_d(0.000198412698960509205564975)); - u = vmla(u, s, vcast_vd_d(0.00138888888889774492207962)); - u = vmla(u, s, vcast_vd_d(0.00833333333331652721664984)); - u = vmla(u, s, vcast_vd_d(0.0416666666666665047591422)); - u = vmla(u, s, vcast_vd_d(0.166666666666666851703837)); - u = vmla(u, s, vcast_vd_d(0.5)); + u = vcast_vd_d(2.08860621107283687536341e-09); + u = vmla(u, s, vcast_vd_d(2.51112930892876518610661e-08)); + u = vmla(u, s, vcast_vd_d(2.75573911234900471893338e-07)); + u = vmla(u, s, vcast_vd_d(2.75572362911928827629423e-06)); + u = vmla(u, s, vcast_vd_d(2.4801587159235472998791e-05)); + u = vmla(u, s, vcast_vd_d(0.000198412698960509205564975)); + u = vmla(u, s, vcast_vd_d(0.00138888888889774492207962)); + u = vmla(u, s, vcast_vd_d(0.00833333333331652721664984)); + u = vmla(u, s, vcast_vd_d(0.0416666666666665047591422)); + u = vmla(u, s, vcast_vd_d(0.166666666666666851703837)); + u = vmla(u, s, vcast_vd_d(0.5)); - u = vadd(vcast_vd_d(1), vadd(s, vmul(vmul(s, s), u))); + u = vadd(vcast_vd_d(1), vadd(s, vmul(vmul(s, s), u))); - u = vldexp(u, q); + u = vldexp(u, q); - u = vsel(vmask_isminf(d), vcast_vd_d(0), u); + u = vsel(vmask_isminf(d), vcast_vd_d(0), u); - return u; + return u; } static INLINE vdouble2 logk(vdouble d) { - vdouble2 x, x2; - vdouble t, m; - vint e; + vdouble2 x, x2; + vdouble t, m; + vint e; - e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); - m = vldexp(d, vsubi(vcast_vi_i(0), e)); + e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); + m = vldexp(d, vsubi(vcast_vi_i(0), e)); - x = div_dd(add2_ss(vcast_vd_d(-1), m), add2_ss(vcast_vd_d(1), m)); - x2 = squ_d(x); - x2 = normalize_d(x2); + x = div_dd(add2_ss(vcast_vd_d(-1), m), add2_ss(vcast_vd_d(1), m)); + x2 = squ_d(x); + x2 = normalize_d(x2); - t = vcast_vd_d(0.134601987501262130076155); - t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); - t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); - t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); - t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); - t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); - t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); - t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); + t = vcast_vd_d(0.134601987501262130076155); + t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); + t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); + t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); + t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); + t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); + t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); + t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); - return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), - vcast_vd_vi(e)), - add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); + return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), + vcast_vd_vi(e)), + add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); } static INLINE vdouble expk(vdouble2 d) { - vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); - vint q = vrint_vi_vd(u); - vdouble2 s, t; + vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); + vint q = vrint_vi_vd(u); + vdouble2 s, t; - s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); - s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); - q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); + q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); - s = normalize_d(s); + s = normalize_d(s); - u = vcast_vd_d(2.51069683420950419527139e-08); - u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); - u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); - u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); - u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); - u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); - u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); - u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); - u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); - u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); + u = vcast_vd_d(2.51069683420950419527139e-08); + u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); + u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); + u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); + u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); + u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); + u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); + u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); + u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); + u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); - t = add_dd(s, mul_ds(squ_d(s), u)); + t = add_dd(s, mul_ds(squ_d(s), u)); - t = add_sd(vcast_vd_d(1), t); - u = vadd(t.x, t.y); - u = vldexp(u, q); + t = add_sd(vcast_vd_d(1), t); + u = vadd(t.x, t.y); + u = vldexp(u, q); - return u; + return u; } static INLINE vdouble xpow(vdouble x, vdouble y) { #if 1 - vmask yisint = vmask_eq(vcast_vd_vi(vrint_vi_vd(y)), y); - vmask yisodd = vandm(vmaski_eq(vandi(vrint_vi_vd(y), vcast_vi_i(1)), vcast_vi_i(1)), yisint); + vmask yisint = vmask_eq(vcast_vd_vi(vrint_vi_vd(y)), y); + vmask yisodd = vandm(vmaski_eq(vandi(vrint_vi_vd(y), vcast_vi_i(1)), vcast_vi_i(1)), yisint); - vdouble result = expk(mul_ds(logk(vabs(x)), y)); + vdouble result = expk(mul_ds(logk(vabs(x)), y)); - //result = vsel(vmask_isnan(result), vcast_vd_d(rtengine::RT_INFINITY), result); + //result = vsel(vmask_isnan(result), vcast_vd_d(rtengine::RT_INFINITY), result); - result = vmul(result, - vsel(vmask_gt(x, vcast_vd_d(0)), - vcast_vd_d(1), - vsel(yisint, - vsel(yisodd, - vcast_vd_d(-1), - vcast_vd_d(1)), - vcast_vd_d(rtengine::RT_NAN)))); + result = vmul(result, + vsel(vmask_gt(x, vcast_vd_d(0)), + vcast_vd_d(1), + vsel(yisint, + vsel(yisodd, + vcast_vd_d(-1), + vcast_vd_d(1)), + vcast_vd_d(rtengine::RT_NAN)))); - vdouble efx = vreinterpret_vd_vm(vxorm(vreinterpret_vm_vd(vsub(vabs(x), vcast_vd_d(1))), vsignbit(y))); + vdouble efx = vreinterpret_vd_vm(vxorm(vreinterpret_vm_vd(vsub(vabs(x), vcast_vd_d(1))), vsignbit(y))); - result = vsel(vmask_isinf(y), - vsel(vmask_lt(efx, vcast_vd_d(0)), - vcast_vd_d(0), - vsel(vmask_eq(efx, vcast_vd_d(0)), - vcast_vd_d(1.0), - vcast_vd_d(rtengine::RT_INFINITY))), - result); + result = vsel(vmask_isinf(y), + vsel(vmask_lt(efx, vcast_vd_d(0)), + vcast_vd_d(0), + vsel(vmask_eq(efx, vcast_vd_d(0)), + vcast_vd_d(1.0), + vcast_vd_d(rtengine::RT_INFINITY))), + result); - result = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), - vmul(vsel(yisodd, vsign(x), vcast_vd_d(1)), - vsel(vmask_lt(vsel(vmask_eq(x, vcast_vd_d(0)), vneg(y), y), vcast_vd_d(0)), - vcast_vd_d(0), - vcast_vd_d(rtengine::RT_INFINITY))), - result); + result = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), + vmul(vsel(yisodd, vsign(x), vcast_vd_d(1)), + vsel(vmask_lt(vsel(vmask_eq(x, vcast_vd_d(0)), vneg(y), y), vcast_vd_d(0)), + vcast_vd_d(0), + vcast_vd_d(rtengine::RT_INFINITY))), + result); - result = vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), result); + result = vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), result); - result = vsel(vorm(vmask_eq(y, vcast_vd_d(0)), vmask_eq(x, vcast_vd_d(1))), vcast_vd_d(1), result); + result = vsel(vorm(vmask_eq(y, vcast_vd_d(0)), vmask_eq(x, vcast_vd_d(1))), vcast_vd_d(1), result); - return result; + return result; #else - return expk(mul_ds(logk(x), y)); + return expk(mul_ds(logk(x), y)); #endif } static INLINE vdouble2 expk2(vdouble2 d) { - vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); - vint q = vrint_vi_vd(u); - vdouble2 s, t; + vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); + vint q = vrint_vi_vd(u); + vdouble2 s, t; - s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); - s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); - q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); + q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); - s = normalize_d(s); + s = normalize_d(s); - u = vcast_vd_d(2.51069683420950419527139e-08); - u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); - u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); - u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); - u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); - u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); - u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); - u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); - u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); - u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); + u = vcast_vd_d(2.51069683420950419527139e-08); + u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); + u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); + u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); + u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); + u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); + u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); + u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); + u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); + u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); - t = add_dd(s, mul_ds(squ_d(s), u)); + t = add_dd(s, mul_ds(squ_d(s), u)); - t = add_sd(vcast_vd_d(1), t); + t = add_sd(vcast_vd_d(1), t); - return dd(vldexp(t.x, q), vldexp(t.y, q)); + return dd(vldexp(t.x, q), vldexp(t.y, q)); } static INLINE vdouble xsinh(vdouble x) { - vdouble y = vabs(x); - vdouble2 d = expk2(dd(y, vcast_vd_d(0))); - d = add2_dd(d, div_dd(dd(vcast_vd_d(-1), vcast_vd_d(0)), d)); - y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); + vdouble y = vabs(x); + vdouble2 d = expk2(dd(y, vcast_vd_d(0))); + d = add2_dd(d, div_dd(dd(vcast_vd_d(-1), vcast_vd_d(0)), d)); + y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); - y = vmulsign(y, x); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble xcosh(vdouble x) { - vdouble2 d = expk2(dd(x, vcast_vd_d(0))); - d = add2_dd(d, div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d)); - vdouble y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); + vdouble2 d = expk2(dd(x, vcast_vd_d(0))); + d = add2_dd(d, div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d)); + vdouble y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble xtanh(vdouble x) { - vdouble y = vabs(x); - vdouble2 d = expk2(dd(y, vcast_vd_d(0))); - vdouble2 e = div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d); - d = div_dd(add2_dd(d, scale_d(e, vcast_vd_d(-1))), add2_dd(d, e)); - y = d.x + d.y; + vdouble y = vabs(x); + vdouble2 d = expk2(dd(y, vcast_vd_d(0))); + vdouble2 e = div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d); + d = div_dd(add2_dd(d, scale_d(e, vcast_vd_d(-1))), add2_dd(d, e)); + y = d.x + d.y; - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(1.0), y); - y = vmulsign(y, x); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(1.0), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble2 logk2(vdouble2 d) { - vdouble2 x, x2, m; - vdouble t; - vint e; + vdouble2 x, x2, m; + vdouble t; + vint e; - d = normalize_d(d); - e = vilogbp1(vmul(d.x, vcast_vd_d(0.7071))); - m = scale_d(d, vldexp(vcast_vd_d(1), vsubi(vcast_vi_i(0), e))); + d = normalize_d(d); + e = vilogbp1(vmul(d.x, vcast_vd_d(0.7071))); + m = scale_d(d, vldexp(vcast_vd_d(1), vsubi(vcast_vi_i(0), e))); - x = div_dd(add2_ds(m, vcast_vd_d(-1)), add2_ds(m, vcast_vd_d(1))); - x2 = squ_d(x); - x2 = normalize_d(x2); + x = div_dd(add2_ds(m, vcast_vd_d(-1)), add2_ds(m, vcast_vd_d(1))); + x2 = squ_d(x); + x2 = normalize_d(x2); - t = vcast_vd_d(0.134601987501262130076155); - t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); - t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); - t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); - t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); - t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); - t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); - t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); + t = vcast_vd_d(0.134601987501262130076155); + t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); + t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); + t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); + t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); + t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); + t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); + t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); - return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), - vcast_vd_vi(e)), - add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); + return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), + vcast_vd_vi(e)), + add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); } static INLINE vdouble xasinh(vdouble x) { - vdouble y = vabs(x); - vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), vcast_vd_d(1))), y)); - y = vadd(d.x, d.y); + vdouble y = vabs(x); + vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), vcast_vd_d(1))), y)); + y = vadd(d.x, d.y); - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); - y = vmulsign(y, x); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble xacosh(vdouble x) { - vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), vcast_vd_d(-1))), x)); - vdouble y = vadd(d.x, d.y); + vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), vcast_vd_d(-1))), x)); + vdouble y = vadd(d.x, d.y); - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); - y = vsel(vmask_eq(x, vcast_vd_d(1.0)), vcast_vd_d(0.0), y); - y = vsel(vmask_lt(x, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_NAN), y); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_INFINITY), y); + y = vsel(vmask_eq(x, vcast_vd_d(1.0)), vcast_vd_d(0.0), y); + y = vsel(vmask_lt(x, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble xatanh(vdouble x) { - vdouble y = vabs(x); - vdouble2 d = logk2(div_dd(add2_ss(vcast_vd_d(1), y), add2_ss(vcast_vd_d(1), -y))); - y = vsel(vmask_gt(y, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_NAN), vsel(vmask_eq(y, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_INFINITY), vmul(vadd(d.x, d.y), vcast_vd_d(0.5)))); + vdouble y = vabs(x); + vdouble2 d = logk2(div_dd(add2_ss(vcast_vd_d(1), y), add2_ss(vcast_vd_d(1), -y))); + y = vsel(vmask_gt(y, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_NAN), vsel(vmask_eq(y, vcast_vd_d(1.0)), vcast_vd_d(rtengine::RT_INFINITY), vmul(vadd(d.x, d.y), vcast_vd_d(0.5)))); - y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), y); - y = vmulsign(y, x); - y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(rtengine::RT_NAN), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(rtengine::RT_NAN), y); - return y; + return y; } static INLINE vdouble xcbrt(vdouble d) { - vdouble x, y, q = vcast_vd_d(1.0); - vint e, qu, re; - vdouble t; + vdouble x, y, q = vcast_vd_d(1.0); + vint e, qu, re; + vdouble t; - e = vilogbp1(vabs(d)); - d = vldexp(d, vsubi(vcast_vi_i(0), e)); + e = vilogbp1(vabs(d)); + d = vldexp(d, vsubi(vcast_vi_i(0), e)); - t = vadd(vcast_vd_vi(e), vcast_vd_d(6144)); - qu = vtruncate_vi_vd(vdiv(t, vcast_vd_d(3))); - re = vtruncate_vi_vd(vsub(t, vmul(vcast_vd_vi(qu), vcast_vd_d(3)))); + t = vadd(vcast_vd_vi(e), vcast_vd_d(6144)); + qu = vtruncate_vi_vd(vdiv(t, vcast_vd_d(3))); + re = vtruncate_vi_vd(vsub(t, vmul(vcast_vd_vi(qu), vcast_vd_d(3)))); - q = vsel(vmaski_eq(re, vcast_vi_i(1)), vcast_vd_d(1.2599210498948731647672106), q); - q = vsel(vmaski_eq(re, vcast_vi_i(2)), vcast_vd_d(1.5874010519681994747517056), q); - q = vldexp(q, vsubi(qu, vcast_vi_i(2048))); + q = vsel(vmaski_eq(re, vcast_vi_i(1)), vcast_vd_d(1.2599210498948731647672106), q); + q = vsel(vmaski_eq(re, vcast_vi_i(2)), vcast_vd_d(1.5874010519681994747517056), q); + q = vldexp(q, vsubi(qu, vcast_vi_i(2048))); - q = vmulsign(q, d); + q = vmulsign(q, d); - d = vabs(d); + d = vabs(d); - x = vcast_vd_d(-0.640245898480692909870982); - x = vmla(x, d, vcast_vd_d(2.96155103020039511818595)); - x = vmla(x, d, vcast_vd_d(-5.73353060922947843636166)); - x = vmla(x, d, vcast_vd_d(6.03990368989458747961407)); - x = vmla(x, d, vcast_vd_d(-3.85841935510444988821632)); - x = vmla(x, d, vcast_vd_d(2.2307275302496609725722)); + x = vcast_vd_d(-0.640245898480692909870982); + x = vmla(x, d, vcast_vd_d(2.96155103020039511818595)); + x = vmla(x, d, vcast_vd_d(-5.73353060922947843636166)); + x = vmla(x, d, vcast_vd_d(6.03990368989458747961407)); + x = vmla(x, d, vcast_vd_d(-3.85841935510444988821632)); + x = vmla(x, d, vcast_vd_d(2.2307275302496609725722)); - y = vmul(x, x); y = vmul(y, y); x = vsub(x, vmul(vmla(d, y, vneg(x)), vcast_vd_d(1.0 / 3.0))); - y = vmul(vmul(d, x), x); - y = vmul(vsub(y, vmul(vmul(vcast_vd_d(2.0 / 3.0), y), vmla(y, x, vcast_vd_d(-1.0)))), q); + y = vmul(x, x); y = vmul(y, y); x = vsub(x, vmul(vmla(d, y, vneg(x)), vcast_vd_d(1.0 / 3.0))); + y = vmul(vmul(d, x), x); + y = vmul(vsub(y, vmul(vmul(vcast_vd_d(2.0 / 3.0), y), vmla(y, x, vcast_vd_d(-1.0)))), q); - return y; + return y; } static INLINE vdouble xexp2(vdouble a) { - vdouble u = expk(mul_ds(dd(vcast_vd_d(0.69314718055994528623), vcast_vd_d(2.3190468138462995584e-17)), a)); - u = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), u); - u = vsel(vmask_isminf(a), vcast_vd_d(0), u); - return u; + vdouble u = expk(mul_ds(dd(vcast_vd_d(0.69314718055994528623), vcast_vd_d(2.3190468138462995584e-17)), a)); + u = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), u); + u = vsel(vmask_isminf(a), vcast_vd_d(0), u); + return u; } static INLINE vdouble xexp10(vdouble a) { - vdouble u = expk(mul_ds(dd(vcast_vd_d(2.3025850929940459011), vcast_vd_d(-2.1707562233822493508e-16)), a)); - u = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), u); - u = vsel(vmask_isminf(a), vcast_vd_d(0), u); - return u; + vdouble u = expk(mul_ds(dd(vcast_vd_d(2.3025850929940459011), vcast_vd_d(-2.1707562233822493508e-16)), a)); + u = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), u); + u = vsel(vmask_isminf(a), vcast_vd_d(0), u); + return u; } static INLINE vdouble xexpm1(vdouble a) { - vdouble2 d = add2_ds(expk2(dd(a, vcast_vd_d(0))), vcast_vd_d(-1.0)); - vdouble x = d.x + d.y; - x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); - x = vsel(vmask_isminf(a), vcast_vd_d(-1), x); - return x; + vdouble2 d = add2_ds(expk2(dd(a, vcast_vd_d(0))), vcast_vd_d(-1.0)); + vdouble x = d.x + d.y; + x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); + x = vsel(vmask_isminf(a), vcast_vd_d(-1), x); + return x; } static INLINE vdouble xlog10(vdouble a) { - vdouble2 d = mul_dd(logk(a), dd(vcast_vd_d(0.43429448190325176116), vcast_vd_d(6.6494347733425473126e-17))); - vdouble x = d.x + d.y; + vdouble2 d = mul_dd(logk(a), dd(vcast_vd_d(0.43429448190325176116), vcast_vd_d(6.6494347733425473126e-17))); + vdouble x = d.x + d.y; - x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); - x = vsel(vmask_gt(vcast_vd_d(0), a), vcast_vd_d(rtengine::RT_NAN), x); - x = vsel(vmask_eq(a, vcast_vd_d(0)), vcast_vd_d(-rtengine::RT_INFINITY), x); + x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(0), a), vcast_vd_d(rtengine::RT_NAN), x); + x = vsel(vmask_eq(a, vcast_vd_d(0)), vcast_vd_d(-rtengine::RT_INFINITY), x); - return x; + return x; } static INLINE vdouble xlog1p(vdouble a) { - vdouble2 d = logk2(add2_ss(a, vcast_vd_d(1))); - vdouble x = d.x + d.y; + vdouble2 d = logk2(add2_ss(a, vcast_vd_d(1))); + vdouble x = d.x + d.y; - x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); - x = vsel(vmask_gt(vcast_vd_d(-1), a), vcast_vd_d(rtengine::RT_NAN), x); - x = vsel(vmask_eq(a, vcast_vd_d(-1)), vcast_vd_d(-rtengine::RT_INFINITY), x); + x = vsel(vmask_ispinf(a), vcast_vd_d(rtengine::RT_INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(-1), a), vcast_vd_d(rtengine::RT_NAN), x); + x = vsel(vmask_eq(a, vcast_vd_d(-1)), vcast_vd_d(-rtengine::RT_INFINITY), x); - return x; + return x; } // typedef struct { - vfloat x, y; + vfloat x, y; } vfloat2; static INLINE vfloat vabsf(vfloat f) { return (vfloat)vandnotm((vmask)vcast_vf_f(-0.0f), (vmask)f); } static INLINE vfloat vnegf(vfloat f) { return (vfloat)vxorm((vmask)f, (vmask)vcast_vf_f(-0.0f)); } #ifdef __SSE4_1__ - // only one instruction when using SSE4.1 - static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { - return _mm_blendv_ps(y,x,(vfloat)mask); - } +// only one instruction when using SSE4.1 +static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { + return _mm_blendv_ps(y,x,(vfloat)mask); +} - static INLINE vint vselc(vmask mask, vint x, vint y) { - return _mm_blendv_epi8(y,x,mask); - } +static INLINE vint vselc(vmask mask, vint x, vint y) { + return _mm_blendv_epi8(y,x,mask); +} #else - // three instructions when using SSE2 - static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { - return (vfloat)vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); - } +// three instructions when using SSE2 +static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { + return (vfloat)vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); +} - static INLINE vint vselc(vmask mask, vint x, vint y) { - return vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); - } +static INLINE vint vselc(vmask mask, vint x, vint y) { + return vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); +} #endif static INLINE vfloat vselfzero(vmask mask, vfloat x) { - // returns value of x if corresponding mask bits are 1, else returns 0 - // faster than vself(mask, x, ZEROV) + // returns value of x if corresponding mask bits are 1, else returns 0 + // faster than vself(mask, x, ZEROV) return _mm_and_ps((vfloat)mask, x); } static INLINE vfloat vselfnotzero(vmask mask, vfloat x) { @@ -939,8 +939,8 @@ static INLINE vfloat vselfnotzero(vmask mask, vfloat x) { } static INLINE vint vselizero(vmask mask, vint x) { - // returns value of x if corresponding mask bits are 1, else returns 0 - // faster than vselc(mask, x, ZEROV) + // returns value of x if corresponding mask bits are 1, else returns 0 + // faster than vselc(mask, x, ZEROV) return _mm_and_si128(mask, x); } static INLINE vint vselinotzero(vmask mask, vint x) { @@ -950,20 +950,20 @@ static INLINE vint vselinotzero(vmask mask, vint x) { } static INLINE vint2 vseli2_lt(vfloat f0, vfloat f1, vint2 x, vint2 y) { - vint2 m2 = vcast_vi2_vm(vmaskf_lt(f0, f1)); - return vori2(vandi2(m2, x), vandnoti2(m2, y)); + vint2 m2 = vcast_vi2_vm(vmaskf_lt(f0, f1)); + return vori2(vandi2(m2, x), vandnoti2(m2, y)); } static INLINE vmask vsignbitf(vfloat f) { - return vandm((vmask)f, (vmask)vcast_vf_f(-0.0f)); + return vandm((vmask)f, (vmask)vcast_vf_f(-0.0f)); } static INLINE vfloat vmulsignf(vfloat x, vfloat y) { - return (vfloat)vxorm((vmask)x, vsignbitf(y)); + return (vfloat)vxorm((vmask)x, vsignbitf(y)); } static INLINE vfloat vsignf(vfloat f) { - return (vfloat)vorm((vmask)vcast_vf_f(1.0f), vandm((vmask)vcast_vf_f(-0.0f), (vmask)f)); + return (vfloat)vorm((vmask)vcast_vf_f(1.0f), vandm((vmask)vcast_vf_f(-0.0f), (vmask)f)); } static INLINE vmask vmaskf_isinf(vfloat d) { return vmaskf_eq(vabsf(d), vcast_vf_f(INFINITYf)); } @@ -976,396 +976,396 @@ static INLINE vfloat visinf2f(vfloat d, vfloat m) { return (vfloat)vandm(vmaskf_ static INLINE vfloat visinff(vfloat d) { return visinf2f(d, vcast_vf_f(1.0f)); } static INLINE vint2 vilogbp1f(vfloat d) { - vmask m = vmaskf_lt(d, vcast_vf_f(5.421010862427522E-20f)); - d = vself(m, vmulf(vcast_vf_f(1.8446744073709552E19f), d), d); - vint2 q = vandi2(vsrli2(vcast_vi2_vm(vreinterpret_vm_vf(d)), 23), vcast_vi2_i(0xff)); - q = vsubi2(q, vseli2(m, vcast_vi2_i(64 + 0x7e), vcast_vi2_i(0x7e))); - return q; + vmask m = vmaskf_lt(d, vcast_vf_f(5.421010862427522E-20f)); + d = vself(m, vmulf(vcast_vf_f(1.8446744073709552E19f), d), d); + vint2 q = vandi2(vsrli2(vcast_vi2_vm(vreinterpret_vm_vf(d)), 23), vcast_vi2_i(0xff)); + q = vsubi2(q, vseli2(m, vcast_vi2_i(64 + 0x7e), vcast_vi2_i(0x7e))); + return q; } static INLINE vfloat vldexpf(vfloat x, vint2 q) { - vfloat u; - vint2 m = vsrai2(q, 31); - m = vslli2(vsubi2(vsrai2(vaddi2(m, q), 6), m), 4); - q = vsubi2(q, vslli2(m, 2)); - u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(m, vcast_vi2_i(0x7f)), 23))); - x = vmulf(vmulf(vmulf(vmulf(x, u), u), u), u); - u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(q, vcast_vi2_i(0x7f)), 23))); - return vmulf(x, u); + vfloat u; + vint2 m = vsrai2(q, 31); + m = vslli2(vsubi2(vsrai2(vaddi2(m, q), 6), m), 4); + q = vsubi2(q, vslli2(m, 2)); + u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(m, vcast_vi2_i(0x7f)), 23))); + x = vmulf(vmulf(vmulf(vmulf(x, u), u), u), u); + u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(q, vcast_vi2_i(0x7f)), 23))); + return vmulf(x, u); } static INLINE vfloat xsinf(vfloat d) { - vint2 q; - vfloat u, s; + vint2 q; + vfloat u, s; - q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)rtengine::RT_1_PI))); + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)rtengine::RT_1_PI))); - u = vcast_vf_vi2(q); - d = vmlaf(u, vcast_vf_f(-PI4_Af*4), d); - d = vmlaf(u, vcast_vf_f(-PI4_Bf*4), d); - d = vmlaf(u, vcast_vf_f(-PI4_Cf*4), d); - d = vmlaf(u, vcast_vf_f(-PI4_Df*4), d); + u = vcast_vf_vi2(q); + d = vmlaf(u, vcast_vf_f(-PI4_Af*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Bf*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Cf*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Df*4), d); - s = vmulf(d, d); + s = vmulf(d, d); - d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vnegf(d), d); + d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vnegf(d), d); - u = vcast_vf_f(2.6083159809786593541503e-06f); - u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); - u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); - u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); + u = vcast_vf_f(2.6083159809786593541503e-06f); + u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); + u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); - u = vmlaf(s, vmulf(u, d), d); + u = vmlaf(s, vmulf(u, d), d); - return u; + return u; } static INLINE vfloat xcosf(vfloat d) { - vint2 q; - vfloat u, s; + vint2 q; + vfloat u, s; - q = vrint_vi2_vf(vsubf(vmulf(d, vcast_vf_f((float)rtengine::RT_1_PI)), vcast_vf_f(0.5f))); - q = vaddi2(vaddi2(q, q), vcast_vi2_i(1)); + q = vrint_vi2_vf(vsubf(vmulf(d, vcast_vf_f((float)rtengine::RT_1_PI)), vcast_vf_f(0.5f))); + q = vaddi2(vaddi2(q, q), vcast_vi2_i(1)); - u = vcast_vf_vi2(q); - d = vmlaf(u, vcast_vf_f(-PI4_Af*2), d); - d = vmlaf(u, vcast_vf_f(-PI4_Bf*2), d); - d = vmlaf(u, vcast_vf_f(-PI4_Cf*2), d); - d = vmlaf(u, vcast_vf_f(-PI4_Df*2), d); + u = vcast_vf_vi2(q); + d = vmlaf(u, vcast_vf_f(-PI4_Af*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Bf*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Cf*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Df*2), d); - s = vmulf(d, d); + s = vmulf(d, d); - d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), d, vnegf(d)); + d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), d, vnegf(d)); - u = vcast_vf_f(2.6083159809786593541503e-06f); - u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); - u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); - u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); + u = vcast_vf_f(2.6083159809786593541503e-06f); + u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); + u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); - u = vmlaf(s, vmulf(u, d), d); + u = vmlaf(s, vmulf(u, d), d); - return u; + return u; } static INLINE vfloat2 xsincosf(vfloat d) { - vint2 q; - vmask m; - vfloat u, s, t, rx, ry; - vfloat2 r; + vint2 q; + vmask m; + vfloat u, s, t, rx, ry; + vfloat2 r; - q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)rtengine::RT_2_PI))); + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)rtengine::RT_2_PI))); - s = d; + s = d; - u = vcast_vf_vi2(q); - s = vmlaf(u, vcast_vf_f(-PI4_Af*2), s); - s = vmlaf(u, vcast_vf_f(-PI4_Bf*2), s); - s = vmlaf(u, vcast_vf_f(-PI4_Cf*2), s); - s = vmlaf(u, vcast_vf_f(-PI4_Df*2), s); + u = vcast_vf_vi2(q); + s = vmlaf(u, vcast_vf_f(-PI4_Af*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Bf*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Cf*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Df*2), s); - t = s; + t = s; - s = vmulf(s, s); + s = vmulf(s, s); - u = vcast_vf_f(-0.000195169282960705459117889f); - u = vmlaf(u, s, vcast_vf_f(0.00833215750753879547119141f)); - u = vmlaf(u, s, vcast_vf_f(-0.166666537523269653320312f)); - u = vmulf(vmulf(u, s), t); + u = vcast_vf_f(-0.000195169282960705459117889f); + u = vmlaf(u, s, vcast_vf_f(0.00833215750753879547119141f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666537523269653320312f)); + u = vmulf(vmulf(u, s), t); - rx = vaddf(t, u); + rx = vaddf(t, u); - u = vcast_vf_f(-2.71811842367242206819355e-07f); - u = vmlaf(u, s, vcast_vf_f(2.47990446951007470488548e-05f)); - u = vmlaf(u, s, vcast_vf_f(-0.00138888787478208541870117f)); - u = vmlaf(u, s, vcast_vf_f(0.0416666641831398010253906f)); - u = vmlaf(u, s, vcast_vf_f(-0.5)); + u = vcast_vf_f(-2.71811842367242206819355e-07f); + u = vmlaf(u, s, vcast_vf_f(2.47990446951007470488548e-05f)); + u = vmlaf(u, s, vcast_vf_f(-0.00138888787478208541870117f)); + u = vmlaf(u, s, vcast_vf_f(0.0416666641831398010253906f)); + u = vmlaf(u, s, vcast_vf_f(-0.5)); - ry = vaddf(vcast_vf_f(1), vmulf(s, u)); + ry = vaddf(vcast_vf_f(1), vmulf(s, u)); - m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(0)); - r.x = vself(m, rx, ry); - r.y = vself(m, ry, rx); + m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(0)); + r.x = vself(m, rx, ry); + r.y = vself(m, ry, rx); - m = vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)); - r.x = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.x))); + m = vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)); + r.x = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.x))); - m = vmaski2_eq(vandi2(vaddi2(q, vcast_vi2_i(1)), vcast_vi2_i(2)), vcast_vi2_i(2)); - r.y = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.y))); + m = vmaski2_eq(vandi2(vaddi2(q, vcast_vi2_i(1)), vcast_vi2_i(2)), vcast_vi2_i(2)); + r.y = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.y))); - m = vmaskf_isinf(d); - r.x = vself(m, vcast_vf_f(rtengine::RT_NAN), r.x); - r.y = vself(m, vcast_vf_f(rtengine::RT_NAN), r.y); + m = vmaskf_isinf(d); + r.x = vself(m, vcast_vf_f(rtengine::RT_NAN), r.x); + r.y = vself(m, vcast_vf_f(rtengine::RT_NAN), r.y); - return r; + return r; } static INLINE vfloat xtanf(vfloat d) { - vint2 q; - vmask m; - vfloat u, s, x; + vint2 q; + vmask m; + vfloat u, s, x; - q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)(2 * rtengine::RT_1_PI)))); + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)(2 * rtengine::RT_1_PI)))); - x = d; + x = d; - u = vcast_vf_vi2(q); - x = vmlaf(u, vcast_vf_f(-PI4_Af*2), x); - x = vmlaf(u, vcast_vf_f(-PI4_Bf*2), x); - x = vmlaf(u, vcast_vf_f(-PI4_Cf*2), x); - x = vmlaf(u, vcast_vf_f(-PI4_Df*2), x); + u = vcast_vf_vi2(q); + x = vmlaf(u, vcast_vf_f(-PI4_Af*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Bf*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Cf*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Df*2), x); - s = vmulf(x, x); + s = vmulf(x, x); - m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)); - x = vself(m, vnegf(x), x); + m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)); + x = vself(m, vnegf(x), x); - u = vcast_vf_f(0.00927245803177356719970703f); - u = vmlaf(u, s, vcast_vf_f(0.00331984995864331722259521f)); - u = vmlaf(u, s, vcast_vf_f(0.0242998078465461730957031f)); - u = vmlaf(u, s, vcast_vf_f(0.0534495301544666290283203f)); - u = vmlaf(u, s, vcast_vf_f(0.133383005857467651367188f)); - u = vmlaf(u, s, vcast_vf_f(0.333331853151321411132812f)); + u = vcast_vf_f(0.00927245803177356719970703f); + u = vmlaf(u, s, vcast_vf_f(0.00331984995864331722259521f)); + u = vmlaf(u, s, vcast_vf_f(0.0242998078465461730957031f)); + u = vmlaf(u, s, vcast_vf_f(0.0534495301544666290283203f)); + u = vmlaf(u, s, vcast_vf_f(0.133383005857467651367188f)); + u = vmlaf(u, s, vcast_vf_f(0.333331853151321411132812f)); - u = vmlaf(s, vmulf(u, x), x); + u = vmlaf(s, vmulf(u, x), x); - u = vself(m, vrecf(u), u); + u = vself(m, vrecf(u), u); - u = vself(vmaskf_isinf(d), vcast_vf_f(NANf), u); + u = vself(vmaskf_isinf(d), vcast_vf_f(NANf), u); - return u; + return u; } static INLINE vfloat xatanf(vfloat s) { - vfloat t, u; - vint2 q; + vfloat t, u; + vint2 q; - q = vseli2_lt(s, vcast_vf_f(0.0f), vcast_vi2_i(2), vcast_vi2_i(0)); - s = vabsf(s); + q = vseli2_lt(s, vcast_vf_f(0.0f), vcast_vi2_i(2), vcast_vi2_i(0)); + s = vabsf(s); - q = vseli2_lt(vcast_vf_f(1.0f), s, vaddi2(q, vcast_vi2_i(1)), q); - s = vself(vmaskf_lt(vcast_vf_f(1.0f), s), vdivf(vcast_vf_f(1.0f), s), s); + q = vseli2_lt(vcast_vf_f(1.0f), s, vaddi2(q, vcast_vi2_i(1)), q); + s = vself(vmaskf_lt(vcast_vf_f(1.0f), s), vdivf(vcast_vf_f(1.0f), s), s); - t = vmulf(s, s); + t = vmulf(s, s); - u = vcast_vf_f(0.00282363896258175373077393f); - u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); - u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); - u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); - u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); - u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); - u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); - u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); + u = vcast_vf_f(0.00282363896258175373077393f); + u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); + u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); + u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); + u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); + u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); + u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); + u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); - t = vaddf(s, vmulf(s, vmulf(t, u))); + t = vaddf(s, vmulf(s, vmulf(t, u))); - t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), t), t); - t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), vnegf(t), t); + t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), t), t); + t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), vnegf(t), t); - return t; + return t; } static INLINE vfloat atan2kf(vfloat y, vfloat x) { - vfloat s, t, u; - vint2 q; - vmask p; + vfloat s, t, u; + vint2 q; + vmask p; - q = vseli2_lt(x, vcast_vf_f(0.0f), vcast_vi2_i(-2), vcast_vi2_i(0)); - x = vabsf(x); + q = vseli2_lt(x, vcast_vf_f(0.0f), vcast_vi2_i(-2), vcast_vi2_i(0)); + x = vabsf(x); - q = vseli2_lt(x, y, vaddi2(q, vcast_vi2_i(1)), q); - p = vmaskf_lt(x, y); - s = vself(p, vnegf(x), y); - t = vmaxf(x, y); + q = vseli2_lt(x, y, vaddi2(q, vcast_vi2_i(1)), q); + p = vmaskf_lt(x, y); + s = vself(p, vnegf(x), y); + t = vmaxf(x, y); - s = vdivf(s, t); - t = vmulf(s, s); + s = vdivf(s, t); + t = vmulf(s, s); - u = vcast_vf_f(0.00282363896258175373077393f); - u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); - u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); - u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); - u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); - u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); - u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); - u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); + u = vcast_vf_f(0.00282363896258175373077393f); + u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); + u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); + u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); + u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); + u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); + u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); + u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); - t = vaddf(s, vmulf(s, vmulf(t, u))); - t = vaddf(t, vmulf(vcast_vf_vi2(q), vcast_vf_f((float)(rtengine::RT_PI/2)))); + t = vaddf(s, vmulf(s, vmulf(t, u))); + t = vaddf(t, vmulf(vcast_vf_vi2(q), vcast_vf_f((float)(rtengine::RT_PI/2)))); - return t; + return t; } static INLINE vfloat xatan2f(vfloat y, vfloat x) { - vfloat r = atan2kf(vabsf(y), x); + vfloat r = atan2kf(vabsf(y), x); - r = vmulsignf(r, x); - r = vself(vorm(vmaskf_isinf(x), vmaskf_eq(x, vcast_vf_f(0.0f))), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(rtengine::RT_PI/2)), x))), r); - r = vself(vmaskf_isinf(y), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(rtengine::RT_PI/4)), x))), r); - r = vself(vmaskf_eq(y, vcast_vf_f(0.0f)), vselfzero(vmaskf_eq(vsignf(x), vcast_vf_f(-1.0f)), vcast_vf_f((float)rtengine::RT_PI)), r); + r = vmulsignf(r, x); + r = vself(vorm(vmaskf_isinf(x), vmaskf_eq(x, vcast_vf_f(0.0f))), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(rtengine::RT_PI/2)), x))), r); + r = vself(vmaskf_isinf(y), vsubf(vcast_vf_f((float)(rtengine::RT_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(rtengine::RT_PI/4)), x))), r); + r = vself(vmaskf_eq(y, vcast_vf_f(0.0f)), vselfzero(vmaskf_eq(vsignf(x), vcast_vf_f(-1.0f)), vcast_vf_f((float)rtengine::RT_PI)), r); - return vself(vmaskf_isnan(x, y), vcast_vf_f(NANf), vmulsignf(r, y)); + return vself(vmaskf_isnan(x, y), vcast_vf_f(NANf), vmulsignf(r, y)); } static INLINE vfloat xasinf(vfloat d) { - vfloat x, y; - x = vaddf(vcast_vf_f(1.0f), d); - y = vsubf(vcast_vf_f(1.0f), d); - x = vmulf(x, y); - x = vsqrtf(x); - x = vself(vmaskf_isnan(x), vcast_vf_f(NANf), atan2kf(vabsf(d), x)); - return vmulsignf(x, d); + vfloat x, y; + x = vaddf(vcast_vf_f(1.0f), d); + y = vsubf(vcast_vf_f(1.0f), d); + x = vmulf(x, y); + x = vsqrtf(x); + x = vself(vmaskf_isnan(x), vcast_vf_f(NANf), atan2kf(vabsf(d), x)); + return vmulsignf(x, d); } static INLINE vfloat xacosf(vfloat d) { - vfloat x, y; - x = vaddf(vcast_vf_f(1.0f), d); - y = vsubf(vcast_vf_f(1.0f), d); - x = vmulf(x, y); - x = vsqrtf(x); - x = vmulsignf(atan2kf(x, vabsf(d)), d); - y = (vfloat)vandm(vmaskf_lt(d, vcast_vf_f(0.0f)), (vmask)vcast_vf_f((float)rtengine::RT_PI)); - x = vaddf(x, y); - return x; + vfloat x, y; + x = vaddf(vcast_vf_f(1.0f), d); + y = vsubf(vcast_vf_f(1.0f), d); + x = vmulf(x, y); + x = vsqrtf(x); + x = vmulsignf(atan2kf(x, vabsf(d)), d); + y = (vfloat)vandm(vmaskf_lt(d, vcast_vf_f(0.0f)), (vmask)vcast_vf_f((float)rtengine::RT_PI)); + x = vaddf(x, y); + return x; } static INLINE vfloat xlogf(vfloat d) { - vfloat x, x2, t, m; - vint2 e; + 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)); + 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); + 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)); + 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 = 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 = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(NANf), x); - x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(-INFINITYf), x); + x = vself(vmaskf_ispinf(d), vcast_vf_f(INFINITYf), x); + x = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(NANf), x); + x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(-INFINITYf), x); - return x; + return x; } static INLINE vfloat xlogf0(vfloat d) { - vfloat x, x2, t, m; - vint2 e; + 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)); + 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); + 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)); + 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 = vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e))); - x = vself(vmaskf_ispinf(d), vcast_vf_f(0), x); - x = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(0), x); - x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(0), x); + x = vself(vmaskf_ispinf(d), vcast_vf_f(0), x); + x = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(0), x); + x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(0), x); - return x; + return x; } static INLINE vfloat xlogfNoCheck(vfloat d) { // this version does not check input values. Use it only when you know the input values are > 0 e.g. when filling a lookup table - vfloat x, x2, t, m; - vint2 e; + 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)); + 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); + 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)); + 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)); - return vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e))); + return vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e))); } static INLINE vfloat xexpf(vfloat d) { - vint2 q = vrint_vi2_vf(vmulf(d, vcast_vf_f(R_LN2f))); - vfloat s, u; + vint2 q = vrint_vi2_vf(vmulf(d, vcast_vf_f(R_LN2f))); + vfloat s, u; - s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf),d); - s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf),s); + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf),d); + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf),s); - u = vcast_vf_f(0.00136324646882712841033936f); - u = vmlaf(u, s, vcast_vf_f(0.00836596917361021041870117f)); - u = vmlaf(u, s, vcast_vf_f(0.0416710823774337768554688f)); - u = vmlaf(u, s, vcast_vf_f(0.166665524244308471679688f)); - u = vmlaf(u, s, vcast_vf_f(0.499999850988388061523438f)); + u = vcast_vf_f(0.00136324646882712841033936f); + u = vmlaf(u, s, vcast_vf_f(0.00836596917361021041870117f)); + u = vmlaf(u, s, vcast_vf_f(0.0416710823774337768554688f)); + u = vmlaf(u, s, vcast_vf_f(0.166665524244308471679688f)); + u = vmlaf(u, s, vcast_vf_f(0.499999850988388061523438f)); - u = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); + u = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); - u = vldexpf(u, q); + u = vldexpf(u, q); - // -104.0 - return vselfnotzero(vmaskf_gt(vcast_vf_f(-104.f), d), u); + // -104.0 + return vselfnotzero(vmaskf_gt(vcast_vf_f(-104.f), d), u); } static INLINE vfloat xexpfNoCheck(vfloat d) { // this version does not check input values. Use it only when you know the input values are > -104.f e.g. when filling a lookup table - vint2 q = vrint_vi2_vf(vmulf(d, vcast_vf_f(R_LN2f))); - vfloat s, u; + vint2 q = vrint_vi2_vf(vmulf(d, vcast_vf_f(R_LN2f))); + vfloat s, u; - s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf),d); - s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf),s); + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf),d); + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf),s); - u = vcast_vf_f(0.00136324646882712841033936f); - u = vmlaf(u, s, vcast_vf_f(0.00836596917361021041870117f)); - u = vmlaf(u, s, vcast_vf_f(0.0416710823774337768554688f)); - u = vmlaf(u, s, vcast_vf_f(0.166665524244308471679688f)); - u = vmlaf(u, s, vcast_vf_f(0.499999850988388061523438f)); + u = vcast_vf_f(0.00136324646882712841033936f); + u = vmlaf(u, s, vcast_vf_f(0.00836596917361021041870117f)); + u = vmlaf(u, s, vcast_vf_f(0.0416710823774337768554688f)); + u = vmlaf(u, s, vcast_vf_f(0.166665524244308471679688f)); + u = vmlaf(u, s, vcast_vf_f(0.499999850988388061523438f)); - u = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); + u = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); - return vldexpf(u, q); + return vldexpf(u, q); } static INLINE vfloat xcbrtf(vfloat d) { - vfloat x, y, q = vcast_vf_f(1.0), t; - vint2 e, qu, re; + vfloat x, y, q = vcast_vf_f(1.0), t; + vint2 e, qu, re; - e = vilogbp1f(vabsf(d)); - d = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); + e = vilogbp1f(vabsf(d)); + d = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); - t = vaddf(vcast_vf_vi2(e), vcast_vf_f(6144)); - qu = vtruncate_vi2_vf(vdivf(t, vcast_vf_f(3))); - re = vtruncate_vi2_vf(vsubf(t, vmulf(vcast_vf_vi2(qu), vcast_vf_f(3)))); + t = vaddf(vcast_vf_vi2(e), vcast_vf_f(6144)); + qu = vtruncate_vi2_vf(vdivf(t, vcast_vf_f(3))); + re = vtruncate_vi2_vf(vsubf(t, vmulf(vcast_vf_vi2(qu), vcast_vf_f(3)))); - q = vself(vmaski2_eq(re, vcast_vi2_i(1)), vcast_vf_f(1.2599210498948731647672106f), q); - q = vself(vmaski2_eq(re, vcast_vi2_i(2)), vcast_vf_f(1.5874010519681994747517056f), q); - q = vldexpf(q, vsubi2(qu, vcast_vi2_i(2048))); + q = vself(vmaski2_eq(re, vcast_vi2_i(1)), vcast_vf_f(1.2599210498948731647672106f), q); + q = vself(vmaski2_eq(re, vcast_vi2_i(2)), vcast_vf_f(1.5874010519681994747517056f), q); + q = vldexpf(q, vsubi2(qu, vcast_vi2_i(2048))); - q = vmulsignf(q, d); - d = vabsf(d); + q = vmulsignf(q, d); + d = vabsf(d); - x = vcast_vf_f(-0.601564466953277587890625f); - x = vmlaf(x, d, vcast_vf_f(2.8208892345428466796875f)); - x = vmlaf(x, d, vcast_vf_f(-5.532182216644287109375f)); - x = vmlaf(x, d, vcast_vf_f(5.898262500762939453125f)); - x = vmlaf(x, d, vcast_vf_f(-3.8095417022705078125f)); - x = vmlaf(x, d, vcast_vf_f(2.2241256237030029296875f)); + x = vcast_vf_f(-0.601564466953277587890625f); + x = vmlaf(x, d, vcast_vf_f(2.8208892345428466796875f)); + x = vmlaf(x, d, vcast_vf_f(-5.532182216644287109375f)); + x = vmlaf(x, d, vcast_vf_f(5.898262500762939453125f)); + x = vmlaf(x, d, vcast_vf_f(-3.8095417022705078125f)); + x = vmlaf(x, d, vcast_vf_f(2.2241256237030029296875f)); - y = vmulf(vmulf(d, x), x); - y = vmulf(vsubf(y, vmulf(vmulf(vcast_vf_f(2.0f / 3.0f), y), vmlaf(y, x, vcast_vf_f(-1.0f)))), q); + y = vmulf(vmulf(d, x), x); + y = vmulf(vsubf(y, vmulf(vmulf(vcast_vf_f(2.0f / 3.0f), y), vmlaf(y, x, vcast_vf_f(-1.0f)))), q); - return y; + return y; } static INLINE vfloat vclampf(vfloat value, vfloat low, vfloat high) { @@ -1374,7 +1374,7 @@ static INLINE vfloat vclampf(vfloat value, vfloat low, vfloat high) { } static INLINE vfloat SQRV(vfloat a){ - return a * a; + return a * a; } static inline void vswap( vmask condition, vfloat &a, vfloat &b) { @@ -1390,9 +1390,21 @@ static inline float vhadd( vfloat a ) { return _mm_cvtss_f32(_mm_add_ss(a, _mm_shuffle_ps(a, a, 1))); } +static inline float vhmin(vfloat a) { + // returns min(a[0], a[1], a[2], a[3]) + a = vminf(a, _mm_movehl_ps(a, a)); + return _mm_cvtss_f32(vminf(a, _mm_shuffle_ps(a, a, 1))); +} + +static inline float vhmax(vfloat a) { + // returns max(a[0], a[1], a[2], a[3]) + a = vmaxf(a, _mm_movehl_ps(a, a)); + return _mm_cvtss_f32(vmaxf(a, _mm_shuffle_ps(a, a, 1))); +} + static INLINE vfloat vmul2f(vfloat a){ // fastest way to multiply by 2 - return a + a; + return a + a; } static INLINE vfloat vintpf(vfloat a, vfloat b, vfloat c) { diff --git a/rtengine/slicer.cc b/rtengine/slicer.cc deleted file mode 100644 index 96c0a0ee8..000000000 --- a/rtengine/slicer.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ - -#include -#include -#include "rt_math.h" - -#include "slicer.h" - -#ifdef _OPENMP -#include -#endif - -using namespace std; - -// If no parameter set, everything = 0 -> process all the image -Block::Block() -{ - posX = 0; - posY = 0; - width = 0; - height = 0; -} - -Block::Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h) -{ - posX = x; - posY = y; - width = w; - height = h; -} - -/* - * Slice a sub-region to process in blocks who's size is given by the number of processor - * and the number of pixel per block (and hence the memory footprint) - */ -Slicer::Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels ) -{ - // If the sub-region has a portrait shape, X and Y coordinates are swapped for better result - // It will be swapped back when sending back the block coordinates - region.width = !(subRegion->width) ? imageWidth : subRegion->width; - region.height = !(subRegion->height) ? imageHeight : subRegion->height; // Assuming that the sub-region is under posY - - if (region.width < region.height) { - region.width = !(subRegion->height) ? imageHeight : subRegion->height; - region.height = !(subRegion->width) ? imageWidth : subRegion->width; // Assuming that the sub-region is under posY - portrait = true; - imWidth = imageHeight; - imHeight = imageWidth; - region.posX = subRegion->posY; - region.posY = subRegion->posX; - } else { - portrait = false; - imWidth = imageWidth; - imHeight = imageHeight; - region.posX = subRegion->posX; - region.posY = subRegion->posY; - } - - double subRegionRatio = (double)(region.width) / (double)(region.height); - - //total number of core/processor -#ifdef _OPENMP - unsigned int procNumber = omp_get_num_procs(); -#else - unsigned int procNumber = 1; -#endif - - //calculate the number of block - blockNumber = (double(region.width * region.height) / (double)pixels); - blockNumber = int((rtengine::max(blockNumber, 1U) + (double)procNumber / 2.) / procNumber) * procNumber; - vBlockNumber = (unsigned int)(sqrt((double)blockNumber / subRegionRatio) + 0.5); - vBlockNumber = CLAMP(vBlockNumber, 1, blockNumber); - hBlockNumber = (double)blockNumber / (double)vBlockNumber; - blockWidth = 1.0 / hBlockNumber; - - double maxPixelNumberX = (double)region.height / (double)vBlockNumber; - double maxPixelNumberY = (double)region.width / (double)((unsigned int)hBlockNumber); - - if (maxPixelNumberX - (double)((unsigned int)maxPixelNumberX) != 0.) { - maxPixelNumberX += 1.; - } - - if (maxPixelNumberY - (double)((unsigned int)maxPixelNumberY) != 0.) { - maxPixelNumberY += 1.; - } - - maxPixelNumber = (unsigned int)maxPixelNumberX * (unsigned int)maxPixelNumberY; - -} - -// return the absolute position and size of the requested block -void Slicer::get_block(unsigned int numBlock, Block *block) -{ - double roundingTradeOff = (hBlockNumber - (double)((int)hBlockNumber)) == 0.5 ? 2.1 : 2.0; - unsigned int alreadyCompletedLineNbr = (unsigned int)((double)(numBlock) * blockWidth + (blockWidth / roundingTradeOff)); - - unsigned int prevLineEnd = (unsigned int)((double)alreadyCompletedLineNbr * hBlockNumber + 0.5); - unsigned int myLineEnd = (unsigned int)((double)(alreadyCompletedLineNbr + 1) * hBlockNumber + 0.5); - - unsigned int nbrCellsOnMyLine = myLineEnd - prevLineEnd; - unsigned int cellOnMyLine = numBlock - prevLineEnd; - - unsigned int blockStart = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine) * (double)(cellOnMyLine)); - unsigned int blockEnd = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine) * (double)(cellOnMyLine + 1)); - block->width = blockEnd - blockStart; - block->posX = region.posX + blockStart; - - if (cellOnMyLine == (nbrCellsOnMyLine - 1)) { - // We make sure that the last block of the row take the rest of the remaining X space - block->width = region.posX + region.width - block->posX; - } - - blockStart = (unsigned int)(((double)region.height / (double)vBlockNumber) * (double)(alreadyCompletedLineNbr)); - blockEnd = (unsigned int)(((double)region.height / (double)vBlockNumber) * (double)(alreadyCompletedLineNbr + 1)); - block->height = blockEnd - blockStart; - block->posY = region.posY + blockStart; - - if (alreadyCompletedLineNbr == (vBlockNumber - 1)) { - block->height = region.posY + region.height - block->posY; - } - - if (portrait) { - // we swap back the X/Y coordinates - unsigned int temp; - - temp = block->posX; - block->posX = block->posY; - block->posY = temp; - - temp = block->width; - block->width = block->height; - block->height = temp; - - } -} diff --git a/rtengine/slicer.h b/rtengine/slicer.h deleted file mode 100644 index 658133e5f..000000000 --- a/rtengine/slicer.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _SLICER_ -#define _SLICER_ - -//The image is divided in blocks even on single processor machine, mainly to decrease memory consumption -//maximum number of pixel per block -#define PIXELS_PER_BLOCK 250000 - -/* - * Used to specify a subregion of an image and to specify a cell in this subregion - */ -class Block -{ -public: - unsigned int posX; - unsigned int posY; - unsigned int width; // If 0, use the full width of the image - unsigned int height; // If 0, use the full height of the image - Block(); - Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h); -}; - -/* - * This class handle the best slicing of the image with a given number of pixels per block and the number of - * processor, and tries to create blocks as square as possible. There can be a different number of block on - * each line, and the pixel per block requested may be oversized by very few percents. - */ -class Slicer -{ -protected: - bool portrait; // Orientation of the sub-region - unsigned int imWidth; // Image width - unsigned int imHeight; // Image height - Block region; // Sub-region to process - double hBlockNumber; // Horizontal number of block for the sub-region - unsigned int vBlockNumber; // Vertical number of block for the sub-region - double blockWidth; - -public: - unsigned int blockNumber; // number of block for the sub-region - unsigned int maxPixelNumber; // number of pixel of the biggest block (for memory allocation purpose) - Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels); - void get_block(unsigned int blockId, Block *block); -}; - -#endif diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 2ec1529f7..1cb11e94d 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -19,19 +19,20 @@ #include "stdimagesource.h" #include "color.h" -#include "curves.h" #include "iccstore.h" +#include "image8.h" +#include "image16.h" +#include "imagefloat.h" #include "imageio.h" #include "mytime.h" #include "procparams.h" +#include "utils.h" #undef THREAD_PRIORITY_NORMAL namespace rtengine { -extern const Settings* settings; - template void freeArray (T** a, int H) { for (int i = 0; i < H; i++) { diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 0dffe2fd0..b95328c80 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -16,14 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _STDIMAGESOURCE_ -#define _STDIMAGESOURCE_ +#pragma once +#include "colortemp.h" #include "imagesource.h" namespace rtengine { +class ImageIO; + +namespace procparams +{ + +class ProcParams; + +struct ToneCurveParams; +struct RAWParams; +struct ColorManagementParams; + +} + class StdImageSource : public ImageSource { @@ -43,7 +56,7 @@ public: ~StdImageSource () override; int load (const Glib::ustring &fname) override; - void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) override; + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; ColorTemp getWB () const override { return wb; @@ -87,8 +100,8 @@ public: plistener = pl; } - void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) override;// RAWParams raw will not be used for non-raw files (see imagesource.h) - static void colorSpaceConversion (Imagefloat* im, const ColorManagementParams &cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat); + void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override;// RAWParams raw will not be used for non-raw files (see imagesource.h) + static void colorSpaceConversion (Imagefloat* im, const procparams::ColorManagementParams &cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat); bool isRGBSourceModified() const override { @@ -104,5 +117,5 @@ public: void flushRGB () override; void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override {}; }; + } -#endif diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index 6b5460ffd..feba5c95f 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -50,31 +50,33 @@ * $Id: tmo_fattal02.cpp,v 1.3 2008/11/04 23:43:08 rafm Exp $ */ - #ifdef _OPENMP #include #endif + +#include #include #include #include -#include -#include #include +#include -#include #include #include +#include #include "array2D.h" -#include "improcfun.h" -#include "settings.h" +#include "color.h" #include "iccstore.h" -#include "StopWatch.h" -#include "sleef.c" +#include "imagefloat.h" +#include "improcfun.h" #include "opthelper.h" -#include "rt_algo.h" -#include "rescale.h" #include "procparams.h" +#include "rescale.h" +#include "rt_algo.h" +#include "settings.h" +#include "sleef.h" +#include "StopWatch.h" namespace rtengine { @@ -83,7 +85,6 @@ namespace rtengine * RT code ******************************************************************************/ -extern const Settings *settings; extern MyMutex *fftwMutex; using namespace std; @@ -1093,7 +1094,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb) float oldMedian; const float percentile = float(LIM(params->fattal.anchor, 1, 100)) / 100.f; - findMinMaxPercentile (Yr.data(), Yr.getRows() * Yr.getCols(), percentile, oldMedian, percentile, oldMedian, multiThread); + findMinMaxPercentile (Yr.data(), static_cast(Yr.getRows()) * Yr.getCols(), percentile, oldMedian, percentile, oldMedian, multiThread); // median filter on the deep shadows, to avoid boosting noise // because w2 >= w and h2 >= h, we can use the L buffer as temporary buffer for Median_Denoise() int w2 = find_fast_dim (w) + 1; @@ -1135,7 +1136,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb) const float wr = float(w2) / float(w); float newMedian; - findMinMaxPercentile (L.data(), L.getRows() * L.getCols(), percentile, newMedian, percentile, newMedian, multiThread); + findMinMaxPercentile (L.data(), static_cast(L.getRows()) * L.getCols(), percentile, newMedian, percentile, newMedian, multiThread); const float scale = (oldMedian == 0.f || newMedian == 0.f) ? 65535.f : (oldMedian / newMedian); // avoid Nan #ifdef _OPENMP diff --git a/rtengine/vng4_demosaic_RT.cc b/rtengine/vng4_demosaic_RT.cc index 66413e4c7..47982b6da 100644 --- a/rtengine/vng4_demosaic_RT.cc +++ b/rtengine/vng4_demosaic_RT.cc @@ -21,8 +21,8 @@ //////////////////////////////////////////////////////////////// #include "rtengine.h" +#include "rawimage.h" #include "rawimagesource.h" -#include "procparams.h" #include "../rtgui/multilangmgr.h" //#define BENCHMARK #include "StopWatch.h" @@ -102,7 +102,7 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D(height) * width, sizeof * image); int lcode[16][16][32]; float mul[16][16][8]; @@ -384,7 +384,7 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D 1 ? 8 : 11, red, green, blue); } #undef CLIP void RawImageSource::fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue) diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt index 9747b03fb..5a3831455 100644 --- a/rtexif/CMakeLists.txt +++ b/rtexif/CMakeLists.txt @@ -1,4 +1,16 @@ -add_library(rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc panasonicattribs.cc) +add_library(rtexif STATIC + canonattribs.cc + fujiattribs.cc + kodakattribs.cc + nikonattribs.cc + olympusattribs.cc + panasonicattribs.cc + pentaxattribs.cc + rtexif.cc + sonyminoltaattribs.cc + stdattribs.cc +) + add_dependencies(rtexif UpdateInfo) if(WIN32) diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 4e3be8486..89ff6cd33 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -29,6 +29,7 @@ #include #include +#include #include "rtexif.h" @@ -53,13 +54,13 @@ Interpreter stdInterpreter; //----------------------------------------------------------------------------- TagDirectory::TagDirectory () - : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr) {} + : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr), parseJPEG(true) {} TagDirectory::TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border) - : attribs (ta), order (border), parent (p) {} + : attribs (ta), order (border), parent (p), parseJPEG(true) {} -TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored) - : attribs (ta), order (border), parent (p) +TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored, bool parseJpeg) + : attribs (ta), order (border), parent (p), parseJPEG(parseJpeg) { int numOfTags = get2 (f, order); @@ -979,9 +980,10 @@ Tag::Tag (TagDirectory* p, FILE* f, int base) } } - if (tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras + if (parent->getParseJpeg() && tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras ExifManager eManager(f, nullptr, true); const auto fpos = ftell(f); + if (fpos >= 0) { eManager.parseJPEG(fpos); // try to parse the exif data from the preview image @@ -1238,7 +1240,7 @@ defsubdirs: for (size_t j = 0, i = 0; j < count; j++, i++) { int newpos = base + toInt (j * 4, LONG); fseek (f, newpos, SEEK_SET); - directory[i] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order); + directory[i] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order, true, parent->getParseJpeg()); } // set the terminating NULL @@ -1373,7 +1375,7 @@ bool Tag::parseMakerNote (FILE* f, int base, ByteOrder bom ) value = new unsigned char[12]; fread (value, 1, 12, f); directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom); + directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom, true, parent->getParseJpeg()); directory[1] = nullptr; } else { return false; @@ -2776,7 +2778,7 @@ void ExifManager::parseStd (bool skipIgnored) { parse(false, skipIgnored); } -void ExifManager::parse (bool isRaw, bool skipIgnored) +void ExifManager::parse (bool isRaw, bool skipIgnored, bool parseJpeg) { int ifdOffset = IFDOffset; @@ -2805,7 +2807,7 @@ void ExifManager::parse (bool isRaw, bool skipIgnored) fseek (f, rml->exifBase + ifdOffset, SEEK_SET); // first read the IFD directory - TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored); + TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored, parseJpeg); // fix ISO issue with nikon and panasonic cameras Tag* make = root->getTag ("Make"); @@ -3173,7 +3175,7 @@ void ExifManager::parseJPEG (int offset) rml.reset(new rtengine::RawMetaDataLocation(0)); } rml->exifBase = tiffbase; - parse (false); + parse (false, true, false); if (rmlCreated) { rml.reset(); } diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index f4b0e089e..c37533352 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MEXIF3_ -#define _MEXIF3_ +#pragma once #include #include @@ -30,11 +29,15 @@ #include #include -#include +#include #include "../rtengine/noncopyable.h" #include "../rtengine/rawmetadatalocation.h" +namespace Glib +{ + class KeyFile; +} namespace rtengine { @@ -116,11 +119,12 @@ protected: const TagAttrib* attribs; // descriptor table to decode the tags ByteOrder order; // byte order TagDirectory* parent; // parent directory (NULL if root) + bool parseJPEG; static Glib::ustring getDumpKey (int tagID, const Glib::ustring &tagName); public: TagDirectory (); - TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored = true); + TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored = true, bool parseJpeg = true); TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border); virtual ~TagDirectory (); @@ -132,6 +136,10 @@ public: { return parent; } + inline bool getParseJpeg() const + { + return parseJPEG; + } TagDirectory* getRoot (); inline int getCount () const { @@ -343,7 +351,7 @@ class ExifManager Tag* saveCIFFMNTag (TagDirectory* root, int len, const char* name); void parseCIFF (int length, TagDirectory* root); - void parse (bool isRaw, bool skipIgnored = true); + void parse (bool isRaw, bool skipIgnored = true, bool parseJpeg = true); public: FILE* f; @@ -686,5 +694,5 @@ extern const TagAttrib kodakIfdAttribs[]; void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif); extern const TagAttrib panasonicAttribs[]; extern const TagAttrib panasonicRawAttribs[]; + } -#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index a1811280c..6c6a7cb21 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -79,7 +79,6 @@ set(NONCLISOURCEFILES hsvequalizer.cc iccprofilecreator.cc icmpanel.cc - ilabel.cc imagearea.cc imageareapanel.cc impulsedenoise.cc @@ -287,6 +286,7 @@ target_link_libraries(rth rtengine ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} + ${TCMALLOC_LIBRARIES} ) target_link_libraries(rth-cli rtengine @@ -308,6 +308,7 @@ target_link_libraries(rth-cli rtengine ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} + ${TCMALLOC_LIBRARIES} ) # Install executables diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 6a4ea83d3..05150517f 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -1,6 +1,4 @@ -#ifndef _ADDSETIDS_ -#define _ADDSETIDS_ - +#pragma once // UPDATE THE DEFAULT VALUE IN OPTIONS.CC int babehav[] TOO !!! @@ -142,9 +140,6 @@ enum { ADDSET_XTRANS_FALSE_COLOR_SUPPRESSION, ADDSET_SOFTLIGHT_STRENGTH, ADDSET_DEHAZE_STRENGTH, - ADDSET_SHARP_GAMMA, ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! }; - -#endif diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 5182cd825..2267a9fc1 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -17,14 +17,14 @@ * along with RawTherapee. If not, see . */ #include "adjuster.h" + #include #include -#include "multilangmgr.h" -#include "../rtengine/rtengine.h" -#include "options.h" -#include "guiutils.h" -#include "rtimage.h" +#include "multilangmgr.h" +#include "options.h" +#include "rtimage.h" +#include "../rtengine/rt_math.h" namespace { @@ -246,7 +246,7 @@ void Adjuster::autoToggled () } if (adjusterListener != nullptr && !blocked) { - adjusterListener->adjusterAutoToggled(this, automatic->get_active()); + adjusterListener->adjusterAutoToggled(this); } } @@ -493,7 +493,7 @@ bool Adjuster::notifyListenerAutoToggled () { if (adjusterListener != nullptr && !blocked) { - adjusterListener->adjusterAutoToggled(this, automatic->get_active()); + adjusterListener->adjusterAutoToggled(this); } return false; diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index 52857a3d2..59250bc81 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -16,10 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ADJUSTER_H_ -#define _ADJUSTER_H_ +#pragma once -#include #include "editedstate.h" #include "guiutils.h" @@ -30,7 +28,7 @@ class AdjusterListener public: virtual ~AdjusterListener() = default; virtual void adjusterChanged (Adjuster* a, double newval) = 0; - virtual void adjusterAutoToggled (Adjuster* a, bool newval) {} + virtual void adjusterAutoToggled (Adjuster* a) {} }; typedef double(*double2double_fun)(double val); @@ -130,5 +128,3 @@ public: void trimValue (int &val) const; void setLogScale(double base, double pivot, bool anchorMiddle = false); }; - -#endif diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index abb37b24d..8b4583877 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include +#include #include #include #include @@ -28,12 +28,15 @@ #include #include +#include "cachemanager.h" #include "thumbnail.h" #include "batchqueue.h" +#include "batchqueueentry.h" #include "multilangmgr.h" #include "filecatalog.h" #include "batchqueuebuttonset.h" #include "guiutils.h" +#include "pathutils.h" #include "rtimage.h" #include @@ -144,7 +147,7 @@ int BatchQueue::getThumbnailHeight () return std::max(std::min(options.thumbSizeQueue, 200), 10); } -void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) +void BatchQueue::rightClicked () { pmenu.popup (3, this->eventTime); } @@ -341,9 +344,8 @@ bool BatchQueue::loadBatchQueue () auto job = rtengine::ProcessingJob::create (source, thumb->getType () == FT_Raw, pparams, fast); - auto prevh = getMaxThumbnailHeight (); - auto prevw = prevh; - thumb->getThumbnailSize (prevw, prevh, &pparams); + const auto prevh = getMaxThumbnailHeight (); + const auto prevw = thumb->getThumbnailWidth(prevh, &pparams); auto entry = new BatchQueueEntry (job, pparams, source, prevw, prevh, thumb, options.overwriteOutputFile); thumb->decreaseRef (); // Removing the refCount acquired by cacheMgr->getEntry diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index f61b7b5c4..5cde37748 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -15,22 +15,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BATCHQUEUE_ -#define _BATCHQUEUE_ +#pragma once #include #include -#include "../rtengine/rtengine.h" - -#include "batchqueueentry.h" +#include "lwbutton.h" #include "lwbuttonset.h" -#include "options.h" #include "threadutils.h" #include "thumbbrowserbase.h" + +#include "../rtengine/rtengine.h" #include "../rtengine/noncopyable.h" +class BatchQueueEntry; + class BatchQueueListener { @@ -74,7 +74,7 @@ public: void error(const Glib::ustring& descr) override; rtengine::ProcessingJob* imageReady(rtengine::IImagefloat* img) override; - void rightClicked (ThumbBrowserEntryBase* entry) override; + void rightClicked () override; void doubleClicked (ThumbBrowserEntryBase* entry) override; bool keyPressed (GdkEventKey* event) override; void buttonPressed (LWButton* button, int actionCode, void* actionData) override; @@ -124,5 +124,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc index a8be9eedf..969a55079 100644 --- a/rtgui/batchqueuebuttonset.cc +++ b/rtgui/batchqueuebuttonset.cc @@ -18,8 +18,10 @@ */ #include "batchqueuebuttonset.h" +#include "lwbutton.h" #include "multilangmgr.h" #include "rtimage.h" +#include "rtsurface.h" bool BatchQueueButtonSet::iconsLoaded = false; diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h index 19479ccc1..fb45df518 100644 --- a/rtgui/batchqueuebuttonset.h +++ b/rtgui/batchqueuebuttonset.h @@ -16,14 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BATCHQUEUEBUTTONSET_ -#define _BATCHQUEUEBUTTONSET_ +#pragma once -#include "lwbuttonset.h" -#include "rtsurface.h" #include +#include "lwbuttonset.h" + class BatchQueueEntry; +class RTSurface; + class BatchQueueButtonSet : public LWButtonSet { @@ -40,5 +41,3 @@ public: explicit BatchQueueButtonSet (BatchQueueEntry* myEntry); }; - -#endif diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 424c8e486..90079b2cc 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -25,8 +25,10 @@ #include "rtimage.h" #include "multilangmgr.h" #include "thumbbrowserbase.h" +#include "thumbnail.h" #include "../rtengine/procparams.h" +#include "../rtengine/rtengine.h" bool BatchQueueEntry::iconsLoaded(false); Glib::RefPtr BatchQueueEntry::savedAsIcon; diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 03097e55e..c4cd48615 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -16,18 +16,33 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BATCHQUEUEENTRY_ -#define _BATCHQUEUEENTRY_ +#pragma once #include #include -#include "../rtengine/rtengine.h" -#include "thumbbrowserentrybase.h" -#include "thumbnail.h" + #include "bqentryupdater.h" +#include "options.h" +#include "thumbbrowserentrybase.h" + #include "../rtengine/noncopyable.h" +class Thumbnail; + +namespace rtengine +{ +class ProcessingJob; + +namespace procparams +{ + +class ProcParams; + +} + +} + class BatchQueueEntry; struct BatchQueueEntryIdleHelper { BatchQueueEntry* bqentry; @@ -77,7 +92,3 @@ public: void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) override; void _updateImage (guint8* img, int w, int h); // inside gtk thread }; - - - -#endif diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 9107aaaa8..f7a73a30b 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -18,7 +18,6 @@ */ #include "batchqueuepanel.h" #include "options.h" -#include "preferences.h" #include "multilangmgr.h" #include "rtwindow.h" #include "soundman.h" diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index 2f8e27057..7c0a367d4 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -16,19 +16,20 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BATCHQUEUEPANEL_ -#define _BATCHQUEUEPANEL_ +#pragma once #include #include + #include "batchqueue.h" -#include "saveformatpanel.h" #include "guiutils.h" +#include "saveformatpanel.h" class RTWindow; class FileCatalog; class Thumbnail; + class BatchQueuePanel : public Gtk::VBox, public BatchQueueListener, public FormatChangeListener @@ -83,5 +84,3 @@ private: void formatChanged(const Glib::ustring& format) override; void updateTab (int qsize, int forceOrientation = 0); // forceOrientation=0: base on options / 1: horizontal / 2: vertical }; -#endif - diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 2b6895025..db57fe305 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -16,12 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include "bayerpreprocess.h" +#include "bayerprocess.h" + #include "multilangmgr.h" #include "batchtoolpanelcoord.h" #include "options.h" #include "filepanel.h" #include "procparamchangers.h" #include "addsetids.h" +#include "thumbnail.h" using namespace rtengine::procparams; @@ -152,7 +157,7 @@ void BatchToolPanelCoordinator::initSession () cacorrection->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false, false, false, false, false, false, false); prsharpening->setAdjusterBehavior (false, false, false, false, false, false, false); - pdSharpening->setAdjusterBehavior (false, false, false, false); + pdSharpening->setAdjusterBehavior (false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false, false); epd->setAdjusterBehavior (false, false, false, false, false); diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h index cf30c0fbe..0888fdcc2 100644 --- a/rtgui/batchtoolpanelcoord.h +++ b/rtgui/batchtoolpanelcoord.h @@ -16,17 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __BATCHTOOLPANELCCORD__ -#define __BATCHTOOLPANELCCORD__ +#pragma once -#include "thumbnail.h" -#include "toolpanelcoord.h" #include "fileselectionchangelistener.h" -#include "../rtengine/rtengine.h" #include "paramsedited.h" #include "thumbnaillistener.h" +#include "toolpanelcoord.h" + +#include "../rtengine/procevents.h" +#include "../rtengine/procparams.h" class FilePanel; +class Thumbnail; class BatchToolPanelCoordinator : public ToolPanelCoordinator, public FileSelectionChangeListener, @@ -86,5 +87,3 @@ public: void optionsChanged (); }; - -#endif diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h index 5d2b101d9..16b469626 100644 --- a/rtgui/bayerpreprocess.h +++ b/rtgui/bayerpreprocess.h @@ -16,15 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BAYERPREPROCESS_H_ -#define _BAYERPREPROCESS_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -#include "../rtengine/rawimage.h" -class BayerPreProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class BayerPreProcess final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { protected: @@ -54,5 +53,3 @@ public: void lineDenoiseDirectionChanged(); void pdafLinesFilterChanged(); }; - -#endif diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index aa09067e4..5b5cfe9c4 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -23,6 +23,7 @@ #include "options.h" #include "../rtengine/procparams.h" +#include "../rtengine/utils.h" using namespace rtengine; using namespace rtengine::procparams; @@ -671,7 +672,7 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) } } -void BayerProcess::adjusterAutoToggled(Adjuster* a, bool newval) +void BayerProcess::adjusterAutoToggled(Adjuster* a) { if (multiImage) { if (dualDemosaicContrast->getAutoInconsistent()) { diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index 893010e65..f8348e02b 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -16,16 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BAYERPROCESS_H_ -#define _BAYERPROCESS_H_ +#pragma once #include + #include "adjuster.h" #include "checkbox.h" #include "guiutils.h" #include "toolpanel.h" -class BayerProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FrameCountListener, public rtengine::AutoContrastListener +class BayerProcess final : + public ToolParamBlock, + public AdjusterListener, + public CheckBoxListener, + public FoldableToolPanel, + public rtengine::FrameCountListener, + public rtengine::AutoContrastListener { protected: @@ -82,12 +88,10 @@ public: void methodChanged(); void imageNumberChanged(); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; + void adjusterAutoToggled (Adjuster* a) override; void checkBoxToggled(CheckBox* c, CheckValue newval) override; void pixelShiftMotionMethodChanged(); void pixelShiftDemosaicMethodChanged(); void autoContrastChanged (double autoContrast) override; void FrameCountChanged(int n, int frameNum) override; }; - -#endif diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h index 5825383be..eb18aa0e3 100644 --- a/rtgui/bayerrawexposure.h +++ b/rtgui/bayerrawexposure.h @@ -16,26 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BAYERRAWEXPOSURE_H_ -#define _BAYERRAWEXPOSURE_H_ +#pragma once #include + #include "adjuster.h" #include "checkbox.h" #include "toolpanel.h" -class BayerRAWExposure : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel +class BayerRAWExposure final : + public ToolParamBlock, + public AdjusterListener, + public CheckBoxListener, + public FoldableToolPanel { - -protected: - Adjuster* PexBlack0; - Adjuster* PexBlack1; - Adjuster* PexBlack2; - Adjuster* PexBlack3; - CheckBox* PextwoGreen; - public: - BayerRAWExposure (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; @@ -46,6 +41,11 @@ public: void checkBoxToggled (CheckBox* c, CheckValue newval) override; void setAdjusterBehavior (bool pexblackadd); void trimValues (rtengine::procparams::ProcParams* pp) override; -}; -#endif +protected: + Adjuster* PexBlack0; + Adjuster* PexBlack1; + Adjuster* PexBlack2; + Adjuster* PexBlack3; + CheckBox* PextwoGreen; +}; diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index b5ecb96bd..596d99607 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -21,11 +21,15 @@ #include "blackwhite.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "guiutils.h" #include "rtimage.h" +#include "options.h" #include "../rtengine/color.h" #include "../rtengine/procparams.h" +#include "../rtengine/utils.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h index 36234cda5..1aed86997 100644 --- a/rtgui/blackwhite.h +++ b/rtgui/blackwhite.h @@ -16,19 +16,20 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BLACKWHITE_H_ -#define _BLACKWHITE_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "mycurve.h" -#include "colorprovider.h" +#include "adjuster.h" +#include "colorprovider.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" + +class DiagonalCurveEditor; +class CurveEditorGroup; class EditDataProvider; +class FlatCurveEditor; class BlackWhite final : public ToolParamBlock, @@ -144,5 +145,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc index 21a0f5ad0..61683e158 100644 --- a/rtgui/bqentryupdater.cc +++ b/rtgui/bqentryupdater.cc @@ -17,8 +17,26 @@ * along with RawTherapee. If not, see . */ #include "bqentryupdater.h" -#include + #include "guiutils.h" +#include "options.h" +#include "thumbnail.h" +#include "../rtengine/utils.h" + +namespace +{ + +void thumbInterp(const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) +{ + + if (options.thumbInterp == 0) { + rtengine::nearestInterp (src, sw, sh, dst, dw, dh); + } else if (options.thumbInterp == 1) { + rtengine::bilinearInterp (src, sw, sh, dst, dw, dh); + } +} + +} BatchQueueEntryUpdater batchQueueEntryUpdater; @@ -27,7 +45,7 @@ BatchQueueEntryUpdater::BatchQueueEntryUpdater () { } -void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::ProcParams* pparams, Thumbnail* thumbnail) +void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::procparams::ProcParams* pparams, Thumbnail* thumbnail) { if (!oimg && (!pparams || !thumbnail)) { //printf("WARNING! !oimg && (!pparams || !thumbnail)\n"); diff --git a/rtgui/bqentryupdater.h b/rtgui/bqentryupdater.h index efd63f9de..dfd42aff1 100644 --- a/rtgui/bqentryupdater.h +++ b/rtgui/bqentryupdater.h @@ -16,14 +16,24 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BQENTRYUPDATER_ -#define _BQENTRYUPDATER_ +#pragma once + +#include -#include -#include "../rtengine/rtengine.h" #include "threadutils.h" -#include "thumbnail.h" +class Thumbnail; + +namespace rtengine +{ +namespace procparams +{ + +class ProcParams; + +} + +} class BQEntryUpdateListener { @@ -39,7 +49,7 @@ class BatchQueueEntryUpdater guint8* oimg; int ow, oh, newh; BQEntryUpdateListener* listener; - rtengine::ProcParams* pparams; + rtengine::procparams::ProcParams* pparams; Thumbnail* thumbnail; }; @@ -53,7 +63,7 @@ protected: public: BatchQueueEntryUpdater (); - void process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::ProcParams* pparams = nullptr, Thumbnail* thumbnail = nullptr); + void process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::procparams::ProcParams* pparams = nullptr, Thumbnail* thumbnail = nullptr); void removeJobs (BQEntryUpdateListener* listener); void terminate (); @@ -61,5 +71,3 @@ public: }; extern BatchQueueEntryUpdater batchQueueEntryUpdater; - -#endif diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index f5dac180e..df9a94c11 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -16,15 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _BROWSERFILTER_ -#define _BROWSERFILTER_ +#pragma once + +#include #include "exiffiltersettings.h" -#include class BrowserFilter { - public: bool showRanked[6]; bool showCLabeled[6]; @@ -41,5 +40,3 @@ public: BrowserFilter (); }; - -#endif diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index d31b6c7a5..d44ca28ec 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -19,10 +19,12 @@ #include "cacheimagedata.h" #include #include +#include #include "version.h" #include #include "../rtengine/procparams.h" +#include "../rtengine/settings.h" CacheImageData::CacheImageData() : supported(false), @@ -223,11 +225,11 @@ int CacheImageData::load (const Glib::ustring& fname) return 0; } } catch (Glib::Error &err) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CacheImageData::load / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } } catch (...) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CacheImageData::load / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); } } @@ -305,11 +307,11 @@ int CacheImageData::save (const Glib::ustring& fname) keyData = keyFile.to_data (); } catch (Glib::Error &err) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CacheImageData::save / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } } catch (...) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CacheImageData::save / Unknown exception while trying to save \"%s\"!\n", fname.c_str()); } } @@ -321,7 +323,7 @@ int CacheImageData::save (const Glib::ustring& fname) FILE *f = g_fopen (fname.c_str (), "wt"); if (!f) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CacheImageData::save / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); } diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 72bf55749..caab1de5b 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -16,17 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CACHEIMAGEDATA_ -#define _CACHEIMAGEDATA_ +#pragma once + +#include -#include #include "options.h" -#include "../rtengine/rtengine.h" + #include "../rtengine/imageformat.h" +#include "../rtengine/rtengine.h" -class CacheImageData: public rtengine::FramesMetaData +class CacheImageData : + public rtengine::FramesMetaData { - public: // basic information @@ -115,4 +116,3 @@ public: std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const override { return sampleFormat; } }; -#endif diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index 419538656..c37964e23 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -25,15 +25,15 @@ #include #ifdef WIN32 -#include +#include #endif #include "cachemanager.h" #include "guiutils.h" #include "options.h" -#include "procparamchangers.h" #include "thumbnail.h" +#include "procparamchangers.h" namespace { @@ -64,7 +64,7 @@ void CacheManager::init () } } - if (error != 0 && options.rtSettings.verbose) { + if (error != 0 && rtengine::settings->verbose) { std::cerr << "Failed to create all cache directories: " << g_strerror(errno) << std::endl; } } @@ -191,7 +191,7 @@ void CacheManager::renameEntry (const std::string& oldfilename, const std::strin error |= g_rename (getCacheFileName ("embprofiles", oldfilename, ".icc", oldmd5).c_str (), getCacheFileName ("embprofiles", newfilename, ".icc", newmd5).c_str ()); error |= g_rename (getCacheFileName ("data", oldfilename, ".txt", oldmd5).c_str (), getCacheFileName ("data", newfilename, ".txt", newmd5).c_str ()); - if (error != 0 && options.rtSettings.verbose) { + if (error != 0 && rtengine::settings->verbose) { std::cerr << "Failed to rename all files for cache entry '" << oldfilename << "': " << g_strerror(errno) << std::endl; } @@ -263,7 +263,7 @@ void CacheManager::deleteDir (const Glib::ustring& dirName) const error |= g_remove (Glib::build_filename (baseDir, dirName, *entry).c_str ()); } - if (error != 0 && options.rtSettings.verbose) { + if (error != 0 && rtengine::settings->verbose) { std::cerr << "Failed to delete all entries in cache directory '" << dirName << "': " << g_strerror(errno) << std::endl; } @@ -288,7 +288,7 @@ void CacheManager::deleteFiles (const Glib::ustring& fname, const std::string& m error |= g_remove (getCacheFileName ("profiles", fname, paramFileExtension, md5).c_str ()); } - if (error != 0 && options.rtSettings.verbose) { + if (error != 0 && rtengine::settings->verbose) { std::cerr << "Failed to delete all files for cache entry '" << fname << "': " << g_strerror(errno) << std::endl; } } diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h index 3e987866d..56370e966 100644 --- a/rtgui/cachemanager.h +++ b/rtgui/cachemanager.h @@ -16,18 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CACHEMANAGER_ -#define _CACHEMANAGER_ +#pragma once -#include #include +#include #include -#include "../rtengine/noncopyable.h" - #include "threadutils.h" +#include "../rtengine/noncopyable.h" + class Thumbnail; class CacheManager : @@ -70,6 +69,3 @@ public: }; #define cacheMgr CacheManager::getInstance() - -#endif - diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h index f6e1f89e3..12d6396eb 100644 --- a/rtgui/cacorrection.h +++ b/rtgui/cacorrection.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CACORRECTION_H_ -#define _CACORRECTION_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class CACorrection : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class CACorrection final: + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -43,5 +46,3 @@ public: void setAdjusterBehavior (bool badd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/checkbox.h b/rtgui/checkbox.h index 48324d4c8..45433300c 100644 --- a/rtgui/checkbox.h +++ b/rtgui/checkbox.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CHECKBOX_H_ -#define _CHECKBOX_H_ +#pragma once #include + #include "editedstate.h" #include "guiutils.h" @@ -72,5 +72,3 @@ public: void set_tooltip_markup (const Glib::ustring& tooltip); */ }; - -#endif diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h index 94f54ed3d..d80b89cf7 100644 --- a/rtgui/chmixer.h +++ b/rtgui/chmixer.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CHMIXER_H_ -#define _CHMIXER_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class ChMixer : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class ChMixer final: + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -46,5 +49,3 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void enabledChanged() override; }; - -#endif diff --git a/rtgui/clipboard.cc b/rtgui/clipboard.cc index 4cd50f574..f64f2ed07 100644 --- a/rtgui/clipboard.cc +++ b/rtgui/clipboard.cc @@ -18,6 +18,7 @@ */ #include "clipboard.h" +#include "paramsedited.h" #include "../rtengine/procparams.h" Clipboard clipboard; diff --git a/rtgui/clipboard.h b/rtgui/clipboard.h index 4c0ec452f..0a1c8e2fa 100644 --- a/rtgui/clipboard.h +++ b/rtgui/clipboard.h @@ -16,25 +16,24 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CLIPBOARD_ -#define _CLIPBOARD_ +#pragma once #include #include -#include "mydiagonalcurve.h" -#include "myflatcurve.h" -#include "paramsedited.h" +#include "../rtengine/diagonalcurvetypes.h" +#include "../rtengine/flatcurvetypes.h" -#include "../rtengine/rtengine.h" +struct ParamsEdited; namespace rtengine { namespace procparams { - +class ProcParams; class PartialProfile; +class IPTCPairs; } @@ -80,5 +79,3 @@ private: }; extern Clipboard clipboard; - -#endif diff --git a/rtgui/coarsepanel.h b/rtgui/coarsepanel.h index 2da56b904..b7b4f8cf7 100644 --- a/rtgui/coarsepanel.h +++ b/rtgui/coarsepanel.h @@ -16,13 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __COARSEPANEL__ -#define __COARSEPANEL__ +#pragma once #include + #include "toolpanel.h" -class CoarsePanel : public Gtk::HBox, public ToolPanel +class CoarsePanel final : + public Gtk::HBox, + public ToolPanel { protected: @@ -46,5 +48,3 @@ public: void flipHorizontal (); void flipVertical (); }; - -#endif diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index f8eb736d4..62f6eee2c 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -20,10 +20,15 @@ #include "colorappearance.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "guiutils.h" +#include "options.h" +#include "rtimage.h" #include "../rtengine/color.h" #include "../rtengine/procparams.h" +#include "../rtengine/utils.h" #define MINTEMP0 2000 //1200 #define MAXTEMP0 12000 //12000 @@ -1560,7 +1565,7 @@ void ColorAppearance::adjusterChanged(Adjuster* a, double newval) } } -void ColorAppearance::adjusterAutoToggled(Adjuster* a, bool newval) +void ColorAppearance::adjusterAutoToggled(Adjuster* a) { if (multiImage) { if (degree->getAutoInconsistent()) { diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index da2e3c8b9..c42bca774 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -16,25 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _COLORAPPEARANCE_H_ -#define _COLORAPPEARANCE_H_ +#pragma once #include + #include "adjuster.h" -#include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "mycurve.h" -#include "guiutils.h" #include "colorprovider.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" + +class DiagonalCurveEditor; +class CurveEditorGroup; +class CurveEditor; class ColorAppearance final : - public ToolParamBlock, - public AdjusterListener, - public FoldableToolPanel, - public rtengine::AutoCamListener, - public CurveListener, - public ColorProvider + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public rtengine::AutoCamListener, + public CurveListener, + public ColorProvider { public: ColorAppearance (); @@ -45,7 +47,7 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; + void adjusterAutoToggled (Adjuster* a) override; // void adjusterAdapToggled (Adjuster* a, bool newval); void enabledChanged () override; void surroundChanged (); @@ -173,5 +175,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc index ca9a381cf..adafcbdde 100644 --- a/rtgui/coloredbar.cc +++ b/rtgui/coloredbar.cc @@ -142,7 +142,7 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) case (RTO_Left2Right): for (int py = 0; py < h; ++py) { for (int px = 0; px < w; ++px) { - unsigned char *pixel = surfaceData + (py * w + px) * 4; + unsigned char *pixel = surfaceData + (py * w + px) * 4; double x_ = double( px); //double y_ = double((h-1)-py); unused double x01 = x_ / double(w - 1); @@ -158,7 +158,7 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) case (RTO_Right2Left): for (int py = 0; py < h; ++py) { for (int px = 0; px < w; ++px) { - unsigned char *pixel = surfaceData + (py * w + px) * 4; + unsigned char *pixel = surfaceData + (py * w + px) * 4; //double x_ = double((w-1)-px); unused //double y_ = double((h-1)-py); unused double x01 = double(px) / double(w - 1); @@ -174,7 +174,7 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) case (RTO_Bottom2Top): for (int py = 0; py < h; ++py) { for (int px = 0; px < w; ++px) { - unsigned char *pixel = surfaceData + (py * w + px) * 4; + unsigned char *pixel = surfaceData + (py * w + px) * 4; //double x_ = double((w-1)-px); unused //double y_ = double((h-1)-py); unused double x01 = double(px) / double(w - 1); @@ -191,7 +191,7 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) default: for (int py = 0; py < h; ++py) { for (int px = 0; px < w; ++px) { - unsigned char *pixel = surfaceData + (py * w + px) * 4; + unsigned char *pixel = surfaceData + (py * w + px) * 4; double x_ = double( px); double y_ = double( py); double x01 = x_ / double(w - 1); diff --git a/rtgui/coloredbar.h b/rtgui/coloredbar.h index 089dfa8cd..6cc121cd5 100644 --- a/rtgui/coloredbar.h +++ b/rtgui/coloredbar.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _COLOREDBAR_ -#define _COLOREDBAR_ +#pragma once #include "colorprovider.h" #include "guiutils.h" @@ -62,5 +61,3 @@ public: BackBuffer::setDirty(isDirty); } }; - -#endif diff --git a/rtgui/colorprovider.h b/rtgui/colorprovider.h index feea792b6..988b080bd 100644 --- a/rtgui/colorprovider.h +++ b/rtgui/colorprovider.h @@ -16,10 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _COLORPROVIDER_ -#define _COLORPROVIDER_ - -#include +#pragma once class ColorProvider; @@ -61,10 +58,7 @@ public: */ class ColorProvider { - public: - virtual ~ColorProvider() {}; + virtual ~ColorProvider() = default; virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) {}; }; - -#endif diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index e164739e5..59768a6ce 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -2,10 +2,14 @@ * This file is part of RawTherapee. */ #include "colortoning.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "mycurve.h" #include "rtimage.h" #include "eventmapper.h" #include "labgrid.h" +#include "options.h" +#include "../rtengine/color.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index faba1e383..f1024f41c 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -1,20 +1,25 @@ /* * This file is part of RawTherapee. */ -#ifndef _COLORTONING_H_ -#define _COLORTONING_H_ +#pragma once #include + #include "adjuster.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "thresholdadjuster.h" #include "colorprovider.h" -#include "labgrid.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + #include "../rtengine/procparams.h" +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; +class FlatCurveEditor; +class LabGrid; + class ColorToning final : public ToolParamBlock, public FoldableToolPanel, @@ -166,5 +171,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/coordinateadjuster.h b/rtgui/coordinateadjuster.h index d705915ab..70fe42233 100644 --- a/rtgui/coordinateadjuster.h +++ b/rtgui/coordinateadjuster.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _COORDINATEADJUSTER_ -#define _COORDINATEADJUSTER_ +#pragma once #include @@ -160,6 +159,3 @@ public: void stopNumericalAdjustment(); }; - - -#endif diff --git a/rtgui/crop.cc b/rtgui/crop.cc index b1780538e..3bdcf14cf 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -26,8 +26,6 @@ using namespace rtengine; using namespace rtengine::procparams; -extern Options options; - namespace { diff --git a/rtgui/crop.h b/rtgui/crop.h index 1bbad548d..b9221a803 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -16,14 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CROP_H_ -#define _CROP_H_ +#pragma once + +#include #include + #include "cropguilistener.h" -#include "toolpanel.h" #include "guiutils.h" -#include +#include "toolpanel.h" class CropPanelListener { @@ -129,5 +130,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h index c20d6556a..a7e18683a 100644 --- a/rtgui/cropguilistener.h +++ b/rtgui/cropguilistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __CROPGUILISTENER__ -#define __CROPGUILISTENER__ +#pragma once class CropGUIListener { @@ -39,5 +38,3 @@ public: virtual bool inImageArea(int x, int y) = 0; virtual double getRatio() const = 0; }; - -#endif diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h index 77355b868..98c925b67 100644 --- a/rtgui/crophandler.h +++ b/rtgui/crophandler.h @@ -16,21 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __CROPHANDLER__ -#define __CROPHANDLER__ +#pragma once #include -#include #include +#include #include -#include "../rtengine/rtengine.h" -#include "editbuffer.h" - #include "lockablecolorpicker.h" #include "threadutils.h" +#include "../rtengine/rtengine.h" + class EditSubscriber; class CropDisplayHandler @@ -139,5 +137,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 40eabb091..34f7f7072 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -17,6 +17,9 @@ * along with RawTherapee. If not, see . */ #include +#ifdef WIN32 +#include +#endif #include "cropwindow.h" @@ -30,9 +33,10 @@ #include "editcallbacks.h" #include "editbuffer.h" #include "editwidgets.h" +#include "pointermotionlistener.h" +#include "rtsurface.h" #include "../rtengine/dcrop.h" -#include "../rtengine/mytime.h" #include "../rtengine/procparams.h" #include "../rtengine/rt_math.h" @@ -256,7 +260,7 @@ void CropWindow::getCropAnchorPosition (int& x, int& y) cropHandler.getAnchorPosition(x, y); } -void CropWindow::setCropAnchorPosition (int& x, int& y) +void CropWindow::setCropAnchorPosition (int x, int y) { cropHandler.setAnchorPosition(x, y); } diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 99b0fd897..491124ad5 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -16,24 +16,32 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CROPWINDOW_ -#define _CROPWINDOW_ +#pragma once -#include "../rtengine/rtengine.h" -#include -#include "lwbutton.h" -#include "lwbuttonset.h" -#include "editenums.h" -#include "crophandler.h" #include + +#include + #include "cropguilistener.h" -#include "pointermotionlistener.h" +#include "crophandler.h" #include "cursormanager.h" #include "editbuffer.h" #include "editcoordsys.h" +#include "editenums.h" +#include "lwbutton.h" +#include "lwbuttonset.h" + #include "../rtengine/noncopyable.h" +namespace rtengine +{ + +struct Coord; + +} + class CropWindow; +class PointerMotionListener; class CropWindowListener { @@ -216,7 +224,7 @@ public: void centerCrop (bool update = true); void getCropSize (int& w, int& h); void getCropAnchorPosition (int& w, int& h); - void setCropAnchorPosition (int& w, int& h); + void setCropAnchorPosition (int w, int h); // listeners void setCropGUIListener (CropGUIListener* cgl); @@ -239,5 +247,3 @@ public: ImageArea* getImageArea(); }; - -#endif diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 76b4eabfb..e915150aa 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -18,7 +18,6 @@ */ #include "cursormanager.h" -#include "options.h" #include "rtimage.h" CursorManager mainWindowCursorManager; diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h index aec5110d1..38f198e32 100644 --- a/rtgui/cursormanager.h +++ b/rtgui/cursormanager.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CURSORMANAGER_ -#define _CURSORMANAGER_ +#pragma once #include @@ -89,6 +88,3 @@ public: extern CursorManager mainWindowCursorManager; extern CursorManager editWindowCursorManager; - -#endif - diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index 07b309839..5b5d4395d 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -21,6 +21,7 @@ #include #include "guiutils.h" #include "multilangmgr.h" +#include "popuptogglebutton.h" #include "../rtengine/LUT.h" #include diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 224f843df..81176a82f 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -16,20 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CURVEEDITOR_ -#define _CURVEEDITOR_ +#pragma once -#include "popuptogglebutton.h" -#include "../rtengine/LUT.h" #include "coloredbar.h" #include "editcallbacks.h" -#include "mydiagonalcurve.h" -#include "myflatcurve.h" + +#include "../rtengine/diagonalcurvetypes.h" +#include "../rtengine/flatcurvetypes.h" +#include "../rtengine/LUT.h" #include "../rtengine/noncopyable.h" class CurveEditorGroup; class CurveEditorSubGroup; - +class PopUpToggleButton; /* *********************** Curve Editor *********************** @@ -144,7 +143,7 @@ public: */ -class DiagonalCurveEditor : public CurveEditor +class DiagonalCurveEditor final : public CurveEditor { friend class DiagonalCurveEditorSubGroup; @@ -180,9 +179,8 @@ public: */ -class FlatCurveEditor : public CurveEditor +class FlatCurveEditor final : public CurveEditor { - friend class FlatCurveEditorSubGroup; protected: @@ -207,5 +205,3 @@ public: // set the reset curve for a given curve type. This is optional; all curve type have a default reset curve void setResetCurve(FlatCurveType cType, const std::vector &resetCurve); }; - -#endif diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 0e7205518..cad49d331 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -24,7 +24,10 @@ #include "diagonalcurveeditorsubgroup.h" #include "flatcurveeditorsubgroup.h" #include "multilangmgr.h" +#include "popuptogglebutton.h" #include "rtimage.h" +#include "options.h" +#include "pathutils.h" CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), line(0), curve_reset(nullptr), displayedCurve(nullptr), flatSubGroup(nullptr), diagonalSubGroup(nullptr), cl(nullptr), numberOfPackedCurve(0) diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index 6f7b98d9b..5ef13656b 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -16,18 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CURVEEDITORGROUP_ -#define _CURVEEDITORGROUP_ +#pragma once -#include #include #include + +#include + #include "guiutils.h" #include "mycurve.h" -#include "myflatcurve.h" -#include "mydiagonalcurve.h" #include "shcselector.h" -#include "adjuster.h" + +#include "../rtengine/diagonalcurvetypes.h" +#include "../rtengine/flatcurvetypes.h" class CurveEditor; class DiagonalCurveEditorSubGroup; @@ -39,7 +40,7 @@ class FlatCurveEditorSubGroup; * - to start a new line of curve button, use the 'newLine' method * - if you add more than one curve, you must add a "CurveEditor* ce" parameter to your listener */ -class CurveEditorGroup : public Gtk::Grid, public CurveListener +class CurveEditorGroup final : public Gtk::Grid, public CurveListener { friend class CurveEditor; @@ -169,5 +170,3 @@ protected: virtual const std::vector getCurveFromGUI (int type) = 0; }; - -#endif diff --git a/rtgui/curvelistener.h b/rtgui/curvelistener.h index 05a9a4e99..d99167a98 100644 --- a/rtgui/curvelistener.h +++ b/rtgui/curvelistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _CURVELISTENER_ -#define _CURVELISTENER_ +#pragma once #include @@ -86,5 +85,3 @@ public: return retVal; } }; - -#endif diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index af7ffeace..74ef1384a 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -25,6 +25,7 @@ #include "rtimage.h" #include "../rtengine/procparams.h" +#include "../rtengine/rawimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h index c576712a8..30696e3db 100644 --- a/rtgui/darkframe.h +++ b/rtgui/darkframe.h @@ -16,24 +16,34 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DARKFRAME_H_ -#define _DARKFRAME_H_ +#pragma once #include + #include -#include "toolpanel.h" -#include "../rtengine/rawimage.h" + #include "guiutils.h" +#include "toolpanel.h" + +namespace rtengine +{ + +class RawImage; + +} class DFProvider { public: + virtual ~DFProvider() = default; virtual rtengine::RawImage* getDF() = 0; virtual Glib::ustring GetCurrentImageFilePath() = 0; // add other info here }; -class DarkFrame : public ToolParamBlock, public FoldableToolPanel +class DarkFrame final: + public ToolParamBlock, + public FoldableToolPanel { protected: @@ -66,5 +76,3 @@ public: dfp = p; }; }; - -#endif diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index 659d41960..cdec88edc 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -20,7 +20,11 @@ #include #include "defringe.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "options.h" +#include "../rtengine/color.h" #include "../rtengine/procparams.h" using namespace rtengine; diff --git a/rtgui/defringe.h b/rtgui/defringe.h index 8a6eb0753..ebf1eecd8 100644 --- a/rtgui/defringe.h +++ b/rtgui/defringe.h @@ -16,18 +16,25 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DEFRINGE_H_ -#define _DEFRINGE_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "colorprovider.h" -class Defringe : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider +#include "adjuster.h" +#include "colorprovider.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" + +class CurveEditorGroup; +class FlatCurveEditor; + +class Defringe final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public CurveListener, + public ColorProvider { protected: @@ -54,5 +61,3 @@ public: void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; }; - -#endif diff --git a/rtgui/dehaze.cc b/rtgui/dehaze.cc index 6f60d08d6..6b7fcd64f 100644 --- a/rtgui/dehaze.cc +++ b/rtgui/dehaze.cc @@ -36,6 +36,7 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, EvDehazeStrength = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_STRENGTH"); EvDehazeShowDepthMap = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP"); EvDehazeDepth = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_DEPTH"); + EvDehazeLuminance = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_LUMINANCE"); strength = Gtk::manage(new Adjuster(M("TP_DEHAZE_STRENGTH"), 0., 100., 1., 50.)); strength->setAdjusterListener(this); @@ -45,12 +46,17 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, depth->setAdjusterListener(this); depth->show(); + luminance = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_LUMINANCE"))); + luminance->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::luminanceChanged)); + luminance->show(); + showDepthMap = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_SHOW_DEPTH_MAP"))); showDepthMap->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::showDepthMapChanged)); showDepthMap->show(); pack_start(*strength); pack_start(*depth); + pack_start(*luminance); pack_start(*showDepthMap); } @@ -64,12 +70,14 @@ void Dehaze::read(const ProcParams *pp, const ParamsEdited *pedited) depth->setEditedState(pedited->dehaze.depth ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->dehaze.enabled); showDepthMap->set_inconsistent(!pedited->dehaze.showDepthMap); + luminance->set_inconsistent(!pedited->dehaze.luminance); } setEnabled(pp->dehaze.enabled); strength->setValue(pp->dehaze.strength); depth->setValue(pp->dehaze.depth); showDepthMap->set_active(pp->dehaze.showDepthMap); + luminance->set_active(pp->dehaze.luminance); enableListener(); } @@ -81,12 +89,14 @@ void Dehaze::write(ProcParams *pp, ParamsEdited *pedited) pp->dehaze.depth = depth->getValue(); pp->dehaze.enabled = getEnabled(); pp->dehaze.showDepthMap = showDepthMap->get_active(); + pp->dehaze.luminance = luminance->get_active(); if (pedited) { pedited->dehaze.strength = strength->getEditedState(); pedited->dehaze.depth = depth->getEditedState(); pedited->dehaze.enabled = !get_inconsistent(); pedited->dehaze.showDepthMap = !showDepthMap->get_inconsistent(); + pedited->dehaze.luminance = !luminance->get_inconsistent(); } } @@ -138,6 +148,12 @@ void Dehaze::showDepthMapChanged() } } +void Dehaze::luminanceChanged() +{ + if (listener) { + listener->panelChanged(EvDehazeLuminance, luminance->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} void Dehaze::setBatchMode(bool batchMode) { diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 3120dfc91..79d2e015c 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -23,17 +23,19 @@ #include "adjuster.h" #include "toolpanel.h" -class Dehaze: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class Dehaze final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *strength; Adjuster *depth; - Gtk::CheckButton *showDepthMap; + Gtk::CheckButton *showDepthMap; + Gtk::CheckButton *luminance; rtengine::ProcEvent EvDehazeEnabled; rtengine::ProcEvent EvDehazeStrength; rtengine::ProcEvent EvDehazeDepth; rtengine::ProcEvent EvDehazeShowDepthMap; + rtengine::ProcEvent EvDehazeLuminance; public: @@ -47,6 +49,7 @@ public: void adjusterChanged(Adjuster *a, double newval) override; void enabledChanged() override; void showDepthMapChanged(); + void luminanceChanged(); void setAdjusterBehavior(bool strengthAdd); }; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index 21b42a6ce..eed6c63d3 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -31,6 +31,8 @@ #include "curveeditor.h" #include "diagonalcurveeditorsubgroup.h" #include "rtimage.h" +#include "options.h" +#include "popuptogglebutton.h" #include "../rtengine/curves.h" diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index 077ef590e..a077da807 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -16,16 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DIAGONALCURVEEDITORSUBGROUP_ -#define _DIAGONALCURVEEDITORSUBGROUP_ +#pragma once #include + #include "curveeditorgroup.h" +#include "adjuster.h" #include "../rtengine/noncopyable.h" class DiagonalCurveEditor; +class MyDiagonalCurve; -class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener, public rtengine::NonCopyable +class DiagonalCurveEditorSubGroup : + public CurveEditorSubGroup, + public SHCListener, + public AdjusterListener, + public rtengine::NonCopyable { friend class DiagonalCurveEditor; @@ -111,5 +117,3 @@ protected: void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); void setSubGroupBottomBarBgGradient(); }; - -#endif diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 32361d5c5..669528ac1 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -63,7 +63,7 @@ std::vector listSubDirs (const Glib::RefPtr& dir, bool subDirs.push_back (file->get_name ()); } catch (const Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << exception.what().c_str() << std::endl; } @@ -72,7 +72,7 @@ std::vector listSubDirs (const Glib::RefPtr& dir, bool } catch (const Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << "Failed to list subdirectories of \"" << dir->get_parse_name() << "\": " << exception.what () << std::endl; } diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h index 68422f8be..6ead83919 100644 --- a/rtgui/dirbrowser.h +++ b/rtgui/dirbrowser.h @@ -16,16 +16,12 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DIRBROWSER_ -#define _DIRBROWSER_ +#pragma once #include #include #include "guiutils.h" -#ifdef WIN32 -#include "windows.h" -#endif class DirBrowser : public Gtk::VBox { @@ -110,5 +106,3 @@ inline DirBrowser::DirSelectionSignal DirBrowser::dirSelected () const { return dirSelectionSignal; } - -#endif diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index 2a0bba596..7129542d1 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -21,14 +21,17 @@ #include "dirpyrdenoise.h" -#include "guiutils.h" - -#include "../rtengine/procparams.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "editbuffer.h" +#include "guiutils.h" +#include "options.h" + +#include "../rtengine/color.h" +#include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; -extern Options options; DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index a513eb262..c754e705c 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -16,18 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DIRPYRDENOISE_H_ -#define _DIRPYRDENOISE_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "colorprovider.h" -#include "guiutils.h" -#include "options.h" +#include "adjuster.h" +#include "colorprovider.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" + +class CurveEditor; +class CurveEditorGroup; +class FlatCurveEditor; class EditDataProvider; class DirPyrDenoise final : @@ -138,5 +139,3 @@ private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index fc03c83ad..fd0268efa 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -19,6 +19,8 @@ #include "dirpyrequalizer.h" +#include "../rtengine/color.h" + using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index e236dc29b..84924099e 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -16,17 +16,20 @@ * * (C) 2010 Emil Martinec */ - -#ifndef DIRPYREQUALIZER_H_INCLUDED -#define DIRPYREQUALIZER_H_INCLUDED +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "thresholdadjuster.h" -#include "colorprovider.h" -class DirPyrEqualizer : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +#include "adjuster.h" +#include "colorprovider.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + +class DirPyrEqualizer final : + public ToolParamBlock, + public ThresholdAdjusterListener, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -77,5 +80,3 @@ public: void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) override; void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; }; - -#endif diff --git a/rtgui/distortion.h b/rtgui/distortion.h index 5e1cf6a6b..7ef33d73a 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -16,15 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DISTORTION_H_ -#define _DISTORTION_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "lensgeomlistener.h" -class Distortion : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +#include "adjuster.h" +#include "lensgeomlistener.h" +#include "toolpanel.h" + +class Distortion final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -51,5 +54,3 @@ public: rlistener = l; } }; - -#endif diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index 38029af71..d7ed8ee97 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -22,6 +22,7 @@ #include "../rtengine/profilestore.h" #include "../rtengine/rtengine.h" #include "../rtengine/dynamicprofile.h" +#include "../rtengine/settings.h" #include #include @@ -615,7 +616,7 @@ void DynamicProfilePanel::save() if (!ProfileStore::getInstance()->storeRules()) { printf ("Error in saving dynamic profile rules\n"); - } else if (options.rtSettings.verbose) { + } else if (rtengine::settings->verbose) { printf ("Saved %d dynamic profile rules\n", int (rules.size())); } } diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index fd4a6e80e..5796c9c85 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -16,14 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _DYNAMICPROFILEPANEL_H_ -#define _DYNAMICPROFILEPANEL_H_ +#pragma once #include -#include "../rtengine/dynamicprofile.h" + #include "profilestorecombobox.h" -class DynamicProfilePanel: public Gtk::VBox +#include "../rtengine/dynamicprofile.h" + +class DynamicProfilePanel : + public Gtk::VBox { public: DynamicProfilePanel(); @@ -133,5 +135,3 @@ private: Gtk::Button button_edit_; Gtk::Button button_delete_; }; - -#endif // _DYNAMICPROFILEPANEL_H_ diff --git a/rtgui/editbuffer.h b/rtgui/editbuffer.h index 77afb6449..a5cf8d0e4 100644 --- a/rtgui/editbuffer.h +++ b/rtgui/editbuffer.h @@ -19,12 +19,13 @@ #pragma once #include "editid.h" -#include "../rtengine/coord.h" #include -#ifdef GUIVERSION -#include "rtsurface.h" -#endif +namespace rtengine { + +struct Coord; + +} class EditDataProvider; class EditSubscriber; diff --git a/rtgui/editedstate.h b/rtgui/editedstate.h index 2cee07eb9..c34aaf539 100644 --- a/rtgui/editedstate.h +++ b/rtgui/editedstate.h @@ -16,10 +16,6 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EDITEDSTATE_ -#define _EDITEDSTATE_ +#pragma once enum EditedState { UnEdited = 0, Edited = 1, Irrelevant = 2 }; - -#endif - diff --git a/rtgui/editenums.h b/rtgui/editenums.h index 8fc28e922..f1ade8bfc 100644 --- a/rtgui/editenums.h +++ b/rtgui/editenums.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EDITENUMS_ -#define _EDITENUMS_ +#pragma once enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove, @@ -26,5 +25,3 @@ enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH enum CursorArea {CropWinButtons, CropToolBar, CropImage, ColorPicker, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft, CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved }; - -#endif diff --git a/rtgui/editid.h b/rtgui/editid.h index 88d77f859..39dc2bf7c 100644 --- a/rtgui/editid.h +++ b/rtgui/editid.h @@ -16,9 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EDITID_H_ -#define _EDITID_H_ - +#pragma once /// @brief List of pipette editing operation enum EditUniqueID : int { @@ -67,5 +65,3 @@ enum ObjectMode { OM_255, /// less or equal than 255 objects OM_65535 /// less or equal than 65535 objects }; - -#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 6aab153a1..1b5ed3fa7 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -23,15 +23,27 @@ #include "../rtengine/imagesource.h" #include "../rtengine/iccstore.h" +#include "batchqueue.h" +#include "batchqueueentry.h" #include "soundman.h" #include "rtimage.h" #include "rtwindow.h" +#include "filepanel.h" #include "guiutils.h" #include "popupbutton.h" #include "options.h" +#include "navigator.h" +#include "previewwindow.h" #include "progressconnector.h" #include "procparamchangers.h" #include "placesbrowser.h" +#include "pathutils.h" +#include "thumbnail.h" +#include "toolpanelcoord.h" + +#ifdef WIN32 +#include "windows.h" +#endif using namespace rtengine::procparams; @@ -889,41 +901,17 @@ EditorPanel::~EditorPanel () delete vboxright; //delete saveAsDialog; - if (catalogPane) { - delete catalogPane; - } - - if (iTopPanel_1_Show) { - delete iTopPanel_1_Show; - } - - if (iTopPanel_1_Hide) { - delete iTopPanel_1_Hide; - } - - if (iHistoryShow) { - delete iHistoryShow; - } - - if (iHistoryHide) { - delete iHistoryHide; - } - - if (iBeforeLockON) { - delete iBeforeLockON; - } - - if (iBeforeLockOFF) { - delete iBeforeLockOFF; - } - - if (iRightPanel_1_Show) { - delete iRightPanel_1_Show; - } - - if (iRightPanel_1_Hide) { - delete iRightPanel_1_Hide; - } + delete catalogPane; + delete iTopPanel_1_Show; + delete iTopPanel_1_Hide; + delete iHistoryShow; + delete iHistoryHide; + delete iBeforeLockON; + delete iBeforeLockOFF; + delete iRightPanel_1_Show; + delete iRightPanel_1_Hide; + delete iShowHideSidePanels_exit; + delete iShowHideSidePanels; } void EditorPanel::leftPaneButtonReleased (GdkEventButton *event) @@ -1130,7 +1118,7 @@ Glib::ustring EditorPanel::getShortName () } } -Glib::ustring EditorPanel::getFileName () +Glib::ustring EditorPanel::getFileName () const { if (openThm) { return openThm->getFileName (); @@ -2034,9 +2022,9 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p if (img) { // get file name base - Glib::ustring shortname = removeExtension (Glib::path_get_basename (fname)); - Glib::ustring dirname = Glib::get_tmp_dir (); - Glib::ustring fname = Glib::build_filename (dirname, shortname); + const Glib::ustring shortname = removeExtension (Glib::path_get_basename (fname)); + const Glib::ustring dirname = Glib::get_tmp_dir (); + const Glib::ustring lfname = Glib::build_filename (dirname, shortname); SaveFormat sf; sf.format = "tif"; @@ -2045,13 +2033,13 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p sf.tiffUncompressed = true; sf.saveParams = true; - Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); + Glib::ustring fileName = Glib::ustring::compose ("%1.%2", lfname, sf.format); // TODO: Just list all file with a suitable name instead of brute force... int tries = 1; while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) { - fileName = Glib::ustring::compose ("%1-%2.%3", fname, tries, sf.format); + fileName = Glib::ustring::compose ("%1-%2.%3", lfname, tries, sf.format); tries++; } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index c4349f693..8993fea07 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -17,27 +17,28 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EDITORPANEL_ -#define _EDITORPANEL_ +#pragma once #include -#include "imageareapanel.h" -#include "toolpanelcoord.h" -#include "profilepanel.h" -#include "../rtengine/rtengine.h" -#include "history.h" -#include "histogrampanel.h" -#include "thumbnail.h" -#include "saveasdlg.h" -#include "batchqueueentry.h" -#include "thumbnaillistener.h" -#include "navigator.h" -#include "progressconnector.h" -#include "filepanel.h" -#include "../rtengine/noncopyable.h" +#include "histogrampanel.h" +#include "history.h" +#include "imageareapanel.h" +#include "profilepanel.h" +#include "progressconnector.h" +#include "saveasdlg.h" +#include "thumbnaillistener.h" + +#include "../rtengine/noncopyable.h" +#include "../rtengine/rtengine.h" + +class BatchQueueEntry; class EditorPanel; +class FilePanel; class MyProgressBar; +class Navigator; +class Thumbnail; +class ToolPanelCoordinator; struct EditorPanelIdleHelper { EditorPanel* epanel; @@ -149,7 +150,7 @@ public: void saveProfile (); Glib::ustring getShortName (); - Glib::ustring getFileName (); + Glib::ustring getFileName () const; bool handleShortcutKey (GdkEventKey* event); bool getIsProcessing() const @@ -259,6 +260,3 @@ private: IdleRegister idle_register; }; - -#endif - diff --git a/rtgui/editwidgets.cc b/rtgui/editwidgets.cc index 5d3c1f92f..8d4684a11 100644 --- a/rtgui/editwidgets.cc +++ b/rtgui/editwidgets.cc @@ -18,8 +18,10 @@ */ #include "editwidgets.h" + #include "editbuffer.h" #include "editcallbacks.h" +#include "rtsurface.h" const std::vector Geometry::dash = {3., 1.5}; diff --git a/rtgui/editwidgets.h b/rtgui/editwidgets.h index e041a6bee..2dcd5274c 100644 --- a/rtgui/editwidgets.h +++ b/rtgui/editwidgets.h @@ -20,13 +20,15 @@ #ifdef GUIVERSION -#include "rtsurface.h" -#include "editbuffer.h" +#include +#include + #include "editcoordsys.h" #include "../rtengine/coord.h" #include "../rtengine/rt_math.h" class ObjectMOBuffer; +class RTSurface; /** @file * @@ -289,7 +291,7 @@ public: rtengine::Coord end; Line (); - Line (rtengine::Coord& begin, rtengine::Coord& end); + Line (const rtengine::Coord& begin, const rtengine::Coord& end); Line (int beginX, int beginY, int endX, int endY); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) override; @@ -548,7 +550,7 @@ inline Circle::Circle (int centerX, int centerY, int radius, bool filled, radiusInImageSpace) { } -inline Line::Line (rtengine::Coord& begin, rtengine::Coord& end) : +inline Line::Line (const rtengine::Coord& begin, const rtengine::Coord& end) : begin (begin), end (end) { } diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index 50a1484cf..8841d3d42 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -16,12 +16,14 @@ */ #include "editwindow.h" +#include "editorpanel.h" +#include "filepanel.h" +#include "../rtengine/procparams.h" #include "options.h" #include "preferences.h" #include "cursormanager.h" #include "rtwindow.h" #include -#include "rtimage.h" #include "threadutils.h" extern Glib::ustring argv0; diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index 8a2ade6ba..f4ada571d 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -14,15 +14,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EDITWINDOW_ -#define _EDITWINDOW_ +#pragma once -#include -#include "filepanel.h" -#include "editorpanel.h" #include -class EditWindow : public Gtk::Window +#include + +#include "rtimage.h" + +class EditorPanel; +class RTWindow; + +class EditWindow : + public Gtk::Window { private: @@ -66,5 +70,3 @@ public: void set_title_decorated(Glib::ustring fname); void on_realize () override; }; - -#endif diff --git a/rtgui/epd.h b/rtgui/epd.h index d8781ef27..6a5160623 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EPD_H_ -#define _EPD_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class EdgePreservingDecompositionUI : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class EdgePreservingDecompositionUI final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: Adjuster *strength; @@ -45,5 +48,3 @@ public: void enabledChanged () override; void setAdjusterBehavior (bool stAdd, bool gAdd, bool esAdd, bool scAdd, bool rAdd); }; - -#endif diff --git a/rtgui/exiffiltersettings.h b/rtgui/exiffiltersettings.h index e820a2cac..5a25af6ad 100644 --- a/rtgui/exiffiltersettings.h +++ b/rtgui/exiffiltersettings.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EXIFFILTERSETTINGS_ -#define _EXIFFILTERSETTINGS_ +#pragma once #include #include @@ -51,6 +50,3 @@ public: ExifFilterSettings (); void clear (); }; - -#endif - diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index f054f37c7..0894c21ad 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -16,16 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EXIFPANEL_ -#define _EXIFPANEL_ +#pragma once #include #include #include "toolpanel.h" +#include "../rtexif/rtexif.h" -class ExifPanel : public Gtk::VBox, public ToolPanel +class ExifPanel : + public Gtk::VBox, + public ToolPanel { private: @@ -114,5 +116,3 @@ public: void notifyListener(); }; - -#endif diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h index d13ca08ad..7ae7e043c 100644 --- a/rtgui/exportpanel.h +++ b/rtgui/exportpanel.h @@ -17,12 +17,11 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _EXPORTPANEL_ -#define _EXPORTPANEL_ +#pragma once #include + #include "guiutils.h" -#include "adjuster.h" class ExportPanelListener { @@ -122,5 +121,3 @@ public: listener = l; } }; - -#endif diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index a6a9050c0..57d57ecd8 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -22,10 +22,12 @@ #include #ifdef WIN32 -#include #include +#include #endif +#include + #include "options.h" #include "multilangmgr.h" @@ -58,7 +60,7 @@ bool ExtProgAction::execute (const std::vector& fileNames) const } for (const auto& fileName : fileNames) { - cmdLine += " \"" + fileName + "\""; + cmdLine += " " + Glib::shell_quote(fileName); } return ExtProgStore::spawnCommandAsync (cmdLine); @@ -143,20 +145,19 @@ bool ExtProgStore::searchProgram (const Glib::ustring& name, filePath = progFilesDir + "\\" + Glib::ustring::compose(exePath, ver); - if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test(filePath, Glib::FILE_TEST_EXISTS)) { break; } - if (!exePath86.empty ()) { + if (!exePath86.empty()) { filePath = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, ver); - if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test(filePath, Glib::FILE_TEST_EXISTS)) { break; } } - - filePath.clear (); + filePath.clear(); } } else { @@ -164,21 +165,19 @@ bool ExtProgStore::searchProgram (const Glib::ustring& name, filePath = progFilesDir + "\\" + exePath; - if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test(filePath, Glib::FILE_TEST_EXISTS)) { break; } - if (!exePath86.empty ()) { + if (!exePath86.empty()) { filePath = progFilesDirx86 + "\\" + exePath86; - if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test(filePath, Glib::FILE_TEST_EXISTS)) { break; } } - - filePath.clear (); - + filePath.clear(); } while (false); } @@ -211,7 +210,7 @@ bool ExtProgStore::spawnCommandAsync (const Glib::ustring& cmd) } catch (const Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl; } @@ -230,7 +229,7 @@ bool ExtProgStore::spawnCommandSync (const Glib::ustring& cmd) } catch (const Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl; } @@ -256,13 +255,13 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #else - auto cmdLine = Glib::ustring("gimp \"") + fileName + Glib::ustring("\""); + auto cmdLine = Glib::ustring("gimp ") + Glib::shell_quote(fileName); auto success = spawnCommandAsync (cmdLine); #endif #ifdef WIN32 - if ((uintptr_t)success > 32) { + if (reinterpret_cast(success) > 32) { return true; } #else @@ -277,9 +276,9 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename (options.gimpDir, "bin", Glib::ustring::compose (Glib::ustring("gimp-2.%1.exe"), ver)); - auto success = ShellExecute( NULL, "open", executable.c_str(), fileName.c_str(), NULL, SW_SHOWNORMAL ); + auto lsuccess = ShellExecute( NULL, "open", executable.c_str(), fileName.c_str(), NULL, SW_SHOWNORMAL ); - if ((uintptr_t)success > 32) { + if (reinterpret_cast(lsuccess) > 32) { return true; } } @@ -291,7 +290,7 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #else - cmdLine = Glib::ustring("gimp-remote \"") + fileName + Glib::ustring("\""); + cmdLine = Glib::ustring("gimp-remote ") + Glib::shell_quote(fileName); success = ExtProgStore::spawnCommandAsync (cmdLine); #endif @@ -312,7 +311,7 @@ bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName) #else - const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + "\" " + Glib::shell_quote(fileName); #endif @@ -334,7 +333,7 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) #else - const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + const auto cmdLine = options.customEditorProg + Glib::ustring(" ") + Glib::shell_quote(fileName); return spawnCommandAsync (cmdLine); #endif diff --git a/rtgui/extprog.h b/rtgui/extprog.h index ea2749a61..c5e00bb1b 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -16,14 +16,12 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ - -#ifndef _EXTPROG_ -#define _EXTPROG_ - -#include +#pragma once #include +#include + #include "threadutils.h" struct ExtProgAction @@ -74,5 +72,3 @@ inline const std::vector& ExtProgStore::getActions () const { return actions; } - -#endif diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc index a0baf3531..89a1e9e30 100644 --- a/rtgui/fattaltonemap.cc +++ b/rtgui/fattaltonemap.cc @@ -23,6 +23,7 @@ #include "fattaltonemap.h" #include "eventmapper.h" +#include "rtimage.h" #include "../rtengine/procparams.h" diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h index 9f788351c..3d36ec7d2 100644 --- a/rtgui/fattaltonemap.h +++ b/rtgui/fattaltonemap.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class FattalToneMapping: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class FattalToneMapping final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { protected: Adjuster *threshold; diff --git a/rtgui/favoritbrowser.h b/rtgui/favoritbrowser.h index 292f17de6..7a73b98af 100644 --- a/rtgui/favoritbrowser.h +++ b/rtgui/favoritbrowser.h @@ -16,17 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FAVORITBROWSER_ -#define _FAVORITBROWSER_ +#pragma once #include + #include "dirbrowserremoteinterface.h" #include "dirselectionlistener.h" -class FavoritBrowser : public Gtk::VBox, public DirSelectionListener +class FavoritBrowser : + public Gtk::VBox, + public DirSelectionListener { - - class FavoritColumns : public Gtk::TreeModel::ColumnRecord + class FavoritColumns : + public Gtk::TreeModel::ColumnRecord { public: Gtk::TreeModelColumn > icon; @@ -61,7 +63,3 @@ public: void delPressed (); void selectionChanged (); }; - -#endif - - diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index f9afcef48..caa60ebbc 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -21,7 +21,7 @@ #include #include -#include +#include #include "filebrowser.h" @@ -29,16 +29,16 @@ #include "clipboard.h" #include "multilangmgr.h" #include "options.h" +#include "profilestorecombobox.h" #include "procparamchangers.h" #include "rtimage.h" #include "threadutils.h" +#include "thumbnail.h" #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" #include "../rtengine/procparams.h" -extern Options options; - namespace { @@ -90,41 +90,36 @@ ThumbBrowserEntryBase* selectOriginalEntry (ThumbBrowserEntryBase* original, Thu void findOriginalEntries (const std::vector& entries) { - typedef std::vector EntryVector; - typedef EntryVector::const_iterator EntryIterator; - typedef std::map BasenameMap; - typedef BasenameMap::const_iterator BasenameIterator; - // Sort all entries into buckets by basename without extension - BasenameMap byBasename; + std::map> byBasename; - for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { - const Glib::ustring basename = Glib::path_get_basename ((*entry)->filename.lowercase()); + for (const auto entry : entries) { + const auto basename = Glib::path_get_basename(entry->filename.lowercase()); - const Glib::ustring::size_type pos = basename.find_last_of ('.'); - if (pos >= basename.length () - 1) { - (*entry)->setOriginal (nullptr); + const auto pos = basename.find_last_of('.'); + if (pos >= basename.length() - 1) { + entry->setOriginal(nullptr); continue; } - const Glib::ustring withoutExtension = basename.substr (0, pos); + const auto withoutExtension = basename.substr(0, pos); - byBasename[withoutExtension].push_back (*entry); + byBasename[withoutExtension].push_back(entry); } // Find the original image for each bucket - for (BasenameIterator bucket = byBasename.begin (); bucket != byBasename.end (); ++bucket) { - const EntryVector& entries = bucket->second; + for (const auto& bucket : byBasename) { + const auto& lentries = bucket.second; ThumbBrowserEntryBase* original = nullptr; // Select the most likely original in a first pass... - for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { - original = selectOriginalEntry (original, *entry); + for (const auto entry : lentries) { + original = selectOriginalEntry(original, entry); } // ...and link all other images to it in a second pass. - for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { - (*entry)->setOriginal (*entry != original ? original : nullptr); + for (const auto entry : lentries) { + entry->setOriginal(entry != original ? original : nullptr); } } } @@ -487,7 +482,7 @@ FileBrowser::~FileBrowser () delete[] amiExtProg; } -void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) +void FileBrowser::rightClicked () { { diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 6911a944f..86ab59395 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -16,25 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILEBROWSER_ -#define _FILEBROWSER_ +#pragma once + +#include #include -#include -#include "thumbbrowserbase.h" -#include "exiffiltersettings.h" -#include "filebrowserentry.h" + #include "browserfilter.h" -#include "pparamschangelistener.h" -#include "partialpastedlg.h" #include "exportpanel.h" #include "extprog.h" -#include "profilestorecombobox.h" +#include "filebrowserentry.h" +#include "lwbutton.h" +#include "partialpastedlg.h" +#include "pparamschangelistener.h" +#include "../rtengine/profilestore.h" +#include "thumbbrowserbase.h" + #include "../rtengine/noncopyable.h" -class ProfileStoreLabel; class FileBrowser; class FileBrowserEntry; +class ProfileStoreLabel; class FileBrowserListener { @@ -171,7 +173,7 @@ public: void buttonPressed (LWButton* button, int actionCode, void* actionData) override; void redrawNeeded (LWButton* button) override; bool checkFilter (ThumbBrowserEntryBase* entry) const override; - void rightClicked (ThumbBrowserEntryBase* entry) override; + void rightClicked () override; void doubleClicked (ThumbBrowserEntryBase* entry) override; bool keyPressed (GdkEventKey* event) override; @@ -210,5 +212,3 @@ public: type_trash_changed trash_changed(); }; - -#endif diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 44146b990..3129e93e2 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -21,12 +21,15 @@ #include #include +#include "cropguilistener.h" #include "cursormanager.h" #include "guiutils.h" #include "inspector.h" #include "rtimage.h" #include "threadutils.h" #include "thumbbrowserbase.h" +#include "thumbnail.h" +#include "toolbar.h" #include "../rtengine/procparams.h" @@ -115,7 +118,7 @@ void FileBrowserEntry::calcThumbnailSize () { if (thumbnail) { - thumbnail->getThumbnailSize (prew, preh); + prew = thumbnail->getThumbnailWidth(preh); } } diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 646e8e67e..ea5140ed6 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -16,28 +16,26 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILEBROWSERENTRY_ -#define _FILEBROWSERENTRY_ +#pragma once #include #include #include -#include "../rtengine/rtengine.h" - -#include "crophandler.h" #include "editenums.h" #include "filethumbnailbuttonset.h" #include "imageareatoollistener.h" #include "thumbbrowserentrybase.h" #include "thumbimageupdater.h" -#include "thumbnail.h" #include "thumbnaillistener.h" -#include "../rtengine/noncopyable.h" +#include "../rtengine/noncopyable.h" +#include "../rtengine/rtengine.h" class FileBrowserEntry; +class Thumbnail; + struct FileBrowserEntryIdleHelper { FileBrowserEntry* fbentry; bool destroyed; @@ -109,5 +107,3 @@ public: bool pressNotify (int button, int type, int bstate, int x, int y) override; bool releaseNotify (int button, int type, int bstate, int x, int y) override; }; - -#endif diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 674501322..109a1bb57 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -25,17 +25,23 @@ #include #include "../rtengine/rt_math.h" +#include "../rtengine/procparams.h" #include "guiutils.h" #include "options.h" #include "rtimage.h" #include "cachemanager.h" #include "multilangmgr.h" +#include "coarsepanel.h" #include "filepanel.h" #include "renamedlg.h" #include "thumbimageupdater.h" #include "batchqueue.h" +#include "batchqueueentry.h" #include "placesbrowser.h" +#include "pathutils.h" +#include "thumbnail.h" +#include "toolbar.h" using namespace std; @@ -602,7 +608,7 @@ std::vector FileCatalog::getFileList() names.push_back(Glib::build_filename(selectedDirectory, fname)); } catch (Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << exception.what() << std::endl; } } @@ -610,7 +616,7 @@ std::vector FileCatalog::getFileList() } catch (Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << "Failed to list directory \"" << selectedDirectory << "\": " << exception.what() << std::endl; } @@ -1218,9 +1224,8 @@ void FileCatalog::developRequested(const std::vector& tbe, bo rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode && options.fastexport_use_fast_pipeline); - int pw; - int ph = BatchQueue::calcMaxThumbnailHeight(); - th->getThumbnailSize (pw, ph); + const int ph = BatchQueue::calcMaxThumbnailHeight(); + const int pw = th->getThumbnailWidth(ph); // processThumbImage is the processing intensive part, but adding to queue must be ordered //#pragma omp ordered diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 09e2cc1ed..8f7e5618f 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -16,25 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILECATALOG_ -#define _FILECATALOG_ +#pragma once -#include "filebrowser.h" -#include "exiffiltersettings.h" -#include -#include "fileselectionlistener.h" #include -#include "fileselectionchangelistener.h" -#include "coarsepanel.h" -#include "toolbar.h" -#include "filterpanel.h" + +#include + +#include "exiffiltersettings.h" #include "exportpanel.h" +#include "filebrowser.h" +#include "fileselectionchangelistener.h" +#include "fileselectionlistener.h" +#include "filterpanel.h" #include "previewloader.h" -#include "multilangmgr.h" #include "threadutils.h" + #include "../rtengine/noncopyable.h" class FilePanel; +class CoarsePanel; +class ToolBar; + /* * Class: * - handling the list of file (add/remove them) @@ -288,5 +290,3 @@ inline void FileCatalog::setDirSelector (const FileCatalog::DirSelectionSlot& se { this->selectDir = selectDir; } - -#endif diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index 3e23cbc5d..1a66aed7c 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -18,9 +18,17 @@ */ #include "filepanel.h" +#include "dirbrowser.h" +#include "batchtoolpanelcoord.h" +#include "editorpanel.h" #include "rtwindow.h" #include "inspector.h" #include "placesbrowser.h" +#include "thumbnail.h" + +#ifdef WIN32 +#include "windows.h" +#endif FilePanel::FilePanel () : parent(nullptr), error(0) { diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index bdeb266f4..cbfe8e53e 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -16,24 +16,25 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILEPANEL_ -#define _FILEPANEL_ +#pragma once #include -#include "batchtoolpanelcoord.h" -#include "filecatalog.h" -#include "dirbrowser.h" -#include "fileselectionlistener.h" -#include "placesbrowser.h" -#include "recentbrowser.h" -#include "pparamschangelistener.h" -#include "history.h" -#include "filterpanel.h" + #include "exportpanel.h" +#include "filecatalog.h" +#include "fileselectionlistener.h" +#include "filterpanel.h" +#include "history.h" +#include "placesbrowser.h" +#include "pparamschangelistener.h" #include "progressconnector.h" +#include "recentbrowser.h" + #include "../rtengine/noncopyable.h" +class BatchToolPanelCoordinator; class RTWindow; +class DirBrowser; class FilePanel final : public Gtk::HPaned, @@ -108,6 +109,3 @@ private: IdleRegister idle_register; }; - -#endif - diff --git a/rtgui/fileselectionchangelistener.h b/rtgui/fileselectionchangelistener.h index 1f3b8e612..64251c1bd 100644 --- a/rtgui/fileselectionchangelistener.h +++ b/rtgui/fileselectionchangelistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILESELECTIONCHANGELISTENER_ -#define _FILESELECTIONCHANGELISTENER_ +#pragma once class Thumbnail; @@ -27,6 +26,3 @@ public: virtual ~FileSelectionChangeListener() = default; virtual void selectionChanged(const std::vector& selected) = 0; }; - -#endif - diff --git a/rtgui/fileselectionlistener.h b/rtgui/fileselectionlistener.h index a7f7fb284..394a35f51 100644 --- a/rtgui/fileselectionlistener.h +++ b/rtgui/fileselectionlistener.h @@ -16,11 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILESELECTIONLISTENER_ -#define _FILESELECTIONLISTENER_ +#pragma once -class Thumbnail; class BatchQueueEntry; +class Thumbnail; class FileSelectionListener { @@ -29,6 +28,3 @@ public: virtual bool fileSelected(Thumbnail* thm) = 0; virtual bool addBatchQueueJobs(const std::vector& entries) = 0; }; - -#endif - diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc index ef497a535..bb64675a1 100644 --- a/rtgui/filethumbnailbuttonset.cc +++ b/rtgui/filethumbnailbuttonset.cc @@ -20,6 +20,8 @@ #include "rtimage.h" #include "multilangmgr.h" +#include "lwbutton.h" +#include "rtsurface.h" bool FileThumbnailButtonSet::iconsLoaded = false; diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index 102b573c8..868d3b58a 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -16,18 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILETHUMBNAILBUTTONSET_ -#define _FILETHUMBNAILBUTTONSET_ +#pragma once #include -#include "lwbuttonset.h" #include -#include "filebrowserentry.h" -#include "rtsurface.h" + +#include "lwbuttonset.h" class FileBrowserEntry; -class FileThumbnailButtonSet : public LWButtonSet +class RTSurface; + +class FileThumbnailButtonSet : + public LWButtonSet { static bool iconsLoaded; @@ -55,5 +56,3 @@ public: void setInTrash (bool inTrash); }; - -#endif diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 1439a759b..f8e552100 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -26,7 +26,6 @@ #include "editcallbacks.h" #include "guiutils.h" #include "toolpanel.h" -#include "wbprovider.h" class FilmNegProvider { @@ -36,7 +35,7 @@ public: virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; }; -class FilmNegative : +class FilmNegative final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/filmsimulation.h b/rtgui/filmsimulation.h index b5c9ffa6b..cfe7016bb 100644 --- a/rtgui/filmsimulation.h +++ b/rtgui/filmsimulation.h @@ -1,14 +1,17 @@ -#ifndef FILM_SIMULATION_INCLUDED -#define FILM_SIMULATION_INCLUDED +#pragma once + +#include #include -#include -#include -#include "toolpanel.h" -#include "guiutils.h" -#include "adjuster.h" -class ClutComboBox : public MyComboBox +#include + +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" + +class ClutComboBox final : + public MyComboBox { public: explicit ClutComboBox(const Glib::ustring &path); @@ -74,5 +77,3 @@ private: Adjuster *m_strength; }; - -#endif diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h index e6e41a416..25a368b27 100644 --- a/rtgui/filterpanel.h +++ b/rtgui/filterpanel.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FILTERPANEL_ -#define _FILTERPANEL_ +#pragma once #include + #include "exiffiltersettings.h" class FilterPanelListener @@ -79,5 +79,3 @@ public: enabled->set_active(enabledState); } }; - -#endif diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 6dc3a1f5b..4e0591ac3 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -32,6 +32,8 @@ #include "curveeditor.h" #include "flatcurveeditorsubgroup.h" #include "rtimage.h" +#include "options.h" +#include "popuptogglebutton.h" #include "../rtengine/curves.h" diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index e9253cd08..c358dde3b 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -16,16 +16,20 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FLATCURVEEDITORSUBGROUP_ -#define _FLATCURVEEDITORSUBGROUP_ +#pragma once #include + #include "curveeditorgroup.h" + #include "../rtengine/noncopyable.h" class FlatCurveEditor; +class MyFlatCurve; -class FlatCurveEditorSubGroup: public CurveEditorSubGroup, public rtengine::NonCopyable +class FlatCurveEditorSubGroup: + public CurveEditorSubGroup, + public rtengine::NonCopyable { friend class FlatCurveEditor; @@ -76,5 +80,3 @@ protected: void editPointToggled(Gtk::ToggleButton *button); void editToggled (Gtk::ToggleButton *button); }; - -#endif diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 03204c037..7433fd4de 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -25,6 +25,7 @@ #include "rtimage.h" #include "../rtengine/procparams.h" +#include "../rtengine/rawimage.h" using namespace rtengine; using namespace rtengine::procparams; @@ -32,18 +33,17 @@ using namespace rtengine::procparams; FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL")) { hbff = Gtk::manage(new Gtk::HBox()); - hbff->set_spacing(2); flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); bindCurrentFolder (*flatFieldFile, options.lastFlatfieldDir); ffLabel = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); flatFieldFileReset = Gtk::manage(new Gtk::Button()); flatFieldFileReset->set_image (*Gtk::manage(new RTImage ("cancel-small.png"))); - hbff->pack_start(*ffLabel, Gtk::PACK_SHRINK, 0); + hbff->pack_start(*ffLabel, Gtk::PACK_SHRINK); hbff->pack_start(*flatFieldFile); - hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK, 0); + hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK); flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_FLATFIELD_AUTOSELECT")))); - ffInfo = Gtk::manage(new Gtk::Label("")); - ffInfo->set_alignment(0, 0); //left align + ffInfo = Gtk::manage(new Gtk::Label("-")); + setExpandAlignProperties(ffInfo, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); flatFieldBlurRadius = Gtk::manage(new Adjuster (M("TP_FLATFIELD_BLURRADIUS"), 0, 200, 2, 32)); flatFieldBlurRadius->setAdjusterListener (this); @@ -54,15 +54,14 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L flatFieldBlurRadius->show(); Gtk::HBox* hbffbt = Gtk::manage (new Gtk::HBox ()); - hbffbt->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_FLATFIELD_BLURTYPE") + ":"))); - hbffbt->set_spacing(4); + hbffbt->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_FLATFIELD_BLURTYPE") + ":")), Gtk::PACK_SHRINK); flatFieldBlurType = Gtk::manage (new MyComboBoxText ()); flatFieldBlurType->append(M("TP_FLATFIELD_BT_AREA")); flatFieldBlurType->append(M("TP_FLATFIELD_BT_VERTICAL")); flatFieldBlurType->append(M("TP_FLATFIELD_BT_HORIZONTAL")); flatFieldBlurType->append(M("TP_FLATFIELD_BT_VERTHORIZ")); flatFieldBlurType->set_active(0); - hbffbt->pack_end (*flatFieldBlurType); + hbffbt->pack_end (*flatFieldBlurType, Gtk::PACK_EXPAND_WIDGET); flatFieldClipControl = Gtk::manage (new Adjuster(M("TP_FLATFIELD_CLIPCONTROL"), 0., 100., 1., 0.)); flatFieldClipControl->setAdjusterListener(this); @@ -75,12 +74,12 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L flatFieldClipControl->show(); flatFieldClipControl->set_tooltip_markup (M("TP_FLATFIELD_CLIPCONTROL_TOOLTIP")); - pack_start( *hbff, Gtk::PACK_SHRINK, 0); - pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK, 0); - pack_start( *ffInfo, Gtk::PACK_SHRINK, 0); - pack_start( *hbffbt, Gtk::PACK_SHRINK, 0); - pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK, 0); - pack_start( *flatFieldClipControl, Gtk::PACK_SHRINK, 0); + pack_start( *hbff, Gtk::PACK_SHRINK); + pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK); + pack_start( *ffInfo, Gtk::PACK_SHRINK); + pack_start( *hbffbt, Gtk::PACK_SHRINK); + pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK); + pack_start( *flatFieldClipControl, Gtk::PACK_SHRINK); flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &FlatField::flatFieldFileChanged)); //, true); flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &FlatField::flatFieldFile_Reset), true ); @@ -169,7 +168,7 @@ void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); } } else { - ffInfo->set_text(""); + ffInfo->set_text("-"); } ffChanged = false; @@ -253,7 +252,7 @@ void FlatField::adjusterChanged(Adjuster* a, double newval) } } -void FlatField::adjusterAutoToggled (Adjuster* a, bool newval) +void FlatField::adjusterAutoToggled (Adjuster* a) { if (multiImage) { if (flatFieldClipControl->getAutoInconsistent()) { @@ -334,7 +333,7 @@ void FlatField::flatFieldFile_Reset() flatFieldFile->set_current_folder(options.lastFlatfieldDir); } - ffInfo->set_text(""); + ffInfo->set_text("-"); if (listener) { listener->panelChanged (EvFlatFieldFile, M("GENERAL_NONE") ); @@ -384,7 +383,7 @@ void FlatField::flatFieldAutoSelectChanged() ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); } } else { - ffInfo->set_text(""); + ffInfo->set_text("-"); } if (listener) { diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index b9997f65e..5cbc49684 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -16,15 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _FLATFIELD_H_ -#define _FLATFIELD_H_ +#pragma once #include + #include + #include "adjuster.h" -#include "toolpanel.h" -#include "../rtengine/rawimage.h" #include "guiutils.h" +#include "toolpanel.h" + +namespace rtengine +{ + +class RawImage; + +} class FFProvider { @@ -35,7 +42,7 @@ public: // add other info here }; -class FlatField : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener +class FlatField final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener { protected: @@ -72,7 +79,7 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; + void adjusterAutoToggled (Adjuster* a) override; void flatFieldFileChanged (); void flatFieldFile_Reset (); void flatFieldAutoSelectChanged (); @@ -84,5 +91,3 @@ public: }; void flatFieldAutoClipValueChanged(int n = 0) override; }; - -#endif diff --git a/rtgui/gradient.h b/rtgui/gradient.h index 3b8a18f97..2e126aaca 100644 --- a/rtgui/gradient.h +++ b/rtgui/gradient.h @@ -1,16 +1,20 @@ /* * This file is part of RawTherapee. */ -#ifndef _GRADIENT_H_ -#define _GRADIENT_H_ +#pragma once #include + #include "adjuster.h" #include "editcallbacks.h" -#include "toolpanel.h" #include "guiutils.h" +#include "toolpanel.h" -class Gradient : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber +class Gradient final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public EditSubscriber { private: @@ -58,5 +62,3 @@ public: bool drag1(int modifierKey) override; void switchOffEditMode () override; }; - -#endif diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 189cf6178..02a28607f 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -217,16 +217,6 @@ bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference) } } -void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) -{ - - if (options.thumbInterp == 0) { - rtengine::nearestInterp (src, sw, sh, dst, dw, dh); - } else if (options.thumbInterp == 1) { - rtengine::bilinearInterp (src, sw, sh, dst, dw, dh); - } -} - bool confirmOverwrite (Gtk::Window& parent, const std::string& filename) { bool safe = true; @@ -956,22 +946,21 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) const double lowerBound = adjust->get_lower(); double value = adjust->get_value(); double step = adjust->get_step_increment(); - double value2 = 0.; if (event->direction == GDK_SCROLL_DOWN) { - value2 = rtengine::min(value + step, upperBound); + const double value2 = rtengine::min(value + step, upperBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_UP) { - value2 = rtengine::max(value - step, lowerBound); + const double value2 = rtengine::max(value - step, lowerBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { - value2 = rtengine::LIM(value + event->delta_y * step, lowerBound, upperBound); + const double value2 = rtengine::LIM(value + event->delta_y * step, lowerBound, upperBound); if (value2 != value) { scroll->set_value(value2); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index b09e20abb..97c72513b 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __GUI_UTILS_ -#define __GUI_UTILS_ +#pragma once #include #include @@ -26,19 +25,29 @@ #include +#include "threadutils.h" + #include "../rtengine/coord.h" #include "../rtengine/noncopyable.h" -#include "../rtengine/rtengine.h" -#include "rtimage.h" +namespace rtengine +{ -// for convenience... -#include "pathutils.h" +namespace procparams +{ +class ProcParams; + +struct CropParams; + +} + +} + +class RTImage; Glib::ustring escapeHtmlChars(const Glib::ustring &src); bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference = true); -void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); bool confirmOverwrite (Gtk::Window& parent, const std::string& filename); void writeFailed (Gtk::Window& parent, const std::string& filename); void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide = true, bool useBgColor = true, bool fullImageVisible = true); @@ -644,5 +653,3 @@ inline Gtk::Window& getToplevelWindow (Gtk::Widget* widget) { return *static_cast (widget->get_toplevel ()); } - -#endif diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 36803ddf2..dd0cbde46 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -24,15 +24,10 @@ #include #include "../rtengine/LUT.h" #include "rtimage.h" -#include "../rtengine/improccoordinator.h" #include "../rtengine/color.h" -#include "../rtengine/opthelper.h" -#include "../rtengine/iccstore.h" using namespace rtengine; -extern Options options; - // // @@ -988,7 +983,7 @@ void HistogramArea::on_realize () } void HistogramArea::drawCurve(Cairo::RefPtr &cr, - LUTu & data, double scale, int hsize, int vsize) + const LUTu & data, double scale, int hsize, int vsize) { double s = RTScalable::getScale(); @@ -1018,7 +1013,7 @@ void HistogramArea::drawCurve(Cairo::RefPtr &cr, } void HistogramArea::drawMarks(Cairo::RefPtr &cr, - LUTu & data, double scale, int hsize, int & ui, int & oi) + const LUTu & data, double scale, int hsize, int & ui, int & oi) { int s = 8 * RTScalable::getScale(); diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index 1515db97a..4fd21bcc2 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -16,21 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _HISTOGRAMPANEL_ -#define _HISTOGRAMPANEL_ - +#pragma once #include -#include -#include -#include "../rtengine/LUT.h" -#include "../rtengine/improccoordinator.h" -#include "guiutils.h" +#include + +#include + +#include "guiutils.h" #include "pointermotionlistener.h" + +#include "../rtengine/LUT.h" #include "../rtengine/noncopyable.h" class HistogramArea; + struct HistogramAreaIdleHelper { HistogramArea* harea; bool destroyed; @@ -164,8 +165,8 @@ public: type_signal_factor_changed signal_factor_changed(); private: - void drawCurve(Cairo::RefPtr &cr, LUTu & data, double scale, int hsize, int vsize); - void drawMarks(Cairo::RefPtr &cr, LUTu & data, double scale, int hsize, int & ui, int & oi); + void drawCurve(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int vsize); + void drawMarks(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi); Gtk::SizeRequestMode get_request_mode_vfunc () const override; void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; @@ -252,5 +253,3 @@ public: // drawModeListener interface void toggleButtonMode () override; }; - -#endif diff --git a/rtgui/history.h b/rtgui/history.h index abf0d1ba5..faebe4765 100644 --- a/rtgui/history.h +++ b/rtgui/history.h @@ -16,14 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _HISTORY_ -#define _HISTORY_ +#pragma once #include -#include "../rtengine/rtengine.h" + +#include "paramsedited.h" #include "pparamschangelistener.h" #include "profilechangelistener.h" -#include "paramsedited.h" + +#include "../rtengine/rtengine.h" class HistoryBeforeLineListener { @@ -135,5 +136,3 @@ public: bmnum = 1; }; }; - -#endif diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index b6b5b04f2..ee3eb90a7 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -18,6 +18,10 @@ */ #include "hsvequalizer.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "options.h" + #include "../rtengine/color.h" #include "../rtengine/procparams.h" diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h index 2ffa9fa0f..77c1ee1b0 100644 --- a/rtgui/hsvequalizer.h +++ b/rtgui/hsvequalizer.h @@ -16,20 +16,24 @@ * * 2010 Ilya Popov */ - -#ifndef HSVEQUALIZER_H_INCLUDED -#define HSVEQUALIZER_H_INCLUDED +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" + #include "colorprovider.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" +class CurveEditor; +class CurveEditorGroup; +class FlatCurveEditor; -class HSVEqualizer : public ToolParamBlock, public FoldableToolPanel, public CurveListener, public ColorProvider +class HSVEqualizer final : + public ToolParamBlock, + public FoldableToolPanel, + public CurveListener, + public ColorProvider { protected: @@ -53,8 +57,5 @@ public: void autoOpenCurve () override; void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; - //void adjusterChanged (Adjuster* a, double newval); void enabledChanged() override; }; - -#endif diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 9efa4360b..a8f9be007 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -17,25 +17,20 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include +#include + #include #include "iccprofilecreator.h" +#include "../rtengine/iccstore.h" #include "multilangmgr.h" #include "cachemanager.h" -#include "addsetids.h" #include "../rtengine/color.h" +#include "options.h" +#include "pathutils.h" #include "rtimage.h" -#ifdef _OPENMP -#include -#endif - -extern Options options; - -namespace rtengine -{ - -extern const Settings* settings; - -} +#include "rtwindow.h" const char* sTRCPreset[] = {"BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "linear_g1.0", "standard_g2.2", "standard_g1.8", "High_g1.3_s3.35", "Low_g2.6_s6.9", "Lab_g3.0s9.03296"}; //gamma free diff --git a/rtgui/iccprofilecreator.h b/rtgui/iccprofilecreator.h index b28ac29f2..2cd19e14f 100644 --- a/rtgui/iccprofilecreator.h +++ b/rtgui/iccprofilecreator.h @@ -19,11 +19,13 @@ */ #pragma once +#include + #include #include "adjuster.h" -#include "options.h" #include -#include "rtwindow.h" + +class RTWindow; class ICCProfileCreator : public Gtk::Dialog, public AdjusterListener { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 012aeca78..3e3c0508c 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -23,6 +23,7 @@ #include "eventmapper.h" #include "guiutils.h" #include "options.h" +#include "pathutils.h" #include "rtimage.h" #include "../rtengine/dcp.h" @@ -32,8 +33,6 @@ using namespace rtengine; using namespace rtengine::procparams; -extern Options options; - ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr) { auto m = ProcEventMapper::getInstance(); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 9b4706ecd..cc46c5d37 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -16,16 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ICMPANEL_ -#define _ICMPANEL_ +#pragma once #include + #include + #include "adjuster.h" #include "guiutils.h" - -#include "toolpanel.h" #include "popupbutton.h" +#include "toolpanel.h" + #include "../rtengine/imagedata.h" class ICMPanelListener @@ -35,7 +36,7 @@ public: virtual void saveInputICCReference(const Glib::ustring& fname, bool apply_wb) = 0; }; -class ICMPanel : +class ICMPanel final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel @@ -148,5 +149,3 @@ public: icmplistener = ipl; } }; - -#endif diff --git a/rtgui/ilabel.cc b/rtgui/ilabel.cc deleted file mode 100644 index 9dfd50b89..000000000 --- a/rtgui/ilabel.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include "ilabel.h" - -ILabel::ILabel (const Glib::ustring &lab) : label(lab) {} - -void ILabel::on_realize() -{ - - Gtk::DrawingArea::on_realize(); - add_events(Gdk::EXPOSURE_MASK); - - Glib::RefPtr fn = create_pango_layout(label); - fn->set_markup (label); - int labw, labh; - fn->get_pixel_size (labw, labh); - set_size_request (2 + labw, 2 + labh); -} - -bool ILabel::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) -{ - - Glib::RefPtr style = get_style_context (); - - Gtk::StateFlags state = get_state_flags(); - Gdk::RGBA c = style->get_background_color(state); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle (0, 0, get_width (), get_height()); - cr->fill (); - - Glib::RefPtr fn = create_pango_layout (label); - fn->set_markup (label); - cr->move_to(1., 1.); - fn->add_to_cairo_context(cr); - c = style->get_color (state); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->fill(); - - return true; -} - -void ILabel::on_style_updated () -{ - - Glib::RefPtr fn = create_pango_layout(label); - fn->set_markup (label); - int labw, labh; - fn->get_pixel_size (labw, labh); - set_size_request (2 + labw, 2 + labh); -} diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index b086f8baf..0be6982f9 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -25,6 +25,7 @@ #include "../rtengine/refreshmap.h" #include "../rtengine/procparams.h" #include "options.h" +#include "rtscalable.h" ImageArea::ImageArea (ImageAreaPanel* p) : parent(p), fullImageWidth(0), fullImageHeight(0) { diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h index 375e3a536..28b52dcd2 100644 --- a/rtgui/imagearea.h +++ b/rtgui/imagearea.h @@ -16,24 +16,29 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __IMAGEAREA_H__ -#define __IMAGEAREA_H__ +#pragma once #include + #include "cropguilistener.h" -#include "imageareapanel.h" -#include "editenums.h" -#include "toolbar.h" -#include "previewhandler.h" -#include "imageareatoollistener.h" #include "cropwindow.h" #include "editcallbacks.h" -#include "zoompanel.h" +#include "editenums.h" +#include "imageareapanel.h" +#include "imageareatoollistener.h" #include "indclippedpanel.h" +#include "previewhandler.h" #include "previewmodepanel.h" +#include "toolbar.h" +#include "zoompanel.h" class ImageAreaPanel; -class ImageArea : public Gtk::DrawingArea, public CropWindowListener, public EditDataProvider, public LockablePickerToolListener + +class ImageArea : + public Gtk::DrawingArea, + public CropWindowListener, + public EditDataProvider, + public LockablePickerToolListener { friend class ZoomPanel; @@ -158,7 +163,3 @@ public: return mainCropWindow; } }; - - - -#endif diff --git a/rtgui/imageareapanel.h b/rtgui/imageareapanel.h index 4ec3ffcf3..831371dbb 100644 --- a/rtgui/imageareapanel.h +++ b/rtgui/imageareapanel.h @@ -16,13 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGEAREAPANEL_ -#define _IMAGEAREAPANEL_ +#pragma once #include "imagearea.h" class ImageArea; -class ImageAreaPanel : public Gtk::VBox + +class ImageAreaPanel : + public Gtk::VBox { protected: @@ -42,5 +43,3 @@ public: void setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft); void syncBeforeAfterViews(); }; - -#endif diff --git a/rtgui/imageareatoollistener.h b/rtgui/imageareatoollistener.h index d387b595c..b022aa4b7 100644 --- a/rtgui/imageareatoollistener.h +++ b/rtgui/imageareatoollistener.h @@ -16,13 +16,11 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGEAREATOOLLISTENER_ -#define _IMAGEAREATOOLLISTENER_ - -#include "toolbar.h" -#include "thumbnail.h" -#include "cropguilistener.h" +#pragma once +class CropGUIListener; +class Thumbnail; +class ToolBar; class ImageAreaToolListener { @@ -36,6 +34,3 @@ public: virtual ToolBar* getToolBar() const = 0; virtual CropGUIListener* startCropEditing(Thumbnail* thm = nullptr) = 0; }; - -#endif - diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h index 1ebdc430b..b8acafcfc 100644 --- a/rtgui/impulsedenoise.h +++ b/rtgui/impulsedenoise.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMPULSEDENOISE_H_ -#define _IMPULSEDENOISE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class ImpulseDenoise : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class ImpulseDenoise final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -45,5 +48,3 @@ public: void setAdjusterBehavior (bool threshadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h index 54476af10..1017b58f1 100644 --- a/rtgui/indclippedpanel.h +++ b/rtgui/indclippedpanel.h @@ -15,14 +15,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _INDCLIPPEDPANEL_ -#define _INDCLIPPEDPANEL_ +#pragma once -#include #include +#include + class ImageArea; -class IndicateClippedPanel : public Gtk::HBox + +class IndicateClippedPanel : + public Gtk::HBox { protected: @@ -59,5 +61,3 @@ public: return indClippedH->get_active(); } }; - -#endif diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 8bd9862a7..9002cc389 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -22,9 +22,10 @@ #include "cursormanager.h" #include "guiutils.h" #include "options.h" +#include "pathutils.h" +#include "rtscalable.h" #include "../rtengine/previewimage.h" - -extern Options options; +#include "../rtengine/rt_math.h" InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform(0), fromRaw(false) { diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 681b90aa3..8338259bf 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -16,12 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _INSPECTOR_ -#define _INSPECTOR_ +#pragma once #include + #include "guiutils.h" + #include "../rtengine/coord.h" +#include "../rtengine/coord2d.h" class InspectorBuffer { @@ -99,5 +101,3 @@ public: void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; }; - -#endif diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h index 0317314a1..15d117f87 100644 --- a/rtgui/iptcpanel.h +++ b/rtgui/iptcpanel.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IPTCPANEL_ -#define _IPTCPANEL_ +#pragma once #include @@ -26,7 +25,9 @@ #include "guiutils.h" #include "toolpanel.h" -class IPTCPanel : public Gtk::VBox, public ToolPanel +class IPTCPanel : + public Gtk::VBox, + public ToolPanel { private: @@ -92,5 +93,3 @@ public: void copyClicked (); void pasteClicked (); }; - -#endif diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index 237f9ea9b..491b02c4c 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -20,6 +20,11 @@ #include "labcurve.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "options.h" + +#include "../rtengine/color.h" #include "../rtengine/improcfun.h" #include "../rtengine/procparams.h" #include "editcallbacks.h" diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index 51ba0fdd6..e8488a8c6 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -16,19 +16,26 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LABCURVE_H_ -#define _LABCURVE_H_ +#pragma once #include + #include "adjuster.h" -#include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" #include "colorprovider.h" +#include "curvelistener.h" +#include "toolpanel.h" +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; +class FlatCurveEditor; -class LCurve : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider +class LCurve final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public CurveListener, + public ColorProvider { protected: @@ -97,5 +104,3 @@ public: void enabledChanged() override; }; - -#endif diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index 5ed2cbd0f..1a5d69f69 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -39,7 +39,9 @@ #include "labgrid.h" #include "options.h" +#include "../rtengine/color.h" #include "options.h" +#include "rtimage.h" using rtengine::Color; diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index 227b4cacc..4693c897c 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -43,7 +43,7 @@ #include "toolpanel.h" -class LabGridArea: public Gtk::DrawingArea, public BackBuffer { +class LabGridArea final : public Gtk::DrawingArea, public BackBuffer { private: rtengine::ProcEvent evt; Glib::ustring evtMsg; diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index 06b8e5689..18b31a619 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -16,14 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LENSGEOM_H_ -#define _LENSGEOM_H_ +#pragma once #include -#include "toolpanel.h" -#include "lensgeomlistener.h" -class LensGeometry : public ToolParamBlock, public FoldableToolPanel +#include "lensgeomlistener.h" +#include "toolpanel.h" + +class LensGeometry final : + public ToolParamBlock, + public FoldableToolPanel { protected: @@ -58,5 +60,3 @@ public: private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/lensgeomlistener.h b/rtgui/lensgeomlistener.h index dbe58f1fa..7bfa0fb45 100644 --- a/rtgui/lensgeomlistener.h +++ b/rtgui/lensgeomlistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LENSGEOMLISTENER_H_ -#define _LENSGEOMLISTENER_H_ +#pragma once class LensGeomListener { @@ -27,5 +26,3 @@ public: virtual void autoCropRequested () = 0; virtual double autoDistorRequested () = 0; }; - -#endif diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 389f15461..be21512d5 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -18,9 +18,10 @@ */ #include #include +#include #include -#include +#include #include "lensprofile.h" @@ -586,7 +587,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) LensProfilePanel::LFDbHelper::LFDbHelper() { #ifdef _OPENMP -#pragma omp parallel sections if (!options.rtSettings.verbose) +#pragma omp parallel sections if (!settings->verbose) #endif { #ifdef _OPENMP @@ -608,7 +609,7 @@ LensProfilePanel::LFDbHelper::LFDbHelper() void LensProfilePanel::LFDbHelper::fillLensfunCameras() { - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "LENSFUN, scanning cameras:" << std::endl; } @@ -618,7 +619,7 @@ void LensProfilePanel::LFDbHelper::fillLensfunCameras() for (const auto& c : camlist) { camnames[c.getMake()].insert(c.getModel()); - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << " found: " << c.getDisplayString().c_str() << std::endl; } } @@ -638,7 +639,7 @@ void LensProfilePanel::LFDbHelper::fillLensfunCameras() void LensProfilePanel::LFDbHelper::fillLensfunLenses() { - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << "LENSFUN, scanning lenses:" << std::endl; } @@ -650,7 +651,7 @@ void LensProfilePanel::LFDbHelper::fillLensfunLenses() const auto& make = l.getMake(); lenses[make].insert(name); - if (options.rtSettings.verbose) { + if (settings->verbose) { std::cout << " found: " << l.getDisplayString().c_str() << std::endl; } } @@ -760,7 +761,7 @@ bool LensProfilePanel::checkLensfunCanCorrect(bool automatch) rtengine::procparams::ProcParams lpp; write(&lpp); - const std::unique_ptr mod(LFDatabase::findModifier(lpp.lensProf, metadata, 100, 100, lpp.coarse, -1)); + const std::unique_ptr mod(LFDatabase::getInstance()->findModifier(lpp.lensProf, metadata, 100, 100, lpp.coarse, -1)); return static_cast(mod); } diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 7e740e26e..7b5b7343c 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -21,7 +21,6 @@ #include #include "guiutils.h" -#include "lensgeom.h" #include "toolpanel.h" class LensProfilePanel final : diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h index b23bac697..d1d25fb3d 100644 --- a/rtgui/localcontrast.h +++ b/rtgui/localcontrast.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class LocalContrast: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class LocalContrast final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *radius; diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index ef16df6ec..071847424 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -21,12 +21,11 @@ #include "options.h" #include "../rtengine/color.h" #include "../rtengine/rt_math.h" +#include "../rtengine/utils.h" #include "imagearea.h" #include "multilangmgr.h" #include "navigator.h" -extern Options options; - LockableColorPicker::LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile) : cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(0, 0), size(Size::S15), outputProfile(oProfile), workingProfile(wProfile), validity(Validity::OUTSIDE), @@ -241,7 +240,7 @@ void LockableColorPicker::updateBackBuffer () } -void LockableColorPicker::draw (Cairo::RefPtr &cr) +void LockableColorPicker::draw (const Cairo::RefPtr &cr) { if (validity == Validity::OUTSIDE) { return; @@ -285,12 +284,12 @@ void LockableColorPicker::setRGB (const float R, const float G, const float B, c } } -void LockableColorPicker::getImagePosition (rtengine::Coord &imgPos) +void LockableColorPicker::getImagePosition (rtengine::Coord &imgPos) const { imgPos = position; } -void LockableColorPicker::getScreenPosition (rtengine::Coord &screenPos) +void LockableColorPicker::getScreenPosition (rtengine::Coord &screenPos) const { if (cropWindow) { cropWindow->imageCoordToScreen(position.x, position.y, screenPos.x, screenPos.y); @@ -329,7 +328,7 @@ void LockableColorPicker::setSize (Size newSize) } } -LockableColorPicker::Size LockableColorPicker::getSize () +LockableColorPicker::Size LockableColorPicker::getSize () const { return size; } diff --git a/rtgui/lockablecolorpicker.h b/rtgui/lockablecolorpicker.h index f1a63d533..77d2e8e9f 100644 --- a/rtgui/lockablecolorpicker.h +++ b/rtgui/lockablecolorpicker.h @@ -16,13 +16,11 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#pragma once -#ifndef __COLORPICKER__ -#define __COLORPICKER__ - +#include "guiutils.h" #include "../rtengine/coord.h" -#include "guiutils.h" class CropWindow; @@ -76,14 +74,14 @@ public: LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile); - void draw (Cairo::RefPtr &cr); + void draw (const Cairo::RefPtr &cr); // Used to update the RGB color, the HSV values will be updated accordingly void setPosition (const rtengine::Coord &newPos); void setRGB (const float R, const float G, const float B, const float previewR, const float previewG, const float previewB); - void getImagePosition (rtengine::Coord &imgPos); - void getScreenPosition (rtengine::Coord &screenPos); - Size getSize (); + void getImagePosition (rtengine::Coord &imgPos) const; + void getScreenPosition (rtengine::Coord &screenPos) const; + Size getSize () const; bool isOver (int x, int y); void setValidity (Validity isValid); void setSize (Size newSize); @@ -93,5 +91,3 @@ public: bool cycleRGB (); bool cycleHSV (); }; - -#endif diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index b5c10c532..26d36f9e0 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -18,6 +18,7 @@ */ #include "lwbutton.h" #include "guiutils.h" +#include "rtsurface.h" LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring* tooltip) : xpos(0), ypos(0), halign(ha), valign(va), icon(i), bgr(0.0), bgg(0.0), bgb(0.0), fgr(0.0), fgg(0.0), fgb(0.0), state(Normal), listener(nullptr), actionCode(aCode), actionData(aData), toolTip(tooltip) @@ -152,7 +153,7 @@ bool LWButton::releaseNotify (int x, int y) { bool in = inside (x, y); - State nstate = state; + State nstate; bool action = false; if (in && (state == Pressed_In || state == Pressed_Out)) { diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h index 16e53a875..a98f1fe46 100644 --- a/rtgui/lwbutton.h +++ b/rtgui/lwbutton.h @@ -16,12 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LWBUTTON_ -#define _LWBUTTON_ +#pragma once #include #include "rtsurface.h" - class LWButton; class LWButtonListener @@ -78,5 +76,3 @@ public: void redraw (Cairo::RefPtr context); }; - -#endif diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc index a03b3064b..f475cf0b3 100644 --- a/rtgui/lwbuttonset.cc +++ b/rtgui/lwbuttonset.cc @@ -17,6 +17,8 @@ * along with RawTherapee. If not, see . */ #include "lwbuttonset.h" +#include "lwbutton.h" +#include "rtscalable.h" LWButtonSet::LWButtonSet () : aw(0), ah(0), ax(-1), ay(-1) { diff --git a/rtgui/lwbuttonset.h b/rtgui/lwbuttonset.h index 07d17a135..63bc5a01b 100644 --- a/rtgui/lwbuttonset.h +++ b/rtgui/lwbuttonset.h @@ -19,9 +19,10 @@ #pragma once #include -#include "lwbutton.h" #include +class LWButton; +class LWButtonListener; class LWButtonSet { diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 09aab1cff..c60cba070 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -33,6 +33,7 @@ #include #include "../rtengine/procparams.h" #include "../rtengine/profilestore.h" +#include "../rtengine/rtengine.h" #include "options.h" #include "soundman.h" #include "rtimage.h" @@ -55,8 +56,6 @@ // Set this to 1 to make RT work when started with Eclipse and arguments, at least on Windows platform #define ECLIPSE_ARGS 0 -extern Options options; - // stores path to data files Glib::ustring argv0; Glib::ustring creditsPath; diff --git a/rtgui/main.cc b/rtgui/main.cc index 098963e0e..f669bcf4a 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -33,12 +33,17 @@ #include #include #include +#include "cachemanager.h" +#include "editorpanel.h" +#include "filecatalog.h" +#include "filepanel.h" #include "options.h" #include "soundman.h" #include "rtimage.h" #include "version.h" #include "extprog.h" #include "../rtengine/dynamicprofile.h" +#include "../rtengine/procparams.h" #ifndef WIN32 #include @@ -48,13 +53,12 @@ #else #include #include "conio.h" +#include "windows.h" #endif // Set this to 1 to make RT work when started with Eclipse and arguments, at least on Windows platform #define ECLIPSE_ARGS 0 -extern Options options; - // stores path to data files Glib::ustring argv0; Glib::ustring creditsPath; @@ -220,7 +224,7 @@ bool init_rt() extProgStore->init(); SoundManager::init(); - if ( !options.rtSettings.verbose ) { + if (!rtengine::settings->verbose) { TIFFSetWarningHandler (nullptr); // avoid annoying message boxes } @@ -529,13 +533,13 @@ int main (int argc, char **argv) int ret = 0; if (options.pseudoHiDPISupport) { - // Reading/updating GDK_SCALE early if it exists - const gchar *gscale = g_getenv("GDK_SCALE"); - if (gscale && gscale[0] == '2') { - initialGdkScale = 2; - } - // HOMBRE: On Windows, if resolution is set to 200%, Gtk internal variables are SCALE=2 and DPI=96 - g_setenv("GDK_SCALE", "1", true); + // Reading/updating GDK_SCALE early if it exists + const gchar *gscale = g_getenv("GDK_SCALE"); + if (gscale && gscale[0] == '2') { + initialGdkScale = 2; + } + // HOMBRE: On Windows, if resolution is set to 200%, Gtk internal variables are SCALE=2 and DPI=96 + g_setenv("GDK_SCALE", "1", true); } gdk_threads_set_lock_functions (G_CALLBACK (myGdkLockEnter), (G_CALLBACK (myGdkLockLeave))); diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index 0c76b4c01..902161eb2 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MULTILANGMGR_ -#define _MULTILANGMGR_ +#pragma once #include #include @@ -45,5 +44,3 @@ inline Glib::ustring M (const std::string& key) { return langMgr.getStr (key); } - -#endif diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 6c00e3f56..7401570c8 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -20,6 +20,7 @@ #include "../rtengine/curves.h" #include #include +#include "rtscalable.h" MyCurve::MyCurve () : pipetteR(-1.f), diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 62d8d30f2..6bdfe4b66 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -16,18 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYCURVE_ -#define _MYCURVE_ +#pragma once + +#include #include -#include -#include "curvelistener.h" -#include "cursormanager.h" + #include "coloredbar.h" #include "coordinateadjuster.h" +#include "cursormanager.h" +#include "curvelistener.h" + #include "../rtengine/LUT.h" -#include "guiutils.h" -#include "options.h" #include "../rtengine/noncopyable.h" #define RADIUS 3.5 /** radius of the control points ; must be x.5 to target the center of a pixel */ @@ -55,6 +55,7 @@ enum SnapToType { class MyCurveIdleHelper; class CurveEditor; +class EditDataProvider; class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable { @@ -152,5 +153,3 @@ public: myCurve->setDirty(true); } }; - -#endif diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index d393c7200..abd339ce0 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -23,6 +23,7 @@ #include "mydiagonalcurve.h" #include "editcallbacks.h" +#include "rtscalable.h" #include "../rtengine/curves.h" @@ -591,7 +592,6 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) curve.x.insert (itx, 0); curve.y.insert (ity, 0); - num++; // the graph is refreshed only if a new point is created curve.x.at(closest_point) = clampedX; @@ -1503,7 +1503,7 @@ void MyDiagonalCurve::setActiveParam (int ac) queue_draw (); } -void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) +void MyDiagonalCurve::updateBackgroundHistogram (const LUTu & hist) { if (hist) { //memcpy (bghist, hist, 256*sizeof(unsigned int)); diff --git a/rtgui/mydiagonalcurve.h b/rtgui/mydiagonalcurve.h index 33fac6090..b38373006 100644 --- a/rtgui/mydiagonalcurve.h +++ b/rtgui/mydiagonalcurve.h @@ -16,28 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYDIAGONALCURVE_ -#define _MYDIAGONALCURVE_ +#pragma once + +#include #include -#include -#include "curvelistener.h" + #include "cursormanager.h" +#include "curvelistener.h" #include "mycurve.h" -#include "../rtengine/LUT.h" +#include "../rtengine/diagonalcurvetypes.h" -// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget -enum DiagonalCurveType { - DCT_Empty = -1, // Also used for identity curves - DCT_Linear, // 0 - DCT_Spline, // 1 - DCT_Parametric, // 2 - DCT_NURBS, // 3 - DCT_CatumullRom, // 4 - // Insert new curve type above this line - DCT_Unchanged // Must remain the last of the enum -}; +template +class LUT; + +using LUTf = LUT; class DiagonalCurveDescr { @@ -91,7 +85,7 @@ public: bool handleEvents (GdkEvent* event) override; void setActiveParam (int ac); void reset (const std::vector &resetCurve, double identityValue = 0.5) override; - void updateBackgroundHistogram (LUTu & hist); + void updateBackgroundHistogram (const LUTu & hist); void pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey) override; bool pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) override; @@ -101,5 +95,3 @@ public: void setPos(double pos, int chanIdx) override; void stopNumericalAdjustment() override; }; - -#endif diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index ec46908ce..362d34f35 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -23,6 +23,7 @@ #include "myflatcurve.h" #include "editcallbacks.h" +#include "rtscalable.h" #include "../rtengine/curves.h" @@ -652,7 +653,6 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) curve.y.insert (ity, 0); curve.leftTangent.insert (itlt, 0); curve.rightTangent.insert (itrt, 0); - num++; if (mod_type & GDK_CONTROL_MASK) { clampedY = point.getVal01(clampedX); diff --git a/rtgui/myflatcurve.h b/rtgui/myflatcurve.h index fa4466b8d..88d651a05 100644 --- a/rtgui/myflatcurve.h +++ b/rtgui/myflatcurve.h @@ -16,24 +16,16 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYFLATCURVE_ -#define _MYFLATCURVE_ +#pragma once + +#include #include -#include -#include "curvelistener.h" -#include "cursormanager.h" -#include "mycurve.h" -// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget -enum FlatCurveType { - FCT_Empty = -1, // Also used for identity curves - FCT_Linear, // 0 - FCT_MinMaxCPoints, // 1 - //FCT_Parametric, // 2 - // Insert new curve type above this line - FCT_Unchanged // Must remain the last of the enum -}; +#include "cursormanager.h" +#include "curvelistener.h" +#include "mycurve.h" +#include "../rtengine/flatcurvetypes.h" enum MouseOverAreas { FCT_Area_None = 1 << 0, // over a zone that don't have any @@ -138,5 +130,3 @@ public: void setPos(double pos, int chanIdx) override; void stopNumericalAdjustment() override; }; - -#endif diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc index de07ffcd7..619ea0cfd 100644 --- a/rtgui/navigator.cc +++ b/rtgui/navigator.cc @@ -18,16 +18,12 @@ */ #include #include "navigator.h" +#include "previewwindow.h" #include "toolpanel.h" -#include "../rtengine/iccmatrices.h" -#include "../rtengine/iccstore.h" -#include "../rtengine/curves.h" #include "../rtengine/color.h" #include "../rtengine/rt_math.h" #include "options.h" -extern Options options; - using namespace rtengine; Navigator::Navigator () : currentRGBUnit(options.navRGBUnit), currentHSVUnit(options.navHSVUnit) diff --git a/rtgui/navigator.h b/rtgui/navigator.h index eb4584f42..c1c23c6dc 100644 --- a/rtgui/navigator.h +++ b/rtgui/navigator.h @@ -16,16 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _NAVIGATOR_ -#define _NAVIGATOR_ +#pragma once #include -#include "previewwindow.h" -#include "pointermotionlistener.h" -#include "options.h" -#include "../rtengine/iccstore.h" -class Navigator : public Gtk::Frame, public PointerMotionListener +#include "options.h" +#include "pointermotionlistener.h" + +class PreviewWindow; + +class Navigator : + public Gtk::Frame, + public PointerMotionListener { typedef const double (*TMatrix)[3]; @@ -63,5 +65,3 @@ public: void getLABText (float l, float a, float b, Glib::ustring &sL, Glib::ustring &sA, Glib::ustring &sB) override; }; - -#endif diff --git a/rtgui/options.cc b/rtgui/options.cc index 20e20620a..f5b6b5b60 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -19,13 +19,18 @@ #include "options.h" #include #include +#include +#include #include #include "multilangmgr.h" #include "addsetids.h" #include "guiutils.h" +#include "pathutils.h" #include "version.h" #include "../rtengine/procparams.h" +#include "../rtengine/rtengine.h" +#include "../rtengine/utils.h" #ifdef _OPENMP #include @@ -1258,7 +1263,7 @@ void Options::readFromFile(Glib::ustring fname) } if (keyFile.has_key("GUI", "PseudoHiDPISupport")) { - pseudoHiDPISupport = keyFile.get_boolean("GUI", "PseudoHiDPISupport"); + pseudoHiDPISupport = keyFile.get_boolean("GUI", "PseudoHiDPISupport"); } if (keyFile.has_key("GUI", "LastPreviewScale")) { diff --git a/rtgui/options.h b/rtgui/options.h index 3bd83cd5b..c0ed2138b 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -16,12 +16,12 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _OPTIONS_ -#define _OPTIONS_ +#pragma once #include -#include -#include "../rtengine/rtengine.h" +#include +#include +#include "../rtengine/settings.h" #include #define STARTUPDIR_CURRENT 0 @@ -103,6 +103,13 @@ enum PPLoadLocation {PLL_Cache = 0, PLL_Input = 1}; enum CPBKeyType {CPBKT_TID = 0, CPBKT_NAME = 1, CPBKT_TID_NAME = 2}; enum prevdemo_t {PD_Sidecar = 1, PD_Fast = 0}; +namespace Glib +{ + +class KeyFile; + +} + class Options { public: @@ -447,5 +454,3 @@ extern bool gimpPlugin; extern bool remote; extern Glib::ustring versionString; extern Glib::ustring paramFileExtension; - -#endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0ad27ce2b..3832c052f 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -169,9 +169,10 @@ void ParamsEdited::set(bool v) pdsharpening.contrast = v; pdsharpening.autoContrast = v; pdsharpening.autoRadius = v; - pdsharpening.gamma = v; pdsharpening.deconvradius = v; + pdsharpening.deconvradiusOffset = v; pdsharpening.deconviter = v; + pdsharpening.deconvitercheck = v; prsharpening.enabled = v; prsharpening.contrast = v; prsharpening.radius = v; @@ -591,6 +592,7 @@ void ParamsEdited::set(bool v) dehaze.strength = v; dehaze.showDepthMap = v; dehaze.depth = v; + dehaze.luminance = v; metadata.mode = v; filmNegative.enabled = v; filmNegative.redRatio = v; @@ -758,9 +760,10 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.contrast = pdsharpening.contrast && p.pdsharpening.contrast == other.pdsharpening.contrast; pdsharpening.autoContrast = pdsharpening.autoContrast && p.pdsharpening.autoContrast == other.pdsharpening.autoContrast; pdsharpening.autoRadius = pdsharpening.autoRadius && p.pdsharpening.autoRadius == other.pdsharpening.autoRadius; - pdsharpening.gamma = pdsharpening.gamma && p.pdsharpening.gamma == other.pdsharpening.gamma; pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; + pdsharpening.deconvradiusOffset = pdsharpening.deconvradiusOffset && p.pdsharpening.deconvradiusOffset == other.pdsharpening.deconvradiusOffset; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; + pdsharpening.deconvitercheck = pdsharpening.deconvitercheck && p.pdsharpening.deconvitercheck == other.pdsharpening.deconvitercheck; prsharpening.enabled = prsharpening.enabled && p.prsharpening.enabled == other.prsharpening.enabled; prsharpening.contrast = prsharpening.contrast && p.prsharpening.contrast == other.prsharpening.contrast; prsharpening.radius = prsharpening.radius && p.prsharpening.radius == other.prsharpening.radius; @@ -1164,6 +1167,7 @@ void ParamsEdited::initFrom(const std::vector& dehaze.strength = dehaze.strength && p.dehaze.strength == other.dehaze.strength; dehaze.showDepthMap = dehaze.showDepthMap && p.dehaze.showDepthMap == other.dehaze.showDepthMap; dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; + dehaze.luminance = dehaze.luminance && p.dehaze.luminance == other.dehaze.luminance; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; @@ -1744,18 +1748,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.autoRadius = mods.pdsharpening.autoRadius; } - if (pdsharpening.gamma) { - toEdit.pdsharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_GAMMA] ? toEdit.pdsharpening.gamma + mods.pdsharpening.gamma : mods.pdsharpening.gamma; - } - if (pdsharpening.deconvradius) { toEdit.pdsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradius + mods.pdsharpening.deconvradius : mods.pdsharpening.deconvradius; } + if (pdsharpening.deconvradiusOffset) { + toEdit.pdsharpening.deconvradiusOffset = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradiusOffset + mods.pdsharpening.deconvradiusOffset : mods.pdsharpening.deconvradiusOffset; + } + if (pdsharpening.deconviter) { toEdit.pdsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.pdsharpening.deconviter + mods.pdsharpening.deconviter : mods.pdsharpening.deconviter; } + if (pdsharpening.deconvitercheck) { + toEdit.pdsharpening.deconvitercheck = mods.pdsharpening.deconvitercheck; + } + if (prsharpening.enabled) { toEdit.prsharpening.enabled = mods.prsharpening.enabled; } @@ -3238,6 +3246,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; } + if (dehaze.luminance) { + toEdit.dehaze.luminance = mods.dehaze.luminance; + } + if (metadata.mode) { toEdit.metadata.mode = mods.metadata.mode; } @@ -3309,5 +3321,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && autoRadius && gamma && deconvradius && deconviter; + return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter && deconvitercheck; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 9037da418..a8fef25ab 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -20,7 +20,19 @@ #include -#include "../rtengine/rtengine.h" +namespace rtengine +{ + +namespace procparams +{ + +class ProcParams; + +class PartialProfile; + +} + +} struct GeneralParamsEdited { bool rank; @@ -203,9 +215,10 @@ struct CaptureSharpeningParamsEdited { bool contrast; bool autoContrast; bool autoRadius; - bool gamma; bool deconvradius; + bool deconvradiusOffset; bool deconviter; + bool deconvitercheck; bool isUnchanged() const; }; @@ -603,6 +616,7 @@ struct DehazeParamsEdited { bool strength; bool showDepthMap; bool depth; + bool luminance; }; struct RAWParamsEdited { diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index a7d2bd0d1..22f608ae4 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -136,6 +136,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_avoid_colourshift = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT"))); //--- filmNegative = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMNEGATIVE")) ); + //--- + captureSharpening = Gtk::manage (new Gtk::CheckButton (M("TP_PDSHARPENING_LABEL")) ); Gtk::VBox* vboxes[8]; Gtk::HSeparator* hseps[8]; @@ -253,6 +255,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[7]->pack_start (*raw_ca_avoid_colourshift, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[7]->pack_start (*filmNegative, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*captureSharpening, Gtk::PACK_SHRINK, 2); Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); @@ -402,6 +405,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_avoid_colourshiftconn = raw_ca_avoid_colourshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); //--- filmNegativeConn = filmNegative->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + //--- + captureSharpeningConn = captureSharpening->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); add_button (M("GENERAL_OK"), Gtk::RESPONSE_OK); add_button (M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); @@ -474,6 +479,7 @@ void PartialPasteDlg::rawToggled () ConnectionBlocker raw_caredblueBlocker(raw_caredblueConn); ConnectionBlocker raw_ca_avoid_colourshiftBlocker(raw_ca_avoid_colourshiftconn); ConnectionBlocker filmNegativeBlocker(filmNegativeConn); + ConnectionBlocker captureSharpeningBlocker(captureSharpeningConn); raw->set_inconsistent (false); @@ -503,6 +509,7 @@ void PartialPasteDlg::rawToggled () raw_caredblue->set_active (raw->get_active ()); raw_ca_avoid_colourshift->set_active (raw->get_active ()); filmNegative->set_active (raw->get_active()); + captureSharpening->set_active (raw->get_active()); } void PartialPasteDlg::basicToggled () @@ -981,6 +988,17 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.filmNegative.blueRatio = falsePE.filmNegative.blueRatio; } + if (!captureSharpening->get_active ()) { + filterPE.pdsharpening.enabled = falsePE.pdsharpening.enabled; + filterPE.pdsharpening.contrast = falsePE.pdsharpening.contrast; + filterPE.pdsharpening.autoContrast = falsePE.pdsharpening.autoContrast; + filterPE.pdsharpening.autoRadius = falsePE.pdsharpening.autoRadius; + filterPE.pdsharpening.deconvradius = falsePE.pdsharpening.deconvradius; + filterPE.pdsharpening.deconvradiusOffset = falsePE.pdsharpening.deconvradiusOffset; + filterPE.pdsharpening.deconviter = falsePE.pdsharpening.deconviter; + filterPE.pdsharpening.deconvitercheck = falsePE.pdsharpening.deconvitercheck; + } + if (dstPE) { *dstPE = filterPE; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index eebb08705..1403e7c1b 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -16,11 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PARTIALPASTEDLG_ -#define _PARTIALPASTEDLG_ +#pragma once #include -#include "../rtengine/rtengine.h" + +namespace rtengine +{ +namespace procparams +{ + +class ProcParams; + + +} + +} struct ParamsEdited; @@ -131,6 +141,7 @@ public: Gtk::CheckButton* ff_ClipControl; Gtk::CheckButton* filmNegative; + Gtk::CheckButton* captureSharpening; sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, advancedConn; @@ -143,6 +154,7 @@ public: sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; sigc::connection filmNegativeConn; + sigc::connection captureSharpeningConn; public: PartialPasteDlg (const Glib::ustring &title, Gtk::Window* parent); @@ -159,6 +171,3 @@ public: void rawToggled (); void advancedToggled (); }; - -#endif - diff --git a/rtgui/pathutils.cc b/rtgui/pathutils.cc index 71ff8b0b2..fc47a0e25 100644 --- a/rtgui/pathutils.cc +++ b/rtgui/pathutils.cc @@ -16,6 +16,8 @@ * along with RawTherapee. If not, see . */ +#include + #include "pathutils.h" diff --git a/rtgui/pathutils.h b/rtgui/pathutils.h index ed7d21984..482dfb82f 100644 --- a/rtgui/pathutils.h +++ b/rtgui/pathutils.h @@ -16,19 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __PATH_UTILS_ -#define __PATH_UTILS_ - -#include -#include -#include "../rtengine/rtengine.h" -#include "../rtengine/coord.h" -#include "rtimage.h" -#include -#include +#pragma once +#include // Removed from guiutils because used by rawtherapee-cli Glib::ustring removeExtension (const Glib::ustring& filename); Glib::ustring getExtension (const Glib::ustring& filename); - -#endif diff --git a/rtgui/pcvignette.h b/rtgui/pcvignette.h index ce41ab75f..87915703f 100644 --- a/rtgui/pcvignette.h +++ b/rtgui/pcvignette.h @@ -1,14 +1,17 @@ /* * This file is part of RawTherapee. */ -#ifndef _PCVIGNETTE_H_ -#define _PCVIGNETTE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class PCVignette : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class PCVignette final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -30,5 +33,3 @@ public: void setAdjusterBehavior (bool strengthadd, bool featheradd, bool roundnessadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index ef0ad90c2..18fa7aa2a 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -18,21 +18,29 @@ */ #include -#include "eventmapper.h" +#include + #include "pdsharpening.h" + +#include "eventmapper.h" #include "options.h" +#include "rtimage.h" + #include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; -PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDSHARPENING_LABEL"), false, true) +PdSharpening::PdSharpening() : + FoldableToolPanel(this, "capturesharpening", M("TP_PDSHARPENING_LABEL"), false, true), + lastAutoContrast(true), + lastAutoRadius(true) { - auto m = ProcEventMapper::getInstance(); EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); - EvPdSharpenGamma = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_GAMMA"); + EvPdShrCheckIter = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CHECKITER"); EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); + EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_BOOST"); EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); EvPdShrAutoContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); EvPdShrAutoRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_AUTO_RADIUS"); @@ -41,7 +49,7 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS hb->show(); contrast = Gtk::manage(new Adjuster(M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); contrast->setAdjusterListener(this); - contrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); + contrast->addAutoButton(); contrast->setAutoValue(true); pack_start(*contrast); @@ -50,27 +58,32 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); - gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 6.0, 0.05, 1.00)); - dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 1.15, 0.01, 0.75)); - dradius->addAutoButton(M("TP_PDSHARPENING_AUTORADIUS_TOOLTIP")); + dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS"), 0.4, 1.15, 0.01, 0.75)); + dradius->addAutoButton(); dradius->setAutoValue(true); + dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_BOOST"), -0.5, 0.5, 0.01, 0.0)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 1, 100, 1, 20)); - rld->pack_start(*gamma); + itercheck = Gtk::manage(new CheckBox(M("TP_SHARPENING_ITERCHECK"), multiImage)); + itercheck->setCheckBoxListener(this); + rld->pack_start(*dradius); + rld->pack_start(*dradiusOffset); rld->pack_start(*diter); - gamma->show(); + rld->pack_start(*itercheck); dradius->show(); + dradiusOffset->show(); diter->show(); + itercheck->show(); rld->show(); pack_start(*rld); dradius->setAdjusterListener(this); - gamma->setAdjusterListener(this); + dradiusOffset->setAdjusterListener(this); diter->setAdjusterListener(this); contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); - gamma->delay = std::max(gamma->delay, options.adjusterMaxDelay); + dradiusOffset->delay = std::max(dradiusOffset->delay, options.adjusterMaxDelay); diter->delay = std::max(diter->delay, options.adjusterMaxDelay); } @@ -89,9 +102,10 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) contrast->setEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); contrast->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoContrast); dradius->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoRadius); - gamma->setEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + dradiusOffset->setEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); + itercheck->setEdited(pedited->pdsharpening.deconvitercheck); set_inconsistent(multiImage && !pedited->pdsharpening.enabled); } @@ -100,10 +114,12 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) contrast->setValue(pp->pdsharpening.contrast); contrast->setAutoValue(pp->pdsharpening.autoContrast); - gamma->setValue(pp->pdsharpening.gamma); dradius->setValue(pp->pdsharpening.deconvradius); dradius->setAutoValue(pp->pdsharpening.autoRadius); + dradiusOffset->setValue(pp->pdsharpening.deconvradiusOffset); diter->setValue(pp->pdsharpening.deconviter); + itercheck->setValue(pp->pdsharpening.deconvitercheck); + lastAutoContrast = pp->pdsharpening.autoContrast; lastAutoRadius = pp->pdsharpening.autoRadius; @@ -116,18 +132,20 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.contrast = contrast->getValue(); pp->pdsharpening.autoContrast = contrast->getAutoValue(); pp->pdsharpening.enabled = getEnabled(); - pp->pdsharpening.gamma = gamma->getValue(); pp->pdsharpening.deconvradius = dradius->getValue(); pp->pdsharpening.autoRadius = dradius->getAutoValue(); + pp->pdsharpening.deconvradiusOffset = dradiusOffset->getValue(); pp->pdsharpening.deconviter =(int)diter->getValue(); + pp->pdsharpening.deconvitercheck = itercheck->getLastActive(); if (pedited) { pedited->pdsharpening.contrast = contrast->getEditedState(); pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent(); - pedited->pdsharpening.gamma = gamma->getEditedState(); pedited->pdsharpening.deconvradius = dradius->getEditedState(); pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); + pedited->pdsharpening.deconvradiusOffset = dradiusOffset->getEditedState(); pedited->pdsharpening.deconviter = diter->getEditedState(); + pedited->pdsharpening.deconvitercheck = !itercheck->get_inconsistent(); pedited->pdsharpening.enabled = !get_inconsistent(); } } @@ -136,30 +154,37 @@ void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* { contrast->setDefault(defParams->pdsharpening.contrast); - gamma->setDefault(defParams->pdsharpening.gamma); dradius->setDefault(defParams->pdsharpening.deconvradius); + dradiusOffset->setDefault(defParams->pdsharpening.deconvradiusOffset); diter->setDefault(defParams->pdsharpening.deconviter); if (pedited) { contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); - gamma->setDefaultEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + dradiusOffset->setDefaultEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); } else { contrast->setDefaultEditedState(Irrelevant); - gamma->setDefaultEditedState(Irrelevant); dradius->setDefaultEditedState(Irrelevant); + dradiusOffset->setDefaultEditedState(Irrelevant); diter->setDefaultEditedState(Irrelevant); } } +void PdSharpening::checkBoxToggled (CheckBox* c, CheckValue newval) +{ + if (listener) { + listener->panelChanged (EvPdShrCheckIter, itercheck->getLastActive() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} + void PdSharpening::adjusterChanged(Adjuster* a, double newval) { if (listener && (multiImage || getEnabled())) { Glib::ustring costr; - if (a == gamma || a == dradius) { + if (a == dradius || a == dradiusOffset) { costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else { costr = Glib::ustring::format((int)a->getValue()); @@ -167,10 +192,10 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) if (a == contrast) { listener->panelChanged(EvPdShrContrast, costr); - } else if (a == gamma) { - listener->panelChanged(EvPdSharpenGamma, costr); } else if (a == dradius) { listener->panelChanged(EvPdShrDRadius, costr); + } else if (a == dradiusOffset) { + listener->panelChanged(EvPdShrDRadiusOffset, costr); } else if (a == diter) { listener->panelChanged(EvPdShrDIterations, costr); } @@ -196,17 +221,17 @@ void PdSharpening::setBatchMode(bool batchMode) ToolPanel::setBatchMode(batchMode); contrast->showEditedCB(); - gamma->showEditedCB(); dradius->showEditedCB(); + dradiusOffset->showEditedCB(); diter->showEditedCB(); } -void PdSharpening::setAdjusterBehavior(bool contrastadd, bool gammaadd, bool radiusadd, bool iteradd) +void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd) { contrast->setAddMode(contrastadd); - gamma->setAddMode(gammaadd); dradius->setAddMode(radiusadd); + dradiusOffset->setAddMode(radiusadd); diter->setAddMode(iteradd); } @@ -214,8 +239,8 @@ void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) { contrast->trimValue(pp->pdsharpening.contrast); - gamma->trimValue(pp->pdsharpening.gamma); dradius->trimValue(pp->pdsharpening.deconvradius); + dradiusOffset->trimValue(pp->pdsharpening.deconvradiusOffset); diter->trimValue(pp->pdsharpening.deconviter); } @@ -245,49 +270,27 @@ void PdSharpening::autoRadiusChanged(double autoRadius) ); } -void PdSharpening::adjusterAutoToggled(Adjuster* a, bool newval) +void PdSharpening::adjusterAutoToggled(Adjuster* a) { - if (a == contrast) { - if (multiImage) { - if (contrast->getAutoInconsistent()) { - contrast->setAutoInconsistent(false); - contrast->setAutoValue(false); - } else if (lastAutoContrast) { - contrast->setAutoInconsistent(true); - } - - lastAutoContrast = contrast->getAutoValue(); + if (multiImage) { + if (a->getAutoInconsistent()) { + a->setAutoInconsistent(false); + a->setAutoValue(false); + } else if (lastAutoRadius) { + a->setAutoInconsistent(true); } - if (listener) { - if (contrast->getAutoInconsistent()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_UNCHANGED")); - } else if (contrast->getAutoValue()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_DISABLED")); - } - } - } else { // must be dradius - if (multiImage) { - if (dradius->getAutoInconsistent()) { - dradius->setAutoInconsistent(false); - dradius->setAutoValue(false); - } else if (lastAutoRadius) { - dradius->setAutoInconsistent(true); - } + (a == contrast ? lastAutoContrast : lastAutoRadius) = a->getAutoValue(); + } - lastAutoRadius = dradius->getAutoValue(); - } - - if (listener) { - if (dradius->getAutoInconsistent()) { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_UNCHANGED")); - } else if (dradius->getAutoValue()) { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_DISABLED")); - } + if (listener) { + const auto event = (a == contrast ? EvPdShrAutoContrast : EvPdShrAutoRadius); + if (a->getAutoInconsistent()) { + listener->panelChanged(event, M("GENERAL_UNCHANGED")); + } else if (a->getAutoValue()) { + listener->panelChanged(event, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(event, M("GENERAL_DISABLED")); } } } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index e56b4b085..eb0576ceb 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -19,22 +19,31 @@ #pragma once #include "adjuster.h" +#include "checkbox.h" #include "toolpanel.h" -class PdSharpening final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener, public rtengine::AutoRadiusListener +class PdSharpening final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public rtengine::AutoContrastListener, + public rtengine::AutoRadiusListener, + public CheckBoxListener { protected: Adjuster* contrast; - Adjuster* gamma; Adjuster* dradius; + Adjuster* dradiusOffset; Adjuster* diter; + CheckBox* itercheck; bool lastAutoContrast; bool lastAutoRadius; rtengine::ProcEvent EvPdShrContrast; + rtengine::ProcEvent EvPdShrCheckIter; rtengine::ProcEvent EvPdShrDRadius; - rtengine::ProcEvent EvPdSharpenGamma; + rtengine::ProcEvent EvPdShrDRadiusOffset; rtengine::ProcEvent EvPdShrDIterations; rtengine::ProcEvent EvPdShrAutoContrast; rtengine::ProcEvent EvPdShrAutoRadius; @@ -50,13 +59,14 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void setBatchMode (bool batchMode) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; + void adjusterAutoToggled (Adjuster* a) override; void adjusterChanged (Adjuster* a, double newval) override; void enabledChanged () override; void autoContrastChanged (double autoContrast) override; void autoRadiusChanged (double autoRadius) override; - void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool iteradds); + void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradd); void trimValues (rtengine::procparams::ProcParams* pp) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; }; diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 9b36ed24d..0564479de 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PERSPECTIVE_PANEL_H_ -#define _PERSPECTIVE_PANEL_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class PerspCorrection : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class PerspCorrection final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -43,5 +46,3 @@ public: void setAdjusterBehavior (bool badd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/placesbrowser.h b/rtgui/placesbrowser.h index 6325bdb45..d4640fff4 100644 --- a/rtgui/placesbrowser.h +++ b/rtgui/placesbrowser.h @@ -16,14 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PLACESBROWSER_ -#define _PLACESBROWSER_ +#pragma once #include -#include -#include "multilangmgr.h" -class PlacesBrowser : public Gtk::VBox +#include + +class PlacesBrowser : + public Gtk::VBox { public: typedef sigc::slot DirSelectionSlot; @@ -84,7 +84,3 @@ inline void PlacesBrowser::setDirSelector (const PlacesBrowser::DirSelectionSlot { this->selectDir = selectDir; } - -#endif - - diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h index 0a2931262..26ca994b0 100644 --- a/rtgui/pointermotionlistener.h +++ b/rtgui/pointermotionlistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _POINTERMOTIONLISTENER_ -#define _POINTERMOTIONLISTENER_ +#pragma once class PointerMotionListener { @@ -26,7 +25,7 @@ protected: sigc::signal sig_cycle_hsv; public: - virtual ~PointerMotionListener() {} + virtual ~PointerMotionListener() = default; virtual void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) = 0; virtual void getRGBText (int r, int g, int b, Glib::ustring &sR, Glib::ustring &sG, Glib::ustring &sB, bool isRaw = false) { sR = "--"; sG = "--"; sB = "--"; } virtual void getHSVText (float h, float s, float v, Glib::ustring &sH, Glib::ustring &sS, Glib::ustring &sV) { sH = "--"; sS = "--"; sV = "--"; } @@ -41,5 +40,3 @@ public: return sig_cycle_hsv; } }; - -#endif diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index fb0b66e0d..87b1b73a6 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -18,13 +18,15 @@ * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ -#ifndef _POPUPBUTTON_ -#define _POPUPBUTTON_ +#pragma once #include + #include "popupcommon.h" -class PopUpButton : public Gtk::Button, public PopUpCommon +class PopUpButton : + public Gtk::Button, + public PopUpCommon { public: @@ -40,5 +42,3 @@ private: bool nextOnClicked; }; - -#endif diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 44ad0886a..b4cf4d7e0 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -18,19 +18,22 @@ * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ -#ifndef _POPUPCOMMON_ -#define _POPUPCOMMON_ +#pragma once #include + #include + #include namespace Gtk { + class Grid; class Menu; class Button; class ImageMenuItem; + } typedef struct _GdkEventButton GdkEventButton; @@ -101,5 +104,3 @@ inline int PopUpCommon::getSelected () const { return posToIndex(selected); } - -#endif diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h index b2949a0b8..a97c75fa2 100644 --- a/rtgui/popuptogglebutton.h +++ b/rtgui/popuptogglebutton.h @@ -18,13 +18,15 @@ * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ -#ifndef _POPUPTOGGLEBUTTON_ -#define _POPUPTOGGLEBUTTON_ +#pragma once #include + #include "popupcommon.h" -class PopUpToggleButton : public Gtk::ToggleButton, public PopUpCommon +class PopUpToggleButton : + public Gtk::ToggleButton, + public PopUpCommon { public: @@ -32,5 +34,3 @@ public: void show (); void set_tooltip_text (const Glib::ustring &text); }; - -#endif diff --git a/rtgui/pparamschangelistener.h b/rtgui/pparamschangelistener.h index 2c73ea3f6..e255b9657 100644 --- a/rtgui/pparamschangelistener.h +++ b/rtgui/pparamschangelistener.h @@ -16,12 +16,30 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PPARAMSCHANGELISTENER_ -#define _PPARAMSCHANGELISTENER_ +#pragma once -#include "../rtengine/rtengine.h" -#include -#include "paramsedited.h" +struct ParamsEdited; + +namespace Glib +{ + +class ustring; + +} +namespace rtengine +{ + +class ProcEvent; + +namespace procparams +{ + +class ProcParams; + + +} + +} class PParamsChangeListener { @@ -43,6 +61,3 @@ public: virtual void beginBatchPParamsChange(int numberOfEntries) = 0; virtual void endBatchPParamsChange() = 0; }; - -#endif - diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index b4447fd44..68ef3b9ce 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -24,8 +24,11 @@ #include "addsetids.h" #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" +#include "../rtengine/iccstore.h" +#include "../rtengine/procparams.h" #include #include "rtimage.h" +#include "rtwindow.h" #ifdef _OPENMP #include #endif @@ -49,7 +52,6 @@ void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::stri } } -extern Options options; extern Glib::ustring argv0; Glib::RefPtr themecss; Glib::RefPtr fontcss; @@ -126,7 +128,7 @@ Preferences::~Preferences () get_size (options.preferencesWidth, options.preferencesHeight); } -int Preferences::getThemeRowNumber (Glib::ustring& longThemeFName) +int Preferences::getThemeRowNumber (const Glib::ustring& longThemeFName) { if (regex->match (longThemeFName + ".css", matchInfo)) { diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 6ca302fe8..76a104ffa 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -16,20 +16,26 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __PREFERENCES_H__ -#define __PREFERENCES_H__ +#pragma once + +#include #include -#include "adjuster.h" -#include "options.h" -#include -#include "rtwindow.h" -#include "dynamicprofilepanel.h" -class Preferences : public Gtk::Dialog, public ProfileStoreListener +#include "dynamicprofilepanel.h" +#include "options.h" +#include "../rtengine/profilestore.h" + +class RTWindow; +class Splash; + +class Preferences : + public Gtk::Dialog, + public ProfileStoreListener { - class ExtensionColumns : public Gtk::TreeModel::ColumnRecord + class ExtensionColumns : + public Gtk::TreeModel::ColumnRecord { public: Gtk::TreeModelColumn enabled; @@ -242,7 +248,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener void switchFontTo (const Glib::ustring &newFontFamily, const int newFontSize); bool splashClosed (GdkEventAny* event); - int getThemeRowNumber (Glib::ustring& longThemeFName); + int getThemeRowNumber (const Glib::ustring& longThemeFName); void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); @@ -303,5 +309,3 @@ public: // void selectICCProfileDir (); // void selectMonitorProfile (); }; - -#endif diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index 015fa3650..d10ff5223 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -16,17 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREPROCESS_H_ -#define _PREPROCESS_H_ +#pragma once #include -//#include "adjuster.h" -#include "toolpanel.h" + #include "adjuster.h" #include "guiutils.h" -#include "../rtengine/rawimage.h" +#include "toolpanel.h" -class PreProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class PreProcess final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -54,5 +55,3 @@ public: //void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd); //void trimValues (rtengine::procparams::ProcParams* pp); }; - -#endif diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h index 7fe7b96f4..d9c91f6ad 100644 --- a/rtgui/previewhandler.h +++ b/rtgui/previewhandler.h @@ -16,19 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREVIEWHANDLER_ -#define _PREVIEWHANDLER_ +#pragma once #include #include #include -#include "threadutils.h" #include "guiutils.h" +#include "threadutils.h" -#include "../rtengine/rtengine.h" #include "../rtengine/noncopyable.h" +#include "../rtengine/rtengine.h" class PreviewListener { @@ -86,5 +85,3 @@ public: Glib::RefPtr getRoughImage (int desiredW, int desiredH, double& zoom); rtengine::procparams::CropParams getCropParams (); }; - -#endif diff --git a/rtgui/previewloader.cc b/rtgui/previewloader.cc index 67de50113..a808e1f71 100644 --- a/rtgui/previewloader.cc +++ b/rtgui/previewloader.cc @@ -18,6 +18,8 @@ */ #include +#include "cachemanager.h" +#include "filebrowserentry.h" #include "previewloader.h" #include "guiutils.h" #include "threadutils.h" diff --git a/rtgui/previewloader.h b/rtgui/previewloader.h index 52dbee43c..9a74ee2eb 100644 --- a/rtgui/previewloader.h +++ b/rtgui/previewloader.h @@ -16,15 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREVIEWLOADER_ -#define _PREVIEWLOADER_ +#pragma once #include -#include + +#include #include "../rtengine/noncopyable.h" -#include "filebrowserentry.h" +class FileBrowserEntry; class PreviewLoaderListener { @@ -94,5 +94,3 @@ private: * To use: \c previewLoader->start() , */ #define previewLoader PreviewLoader::getInstance() - -#endif diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h index b43e8484c..4121dfb92 100644 --- a/rtgui/previewmodepanel.h +++ b/rtgui/previewmodepanel.h @@ -15,14 +15,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREVIEWMODEPANEL_ -#define _PREVIEWMODEPANEL_ +#pragma once #include -#include "adjuster.h"//dev class ImageArea; -class PreviewModePanel : public Gtk::HBox + +class PreviewModePanel : + public Gtk::HBox { protected: @@ -83,5 +83,3 @@ public: int GetbackColor(); }; - -#endif diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc index 54d785313..67fa87e0c 100644 --- a/rtgui/previewwindow.cc +++ b/rtgui/previewwindow.cc @@ -20,6 +20,8 @@ #include "guiutils.h" #include "imagearea.h" #include "cursormanager.h" +#include "options.h" +#include "rtscalable.h" #include "../rtengine/procparams.h" @@ -88,7 +90,7 @@ void PreviewWindow::updatePreviewImage () cc->fill(); if (previewHandler->getCropParams().enabled) { - rtengine::CropParams cparams = previewHandler->getCropParams(); + rtengine::procparams::CropParams cparams = previewHandler->getCropParams(); switch (options.cropGuides) { case Options::CROP_GUIDE_NONE: cparams.guide = "None"; @@ -228,7 +230,7 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) if (x>imgX || y>imgY || w < imgW || h < imgH) { bool inside = event->x > x - 6 && event->x < x + w - 1 + 6 && event->y > y - 6 && event->y < y + h - 1 + 6; - CursorShape newType = cursor_type; + CursorShape newType; if (isMoving) { mainCropWin->remoteMove ((event->x - press_x) / zoom, (event->y - press_y) / zoom); diff --git a/rtgui/previewwindow.h b/rtgui/previewwindow.h index 64aa84afd..245f4a394 100644 --- a/rtgui/previewwindow.h +++ b/rtgui/previewwindow.h @@ -16,16 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PREVIEWWINDOW_ -#define _PREVIEWWINDOW_ +#pragma once #include -#include "previewhandler.h" -#include "cropwindow.h" -#include "guiutils.h" -#include "cursormanager.h" -class PreviewWindow : public Gtk::DrawingArea, public PreviewListener, public CropWindowListener +#include "cropwindow.h" +#include "cursormanager.h" +#include "guiutils.h" +#include "previewhandler.h" + +class PreviewWindow : + public Gtk::DrawingArea, + public PreviewListener, + public CropWindowListener { private: @@ -71,5 +74,3 @@ public: void cropZoomChanged(CropWindow* w) override; void initialImageArrived() override; }; - -#endif diff --git a/rtgui/profilechangelistener.h b/rtgui/profilechangelistener.h index fa7e1b877..656566867 100644 --- a/rtgui/profilechangelistener.h +++ b/rtgui/profilechangelistener.h @@ -16,19 +16,23 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROFILECHANGELISTENER_ -#define _PROFILECHANGELISTENER_ +#pragma once -#include +namespace Glib +{ -#include "../rtengine/rtengine.h" +class ustring; + +} namespace rtengine { +class ProcEvent; namespace procparams { +class ProcParams; class PartialProfile; } @@ -48,6 +52,3 @@ public: ) = 0; virtual void setDefaults(const rtengine::procparams::ProcParams* defparams) = 0; }; - -#endif - diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index b4b85dfd0..4c8e30e44 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -22,9 +22,12 @@ #include "multilangmgr.h" #include "options.h" #include "profilestorecombobox.h" +#include "paramsedited.h" +#include "pathutils.h" #include "rtimage.h" #include "../rtengine/procparams.h" +#include "../rtengine/procevents.h" using namespace rtengine; using namespace rtengine::procparams; @@ -275,9 +278,27 @@ void ProfilePanel::save_clicked (GdkEventButton* event) return; } - Gtk::FileChooserDialog dialog (getToplevelWindow (this), M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); - bindCurrentFolder (dialog, options.loadSaveProfilePath); - dialog.set_current_name (lastFilename); + // If it's a partial profile, it's more intuitive to first allow the user + // to choose which parameters to save before showing the Save As dialog + // #5491 + const auto isPartial = event->state & Gdk::CONTROL_MASK; + if (isPartial) { + if (!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg(Glib::ustring(), parent); + } + + partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE")); + const auto response = partialProfileDlg->run(); + partialProfileDlg->hide(); + + if (response != Gtk::RESPONSE_OK) { + return; + } + } + + Gtk::FileChooserDialog dialog(getToplevelWindow(this), M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); + bindCurrentFolder(dialog, options.loadSaveProfilePath); + dialog.set_current_name(lastFilename); //Add the user's default (or global if multiuser=false) profile path to the Shortcut list try { @@ -294,36 +315,32 @@ void ProfilePanel::save_clicked (GdkEventButton* event) dialog.add_button(M("GENERAL_SAVE"), Gtk::RESPONSE_OK); //Add filters, so that only certain file types can be selected: - - Glib::RefPtr filter_pp = Gtk::FileFilter::create(); + auto filter_pp = Gtk::FileFilter::create(); filter_pp->set_name(M("FILECHOOSER_FILTER_PP")); filter_pp->add_pattern("*" + paramFileExtension); dialog.add_filter(filter_pp); - Glib::RefPtr filter_any = Gtk::FileFilter::create(); + auto filter_any = Gtk::FileFilter::create(); filter_any->set_name(M("FILECHOOSER_FILTER_ANY")); filter_any->add_pattern("*"); dialog.add_filter(filter_any); -// dialog.set_do_overwrite_confirmation (true); - - bool done = false; + bool done = true; do { if (dialog.run() == Gtk::RESPONSE_OK) { std::string fname = dialog.get_filename(); - Glib::ustring ext = getExtension (fname); - if (("." + ext) != paramFileExtension) { + if (("." + getExtension(fname)) != paramFileExtension) { fname += paramFileExtension; } - if (!confirmOverwrite (dialog, fname)) { + if (!confirmOverwrite(dialog, fname)) { continue; } - lastFilename = Glib::path_get_basename (fname); + lastFilename = Glib::path_get_basename(fname); const PartialProfile* toSave; @@ -332,60 +349,36 @@ void ProfilePanel::save_clicked (GdkEventButton* event) } else if (isLastSavedSelected()) { toSave = lastsaved; } else { - const ProfileStoreEntry* entry = profiles->getSelectedEntry(); - toSave = entry ? ProfileStore::getInstance()->getProfile (profiles->getSelectedEntry()) : nullptr; + const auto entry = profiles->getSelectedEntry(); + toSave = entry ? ProfileStore::getInstance()->getProfile(entry) : nullptr; } if (toSave) { - if (event->state & Gdk::CONTROL_MASK) { - // opening the partial paste dialog window - if(!partialProfileDlg) { - partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); - } - partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE")); - int i = partialProfileDlg->run(); - partialProfileDlg->hide(); - - if (i != Gtk::RESPONSE_OK) { - return; - } - - // saving the partial profile + int retCode; + if (isPartial) { + // Build partial profile PartialProfile ppTemp(true); - partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited); - int retCode = ppTemp.pparams->save (fname, "", true, ppTemp.pedited); + partialProfileDlg->applyPaste(ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited); + // Save partial profile + retCode = ppTemp.pparams->save(fname, "", true, ppTemp.pedited); + // Cleanup ppTemp.deleteInstance(); - - if (retCode) { - writeFailed(dialog, fname); - } else { - done = true; - bool ccPrevState = changeconn.block(true); - ProfileStore::getInstance()->parseProfiles(); - changeconn.block (ccPrevState); - } } else { - // saving a full profile - int retCode = toSave->pparams->save (fname); - - if (retCode) { - writeFailed(dialog, fname); - } else { - done = true; - bool ccPrevState = changeconn.block(true); - ProfileStore::getInstance()->parseProfiles(); - changeconn.block (ccPrevState); - } + // Save full profile + retCode = toSave->pparams->save(fname); + } + + if (!retCode) { + const auto ccPrevState = changeconn.block(true); + ProfileStore::getInstance()->parseProfiles(); + changeconn.block(ccPrevState); + } else { + done = false; + writeFailed(dialog, fname); } - } else { - done = true; } - } else { - done = true; } } while (!done); - - return; } /* @@ -465,7 +458,6 @@ void ProfilePanel::load_clicked (GdkEventButton* event) dialog.add_button(M("GENERAL_OPEN"), Gtk::RESPONSE_OK); //Add filters, so that only certain file types can be selected: - Glib::RefPtr filter_pp = Gtk::FileFilter::create(); filter_pp->set_name(M("FILECHOOSER_FILTER_PP")); filter_pp->add_pattern("*" + paramFileExtension); diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index c5717d523..b3c968682 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -16,21 +16,44 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROFILEPANEL_ -#define _PROFILEPANEL_ +#pragma once + +#include #include -#include -#include "../rtengine/rtengine.h" + +#include "guiutils.h" +#include "partialpastedlg.h" #include "pparamschangelistener.h" #include "profilechangelistener.h" -#include "partialpastedlg.h" -#include "guiutils.h" -#include "profilestorecombobox.h" -#include "rtimage.h" + +#include "../rtengine/profilestore.h" #include "../rtengine/noncopyable.h" -class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener, public rtengine::NonCopyable +class ProfileStoreComboBox; + +namespace rtengine +{ + +class ProcEvent; + +namespace procparams +{ + +class ProcParams; + +class PartialProfile; + +} + +} +class RTImage; + +class ProfilePanel : + public Gtk::Grid, + public PParamsChangeListener, + public ProfileStoreListener, + public rtengine::NonCopyable { private: @@ -106,5 +129,3 @@ public: void selection_changed (); void writeOptions(); }; - -#endif diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h index 5d04813d6..bfd713235 100644 --- a/rtgui/profilestorecombobox.h +++ b/rtgui/profilestorecombobox.h @@ -16,21 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROFILESTORECOMBOBOX_ -#define _PROFILESTORECOMBOBOX_ +#pragma once #include #include -#include -#include "../rtengine/rtengine.h" -#include "../rtengine/profilestore.h" +#include -#include "threadutils.h" -#include "paramsedited.h" #include "guiutils.h" +#include "threadutils.h" - +class ProfileStoreEntry; /** * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry */ @@ -92,5 +88,3 @@ public: Gtk::TreeIter addRow (const ProfileStoreEntry *profileStoreEntry); void deleteRow (const ProfileStoreEntry *profileStoreEntry); }; - -#endif diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h index 012039ba6..f4d1d8f7e 100644 --- a/rtgui/progressconnector.h +++ b/rtgui/progressconnector.h @@ -16,13 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PROGRESSCONNECTOR_ -#define _PROGRESSCONNECTOR_ +#pragma once + +#include #include -#include -#include "../rtengine/rtengine.h" + #include "guiutils.h" +#include "multilangmgr.h" +#include "../rtengine/rtengine.h" #undef THREAD_PRIORITY_NORMAL @@ -77,9 +79,9 @@ class ProgressConnector static int emitEndSignalUI (void* data) { - sigc::signal0* opEnd = (sigc::signal0*) data; - int r = opEnd->emit (); - delete opEnd; + const sigc::signal0* lopEnd = reinterpret_cast*>(data); + const int r = lopEnd->emit (); + delete lopEnd; return r; } @@ -109,4 +111,3 @@ public: return retval; } }; -#endif diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index 9d37fa8ba..9738a5cd4 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -16,15 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _PRSHARPENING_H_ -#define _PRSHARPENING_H_ +#pragma once #include + #include "adjuster.h" #include "thresholdadjuster.h" #include "toolpanel.h" -class PrSharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +class PrSharpening final : + public ToolParamBlock, + public ThresholdAdjusterListener, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -79,5 +83,3 @@ public: void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h index d3874d9f9..3c95602a7 100644 --- a/rtgui/rawcacorrection.h +++ b/rtgui/rawcacorrection.h @@ -16,15 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RAWCACORRECTION_H_ -#define _RAWCACORRECTION_H_ +#pragma once #include + #include "adjuster.h" #include "checkbox.h" #include "toolpanel.h" -class RAWCACorr : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel +class RAWCACorr final: + public ToolParamBlock, + public AdjusterListener, + public CheckBoxListener, + public FoldableToolPanel { protected: @@ -52,5 +56,3 @@ public: void adjusterChanged (Adjuster* a, double newval) override; void checkBoxToggled (CheckBox* c, CheckValue newval) override; }; - -#endif diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h index 1dafd4d64..33c897113 100644 --- a/rtgui/rawexposure.h +++ b/rtgui/rawexposure.h @@ -16,22 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RAWEXPOSURE_H_ -#define _RAWEXPOSURE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -#include "../rtengine/rawimage.h" -class RAWExposure : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class RAWExposure final: + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: Adjuster* PexPos; -private: -// Gtk::CheckButton* PextwoGreen; public: RAWExposure (); @@ -44,5 +44,3 @@ public: void setAdjusterBehavior (bool pexposadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/recentbrowser.h b/rtgui/recentbrowser.h index 1ba2c17f4..bc8374087 100644 --- a/rtgui/recentbrowser.h +++ b/rtgui/recentbrowser.h @@ -16,14 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RECENTBROWSER_ -#define _RECENTBROWSER_ +#pragma once #include -#include "multilangmgr.h" + #include "guiutils.h" -class RecentBrowser : public Gtk::VBox +class RecentBrowser : + public Gtk::VBox { public: typedef sigc::slot DirSelectionSlot; @@ -47,7 +47,3 @@ inline void RecentBrowser::setDirSelector (const RecentBrowser::DirSelectionSlot { this->selectDir = selectDir; } - -#endif - - diff --git a/rtgui/renamedlg.cc b/rtgui/renamedlg.cc index 8f55b3653..8908d3419 100644 --- a/rtgui/renamedlg.cc +++ b/rtgui/renamedlg.cc @@ -17,8 +17,8 @@ * along with RawTherapee. If not, see . */ #include "renamedlg.h" +#include "cacheimagedata.h" #include "multilangmgr.h" -#include "options.h" #include "rtimage.h" RenameDialog::RenameDialog (Gtk::Window* parent) diff --git a/rtgui/renamedlg.h b/rtgui/renamedlg.h index a3e16ad0a..f9447fbac 100644 --- a/rtgui/renamedlg.h +++ b/rtgui/renamedlg.h @@ -16,16 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RENAMEDLG_ -#define _RENAMEDLG_ +#pragma once #include -#include "cacheimagedata.h" + #include "guiutils.h" #define RESPONSE_ALL 100 -class RenameDialog : public Gtk::Dialog +class CacheImageData; + +class RenameDialog : + public Gtk::Dialog { protected: @@ -43,6 +45,3 @@ public: Glib::ustring getNewName (); }; - -#endif - diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 456b924ef..a65875426 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -16,6 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include + #include "resize.h" #include "eventmapper.h" diff --git a/rtgui/resize.h b/rtgui/resize.h index 1d38ae674..41b54509e 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -16,14 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RESIZE_H_ -#define _RESIZE_H_ +#pragma once #include + #include "adjuster.h" #include "guiutils.h" -#include "toolpanel.h" #include "guiutils.h" +#include "toolpanel.h" class Resize final : public ToolParamBlock, @@ -86,5 +86,3 @@ private: static constexpr int MAX_SCALE = 16; // 16 to match the main preview max scale of 1600% }; - -#endif diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index e074d7e9c..c78be375f 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -2,8 +2,13 @@ * This file is part of RawTherapee. */ #include "retinex.h" + +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "mycurve.h" #include "rtimage.h" +#include "options.h" +#include "../rtengine/color.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/retinex.h b/rtgui/retinex.h index 1be511cb3..ff524f854 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -1,21 +1,30 @@ /* * This file is part of RawTherapee. */ -#ifndef _RETINEX_H_ -#define _RETINEX_H_ +#pragma once #include + #include "adjuster.h" -#include "toolpanel.h" -#include "guiutils.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "thresholdadjuster.h" #include "colorprovider.h" +#include "curvelistener.h" +#include "curveeditorgroup.h" +#include "guiutils.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" -class Retinex : public ToolParamBlock, public FoldableToolPanel, public rtengine::RetinexListener, public CurveListener, - public AdjusterListener, public ColorProvider +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; +class FlatCurveEditor; +class Retinex final : + public ToolParamBlock, + public FoldableToolPanel, + public rtengine::RetinexListener, + public CurveListener, + public AdjusterListener, + public ColorProvider { private: IdleRegister idle_register; @@ -141,5 +150,3 @@ private: void foldAllButMe (GdkEventButton* event, MyExpander *expander); }; - -#endif diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 2350783e0..d501cf449 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -18,6 +18,10 @@ */ #include "rgbcurves.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "options.h" + #include "../rtengine/procparams.h" using namespace rtengine; diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h index e62fdd7c7..edc80eb41 100644 --- a/rtgui/rgbcurves.h +++ b/rtgui/rgbcurves.h @@ -16,17 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RGBCURVES_H_ -#define _RGBCURVES_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "colorprovider.h" -class RGBCurves : public ToolParamBlock, public FoldableToolPanel, public CurveListener, public ColorProvider +#include "colorprovider.h" +#include "curvelistener.h" +#include "toolpanel.h" + +class CurveEditorGroup; +class DiagonalCurveEditor; + +class RGBCurves final : + public ToolParamBlock, + public FoldableToolPanel, + public CurveListener, + public ColorProvider { protected: @@ -66,5 +71,3 @@ public: void lumamodeChanged (); void enabledChanged() override; }; - -#endif diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 7436186c3..06c53cd4e 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -21,6 +21,7 @@ #include "rotate.h" #include "guiutils.h" +#include "lensgeomlistener.h" #include "rtimage.h" #include "../rtengine/procparams.h" diff --git a/rtgui/rotate.h b/rtgui/rotate.h index bd0613609..41e10eb4d 100644 --- a/rtgui/rotate.h +++ b/rtgui/rotate.h @@ -16,15 +16,18 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ROTATE_H_ -#define _ROTATE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -#include "lensgeomlistener.h" -class Rotate : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class LensGeomListener; +class Rotate final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -52,5 +55,3 @@ public: rlistener = l; } }; - -#endif diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index e35a6d164..44078ed3b 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -20,9 +20,10 @@ #include "rtimage.h" +#include #include -#include "options.h" +#include "../rtengine/settings.h" namespace { @@ -214,7 +215,7 @@ Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::u } */ } catch (const Glib::Exception& exception) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { std::cerr << "Failed to load image \"" << fileName << "\": " << exception.what() << std::endl; } } diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 15211a7ee..a48a95fd2 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -20,16 +20,17 @@ #include "rtscalable.h" #include #include -#include +#include #include #include + +#include "../rtengine/rt_math.h" #include "options.h" double RTScalable::dpi = 0.; int RTScalable::scale = 0; extern Glib::ustring argv0; -extern Options options; extern unsigned char initialGdkScale; extern float fontScale; Gtk::TextDirection RTScalable::direction = Gtk::TextDirection::TEXT_DIR_NONE; @@ -37,9 +38,9 @@ Gtk::TextDirection RTScalable::direction = Gtk::TextDirection::TEXT_DIR_NONE; void RTScalable::setDPInScale (const double newDPI, const int newScale) { if (!options.pseudoHiDPISupport) { - scale = 1; - dpi = baseDPI; - return; + scale = 1; + dpi = baseDPI; + return; } if (scale != newScale || (scale == 1 && dpi != newDPI)) { @@ -101,7 +102,7 @@ void RTScalable::deleteDir(const Glib::ustring& path) error |= g_remove (Glib::build_filename (path, *entry).c_str()); } - if (error != 0 && options.rtSettings.verbose) { + if (error != 0 && rtengine::settings->verbose) { std::cerr << "Failed to delete all entries in '" << path << "': " << g_strerror(errno) << std::endl; } diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 3983f93b1..5ab3ab85d 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -19,12 +19,20 @@ #include #include "rtwindow.h" -#include "options.h" +#include "cachemanager.h" #include "preferences.h" #include "iccprofilecreator.h" #include "cursormanager.h" +#include "editwindow.h" #include "rtimage.h" +#include "thumbnail.h" #include "whitebalance.h" +#include "../rtengine/settings.h" +#include "batchqueuepanel.h" +#include "batchqueueentry.h" +#include "editorpanel.h" +#include "filepanel.h" +#include "filmsimulation.h" float fontScale = 1.f; Glib::RefPtr cssForced; @@ -36,14 +44,14 @@ extern unsigned char initialGdkScale; static gboolean osx_should_quit_cb (GtkosxApplication *app, gpointer data) { - RTWindow *rtWin = (RTWindow *)data; + RTWindow * const rtWin = static_cast(data); return rtWin->on_delete_event (0); } static void osx_will_quit_cb (GtkosxApplication *app, gpointer data) { - RTWindow *rtWin = (RTWindow *)data; + RTWindow *rtWin = static_cast(data); rtWin->on_delete_event (0); gtk_main_quit (); } @@ -67,7 +75,7 @@ bool RTWindow::osxFileOpenEvent (Glib::ustring path) static gboolean osx_open_file_cb (GtkosxApplication *app, gchar *path_, gpointer data) { - RTWindow *rtWin = (RTWindow *)data; + RTWindow *rtWin = static_cast(data); if (!argv1.empty()) { // skip handling if we have a file argument or else we get double open of same file @@ -168,9 +176,9 @@ RTWindow::RTWindow () #endif //GTK318 if (options.pseudoHiDPISupport) { - fontScale = options.fontSize / (float)RTScalable::baseFontSize; + fontScale = options.fontSize / (float)RTScalable::baseFontSize; } - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("\"Non-Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", options.fontSize, (int)initialGdkScale, fontScale); } } else { @@ -196,18 +204,18 @@ RTWindow::RTWindow () pt = fontSize / Pango::SCALE; } if (options.pseudoHiDPISupport) { - fontScale = (float)pt / (float)RTScalable::baseFontSize; + fontScale = (float)pt / (float)RTScalable::baseFontSize; } if ((int)initialGdkScale > 1 || pt != RTScalable::baseFontSize) { css = Glib::ustring::compose ("* { font-size: %1pt}", pt * (int)initialGdkScale); - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("\"Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", pt, (int)initialGdkScale, fontScale); } } } } if (!css.empty()) { - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("CSS:\n%s\n\n", css.c_str()); } try { @@ -224,13 +232,6 @@ RTWindow::RTWindow () } } -#ifndef NDEBUG - else if (!screen) { - printf ("ERROR: Can't get default screen!\n"); - } - -#endif - // ------- end loading theme files RTScalable::init(this); @@ -456,10 +457,9 @@ RTWindow::~RTWindow() g_object_unref (osxApp); #endif - if (fpanel) { - delete fpanel; - } - + delete fpanel; + delete iFullscreen; + delete iFullscreen_exit; RTImage::cleanup(); } @@ -652,8 +652,8 @@ void RTWindow::remEditorPanel (EditorPanel* ep) set_title_decorated (""); } else { - EditorPanel* ep = static_cast (mainNB->get_nth_page (mainNB->get_current_page())); - set_title_decorated (ep->getFileName()); + const EditorPanel* lep = static_cast (mainNB->get_nth_page (mainNB->get_current_page())); + set_title_decorated (lep->getFileName()); } // TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel @@ -1162,3 +1162,8 @@ void RTWindow::createSetmEditor() mainNB->append_page (*epanel, *editorLabelGrid); } + +bool RTWindow::isSingleTabMode() const +{ + return !options.tabbedUI && ! (options.multiDisplayMode > 0); +} diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 93e1c31b9..100ddf636 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -15,23 +15,30 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RTWINDOW_ -#define _RTWINDOW_ +#pragma once + +#include #include -#include "filepanel.h" -#include "editorpanel.h" -#include "batchqueuepanel.h" -#include -#include "progressconnector.h" -#include "editwindow.h" -#include "splash.h" + #if defined(__APPLE__) #include #endif + +#include "progressconnector.h" +#include "splash.h" + #include "../rtengine/noncopyable.h" -class RTWindow : public Gtk::Window, public rtengine::ProgressListener, public rtengine::NonCopyable +class BatchQueueEntry; +class BatchQueuePanel; +class EditorPanel; +class FilePanel; +class PLDBridge; +class RTWindow : + public Gtk::Window, + public rtengine::ProgressListener, + public rtengine::NonCopyable { private: @@ -49,10 +56,7 @@ private: Gtk::Image *iFullscreen, *iFullscreen_exit; - bool isSingleTabMode() - { - return !options.tabbedUI && ! (options.multiDisplayMode > 0); - }; + bool isSingleTabMode() const; bool on_expose_event_epanel (GdkEventExpose* event); bool on_expose_event_fpanel (GdkEventExpose* event); @@ -125,5 +129,3 @@ public: void writeToolExpandedStatus (std::vector &tpOpen); }; - -#endif diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc index 1b61d7d3d..ebf2f5b4a 100644 --- a/rtgui/saveasdlg.cc +++ b/rtgui/saveasdlg.cc @@ -22,12 +22,11 @@ #include "guiutils.h" #include "multilangmgr.h" +#include "pathutils.h" #include "rtimage.h" #include "../rtengine/utils.h" -extern Options options; - namespace { diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h index dd120337d..448b37fd7 100644 --- a/rtgui/saveasdlg.h +++ b/rtgui/saveasdlg.h @@ -16,15 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SAVEASDLG_ -#define _SAVEASDLG_ +#pragma once #include -#include "adjuster.h" -#include "saveformatpanel.h" -#include "options.h" -class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener +#include "saveformatpanel.h" + +class SaveAsDialog : + public Gtk::Dialog, + public FormatChangeListener { protected: @@ -65,6 +65,3 @@ public: void formatChanged(const Glib::ustring& format) override; bool keyPressed (GdkEventKey* event); }; - - -#endif diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index ab5ffef3e..af9baa58a 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -16,13 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __SAVEFORMATPANEL_H__ -#define __SAVEFORMATPANEL_H__ +#pragma once #include + #include "adjuster.h" #include "guiutils.h" #include "options.h" + #include "../rtengine/noncopyable.h" class FormatChangeListener @@ -62,5 +63,3 @@ public: void formatChanged (); void adjusterChanged (Adjuster* a, double newval) override; }; - -#endif diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h index 2d68411ce..2401bf760 100644 --- a/rtgui/sensorbayer.h +++ b/rtgui/sensorbayer.h @@ -16,13 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SENSORBAYER_H_ -#define _SENSORBAYER_H_ +#pragma once #include + #include "toolpanel.h" -class SensorBayer : public ToolParamBlock, public FoldableToolPanel +class SensorBayer final : + public ToolParamBlock, + public FoldableToolPanel { protected: @@ -37,5 +39,3 @@ public: return packBox; } }; - -#endif diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h index fbf71b401..eee014f6c 100644 --- a/rtgui/sensorxtrans.h +++ b/rtgui/sensorxtrans.h @@ -16,13 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SENSORXTRANS_H_ -#define _SENSORXTRANS_H_ +#pragma once #include + #include "toolpanel.h" -class SensorXTrans : public ToolParamBlock, public FoldableToolPanel +class SensorXTrans final: + public ToolParamBlock, + public FoldableToolPanel { protected: @@ -37,5 +39,3 @@ public: return packBox; } }; - -#endif diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h index d675f40d6..7bb0bb01c 100644 --- a/rtgui/shadowshighlights.h +++ b/rtgui/shadowshighlights.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SHADOWSHIGHLIGHTS_H_ -#define _SHADOWSHIGHLIGHTS_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class ShadowsHighlights : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class ShadowsHighlights final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -53,5 +56,3 @@ public: void colorspaceChanged(); }; - -#endif diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h index b136d8e5e..a813d86e1 100644 --- a/rtgui/sharpenedge.h +++ b/rtgui/sharpenedge.h @@ -21,14 +21,17 @@ * * */ -#ifndef _SHARPENEDGE_H_ -#define _SHARPENEDGE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class SharpenEdge : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class SharpenEdge final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -56,5 +59,3 @@ public: void chanthree_toggled (); }; - -#endif diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index ac846a2b6..bd5e6f1b7 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -16,15 +16,19 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SHARPENING_H_ -#define _SHARPENING_H_ +#pragma once #include + #include "adjuster.h" #include "thresholdadjuster.h" #include "toolpanel.h" -class Sharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +class Sharpening final: + public ToolParamBlock, + public ThresholdAdjusterListener, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -82,5 +86,3 @@ public: void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h index 7c292413b..23224dd60 100644 --- a/rtgui/sharpenmicro.h +++ b/rtgui/sharpenmicro.h @@ -21,14 +21,17 @@ * * */ -#ifndef _SHARPENMICRO_H_ -#define _SHARPENMICRO_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class SharpenMicro : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class SharpenMicro final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -60,5 +63,3 @@ public: }; - -#endif diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index 6137c3ec8..e8aca4071 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -17,9 +17,12 @@ * along with RawTherapee. If not, see . */ +#include + #include "shcselector.h" #include "multilangmgr.h" #include "mycurve.h" +#include "rtscalable.h" SHCSelector::SHCSelector() : movingPosition(-1), tmpX(0.0), tmpPos(0.0), wslider(0.0), cl(nullptr), coloredBar(RTO_Left2Right) { diff --git a/rtgui/shcselector.h b/rtgui/shcselector.h index d3ef2adb8..5c4421e0a 100644 --- a/rtgui/shcselector.h +++ b/rtgui/shcselector.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SHCSELECTOR_ -#define _SHCSELECTOR_ +#pragma once #include + #include "coloredbar.h" class SHCListener @@ -82,6 +82,3 @@ public: bool reset (); void refresh(); }; - -#endif - diff --git a/rtgui/softlight.h b/rtgui/softlight.h index a584d3a73..710da4e34 100644 --- a/rtgui/softlight.h +++ b/rtgui/softlight.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class SoftLight: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class SoftLight final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *strength; diff --git a/rtgui/soundman.h b/rtgui/soundman.h index 6d065c87a..5eb6883e0 100644 --- a/rtgui/soundman.h +++ b/rtgui/soundman.h @@ -17,13 +17,13 @@ * along with RawTherapee. If not, see . * */ - -#ifndef _SOUNDMAN_ -#define _SOUNDMAN_ +#pragma once namespace Glib { + class ustring; + } class SoundManager @@ -32,5 +32,3 @@ public: static void init(); static void playSoundAsync(const Glib::ustring &sound); }; - -#endif diff --git a/rtgui/splash.h b/rtgui/splash.h index 29dbb62cf..363c51489 100644 --- a/rtgui/splash.h +++ b/rtgui/splash.h @@ -16,12 +16,12 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __SPLASH__ -#define __SPLASH__ +#pragma once #include -class SplashImage : public Gtk::DrawingArea +class SplashImage : + public Gtk::DrawingArea { private: @@ -59,5 +59,3 @@ public: //virtual bool on_button_release_event (GdkEventButton* event); void closePressed(); }; - -#endif diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index f8107d74c..eae4a9ad2 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THREADUTILS_ -#define _THREADUTILS_ +#pragma once // Uncomment this if you want to bypass the CMakeList options and force the values, but do not commit! //#undef TRACE_MYRWMUTEX @@ -307,5 +306,3 @@ inline MyWriterLock::~MyWriterLock () #define MYREADERLOCK_RELEASE(ln) ln.release(); #define MYWRITERLOCK_RELEASE(ln) ln.release(); #endif - -#endif /* _THREADUTILS_ */ diff --git a/rtgui/thresholdadjuster.h b/rtgui/thresholdadjuster.h index ea3822875..b28f68dee 100644 --- a/rtgui/thresholdadjuster.h +++ b/rtgui/thresholdadjuster.h @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THRESHOLDADJUSTER_H_ -#define _THRESHOLDADJUSTER_H_ +#pragma once #include + #include "editedstate.h" #include "guiutils.h" #include "thresholdselector.h" @@ -160,5 +160,3 @@ public: // this set_tooltip_text method is to set_tooltip_markup, and text can contain markups void set_tooltip_text(const Glib::ustring& text); }; - -#endif diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index b44425be4..35d08279c 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -24,6 +24,7 @@ #include "multilangmgr.h" #include "mycurve.h" +#include "rtscalable.h" #include "../rtengine/procparams.h" diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h index 6b9dda3d0..f948b56ad 100644 --- a/rtgui/thresholdselector.h +++ b/rtgui/thresholdselector.h @@ -16,14 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THRESHOLDSELECTOR_ -#define _THRESHOLDSELECTOR_ +#pragma once -#include "guiutils.h" -#include "../rtengine/procparams.h" -#include "coloredbar.h" #include +#include "coloredbar.h" +#include "guiutils.h" + +#include "../rtengine/procparams.h" + class ThresholdSelector; /* @@ -245,6 +246,3 @@ inline void ThresholdSelector::getPositions (Glib::ustring& botto bottomRight = Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), shapePositionValue(TS_BOTTOMRIGHT)); topRight = Glib::ustring::format(std::fixed, std::setprecision(precisionTop), shapePositionValue(TS_TOPRIGHT)); } - -#endif - diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index adf451f05..5f75ab413 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -16,13 +16,15 @@ */ #include -#include +#include +#include "inspector.h" #include "multilangmgr.h" #include "options.h" +#include "rtscalable.h" #include "thumbbrowserbase.h" +#include "thumbbrowserentrybase.h" -#include "../rtengine/mytime.h" #include "../rtengine/rt_math.h" using namespace std; @@ -965,7 +967,7 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ } MYWRITERLOCK_RELEASE(l); - rightClicked (fileDescr); + rightClicked (); } } // end of MYWRITERLOCK(l, entryRW); diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index 890c37c87..b4caac0a9 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -16,23 +16,28 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBNAILBROWSERBASE_ -#define _THUMBNAILBROWSERBASE_ +#pragma once + +#include #include -#include "thumbbrowserentrybase.h" -#include -#include "options.h" + #include "guiutils.h" -#include "inspector.h" +#include "options.h" /* * Class handling the list of ThumbBrowserEntry objects and their position in it's allocated space */ -class ThumbBrowserBase : public Gtk::Grid + +class Inspector; +class ThumbBrowserEntryBase; + +class ThumbBrowserBase : + public Gtk::Grid { - class Internal : public Gtk::DrawingArea + class Internal : + public Gtk::DrawingArea { //Cairo::RefPtr cc; int ofsX, ofsY; @@ -220,7 +225,7 @@ public: { return true; } - virtual void rightClicked (ThumbBrowserEntryBase* entry) {} + virtual void rightClicked () = 0; virtual void doubleClicked (ThumbBrowserEntryBase* entry) {} virtual bool keyPressed (GdkEventKey* event) { @@ -253,5 +258,3 @@ public: } }; - -#endif diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 9d74fbd79..3840c8bf9 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -20,8 +20,7 @@ #include "options.h" #include "thumbbrowserbase.h" - -#include "../rtengine/mytime.h" +#include "../rtengine/rt_math.h" namespace { diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 5f018eefd..dbc6cf73e 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -26,8 +26,10 @@ #include "guiutils.h" #include "lwbuttonset.h" #include "threadutils.h" -#include "thumbnail.h" +#include "../rtengine/coord2d.h" + +class Thumbnail; class ThumbBrowserBase; class ThumbBrowserEntryBase { diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index 579979eea..540ad625e 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -23,9 +23,11 @@ #include #include "thumbimageupdater.h" +#include "thumbbrowserentrybase.h" #include "guiutils.h" #include "threadutils.h" +#include "thumbnail.h" #include "../rtengine/procparams.h" diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h index 0e46b11d7..a2e2ecb19 100644 --- a/rtgui/thumbimageupdater.h +++ b/rtgui/thumbimageupdater.h @@ -16,16 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBIMAGEUPDATER_ -#define _THUMBIMAGEUPDATER_ +#pragma once -#include #include -#include "../rtengine/rtengine.h" + #include "../rtengine/noncopyable.h" -#include "thumbbrowserentrybase.h" +namespace rtengine +{ + class IImage8; + +namespace procparams +{ + + struct CropParams; + +} + +} + +class ThumbBrowserEntryBase; class ThumbImageUpdateListener { @@ -101,5 +112,3 @@ private: * To use: \c thumbImageUpdater->start() , */ #define thumbImageUpdater ThumbImageUpdater::getInstance() - -#endif diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 7ec1fef4e..bcf578143 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -15,24 +15,32 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#ifdef WIN32 +#include +#endif + +#include "cachemanager.h" #include "multilangmgr.h" #include "thumbnail.h" #include #include -#include "options.h" -#include "../rtengine/mytime.h" #include #include -#include +#include "../rtengine/colortemp.h" #include "../rtengine/imagedata.h" #include "../rtengine/procparams.h" +#include "../rtengine/rtthumbnail.h" #include #include "../rtengine/dynamicprofile.h" +#include "../rtengine/profilestore.h" +#include "../rtengine/settings.h" +#include "../rtexif/rtexif.h" #include "guiutils.h" #include "batchqueue.h" #include "extprog.h" -#include "profilestorecombobox.h" +#include "pathutils.h" +#include "paramsedited.h" #include "procparamchangers.h" using namespace rtengine::procparams; @@ -299,7 +307,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu // For the filename etc. do NOT use streams, since they are not UTF8 safe Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\""); - if (options.rtSettings.verbose) { + if (rtengine::settings->verbose) { printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine).c_str()); } @@ -582,10 +590,8 @@ void Thumbnail::decreaseRef () cachemgr->closeThumbnail (this); } -void Thumbnail::getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams) +int Thumbnail::getThumbnailWidth (const int h, const rtengine::procparams::ProcParams *pparams) const { - MyMutex::MyLock lock(mutex); - int tw_ = tw; int th_ = th; float imgRatio_ = imgRatio; @@ -605,20 +611,17 @@ void Thumbnail::getThumbnailSize (int &w, int &h, const rtengine::procparams::Pr if (thisCoarse != ppCoarse) { // different orientation -> swapping width & height - int tmp = th_; - th_ = tw_; - tw_ = tmp; - + std::swap(th_, tw_); if (imgRatio_ >= 0.0001f) { imgRatio_ = 1.f / imgRatio_; } } } - if (imgRatio_ > 0.) { - w = (int)(imgRatio_ * (float)h); + if (imgRatio_ > 0.f) { + return imgRatio_ * h; } else { - w = tw_ * h / th_; + return tw_ * h / th_; } } @@ -1150,3 +1153,48 @@ bool Thumbnail::imageLoad(bool loading) return false; } + +void Thumbnail::getCamWB(double& temp, double& green) const +{ + if (tpp) { + tpp->getCamWB (temp, green); + } else { + temp = green = -1.0; + } +} + +void Thumbnail::getSpotWB(int x, int y, int rect, double& temp, double& green) +{ + if (tpp) { + tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); + } else { + temp = green = -1.0; + } +} + +void Thumbnail::applyAutoExp (rtengine::procparams::ProcParams& pparams) +{ + if (tpp) { + tpp->applyAutoExp (pparams); + } +} + +const CacheImageData* Thumbnail::getCacheImageData() +{ + return &cfs; +} + +std::string Thumbnail::getMD5() const +{ + return cfs.md5; +} + +bool Thumbnail::isQuick() const +{ + return cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL; +} + +bool Thumbnail::isPParamsValid() const +{ + return pparamsValid; +} diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index ec5dbd249..c22c80cea 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -16,22 +16,31 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBNAIL_ -#define _THUMBNAIL_ +#pragma once #include #include -#include -#include "cachemanager.h" -#include "options.h" -#include "../rtengine/rtengine.h" -#include "../rtengine/rtthumbnail.h" -#include "cacheimagedata.h" -#include "thumbnaillistener.h" -#include "threadutils.h" +#include +#include "cacheimagedata.h" +#include "threadutils.h" +#include "thumbnaillistener.h" + +namespace rtengine +{ +class Thumbnail; + +namespace procparams +{ + +class ProcParams; + +} + +} class CacheManager; + struct ParamsEdited; class Thumbnail @@ -97,14 +106,8 @@ public: void notifylisterners_procParamsChanged(int whoChangedIt); - bool isQuick() const - { - return cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL; - } - bool isPParamsValid() const - { - return pparamsValid; - } + bool isQuick() const; + bool isPParamsValid() const; bool isRecentlySaved () const; void imageDeveloped (); void imageEnqueued (); @@ -116,35 +119,16 @@ public: // unsigned char* getThumbnailImage (int &w, int &h, int fixwh=1); // fixwh = 0: fix w and calculate h, =1: fix h and calculate w rtengine::IImage8* processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale); rtengine::IImage8* upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale); - void getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams = nullptr); + int getThumbnailWidth (int h, const rtengine::procparams::ProcParams *pparams = nullptr) const; void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h); void getOriginalSize (int& w, int& h); const Glib::ustring& getExifString () const; const Glib::ustring& getDateTimeString () const; - void getCamWB (double& temp, double& green) const - { - if (tpp) { - tpp->getCamWB (temp, green); - } else { - temp = green = -1.0; - } - } + void getCamWB (double& temp, double& green) const; void getAutoWB (double& temp, double& green, double equal, double tempBias); - void getSpotWB (int x, int y, int rect, double& temp, double& green) - { - if (tpp) { - tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); - } else { - temp = green = -1.0; - } - } - void applyAutoExp (rtengine::procparams::ProcParams& pparams) - { - if (tpp) { - tpp->applyAutoExp (pparams); - } - } + void getSpotWB (int x, int y, int rect, double& temp, double& green); + void applyAutoExp (rtengine::procparams::ProcParams& pparams); ThFileType getType (); Glib::ustring getFileName () const @@ -155,14 +139,8 @@ public: bool isSupported (); - const CacheImageData* getCacheImageData() - { - return &cfs; - } - std::string getMD5 () const - { - return cfs.md5; - } + const CacheImageData* getCacheImageData(); + std::string getMD5 () const; int getRank () const; void setRank (int rank); @@ -185,7 +163,3 @@ public: bool openDefaultViewer(int destination); bool imageLoad(bool loading); }; - - -#endif - diff --git a/rtgui/thumbnailbrowser.h b/rtgui/thumbnailbrowser.h deleted file mode 100644 index 9d40d1f7d..000000000 --- a/rtgui/thumbnailbrowser.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _THUMBNAILBROWSER_ -#define _THUMBNAILBROWSER_ - -#include -#include "thumbnail.h" -#include "filecatalog.h" - -class ThumbBrowserEntry -{ - -public: -// set by arrangeFiles(): - int width; // minimal width - int height; // minimal height - int exp_width; // ararnged width - int startx; // x coord. in the widget - int starty; // y coord. in the widget -// thumbnail preview properties: - int prew; // width of the thumbnail - int preh; // height of the thumbnail - guint8* preview; -// file and directory attributes: - Glib::ustring filename; - Glib::ustring shortname; - Glib::ustring dirname; -// the associated thumbnail instance: - Thumbnail* thumbnail; - - ThumbBrowserEntry (Thumbnail* thm, Glib::ustring fname, Glib::ustring sname, Glib::ustring dname, int h) - : thumbnail(thm), filename(fname), shortname(sname), dirname(dname), preh(h) - { - preview = thumbnail ? (guint8*) thumbnail->getThumbnailImage (prew, preh) : NULL; - } - - bool operator< (FileDescr& other) - { - return shortname > other.shortname; - } -}; - -class ThumbBrowser : public Gtk::DrawingArea -{ - -protected: - int dx, dy, w, h; - - Gdk::RGBA black; - Gdk::RGBA white; - Gdk::RGBA blue; - Gdk::RGBA bluew; - - std::vector fd; - std::vector selected; - - int rowHeight; - int numOfRows; - - ThumbBrowserListener* tbl; - - void arrangeFiles (int rows); - -public: - - ThumbBrowser (); - - void addEntry (ThumbBrowserEntry* entry); - void setThumbBrowserListener (ThumbBrowserListener* l) - { - tbl = l; - } - - virtual void on_realize(); - virtual bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr); - virtual bool on_button_press_event (GdkEventButton* event); - virtual bool on_button_release_event (GdkEventButton* event); - virtual void previewReady (FileDescr* fdn); - - void resized (Gtk::Allocation& req); - void redraw (); - void styleChanged (const Glib::RefPtr& style); -}; - -#endif diff --git a/rtgui/thumbnaillistener.h b/rtgui/thumbnaillistener.h index 97503c420..18ac99dce 100644 --- a/rtgui/thumbnaillistener.h +++ b/rtgui/thumbnaillistener.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBNAILLISTENER_ -#define _THUMBNAILLISTENER_ +#pragma once class Thumbnail; @@ -27,6 +26,3 @@ public: virtual ~ThumbnailListener() = default; virtual void procParamsChanged(Thumbnail* thm, int whoChangedIt) = 0; }; - -#endif - diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index fa1c80ed8..dc9b17fa9 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -23,10 +23,14 @@ #include "tonecurve.h" #include "adjuster.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "eventmapper.h" #include "ppversion.h" +#include "options.h" #include "../rtengine/procparams.h" +#include "../rtengine/utils.h" #include "editcallbacks.h" using namespace rtengine; diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index fb08c02c2..e0482c5da 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -16,20 +16,26 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _TONECURVE_H_ -#define _TONECURVE_H_ +#pragma once #include -#include "adjuster.h" -#include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" -#include "mycurve.h" -#include "guiutils.h" +#include "adjuster.h" +#include "curvelistener.h" +#include "guiutils.h" +#include "toolpanel.h" + +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; -class ToneCurve : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoExpListener, public CurveListener +class ToneCurve final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public rtengine::AutoExpListener, + public CurveListener { private: IdleRegister idle_register; @@ -141,5 +147,3 @@ public: void methodChanged (); void clampOOGChanged(); }; - -#endif diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index b8e0d64dc..99c4196c6 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -20,6 +20,8 @@ #include "toolbar.h" #include "multilangmgr.h" #include "guiutils.h" +#include "lockablecolorpicker.h" +#include "rtimage.h" ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(nullptr) { diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h index 52f4dcbd4..8ec6bb615 100644 --- a/rtgui/toolbar.h +++ b/rtgui/toolbar.h @@ -16,13 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __TOOLBAR_H__ -#define __TOOLBAR_H__ +#pragma once #include + #include "toolenum.h" -#include "rtimage.h" -#include "lockablecolorpicker.h" + +class RTImage; +class LockablePickerToolListener; class ToolBarListener { @@ -36,7 +37,7 @@ public: virtual void editModeSwitchedOff() = 0; }; -class ToolBar : public Gtk::HBox +class ToolBar final : public Gtk::HBox { private: std::unique_ptr handimg; @@ -99,5 +100,3 @@ public: bool handleShortcutKey (GdkEventKey* event); void setBatchMode(); }; - -#endif diff --git a/rtgui/toolenum.h b/rtgui/toolenum.h index e90a0f685..c3bc873f1 100644 --- a/rtgui/toolenum.h +++ b/rtgui/toolenum.h @@ -16,9 +16,6 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _TOOLENUM_ -#define _TOOLENUM_ +#pragma once enum ToolMode {TMNone = -1, TMHand = 0, TMSpotWB = 1, TMCropSelect = 2, TMStraighten = 3, TMColorPicker = 4}; - -#endif diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index 27f68767e..b1282f523 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -19,6 +19,7 @@ #include "toolpanel.h" #include "toolpanelcoord.h" #include "guiutils.h" +#include "rtimage.h" #include "../rtengine/procparams.h" diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 7ecfe31b8..3c4ea0690 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -16,20 +16,29 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __TOOLPANEL__ -#define __TOOLPANEL__ +#pragma once #include -#include -#include "../rtengine/rtengine.h" -#include "editbuffer.h" + +#include + #include "guiutils.h" #include "multilangmgr.h" #include "paramsedited.h" -#include "../rtengine/noncopyable.h" -class ToolPanel; -class FoldableToolPanel; +#include "../rtengine/noncopyable.h" +#include "../rtengine/rtengine.h" + +namespace rtengine +{ + class ProcEvent; + +namespace procparams +{ + +class ProcParams; +} +} class EditDataProvider; class ToolPanelListener @@ -48,20 +57,23 @@ public: }; /// @brief This class control the space around the group of tools inside a tab, as well as the space separating each tool. */ -class ToolVBox : public Gtk::VBox +class ToolVBox : + public Gtk::VBox { public: ToolVBox(); }; /// @brief This class control the space around a tool's block of parameter. */ -class ToolParamBlock : public Gtk::VBox +class ToolParamBlock : + public Gtk::VBox { public: ToolParamBlock(); }; -class ToolPanel : public rtengine::NonCopyable +class ToolPanel : + public rtengine::NonCopyable { protected: @@ -145,7 +157,8 @@ public: } }; -class FoldableToolPanel : public ToolPanel +class FoldableToolPanel : + public ToolPanel { protected: @@ -227,5 +240,3 @@ public: return exp->signal_enabled_toggled(); } }; - -#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index e02a2bd1b..7c82da8a5 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -18,7 +18,10 @@ */ #include "multilangmgr.h" #include "toolpanelcoord.h" +#include "metadatapanel.h" #include "options.h" +#include "rtimage.h" + #include "../rtengine/imagesource.h" #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" @@ -180,7 +183,6 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit transformPanelSW = Gtk::manage (new MyScrolledWindow ()); rawPanelSW = Gtk::manage (new MyScrolledWindow ()); advancedPanelSW = Gtk::manage (new MyScrolledWindow ()); - updateVScrollbars (options.hideTPVScrollbar); // load panel endings for (int i = 0; i < 7; i++) { @@ -197,6 +199,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit favoritePanel->pack_start(*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); favoritePanel->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); } + updateVScrollbars(options.hideTPVScrollbar); exposurePanelSW->add (*exposurePanel); exposurePanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); @@ -308,13 +311,17 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt { rawPanelSW->set_sensitive(true); sensorxtrans->FoldableToolPanel::hide(); + xtransprocess->FoldableToolPanel::hide(); + xtransrawexposure->FoldableToolPanel::hide(); sensorbayer->FoldableToolPanel::show(); + bayerprocess->FoldableToolPanel::show(); + bayerpreprocess->FoldableToolPanel::show(); + rawcacorrection->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show(); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); - return false; } ); @@ -325,13 +332,17 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt { rawPanelSW->set_sensitive(true); sensorxtrans->FoldableToolPanel::show(); + xtransprocess->FoldableToolPanel::show(); + xtransrawexposure->FoldableToolPanel::show(); sensorbayer->FoldableToolPanel::hide(); + bayerprocess->FoldableToolPanel::hide(); + bayerpreprocess->FoldableToolPanel::hide(); + rawcacorrection->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show(); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); - return false; } ); @@ -342,13 +353,17 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt { rawPanelSW->set_sensitive(true); sensorbayer->FoldableToolPanel::hide(); + bayerprocess->FoldableToolPanel::hide(); + bayerpreprocess->FoldableToolPanel::hide(); + rawcacorrection->FoldableToolPanel::hide(); sensorxtrans->FoldableToolPanel::hide(); + xtransprocess->FoldableToolPanel::hide(); + xtransrawexposure->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::hide(); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); - return false; } ); @@ -358,13 +373,17 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt { rawPanelSW->set_sensitive(true); sensorbayer->FoldableToolPanel::hide(); + bayerprocess->FoldableToolPanel::hide(); + bayerpreprocess->FoldableToolPanel::hide(); + rawcacorrection->FoldableToolPanel::hide(); sensorxtrans->FoldableToolPanel::hide(); + xtransprocess->FoldableToolPanel::hide(); + xtransrawexposure->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); filmNegative->FoldableToolPanel::hide(); pdSharpening->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); - return false; } ); @@ -374,10 +393,18 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt [this]() -> bool { rawPanelSW->set_sensitive(false); + sensorbayer->FoldableToolPanel::hide(); + bayerprocess->FoldableToolPanel::hide(); + bayerpreprocess->FoldableToolPanel::hide(); + rawcacorrection->FoldableToolPanel::hide(); + sensorxtrans->FoldableToolPanel::hide(); + xtransprocess->FoldableToolPanel::hide(); + xtransrawexposure->FoldableToolPanel::hide(); + preprocess->FoldableToolPanel::hide(); + flatfield->FoldableToolPanel::hide(); filmNegative->FoldableToolPanel::hide(); pdSharpening->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(true); - return false; } ); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 5d016422d..d8e85f651 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -16,78 +16,80 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __TOOLPANELCCORD__ -#define __TOOLPANELCCORD__ +#pragma once -#include "../rtengine/rtengine.h" -#include "toolpanel.h" #include -#include "pparamschangelistener.h" -#include "profilechangelistener.h" -#include "imageareatoollistener.h" + #include -#include "whitebalance.h" -#include "coarsepanel.h" -#include "tonecurve.h" -#include "vibrance.h" -#include "colorappearance.h" -#include "shadowshighlights.h" -#include "impulsedenoise.h" -#include "defringe.h" -#include "dirpyrdenoise.h" -#include "epd.h" -#include "sharpening.h" -#include "labcurve.h" -#include "metadatapanel.h" -#include "crop.h" -#include "icmpanel.h" -#include "resize.h" -#include "chmixer.h" -#include "blackwhite.h" -#include "cacorrection.h" -#include "lensprofile.h" -#include "distortion.h" -#include "perspective.h" -#include "rotate.h" -#include "vignetting.h" -#include "retinex.h" -#include "gradient.h" -#include "spot.h" -#include "pcvignette.h" -#include "toolbar.h" -#include "lensgeom.h" -#include "lensgeomlistener.h" -#include "wavelet.h" -#include "dirpyrequalizer.h" -#include "hsvequalizer.h" -#include "preprocess.h" + #include "bayerpreprocess.h" #include "bayerprocess.h" -#include "xtransprocess.h" +#include "bayerrawexposure.h" +#include "blackwhite.h" +#include "cacorrection.h" +#include "chmixer.h" +#include "coarsepanel.h" +#include "colorappearance.h" +#include "colortoning.h" +#include "crop.h" #include "darkframe.h" +#include "defringe.h" +#include "dehaze.h" +#include "dirpyrdenoise.h" +#include "dirpyrequalizer.h" +#include "distortion.h" +#include "epd.h" +#include "fattaltonemap.h" +#include "filmnegative.h" +#include "filmsimulation.h" #include "flatfield.h" -#include "sensorbayer.h" -#include "sensorxtrans.h" +#include "gradient.h" +#include "guiutils.h" +#include "hsvequalizer.h" +#include "icmpanel.h" +#include "imageareatoollistener.h" +#include "impulsedenoise.h" +#include "labcurve.h" +#include "lensgeom.h" +#include "lensgeomlistener.h" +#include "lensprofile.h" +#include "localcontrast.h" +#include "pcvignette.h" +#include "pdsharpening.h" +#include "perspective.h" +#include "pparamschangelistener.h" +#include "preprocess.h" +#include "profilechangelistener.h" +#include "prsharpening.h" #include "rawcacorrection.h" #include "rawexposure.h" -#include "bayerrawexposure.h" -#include "xtransrawexposure.h" -#include "sharpenmicro.h" -#include "sharpenedge.h" +#include "resize.h" +#include "retinex.h" #include "rgbcurves.h" -#include "colortoning.h" -#include "filmsimulation.h" -#include "prsharpening.h" -#include "pdsharpening.h" -#include "fattaltonemap.h" -#include "localcontrast.h" +#include "rotate.h" +#include "sensorbayer.h" +#include "sensorxtrans.h" +#include "shadowshighlights.h" +#include "sharpenedge.h" +#include "sharpening.h" +#include "sharpenmicro.h" #include "softlight.h" -#include "dehaze.h" -#include "guiutils.h" -#include "filmnegative.h" +#include "spot.h" +#include "tonecurve.h" +#include "toolbar.h" +#include "toolpanel.h" +#include "vibrance.h" +#include "vignetting.h" +#include "wavelet.h" +#include "whitebalance.h" +#include "xtransprocess.h" +#include "xtransrawexposure.h" + #include "../rtengine/noncopyable.h" +#include "../rtengine/rtengine.h" class ImageEditorCoordinator; +class MetaDataPanel; class ToolPanelCoordinator : public ToolPanelListener, @@ -337,5 +339,3 @@ public: private: IdleRegister idle_register; }; - -#endif diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 461c4a79f..4a9fab3d3 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -18,6 +18,10 @@ */ #include "vibrance.h" + +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "options.h" #include "../rtengine/color.h" using namespace rtengine; diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index 606bfa80a..12acc7948 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -16,18 +16,25 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _VIBRANCE_ -#define _VIBRANCE_ +#pragma once #include + #include "adjuster.h" +#include "curvelistener.h" #include "thresholdadjuster.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" #include "toolpanel.h" -class Vibrance : public ToolParamBlock, public AdjusterListener, public ThresholdCurveProvider, public ThresholdAdjusterListener, - public FoldableToolPanel, public CurveListener +class CurveEditorGroup; +class DiagonalCurveEditor; + +class Vibrance final : + public ToolParamBlock, + public AdjusterListener, + public ThresholdCurveProvider, + public ThresholdAdjusterListener, + public FoldableToolPanel, + public CurveListener { protected: @@ -76,6 +83,3 @@ public: void pastsattog_toggled (); std::vector getCurvePoints(ThresholdSelector* tAdjuster) const override; }; - - -#endif diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h index 094869f67..be7765094 100644 --- a/rtgui/vignetting.h +++ b/rtgui/vignetting.h @@ -16,14 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _VIGNETTING_H_ -#define _VIGNETTING_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -class Vignetting : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class Vignetting final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -46,5 +49,3 @@ public: void setAdjusterBehavior (bool amountadd, bool radiusadd, bool strengthadd, bool centeradd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 94f96e0cc..3981457e6 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -20,13 +20,16 @@ #include "wavelet.h" #include +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "editcallbacks.h" #include "guiutils.h" #include "rtimage.h" +#include "options.h" +#include "../rtengine/color.h" using namespace rtengine; using namespace rtengine::procparams; -extern Options options; namespace { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index feec85fc9..6551b58d4 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -22,16 +22,18 @@ #include #include "adjuster.h" #include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "thresholdadjuster.h" #include "colorprovider.h" #include "guiutils.h" -#include "options.h" +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; +class FlatCurveEditor; -class Wavelet : +class Wavelet final : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h index 31ba8331a..a56d93cd3 100644 --- a/rtgui/wbprovider.h +++ b/rtgui/wbprovider.h @@ -16,9 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _WBPROVIDER_ -#define _WBPROVIDER_ - +#pragma once class WBProvider { @@ -29,5 +27,3 @@ public: virtual void getCamWB (double& temp, double& green) {} virtual void spotWBRequested (int size) {} }; - -#endif diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 109fb7502..2ab09c10a 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -55,7 +55,7 @@ void WhiteBalance::init () void WhiteBalance::cleanup () { - for (unsigned int i = 0; i < toUnderlying(WBEntry::Type::CUSTOM) + 1; i++) { + for (int i = 0; i < toUnderlying(WBEntry::Type::CUSTOM) + 1; i++) { wbPixbufs[i].reset(); } } diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index fd7efe7ce..b4d09f119 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -16,15 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _WB_H_ -#define _WB_H_ +#pragma once #include -#include "toolpanel.h" + #include "adjuster.h" #include "guiutils.h" +#include "toolpanel.h" #include "wbprovider.h" + #include "../rtengine/procparams.h" +#include "../rtengine/utils.h" class SpotWBListener { @@ -33,7 +35,7 @@ public: virtual void spotWBRequested(int size) = 0; }; -class WhiteBalance : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoWBListener +class WhiteBalance final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoWBListener { enum WB_LabelType { @@ -123,5 +125,3 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void enabledChanged() override; }; - -#endif diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 52c46be65..a371bad88 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -225,7 +225,7 @@ void XTransProcess::adjusterChanged(Adjuster* a, double newval) } } -void XTransProcess::adjusterAutoToggled(Adjuster* a, bool newval) +void XTransProcess::adjusterAutoToggled(Adjuster* a) { if (multiImage) { if (dualDemosaicContrast->getAutoInconsistent()) { diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index dae93822f..fc0dd7502 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -16,17 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _XTRANSPROCESS_H_ -#define _XTRANSPROCESS_H_ +#pragma once #include + #include "adjuster.h" #include "checkbox.h" #include "guiutils.h" #include "toolpanel.h" - -class XTransProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::AutoContrastListener +class XTransProcess final : + public ToolParamBlock, + public AdjusterListener, + public CheckBoxListener, + public FoldableToolPanel, + public rtengine::AutoContrastListener { protected: @@ -62,7 +66,5 @@ public: void autoContrastChanged (double autoContrast) override; void adjusterChanged(Adjuster* a, double newval) override; void checkBoxToggled(CheckBox* c, CheckValue newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; + void adjusterAutoToggled(Adjuster* a) override; }; - -#endif diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h index 08cdcc8bf..a8daf6972 100644 --- a/rtgui/xtransrawexposure.h +++ b/rtgui/xtransrawexposure.h @@ -16,15 +16,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _XTRANSRAWEXPOSURE_H_ -#define _XTRANSRAWEXPOSURE_H_ +#pragma once #include + #include "adjuster.h" #include "toolpanel.h" -#include "../rtengine/rawimage.h" -class XTransRAWExposure : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class XTransRAWExposure final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel { protected: @@ -46,5 +48,3 @@ public: void setAdjusterBehavior (bool pexblackadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; - -#endif diff --git a/rtgui/zoompanel.h b/rtgui/zoompanel.h index e1cb651e3..49e1e848d 100644 --- a/rtgui/zoompanel.h +++ b/rtgui/zoompanel.h @@ -16,13 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _ZOOMPANEL_ -#define _ZOOMPANEL_ +#pragma once #include class ImageArea; -class ZoomPanel : public Gtk::Grid + +class ZoomPanel : + public Gtk::Grid { protected: @@ -48,6 +49,3 @@ public: void newCropClicked (); void refreshZoomLabel (); }; - -#endif - diff --git a/tools/RTProfileBuilderSample.cs b/tools/RTProfileBuilderSample.cs index a097e6883..80474b63b 100644 --- a/tools/RTProfileBuilderSample.cs +++ b/tools/RTProfileBuilderSample.cs @@ -1,293 +1,293 @@ -#region Usings -using System; -using System.Text; -using System.IO; -using System.Globalization; -using System.Diagnostics; -using System.Configuration; -using System.Collections; -using System.Collections.Specialized; -#endregion - -// *** Raw Therapee sample Custom Profile builder (version 2013-08-12) *** -// -// -// WARNING: The command line parameters has changed since this file has been created by Oduis. The new mechanism involves a -// temporary communication file (.ini style) to provide system parameters and metadata read by RawTherapee. This script has -// to be updated by some C# developer in order to work. -// -// -// WARNING: PP3 format may change in the future versions! If this happens there will probably be no automatic migration path, -// you'll have to adjust on your own. This is a sample, and therefore not supported by the RT team (just by oduis) -// -// -// How to use: -// 1. Modify the GetCorrectedSettings function below according to your needs. -// 2. Download and install Microsoft .Net Runtime (latest version is 4.0 as of writing), if it's not already on your machine. -// You can get it for free via Windows Update or from microsoft.com. No need for Visual Studio etc. -// 3. Open a command line and compile this CS-File using the C# 32bit compiler. It is usually installed somewhere here: -// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe -// Call csc.exe (C#-Compiler) with your .CS file as parameter like this (one big line): -// -// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc -// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll -// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Configuration.dll -// RTProfileBuilderSample.cs -// -// (On most machines it already works with "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc RTProfileBuilderSample.cs") -// CSC will compile it and emit an EXE. -// 4. Open your RT options files and find the entry [Profiles]/CustomProfileBuilder -// 5. Enter the path to your newly built exe here. On Windows, don't forget double slashes (e.g. "C:\\MyDir\\Mybuilder.exe") -// And you're done! The EXE is only called on opening the image editor and there is no PP3 already -// -// If you want to use EXIFTOOL to gather more details information to build queries: -// 1. Download exiftool.exe from http://www.sno.phy.queensu.ca/~phil/exiftool/ -// 2. Rename it to exiftool.exe (NOT exiftool(-k).. or something!) -// 3. Copy the RTProfilerBuilder.exe.config next to your own EXE. If you renamed it, rename config to "(Yourname).exe.config" -// 4. Open the config with notepad (it's an XML file). Set ExifToolPath to your downloaded and renamed exe -// -// If you want to know what parameters are available, call "exiftool.exe -tab -short" -// -// This description is for Windows. The C# code does not use anything fancy, will probably work with MONO on Linux/OSX, too - -namespace RTProfilerBuilder { - /// Main class. Mostly change GetCorrectedSettings. - class RTProfileBuilder { - - /// Adds the Nikkor zoom distortion correction profile. - /// First array is list of focal lengths, second array is the RT setting that should correct the - /// distortion for the corresponding focal length. Values between these values are automatically interpolated. - /// The focal length values must already be ordered. The number of sample points is not limited. - static DistortionCorrectProf distNikkor24120f4 = new DistortionCorrectProf( - new double[] { 24, 28, 35, 50, 70, 85, 120 }, - new double[] { -0.1, -0.063, -0.012, 0.018, 0.034, 0.04, 0.048 } - ); - - - /// This is your personalisation function - /// Full EXIF from EXIFTOOL (if configured). - /// Entry, like "Sharpening/Radius" - /// Current value (from default file) - /// FNumberExposure in seconds - /// Focal length in MMISO value - /// Lens from EXIFCamera from EXIF - /// The value to be written. Simply take the current value if you have nothing to touch. - static string GetCorrectedSetting(NameValueCollection exif, string sectionEntry, string value, - double fNumber, double exposureSecs, double focalLength, long iso, string lens, string camera) { - - string s; - - // We don't do anything to the value if it's not our camera - if (camera.EndsWith("NIKON D700", StringComparison.InvariantCultureIgnoreCase) && lens.Contains("24.0-120.0 mm f/4.0")) { - switch (sectionEntry) { - // Here is the place to adjust your settings - // Pretty simple: "SectionName/EntryName" in options file - - case "Vignetting Correction/Amount": - value = (fNumber < 8 && focalLength < 30) ? "30" : "0"; - break; - - case "RAW/CA": - value = ToBool(fNumber < 11); // Means "Enabled if fnumber<11, otherwise disabled" - break; - - case "Impulse Denoising/Enabled": - value = ToBool(iso >= 3200); - break; - - case "HLRecovery/Enabled": - value = ToBool(iso >= 1600); // Dynamic range decreases, so we'll probably need it - break; - - case "Color Boost/Amount": - if (iso >= 6400) value = "0"; // Colors will get poppy anyway... - break; - - case "Distortion/Amount": - // we already checked in the IF upstairs that this is "our" lens - value = distNikkor24120f4.GetDistortionAmount(focalLength); - break; - - // Add other parameters here. Mention this is case sensitive! - - default: break; // we don't touch values we don't care about - } - } // end if camera=xxx - - - // This is for camera independent settings - switch (sectionEntry) { - // These are parsed from EXIFTOOL and XMP in DNG (see http://en.wikipedia.org/wiki/Extensible_Metadata_Platform) - case "IPTC/City": - s = exif.Get("City"); - if (!String.IsNullOrEmpty(s)) value = s; - break; - - case "IPTC/Country": - s = exif.Get("Country"); - if (!String.IsNullOrEmpty(s)) value = s; - break; - - case "IPTC/Caption": - case "IPTC/Title": - s = exif.Get("Headline"); - if (!String.IsNullOrEmpty(s)) value = s; - break; - - // Add other parameters here. Mention this is case sensitive! - - default: break; // we don't touch values we don't care about - } - return value; - } - - #region * Main and Helpers - static string ToBool(bool condition) { return condition ? "true" : "false"; } - static string ToFloat(float f) { return f.ToString(CultureInfo.InvariantCulture); } - - /// Reads default file and parses it. No need to touch it for your personal settings. - /// Command line args - /// 0 on all OK. - static int Main(string[] args) { - int exitCode = 0; - - try { - #region Parse input parameters - int argNo = 0; - - // Name of raw/JPG to process - string sourceFile = args[argNo++]; - - // What the user selected as his base profile - string defaultProfileFilePath = args[argNo++]; - - // Cache directory, for any logging file - string cachePath = args[argNo++]; - - - // True if the image is only being flagged as inTrash, rank or colorLabel but still need valid PP3 - actually not used by this script - bool forFlaggingPurpose = bool.Parse(args[argNo++], CultureInfo.InvariantCulture); - - // Note that old C++ has no automatic number globalization - double fNumber = double.Parse(args[argNo++], CultureInfo.InvariantCulture); - double exposureSecs = double.Parse(args[argNo++], CultureInfo.InvariantCulture); - double focalLength = double.Parse(args[argNo++], CultureInfo.InvariantCulture); - long iso = long.Parse(args[argNo++], CultureInfo.InvariantCulture); - - string lens = args[argNo++]; - string cameraMake = args[argNo++]; - string cameraModel = args[argNo++]; - string camera = cameraMake + " " + cameraModel; - #endregion - - // Read default file as basis - string[] lines = File.ReadAllLines(defaultProfileFilePath); - - NameValueCollection nvEXIF = ParseFullExifData(sourceFile); - - // File should be Windows ANSI - using (TextWriter tw = new StreamWriter(sourceFile + ".pp3", false, new UTF8Encoding(false))) { - string section = ""; - - foreach (string line in lines) { - string l = line.Trim(); - if (!String.IsNullOrEmpty(line)) { - - if (l.StartsWith("[")) - section = l.Trim(new char[] { '[', ']' }); - else if (char.IsLetterOrDigit(l[0]) && l.Contains("=")) { - int valPos = l.IndexOf("=") + 1; - - string newValue = GetCorrectedSetting(nvEXIF, section + "/" + l.Substring(0, valPos - 1), l.Substring(valPos).Trim(), - fNumber, exposureSecs, focalLength, iso, lens, camera); - - // Merge in new value - l = l.Substring(0, valPos) + (newValue ?? ""); - } - } - - tw.WriteLine(l); - } - } - - } catch (Exception ex) { - Console.WriteLine("Error: " + ex.ToString()); // can be seen in the RT console window - - exitCode = 1; - } - - return exitCode; - } - - - static NameValueCollection ParseFullExifData(string filePath) { - NameValueCollection nv = new NameValueCollection(); - - string exifToolPath = ConfigurationManager.AppSettings["ExifToolPath"]; - if (!String.IsNullOrEmpty(exifToolPath)) { - ProcessStartInfo psi = new ProcessStartInfo(exifToolPath, "\"" + filePath + "\" -tab -short"); - psi.CreateNoWindow = false; - psi.UseShellExecute = false; - psi.StandardOutputEncoding = System.Text.Encoding.UTF8; - psi.RedirectStandardOutput = true; - - Process p = Process.Start(psi); - - using (StreamReader sr = p.StandardOutput) { - while (!sr.EndOfStream) { - string line = sr.ReadLine(); - if (line.Contains("\t")) { - string[] split = line.Split('\t'); - nv.Add(split[0], split[1]); - } - } - } - - p.WaitForExit(); - } - - return nv; - } - - #endregion - } - - #region DistortionCorrectProf - /// Holds a distortion correction profile for one lens. Uses sample points (focal length vs. dist. correction) as input. - class DistortionCorrectProf { - double[] adFocLen, adCorrect; - - /// Parses array to internal structure - /// Focal lengths - /// Correction factors - public DistortionCorrectProf(double[] focLen, double[] correct) { - if (focLen == null || correct == null || focLen.Length != correct.Length || focLen.Length < 2) - throw new Exception("DistortionCorrectProf inputs must be valid and of the same lengths, at least 2 points"); - - adFocLen = focLen; adCorrect = correct; - - for (int i = 0; i < adFocLen.Length - 1; i++) - if (adFocLen[i] >= adFocLen[i + 1]) throw new Exception("The distortion correction focal length points must be ordered!"); - } - - /// Calculates regression value of RT distortion amount for the given focal length. - /// Input focal length. - /// Distortion in RT format. - public string GetDistortionAmount(double focalLength) { - // if it's out of area (which should just happen with e.g. rounding errors), return flat defaults. - if (focalLength <= adFocLen[0]) return adCorrect[0].ToString("G", CultureInfo.InvariantCulture); - if (focalLength >= adFocLen[adFocLen.Length - 1]) return adCorrect[adFocLen.Length - 1].ToString("G", CultureInfo.InvariantCulture); - - for (int i = 0; i < adFocLen.Length - 1; i++) { - if (focalLength >= adFocLen[i] && focalLength < adFocLen[i + 1]) { - // from the sample curves taken so far, it it safe to take a simple linear interpolation here - double corr = adCorrect[i] + (adCorrect[i + 1] - adCorrect[i]) * (focalLength - adFocLen[i]) / (adFocLen[i + 1] - adFocLen[i]); - return corr.ToString("G3", CultureInfo.InvariantCulture); - } - } - - return ""; // should never happen - } - } - #endregion -} +#region Usings +using System; +using System.Text; +using System.IO; +using System.Globalization; +using System.Diagnostics; +using System.Configuration; +using System.Collections; +using System.Collections.Specialized; +#endregion + +// *** Raw Therapee sample Custom Profile builder (version 2013-08-12) *** +// +// +// WARNING: The command line parameters has changed since this file has been created by Oduis. The new mechanism involves a +// temporary communication file (.ini style) to provide system parameters and metadata read by RawTherapee. This script has +// to be updated by some C# developer in order to work. +// +// +// WARNING: PP3 format may change in the future versions! If this happens there will probably be no automatic migration path, +// you'll have to adjust on your own. This is a sample, and therefore not supported by the RT team (just by oduis) +// +// +// How to use: +// 1. Modify the GetCorrectedSettings function below according to your needs. +// 2. Download and install Microsoft .Net Runtime (latest version is 4.0 as of writing), if it's not already on your machine. +// You can get it for free via Windows Update or from microsoft.com. No need for Visual Studio etc. +// 3. Open a command line and compile this CS-File using the C# 32bit compiler. It is usually installed somewhere here: +// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe +// Call csc.exe (C#-Compiler) with your .CS file as parameter like this (one big line): +// +// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc +// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll +// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Configuration.dll +// RTProfileBuilderSample.cs +// +// (On most machines it already works with "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc RTProfileBuilderSample.cs") +// CSC will compile it and emit an EXE. +// 4. Open your RT options files and find the entry [Profiles]/CustomProfileBuilder +// 5. Enter the path to your newly built exe here. On Windows, don't forget double slashes (e.g. "C:\\MyDir\\Mybuilder.exe") +// And you're done! The EXE is only called on opening the image editor and there is no PP3 already +// +// If you want to use EXIFTOOL to gather more details information to build queries: +// 1. Download exiftool.exe from http://www.sno.phy.queensu.ca/~phil/exiftool/ +// 2. Rename it to exiftool.exe (NOT exiftool(-k).. or something!) +// 3. Copy the RTProfilerBuilder.exe.config next to your own EXE. If you renamed it, rename config to "(Yourname).exe.config" +// 4. Open the config with notepad (it's an XML file). Set ExifToolPath to your downloaded and renamed exe +// +// If you want to know what parameters are available, call "exiftool.exe -tab -short" +// +// This description is for Windows. The C# code does not use anything fancy, will probably work with MONO on Linux/OSX, too + +namespace RTProfilerBuilder { + /// Main class. Mostly change GetCorrectedSettings. + class RTProfileBuilder { + + /// Adds the Nikkor zoom distortion correction profile. + /// First array is list of focal lengths, second array is the RT setting that should correct the + /// distortion for the corresponding focal length. Values between these values are automatically interpolated. + /// The focal length values must already be ordered. The number of sample points is not limited. + static DistortionCorrectProf distNikkor24120f4 = new DistortionCorrectProf( + new double[] { 24, 28, 35, 50, 70, 85, 120 }, + new double[] { -0.1, -0.063, -0.012, 0.018, 0.034, 0.04, 0.048 } + ); + + + /// This is your personalisation function + /// Full EXIF from EXIFTOOL (if configured). + /// Entry, like "Sharpening/Radius" + /// Current value (from default file) + /// FNumberExposure in seconds + /// Focal length in MMISO value + /// Lens from EXIFCamera from EXIF + /// The value to be written. Simply take the current value if you have nothing to touch. + static string GetCorrectedSetting(NameValueCollection exif, string sectionEntry, string value, + double fNumber, double exposureSecs, double focalLength, long iso, string lens, string camera) { + + string s; + + // We don't do anything to the value if it's not our camera + if (camera.EndsWith("NIKON D700", StringComparison.InvariantCultureIgnoreCase) && lens.Contains("24.0-120.0 mm f/4.0")) { + switch (sectionEntry) { + // Here is the place to adjust your settings + // Pretty simple: "SectionName/EntryName" in options file + + case "Vignetting Correction/Amount": + value = (fNumber < 8 && focalLength < 30) ? "30" : "0"; + break; + + case "RAW/CA": + value = ToBool(fNumber < 11); // Means "Enabled if fnumber<11, otherwise disabled" + break; + + case "Impulse Denoising/Enabled": + value = ToBool(iso >= 3200); + break; + + case "HLRecovery/Enabled": + value = ToBool(iso >= 1600); // Dynamic range decreases, so we'll probably need it + break; + + case "Color Boost/Amount": + if (iso >= 6400) value = "0"; // Colors will get poppy anyway... + break; + + case "Distortion/Amount": + // we already checked in the IF upstairs that this is "our" lens + value = distNikkor24120f4.GetDistortionAmount(focalLength); + break; + + // Add other parameters here. Mention this is case sensitive! + + default: break; // we don't touch values we don't care about + } + } // end if camera=xxx + + + // This is for camera independent settings + switch (sectionEntry) { + // These are parsed from EXIFTOOL and XMP in DNG (see http://en.wikipedia.org/wiki/Extensible_Metadata_Platform) + case "IPTC/City": + s = exif.Get("City"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + case "IPTC/Country": + s = exif.Get("Country"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + case "IPTC/Caption": + case "IPTC/Title": + s = exif.Get("Headline"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + // Add other parameters here. Mention this is case sensitive! + + default: break; // we don't touch values we don't care about + } + return value; + } + +#region * Main and Helpers + static string ToBool(bool condition) { return condition ? "true" : "false"; } + static string ToFloat(float f) { return f.ToString(CultureInfo.InvariantCulture); } + + /// Reads default file and parses it. No need to touch it for your personal settings. + /// Command line args + /// 0 on all OK. + static int Main(string[] args) { + int exitCode = 0; + + try { +#region Parse input parameters + int argNo = 0; + + // Name of raw/JPG to process + string sourceFile = args[argNo++]; + + // What the user selected as his base profile + string defaultProfileFilePath = args[argNo++]; + + // Cache directory, for any logging file + string cachePath = args[argNo++]; + + + // True if the image is only being flagged as inTrash, rank or colorLabel but still need valid PP3 - actually not used by this script + bool forFlaggingPurpose = bool.Parse(args[argNo++], CultureInfo.InvariantCulture); + + // Note that old C++ has no automatic number globalization + double fNumber = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + double exposureSecs = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + double focalLength = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + long iso = long.Parse(args[argNo++], CultureInfo.InvariantCulture); + + string lens = args[argNo++]; + string cameraMake = args[argNo++]; + string cameraModel = args[argNo++]; + string camera = cameraMake + " " + cameraModel; +#endregion + + // Read default file as basis + string[] lines = File.ReadAllLines(defaultProfileFilePath); + + NameValueCollection nvEXIF = ParseFullExifData(sourceFile); + + // File should be Windows ANSI + using (TextWriter tw = new StreamWriter(sourceFile + ".pp3", false, new UTF8Encoding(false))) { + string section = ""; + + foreach (string line in lines) { + string l = line.Trim(); + if (!String.IsNullOrEmpty(line)) { + + if (l.StartsWith("[")) + section = l.Trim(new char[] { '[', ']' }); + else if (char.IsLetterOrDigit(l[0]) && l.Contains("=")) { + int valPos = l.IndexOf("=") + 1; + + string newValue = GetCorrectedSetting(nvEXIF, section + "/" + l.Substring(0, valPos - 1), l.Substring(valPos).Trim(), + fNumber, exposureSecs, focalLength, iso, lens, camera); + + // Merge in new value + l = l.Substring(0, valPos) + (newValue ?? ""); + } + } + + tw.WriteLine(l); + } + } + + } catch (Exception ex) { + Console.WriteLine("Error: " + ex.ToString()); // can be seen in the RT console window + + exitCode = 1; + } + + return exitCode; + } + + + static NameValueCollection ParseFullExifData(string filePath) { + NameValueCollection nv = new NameValueCollection(); + + string exifToolPath = ConfigurationManager.AppSettings["ExifToolPath"]; + if (!String.IsNullOrEmpty(exifToolPath)) { + ProcessStartInfo psi = new ProcessStartInfo(exifToolPath, "\"" + filePath + "\" -tab -short"); + psi.CreateNoWindow = false; + psi.UseShellExecute = false; + psi.StandardOutputEncoding = System.Text.Encoding.UTF8; + psi.RedirectStandardOutput = true; + + Process p = Process.Start(psi); + + using (StreamReader sr = p.StandardOutput) { + while (!sr.EndOfStream) { + string line = sr.ReadLine(); + if (line.Contains("\t")) { + string[] split = line.Split('\t'); + nv.Add(split[0], split[1]); + } + } + } + + p.WaitForExit(); + } + + return nv; + } + +#endregion + } + +#region DistortionCorrectProf + /// Holds a distortion correction profile for one lens. Uses sample points (focal length vs. dist. correction) as input. + class DistortionCorrectProf { + double[] adFocLen, adCorrect; + + /// Parses array to internal structure + /// Focal lengths + /// Correction factors + public DistortionCorrectProf(double[] focLen, double[] correct) { + if (focLen == null || correct == null || focLen.Length != correct.Length || focLen.Length < 2) + throw new Exception("DistortionCorrectProf inputs must be valid and of the same lengths, at least 2 points"); + + adFocLen = focLen; adCorrect = correct; + + for (int i = 0; i < adFocLen.Length - 1; i++) + if (adFocLen[i] >= adFocLen[i + 1]) throw new Exception("The distortion correction focal length points must be ordered!"); + } + + /// Calculates regression value of RT distortion amount for the given focal length. + /// Input focal length. + /// Distortion in RT format. + public string GetDistortionAmount(double focalLength) { + // if it's out of area (which should just happen with e.g. rounding errors), return flat defaults. + if (focalLength <= adFocLen[0]) return adCorrect[0].ToString("G", CultureInfo.InvariantCulture); + if (focalLength >= adFocLen[adFocLen.Length - 1]) return adCorrect[adFocLen.Length - 1].ToString("G", CultureInfo.InvariantCulture); + + for (int i = 0; i < adFocLen.Length - 1; i++) { + if (focalLength >= adFocLen[i] && focalLength < adFocLen[i + 1]) { + // from the sample curves taken so far, it it safe to take a simple linear interpolation here + double corr = adCorrect[i] + (adCorrect[i + 1] - adCorrect[i]) * (focalLength - adFocLen[i]) / (adFocLen[i + 1] - adFocLen[i]); + return corr.ToString("G3", CultureInfo.InvariantCulture); + } + } + + return ""; // should never happen + } + } +#endregion +} diff --git a/tools/RTProfileBuilderSample.exe.config b/tools/RTProfileBuilderSample.exe.config index 2dbb6b973..c054fce6c 100644 --- a/tools/RTProfileBuilderSample.exe.config +++ b/tools/RTProfileBuilderSample.exe.config @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + diff --git a/tools/camconst_creator.ods b/tools/camconst_creator.ods index 954abe6ac..8930587ba 100644 Binary files a/tools/camconst_creator.ods and b/tools/camconst_creator.ods differ diff --git a/tools/osx/Info.plist-bin.in b/tools/osx/Info.plist-bin.in index 20ce5a741..33abd4f7a 100644 --- a/tools/osx/Info.plist-bin.in +++ b/tools/osx/Info.plist-bin.in @@ -1,10 +1,10 @@ - - CFBundleName - RawTherapee-bin - CFBundleIdentifier - com.rawtherapee.rawtherapee - + + CFBundleName + RawTherapee-bin + CFBundleIdentifier + com.rawtherapee.rawtherapee + diff --git a/tools/osx/Info.plist.in b/tools/osx/Info.plist.in index e78db0cc4..eec1ab490 100644 --- a/tools/osx/Info.plist.in +++ b/tools/osx/Info.plist.in @@ -1,167 +1,167 @@ - - CFBundleDevelopmentRegion - English - CFBundleDisplayName - RawTherapee - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - pp3 - PP3 - - CFBundleTypeIconFile - profile.icns - CFBundleTypeName - RawTherapee Profile Data - CFBundleTypeRole - Editor - LSIsAppleDefaultForType - - LSItemContentTypes - - com.rawtherapee.pp3 - - - - CFBundleTypeExtensions - - 3FR - 3fr - ARW - arw - CR2 - cr2 - CRF - crf - CRW - crw - DCR - dcr - DNG - dng - FFF - fff - IIQ - iiq - KDC - kdc - MEF - mef - MOS - mos - MRW - mrw - NEF - nef - NRW - nrw - ORF - orf - PEF - pef - RAF - raf - RAW - raw - RW2 - rw2 - RWZ - rwz - SR2 - sr2 - SRF - srf - SRW - srw - - CFBundleTypeMIMETypes - - image/raw - - CFBundleTypeName - Camera Raw - CFBundleTypeRole - Viewer - - - CFBundleTypeExtensions - - JPEG - jpeg - JPG - jpg - PNG - png - TIF - tif - TIFF - tiff - - CFBundleTypeName - Image - CFBundleTypeRole - Viewer - - - CFBundleExecutable - rawtherapee - CFBundleGetInfoString - @version@, Copyright © 2004-2010 Gábor Horváth, 2010-2017 RawTherapee Development Team - CFBundleIconFile - rawtherapee.icns - CFBundleIdentifier - com.rawtherapee.rawtherapee - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - RawTherapee - CFBundlePackageType - APPL - CFBundleShortVersionString - @shortVersion@ - CFBundleSignature - ???? - CFBundleVersion - @shortVersion@ - LSExecutableArchitectures - - @arch@ - - NSHighResolutionCapable - - NSHumanReadableCopyright - Copyright © 2004-2010 Gábor Horváth, 2010-2017 RawTherapee Development Team - UTExportedTypeDeclarations - - - UTTypeConformsTo - - public.data - - UTTypeDescription - RawTherapee Profile Data - UTTypeIconFile - Icons.icns - UTTypeIdentifier - com.rawtherapee.pp3 - UTTypeReferenceURL - http://www.rawtherapee.com/ - UTTypeTagSpecification - - com.apple.ostype - PP3 - public.filename-extension - - pp3 - PP3 - - - - - + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + RawTherapee + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + pp3 + PP3 + + CFBundleTypeIconFile + profile.icns + CFBundleTypeName + RawTherapee Profile Data + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + com.rawtherapee.pp3 + + + + CFBundleTypeExtensions + + 3FR + 3fr + ARW + arw + CR2 + cr2 + CRF + crf + CRW + crw + DCR + dcr + DNG + dng + FFF + fff + IIQ + iiq + KDC + kdc + MEF + mef + MOS + mos + MRW + mrw + NEF + nef + NRW + nrw + ORF + orf + PEF + pef + RAF + raf + RAW + raw + RW2 + rw2 + RWZ + rwz + SR2 + sr2 + SRF + srf + SRW + srw + + CFBundleTypeMIMETypes + + image/raw + + CFBundleTypeName + Camera Raw + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + JPEG + jpeg + JPG + jpg + PNG + png + TIF + tif + TIFF + tiff + + CFBundleTypeName + Image + CFBundleTypeRole + Viewer + + + CFBundleExecutable + rawtherapee + CFBundleGetInfoString + @version@, Copyright © 2004-2010 Gábor Horváth, 2010-2017 RawTherapee Development Team + CFBundleIconFile + rawtherapee.icns + CFBundleIdentifier + com.rawtherapee.rawtherapee + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + RawTherapee + CFBundlePackageType + APPL + CFBundleShortVersionString + @shortVersion@ + CFBundleSignature + ???? + CFBundleVersion + @shortVersion@ + LSExecutableArchitectures + + @arch@ + + NSHighResolutionCapable + + NSHumanReadableCopyright + Copyright © 2004-2010 Gábor Horváth, 2010-2017 RawTherapee Development Team + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.data + + UTTypeDescription + RawTherapee Profile Data + UTTypeIconFile + Icons.icns + UTTypeIdentifier + com.rawtherapee.pp3 + UTTypeReferenceURL + http://www.rawtherapee.com/ + UTTypeTagSpecification + + com.apple.ostype + PP3 + public.filename-extension + + pp3 + PP3 + + + + + diff --git a/tools/osx/rt.entitlements b/tools/osx/rt.entitlements index 2236af138..082661401 100644 --- a/tools/osx/rt.entitlements +++ b/tools/osx/rt.entitlements @@ -1,20 +1,20 @@ - - application-identifier - com.rawtherapee.rawtherapee - com.apple.security.temporary-exception.files.absolute-path.read-write - - "/" - - com.apple.security.cs.allow-dyld-environment-variables - - com.apple.security.files.user-selected.read-write - - com.apple.security.app-sandbox - - com.apple.security.files.downloads.read-write - - + + application-identifier + com.rawtherapee.rawtherapee + com.apple.security.temporary-exception.files.absolute-path.read-write + + "/" + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.files.user-selected.read-write + + com.apple.security.app-sandbox + + com.apple.security.files.downloads.read-write + +