diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..328af2509 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,4 @@ +If you are filing a bug report, please first read the guide How to Write Useful Bug Reports: +http://rawpedia.rawtherapee.com/How_to_write_useful_bug_reports +You must provide the required information in order for your bug report to be valid. +Delete this text before posting. diff --git a/AUTHORS.txt b/AUTHORS.txt index 8c87a42c3..6aebfcf6e 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -12,6 +12,7 @@ Developement contributors, in last name alphabetical order: Oliver Duis Maciek Dworak Michael Ezra + Flössie Jean-Christophe Frisch Ilias Giarimis Steve Herrell @@ -32,7 +33,7 @@ Developement contributors, in last name alphabetical order: Ingo Weyrich Makoto Yoshida -Other contributors (profiles, ideas, mockups, testing, forum activity, translations, etc.), in last name/nickname alphabetical order: +Other contributors (profiles, ideas, mockups, testing, forum activity, translations, etc.), in last name alphabetical order: Marcin Bajor Thorsten Bartolomäus diff --git a/AboutThisBuild.cmake b/AboutThisBuild.cmake index 68dea478d..2163ed0cb 100644 --- a/AboutThisBuild.cmake +++ b/AboutThisBuild.cmake @@ -5,13 +5,13 @@ find_file(REL_INFO_FILE ReleaseInfo.cmake PATHS "${PROJECT_SOURCE_DIR}" NO_DEFAU if (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) # we look for the git command in this paths by order of preference if (WIN32) - find_file(GIT_CMD git.exe HINTS ENV Path PATH_SUFFIXES ../) + find_program(GIT_CMD git.exe HINTS ENV Path PATH_SUFFIXES ../) elseif (APPLE) - find_file(GIT_CMD git PATHS "/opt/local/bin" "/usr/local/bin" "/usr/bin") - find_file(GIT_CMD git) + find_program(GIT_CMD git PATHS "/opt/local/bin" "/usr/local/bin" "/usr/bin") + find_program(GIT_CMD git) set (SHELL "/bin/bash") else (WIN32) # Linux - find_file(GIT_CMD git) + find_program(GIT_CMD git) set (SHELL "/bin/bash") endif (WIN32) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4ecf0903..0173856b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,13 @@ else (WIN32) cmake_minimum_required(VERSION 2.6) endif (WIN32) +# must stay before the 'project' command +if(${CMAKE_EXTRA_GENERATOR} MATCHES "Eclipse CDT4") + set(CMAKE_CXX_COMPILER_ARG1 "-std=c++11" CACHE STRING "C++ version for eclipse" FORCE) + # users building with Eclipse should set CMAKE_ECLIPSE_VERSION through the command line to their current version of Eclipse + #set(CMAKE_ECLIPSE_VERSION "4.6.0" CACHE STRING "Eclipse version" FORCE) +endif() + PROJECT(RawTherapee) # the default target is 'Debug' @@ -255,7 +262,7 @@ if (WITH_BZIP) find_package(BZip2) if (BZIP2_FOUND) add_definitions (-DBZIP_SUPPORT) - set (EXTRA_INCDIR ${EXTRA_LIB} ${BZIP2_INCLUDE_DIR}) + set (EXTRA_INCDIR ${BZIP2_INCLUDE_DIR}) set (EXTRA_LIB ${EXTRA_LIB} ${BZIP2_LIBRARIES}) endif (BZIP2_FOUND) endif (WITH_BZIP) diff --git a/LICENSE.txt b/LICENSE.txt index 0de1c6985..1e9ad695f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,26 +1,23 @@ + RawTherapee - A powerful, cross-platform raw image processing program. + Copyright (C) 2004-2012 Gabor Horvath - RawTherapee - - -Copyright ©2004-2012 Gábor Horváth - -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 below for more details. + 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 this program. If not, see . GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - + Version 3, 29 June 2007 - Copyright ©2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -638,3 +635,4 @@ Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS + diff --git a/README.md b/README.md index 9dfd4c324..93dbfec59 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ RawTherapee is a powerful, cross-platform raw photo processing program, released ## Target audience -Rawtherapee is a [libre software](https://en.wikipedia.org/wiki/Free_software) designed for developing raw files from a broad range of digital cameras, as well as [HDR DNG](https://helpx.adobe.com/photoshop/digital-negative.html) files and non-raw image formats ([JPEG](https://en.wikipedia.org/wiki/JPEG), [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) and [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics)). The target audience ranges from enthusiast newcomers who whish 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](http://rawpedia.rawtherapee.com/)) as well as look up basic concepts which lie outside the scope of RawPedia, such as [color balance](https://en.wikipedia.org/wiki/Color_balance), elsewhere. +RawTherapee is a [libre software](https://en.wikipedia.org/wiki/Free_software) designed for developing raw files from a broad range of digital cameras, as well as [HDR DNG](https://helpx.adobe.com/photoshop/digital-negative.html) files and non-raw image formats ([JPEG](https://en.wikipedia.org/wiki/JPEG), [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) and [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics)). 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](http://rawpedia.rawtherapee.com/)) as well as look up basic concepts which lie outside the scope of RawPedia, such as [color balance](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/Digital_asset_management), printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the [open-source community](https://en.wikipedia.org/wiki/Open-source_movement) is sufficiently developed by now to offer all those peripheral features in other specialized software. @@ -13,6 +13,9 @@ Of course, professionals may use RawTherapee too while enjoying complete freedom Website: http://rawtherapee.com/ +Forum: +https://discuss.pixls.us/c/software/rawtherapee + Features: http://rawpedia.rawtherapee.com/Features @@ -25,9 +28,6 @@ http://rawtherapee.com/downloads Download source code tarballs: http://rawtherapee.com/shared/source/ -Source code documentation: -http://michaelezra.com/projects/rt/documentation/ - Git handbook: http://git-scm.com/book/en/ diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index c057d41a7..1c78bcd39 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -32,7 +32,8 @@ LIVE CHAT WITH USERS AND DEVELOPERS Network: freenode Server: chat.freenode.net Channel #rawtherapee -Or use freenode webchat to chat without installing anything: + +You can use freenode webchat to communicate without installing anything: http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 More information here: http://rawpedia.rawtherapee.com/IRC @@ -44,5 +45,5 @@ http://plus.google.com/106783532637761598368 REVISION HISTORY ---------------- The complete changelog is available at: -https://github.com/Beep6581/RawTherapee/commits/master +https://github.com/Beep6581/RawTherapee/commits/ diff --git a/doc/manpage/rawtherapee.1 b/doc/manpage/rawtherapee.1 index a626fd0bf..bbd2a4f44 100644 --- a/doc/manpage/rawtherapee.1 +++ b/doc/manpage/rawtherapee.1 @@ -1,86 +1,67 @@ -.TH RAWTHERAPEE 1 "July 31, 2012" +.TH RAWTHERAPEE 1 "July 05, 2016" .SH NAME -rawtherapee \- an advanced cross-platform program for developing raw photos. -.SH SYNOPSIS -\fBrawtherapee\fP [directory|image\-file] -.br -\fBrawtherapee\fP [\-o|\-O ] [\-s|\-S] [\-p ] [\-d] -[\-j[1\-100]|\-t|\-t1|\-n] [\-Y] \-c +RawTherapee - An advanced, cross-platform program for developing raw photos. .SH DESCRIPTION -\fBRawTherapee\fP is an advanced program for developing raw photos and for -processing non-raw photos. It is non-destructive, makes use of OpenMP, supports -all the cameras supported by dcraw and carries out its calculations in a high -precision 32bit floating point engine. +\fBRawTherapee\fP is an advanced program for developing raw photos and for processing non-raw photos. It is non-destructive, makes use of OpenMP, supports all the cameras supported by dcraw and more, and carries out its calculations in a high precision 32-bit floating point engine. +.SH LINKS + Website: http://www.rawtherapee.com/ + Documentation: http://rawpedia.rawtherapee.com/ + Forum: https://discuss.pixls.us/c/software/rawtherapee + Code and bug reports: https://github.com/Beep6581/RawTherapee +.SH SYMBOLS + indicate parameters you can change. + [Square brackets] mean the parameter is optional. + The pipe symbol | indicates a choice of one or the other. + The dash symbol - denotes a range of possible values from one to the other. +.SH SYNOPSIS + rawtherapee Start File Browser inside folder. + rawtherapee Start Image Editor with file. + rawtherapee -c | Convert files in batch with default parameters. + rawtherapee -c | Convert files in batch with your own settings. + rawtherapee [-o |-O ] [-s|-S] [-p [-p ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] -c .SH OPTIONS -.TP -\-o | -select output directory. -.TP -\-O | - select output directory and copy the PP3 file into it. -.TP -\-s -use the PP3 processing profile located next to the input file (which shares -same name as the input file) when building the processing parameters, e.g.: for -IMG001.NEF there should be a IMG001.NEF.pp3 in the same directory. If such a -file is not found, the default values are used. -.TP -\-S -like \-s but skip processing that image if its corresponding PP3 file is not -found. -.TP -\-p -specify a PP3 processing profile to be used for all conversions. You can -specify as many \-p options as you like (see note below). -.TP -\-d -use the default raw or non-raw PP3 file to build the image's parameters -(specified in the options file). -.TP -\-j[1\-100] -specify output to be JPEG (default). The compression value can be in the range -1-100. If none was specified, the default compression value is 90, balanced -subsampling (4:2:2). -.TP -\-t -specify output to be uncompressed 8 bit per channel TIFF. -.TP -\-t1 -specify output to be zip-compressed 8 bit per channel TIFF. -.TP -\-n -specify output to be 8 bit per channel PNG with a compression value of 6. -.TP -\-Y -overwrite output if present. + -c Specify one or more input files. + -c must be the last option. + -o | Set output file or folder. + Saves output file alongside input file if -o is not specified. + -O | Set output file or folder and copy pp3 file into it. + Saves output file alongside input file if -O is not specified. + -s Use the existing sidecar file to build the processing parameters, + e.g. for photo.raw there should be a photo.raw.pp3 file in the same folder. + If the sidecar file does not exist, neutral values will be used. + -S Like -s but skip if the sidecar file does not exist. + -p Specify processing profile to be used for all conversions. + You can specify as many sets of "-p " options as you like, + each will be built on top of the previous one, as explained below. + -d Use the default raw or non-raw processing profile as set in + Preferences > Image Processing > Default Processing Profile + -j[1-100] Specify output to be JPEG (default, if -t and -n are not set). + Optionally, specify compression 1-100 (default value: 92). + -js<1-3> Specify the JPEG chroma subsampling parameter, where: + 1 = Best compression: 2x2, 1x1, 1x1 (4:2:0) + Chroma halved vertically and horizontally. + 2 = Balanced (default): 2x1, 1x1, 1x1 (4:2:2) + Chroma halved horizontally. + 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4) + No chroma subsampling. + -b<8|16> Specify bit depth per channel (default value: 16 for TIFF, 8 for PNG). + Only applies to TIFF and PNG output, JPEG is always 8. + -t[z] Specify output to be TIFF. + Uncompressed by default, or deflate compression with 'z'. + -n Specify output to be compressed PNG. + Compression is hard-coded to 6. + -Y Overwrite output if present. -.P -.B Note: -.br -You can use partial PP3 files, in which case RawTherapee will set the -missing values as follows: -.br - The PP3 file is first built with internal default values; -.br - then overridden by those found in the "default raw" or "default non-raw" photo -profile (if \-d has been set); -.br - then overridden by those found in the PP3 files provided by \-p, each one -overriding the previous values; -.br - then overridden by the sidecar file if \-s is set and if the file exists; -.br - the time when the sidecar file is used depends of the position of the \-s -switch in the command line relative to the \-p parameters -(e.g. "\-p first.pp3 \-p second.pp3 \-s \-p fourth.pp3"). -.SH SEE ALSO -You can find the documentation, including a detailed user manual, on the -project's website: -http://rawtherapee.com/blog/documentation +Your pp3 files can be incomplete, RawTherapee will build the final values as follows: + 1- A new processing profile is created using neutral values, + 2- If the "-d" option is set, the values are overridden by those found in + the default raw or non-raw processing profile. + 3- If one or more "-p" options are set, the values are overridden by those + found in these processing profiles. + 4- If the "-s" or "-S" options are set, the values are finally overridden by those + found in the sidecar files. + The processing profiles are processed in the order specified on the command line. .SH AUTHOR -\fBRawTherapee\fP was originally written by Gabor Horvath of Budapest, -Hungary, before being relicensed as free and open-source software in January -2010 and being maintained by a team of people since. +\fBRawTherapee\fP was originally written by Gabor Horvath of Budapest, Hungary, before being re-licensed as free and open-source software in January 2010. .br -The RawTherapee Development Team comprises of passionate people from all around -the world. +The RawTherapee development team comprises of passionate people from all around the world. diff --git a/rawtherapee.astylerc b/rawtherapee.astylerc index 9c10d81cb..3a0b1ea2f 100644 --- a/rawtherapee.astylerc +++ b/rawtherapee.astylerc @@ -1,5 +1,6 @@ style=1tbs indent=spaces=4 +indent-switches break-blocks pad-oper convert-tabs diff --git a/rtdata/dcpprofiles/Fujifilm X-T1.dcp b/rtdata/dcpprofiles/Fujifilm X-T1.dcp index 494941e22..5d6c48b28 100644 Binary files a/rtdata/dcpprofiles/Fujifilm X-T1.dcp and b/rtdata/dcpprofiles/Fujifilm X-T1.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D7200.dcp b/rtdata/dcpprofiles/Nikon D7200.dcp new file mode 100644 index 000000000..01e5cfa13 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D7200.dcp differ diff --git a/rtdata/dcpprofiles/Sony ILCE-6000.dcp b/rtdata/dcpprofiles/Sony ILCE-6000.dcp new file mode 100644 index 000000000..5ef8c4d31 Binary files /dev/null and b/rtdata/dcpprofiles/Sony ILCE-6000.dcp differ diff --git a/rtdata/iccprofiles/output/Rec2020.icm b/rtdata/iccprofiles/output/Rec2020.icm new file mode 100644 index 000000000..0decaf6dc Binary files /dev/null and b/rtdata/iccprofiles/output/Rec2020.icm differ diff --git a/rtgui/RT.ico b/rtdata/icons/RT.ico similarity index 100% rename from rtgui/RT.ico rename to rtdata/icons/RT.ico diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 7ed78149f..d54566400 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -335,7 +335,7 @@ HISTORY_MSG_145;Microcontrast - uniformitat HISTORY_MSG_146;Afinament de vores HISTORY_MSG_147;Afinant vores - només luminància HISTORY_MSG_148;Microcontrast -HISTORY_MSG_149;Microcontrast - matriu 3x3 +HISTORY_MSG_149;Microcontrast - matriu 3×3 HISTORY_MSG_150;Artefactes en post-demosaicat/reducció de soroll HISTORY_MSG_151;Vibrància HISTORY_MSG_152;Vibrància - tons pastel @@ -1031,9 +1031,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_CLOSE;Close +!GENERAL_OPEN;Open !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_174;CIECAM02 @@ -1271,14 +1273,14 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1300,8 +1302,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1620,11 +1624,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1662,12 +1667,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1678,7 +1683,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1780,8 +1784,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1801,6 +1809,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1820,10 +1829,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1831,6 +1841,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 5c6f5a39f..9b6385249 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -892,7 +892,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. !HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. @@ -943,7 +945,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_144;Microcontrast - Quantity !HISTORY_MSG_145;Microcontrast - Uniformity !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -1188,14 +1190,14 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1217,8 +1219,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). @@ -1554,11 +1558,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1598,12 +1603,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1613,7 +1618,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1750,8 +1754,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1771,6 +1779,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1790,10 +1799,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1801,6 +1811,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) index c79d07525..c797a80d8 100644 --- a/rtdata/languages/Chinese (Traditional) +++ b/rtdata/languages/Chinese (Traditional) @@ -586,11 +586,13 @@ TP_WBALANCE_TEMPERATURE;色溫 !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. @@ -663,7 +665,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -923,14 +925,14 @@ TP_WBALANCE_TEMPERATURE;色溫 !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -952,8 +954,10 @@ TP_WBALANCE_TEMPERATURE;色溫 !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1428,11 +1432,12 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1475,12 +1480,12 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1491,7 +1496,6 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1712,8 +1716,12 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1733,6 +1741,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1752,10 +1761,11 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1763,6 +1773,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index e1c7bc704..f3142f30d 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -1354,11 +1354,6 @@ TP_DARKFRAME_LABEL;Tmavý snímek TP_DEFRINGE_LABEL;Odstranění lemu TP_DEFRINGE_RADIUS;Poloměr TP_DEFRINGE_THRESHOLD;Práh -TP_DIRPYRDENOISE_33;3×3 silný -TP_DIRPYRDENOISE_55;5×5 silný -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (pomalý) -TP_DIRPYRDENOISE_99;9x9 (velmi pomalé) TP_DIRPYRDENOISE_ABM;Pouze barevnost TP_DIRPYRDENOISE_AUT;Automatická celková TP_DIRPYRDENOISE_AUTO;Automatická celková @@ -1401,12 +1396,10 @@ TP_DIRPYRDENOISE_METHOD11;Kvalita TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Kvalita může být přizpůsobena vzoru šumu. Nastavení "Vysoká" vylepší efekt redukce šumu za cenu navýšení času zpracování. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Pro raw obrázky může být použita jak RGB tak i L*a*b* metoda.\n\nPro ostatní obrázky bude vždy použita metoda L*a*b* bez ohledu na výběr. TP_DIRPYRDENOISE_METM_TOOLTIP;Pokud je použito 'Pouze Jas' a 'L*a*b*' metody, bude při odstranění šumu použit filtr medián hned po vlnkové transformaci.\nPokud je použit "RGB" mód, bude filtr použit až na úplný závěr procesu redukce šumu. -TP_DIRPYRDENOISE_MET_TOOLTIP;Aplikuje filtr medián požadované velikosti. Čím větší velikost, tím déle to trvá.\n\n3×3 jemný: upraví 5 pixelů v rozsahu jednoho pixelu.\n3×3: upraví 9 pixelů v rozsahu jednoho pixelu.\n5×5 jemný; upraví 13 pixelů v rozsahu dvou pixelů.\n5×5: upraví 25 pixelů v rozsahu dvou pixelů.\n7×7: upraví 49 pixelů v rozsahu tří pixelů.\n9×9: upraví 81 pixelů v rozsahu čtyř pixelů.\n\nV některých případech může být větší kvality dosaženo pomocí několika průběhů s menším rozsahem než jedním průběhem s velkým rozsahem. TP_DIRPYRDENOISE_NOISELABEL;Náhled šumu: Průměr=%1 Výšky=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;Náhled šumu: Průměr= - Výšky= - TP_DIRPYRDENOISE_NRESID_TOOLTIP;Zobrazuje zbývající úroveň zašumění části obrázku viditelného v náhledu po vlnkové transformaci.\n\n>300 Hodně šumu\n100-300 Šum\n50-100 Málo šumu\n<50 Velmi málo šumu\n\nUpozornění: hodnoty RGB a L*a*b* režimu se budou lišit. Protože v RGB režimu nedochází ke kompletnímu oddělení jasu a barev jsou RGB hodnoty jméně přesné TP_DIRPYRDENOISE_PASSES;Počet průchodů mediánu -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Aplikování medián filtru 3×3 se třemi průchody často vede k lepšímu výsledku než jednou aplikovaný filtr 7×7. TP_DIRPYRDENOISE_PON;Více zónová automatika TP_DIRPYRDENOISE_PRE;Více zónový náhled TP_DIRPYRDENOISE_PREV;Náhled @@ -1417,7 +1410,6 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Běžná TP_DIRPYRDENOISE_SHALBI;Vysoká TP_DIRPYRDENOISE_SLI;Posuvník -TP_DIRPYRDENOISE_SOFT;3×3 TP_DIRPYRDENOISE_TILELABEL;Velikost dlaždice=%1, Střed: Tx=%2 Ty=%3 TP_DIRPYREQUALIZER_ALGO;Rozsah pleťových tónů TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Jemný: blíž k barvám pleti, minimalizuje zásahy na ostatních barvách.\nVelký: více zabrání vzniku artefaktů. @@ -1996,6 +1988,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !!!!!!!!!!!!!!!!!!!!!!!!! !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!GENERAL_APPLY;Apply +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_427;Output rendering intent !HISTORY_MSG_428;Monitor rendering intent @@ -2009,8 +2003,10 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_PRSHARPENING;Post-resize sharpening @@ -2023,6 +2019,14 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_CBDL_BEF;Before Black-and-White !TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !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_PROFILEINTENT;Rendering Intent !TP_NEUTRAL;Reset @@ -2030,11 +2034,16 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_RETINEX_CONTEDIT_MAP;Mask equalizer !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GRAD;Transmission gradient !TP_RETINEX_GRADS;Strength gradient !TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Strength is reduced when iterations increase, and conversely. !TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Variance and Threshold are reduced when iterations increase, and conversely. !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL_MASK;Mask !TP_RETINEX_MAP;Mask method @@ -2045,6 +2054,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_RETINEX_MAP_NONE;None !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. +!TP_RETINEX_SKAL;Scale +!TP_RETINEX_TRANF;Transmission !TP_RETINEX_VIEW;Process !TP_RETINEX_VIEW_MASK;Mask !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. diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 46e8049d6..67ab884c8 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;Temperatur !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 48a293051..9c7478cf7 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -27,6 +27,8 @@ #26 2015-12-22 Korrekturen (TooWaBoo) RT4.2.536 #27 2016-02-12 Retinexübersetzung (TooWaBoo) RT4.2.730 #28 2016-03-19 Erweiterung/Korrekturen (TooWaBoo) RT4.2.880 +#29 2016-05-24 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1005 +#30 2016-09-30 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1234 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -45,7 +47,7 @@ CURVEEDITOR_CURVE;Kurve CURVEEDITOR_CURVES;Kurven CURVEEDITOR_CUSTOM;Angepasst CURVEEDITOR_DARKS;Tiefen -CURVEEDITOR_EDITPOINT_HINT;Bearbeitung der Kurvenpunkte über Zahlenwerte.\n\nRechtsklick auf einen Kurvenpunkt um ihn auszuwählen. Rechtsklick in einen leeren Bereich um ihn abzuwählen. +CURVEEDITOR_EDITPOINT_HINT;Bearbeitung der Kurvenpunkte über Zahlenwerte.\n\nRechtsklick auf einen Kurvenpunkt um ihn auszuwählen.\nRechtsklick in einen leeren Bereich um ihn abzuwählen. CURVEEDITOR_HIGHLIGHTS;Spitzlichter CURVEEDITOR_LIGHTS;Lichter CURVEEDITOR_LINEAR;Linear @@ -226,7 +228,7 @@ FILECHOOSER_FILTER_TIFF;TIFF-Dateien GENERAL_ABOUT;Über GENERAL_AFTER;Nachher GENERAL_APPLY;Anwenden -GENERAL_ASIMAGE;Als Bild +GENERAL_ASIMAGE;Wie Bild GENERAL_AUTO;Automatisch GENERAL_BEFORE;Vorher GENERAL_CANCEL;Abbrechen @@ -367,7 +369,7 @@ HISTORY_MSG_105;(Farbsaum entfernen) HISTORY_MSG_106;(Farbsaum entfernen)\nRadius HISTORY_MSG_107;(Farbsaum entfernen)\nSchwellenwert HISTORY_MSG_108;(Belichtung)\nLichterkompression\nSchwellenwert -HISTORY_MSG_109;(Skalieren) - Breite & Höhe +HISTORY_MSG_109;(Skalieren) - Begrenzungsrahmen HISTORY_MSG_110;(Skalieren) - Anwenden auf: HISTORY_MSG_111;(L*a*b*) - Farbverschiebung\nvermeiden HISTORY_MSG_112;--unused-- @@ -667,28 +669,28 @@ HISTORY_MSG_406;(Wavelet)\nKantenschärfung\nBenachbarte Pixel HISTORY_MSG_407;(Retinex) - Methode HISTORY_MSG_408;(Retinex) - Radius HISTORY_MSG_409;(Retinex) - Einstellungen\nKontrast -HISTORY_MSG_410;(Retinex) - Einstellungen\nHelligkeit +HISTORY_MSG_410;(Retinex) - Einstellungen\nVerstärkung und Ausgleich\nAusgleich HISTORY_MSG_411;(Retinex) - Intensität -HISTORY_MSG_412;(Retinex)\nGaußscher Gradient +HISTORY_MSG_412;(Retinex) - Einstellungen\nDynamikkompression\nGaußscher Gradient HISTORY_MSG_413;(Retinex) - Kontrast -HISTORY_MSG_414;(Retinex) - Einstellungen\nLuminanz(L) - L*a*b* -HISTORY_MSG_415;(Retinex) - Einstellungen\nTransmissionskurve +HISTORY_MSG_414;(Retinex) - Einstellungen\nKorrekturen\nLuminanz(L) - L*a*b* +HISTORY_MSG_415;(Retinex) - Einstellungen\nTransmission\nTransmissionskurve HISTORY_MSG_416;(Retinex) -HISTORY_MSG_417;(Retinex) - Einstellungen\nTransmission Median-\nfilter +HISTORY_MSG_417;(Retinex) - Einstellungen\nTransmission\nMedianfilter HISTORY_MSG_418;(Retinex) - Einstellungen\nTransmission\nSchwellenwert HISTORY_MSG_419;(Retinex) - Farbraum HISTORY_MSG_420;(Retinex) - Einstellungen\nHSL-Kurve -HISTORY_MSG_421;(Retinex) - Einstellungen\nGammakorrektur +HISTORY_MSG_421;(Retinex) - Einstellungen\nKorrekturen\nGammakorrektur HISTORY_MSG_422;(Retinex) - Einstellungen\nGamma HISTORY_MSG_423;(Retinex) - Einstellungen\nGammasteigung HISTORY_MSG_424;(Retinex) - Einstellungen\nHL-Schwellenwert HISTORY_MSG_425;(Retinex) - Einstellungen\nBasis-Logarithmus -HISTORY_MSG_426;(Retinex) - Einstellungen\nFarbton (H) +HISTORY_MSG_426;(Retinex) - Einstellungen\nKorrekturen - Farbton (H) HISTORY_MSG_427;Ausgabe-Rendering-Intent HISTORY_MSG_428;Monitor-Rendering-Intent -HISTORY_MSG_429;(Retinex) - Einstellungen\nIterationen -HISTORY_MSG_430;(Retinex) - Einstellungen\nTransmission Gradient -HISTORY_MSG_431;(Retinex) - Einstellungen\nIntensität Gradient +HISTORY_MSG_429;(Retinex) - Einstellungen\nDynamikkompression\nIterationen +HISTORY_MSG_430;(Retinex) - Einstellungen\nDynamikkompression\nTransmission Gradient +HISTORY_MSG_431;(Retinex) - Einstellungen\nDynamikkompression\nIntensität Gradient HISTORY_MSG_432;(Retinex) - Maske\nLichter HISTORY_MSG_433;(Retinex) - Maske\nTonwertbreite Lichter HISTORY_MSG_434;(Retinex) - Maske\nSchatten @@ -698,6 +700,8 @@ HISTORY_MSG_437;(Retinex) - Maske\nMethode HISTORY_MSG_438;(Retinex) - Maske\nKurve HISTORY_MSG_439;(Retinex) - Vorschau HISTORY_MSG_440;(Detailebenenkontrast)\nProzessreihenfolge +HISTORY_MSG_441;(Retinex) - Einstellungen\nVerstärkung und Ausgleich\nTransmissionsverstärkung +HISTORY_MSG_442;(Retinex) - Einstellungen\nTransmission - Skalierung HISTORY_NEWSNAPSHOT;Hinzufügen HISTORY_NEWSNAPSHOT_TOOLTIP;Taste: Alt + s HISTORY_SNAPSHOT;Schnappschuss @@ -1377,11 +1381,12 @@ TP_DARKFRAME_LABEL;Dunkelbild TP_DEFRINGE_LABEL;Farbsaum entfernen (Defringe) TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Schwellenwert -TP_DIRPYRDENOISE_33;3x3 stark -TP_DIRPYRDENOISE_55;5x5 stark -TP_DIRPYRDENOISE_55SOFT;5x5 -TP_DIRPYRDENOISE_77;7x7 (langsam) -TP_DIRPYRDENOISE_99;9x9 (sehr langsam) +TP_DIRPYRDENOISE_3X3;3×3 +TP_DIRPYRDENOISE_3X3_SOFT;3×3 weich +TP_DIRPYRDENOISE_5X5;5×5 +TP_DIRPYRDENOISE_5X5_SOFT;5×5 weich +TP_DIRPYRDENOISE_7X7;7×7 +TP_DIRPYRDENOISE_9X9;9×9 TP_DIRPYRDENOISE_ABM;Nur Farbe TP_DIRPYRDENOISE_AUT;Automatisch Global TP_DIRPYRDENOISE_AUTO;Automatisch Global @@ -1424,12 +1429,12 @@ TP_DIRPYRDENOISE_METHOD11;Qualität TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Einstellung der Qualität der Rauschreduzierung. Die Einstellung “Hoch“ verbessert die Rauschreduzierung auf Kosten der Verarbeitungszeit. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Für RAW-Bilder kann entweder die RGB- oder L*a*b*-Methode verwendet werden.\n\nFür andere Bilder wird unabhängig von der Auswahl immer die L*a*b*-Methode verwendet. TP_DIRPYRDENOISE_METM_TOOLTIP;Bei der Methode “Nur Luminanz“ und “L*a*b*“, wird der Medianfilter nach den Waveletschritten verarbeitet.\nBei RGB wird der Medianfilter am Ende der Rauschreduzierung verarbeitet. -TP_DIRPYRDENOISE_MET_TOOLTIP;Wendet einen Medianfilter mit der angegebenen Größe an. Je größer der Bereich, desto länger dauert die Verarbeitung..\n\n3x3: Verarbeitet 5 Pixel in einem 1-Pixelbereich.\n3x3 stark: Verarbeitet 9 Pixel in einem 1-Pixelbereich.\n5x5: Verarbeitet 13 Pixel in einem 2-Pixelbereich.\n5x5 stark: Verarbeitet 25 Pixel in einem 2-Pixelbereich.\n7x7: Verarbeitet 49 Pixel in einem 3-Pixelbereich.\n9x9: Verarbeitet 81 Pixel in einem 4-Pixelbereich.\n\nManchmal erzielt man mit einem kleinen Bereich mit mehreren Iterationen eine bessere Qualität als mit einem großen Bereich. +TP_DIRPYRDENOISE_MET_TOOLTIP;Einen Medianfilter mit der gewünschten Fenstergröße auswählen. Je größer das Fenster, umso länger dauert die Verarbeitungszeit.\n\n3×3 weich: Nutzt 5 Pixel in einem 3×3-Pixelfenster.\n3×3: Nutzt 9 Pixel in einem 3×3-Pixelfenster.\n5×5 weich: Nutzt 13 Pixel in einem 5×5-Pixelfenster.\n5×5: Nutzt 25 Pixel in einem 5×5-Pixelfenster.\n7×7: Nutzt 49 Pixel in einem 7×7-Pixelfenster.\n9×9: Nutzt 81 Pixel in einem 9×9-Pixelfenster.\n\nManchmal ist das Ergebnis mit einem kleineren Fenster und mehreren Iterationen besser, als mit einem größeren und nur einer Iteration. TP_DIRPYRDENOISE_NOISELABEL;Rauschen: Mittelwert=%1 Hoch=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;Rauschen: Mittelwert = --- Hoch = --- TP_DIRPYRDENOISE_NRESID_TOOLTIP;Zeigt das Restrauschen des sichtbaren Bildbereichs in der 100%-Ansicht an.\n\n<50: Sehr wenig Rauschen\n50 - 100: Wenig Rauschen\n100 - 300: Durchschnittliches Rauschen\n>300: Hohes Rauschen\n\nDie Werte unterscheiden sich im L*a*b*- und RGB-Modus. Die RGB-Werte sind ungenauer, da der RGB-Modus Luminanz und Chrominanz nicht komplett trennt. TP_DIRPYRDENOISE_PASSES;Medianiterationen -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Ein 3x3-Medianfilter mit 3 Iterationen erzielt oft bessere Ergebnisse als ein 7x7-Medianfilter mit nur einer Iteration. +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Manchmal führt ein kleines 3×3-Fenster mit mehreren Iterationen zu besseren Ergebnissen als ein 7×7-Fenster mit nur einer Iteration. TP_DIRPYRDENOISE_PON;Auto-Multizonen TP_DIRPYRDENOISE_PRE;Vorschau TP_DIRPYRDENOISE_PREV;Vorschau @@ -1440,7 +1445,6 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standard TP_DIRPYRDENOISE_SHALBI;Hoch TP_DIRPYRDENOISE_SLI;Regler -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;Kachelgröße=%1 Zentrum: Tx=%2 Ty=%2 TP_DIRPYREQUALIZER_ALGO;Hautfarbtonbereich TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fein: Ist näher an den Hautfarbtönen und minimiert den Einfluss auf andere Farben.\n\nGrob: Minimiert Artefakte. @@ -1495,7 +1499,7 @@ TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewichteter Standard TP_EXPOS_BLACKPOINT_LABEL;Schwarzpunkt TP_EXPOS_WHITEPOINT_LABEL;Weißpunkt 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 Film Simulation finden Sie auf RawPedia.\n\nMöchten Sie die Suche beenden? +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? TP_FILMSIMULATION_STRENGTH;Intensität TP_FILMSIMULATION_ZEROCLUTSFOUND;HaldCLUT-Verzeichnis in den Einstellungen festlegen TP_FLATFIELD_AUTOSELECT;Automatische Auswahl @@ -1674,7 +1678,7 @@ TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Mit “3-pass“ erzielt man die besten Erg TP_RAW_SENSOR_XTRANS_LABEL;Sensor mit X-Trans-Matrix TP_RESIZE_APPLIESTO;Anwenden auf: TP_RESIZE_CROPPEDAREA;Ausschnitt -TP_RESIZE_FITBOX;Breite & Höhe +TP_RESIZE_FITBOX;Begrenzungsrahmen TP_RESIZE_FULLIMAGE;Ganzes Bild TP_RESIZE_H;Höhe: TP_RESIZE_HEIGHT;Höhe @@ -1696,8 +1700,12 @@ TP_RETINEX_CURVEEDITOR_LH;Intensität=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensität in Abhängigkeit des Farbtons (H)\nBei der Retinex-Methode "Spitzlichter" wirken sich die Änderungen auch auf die Chromakorrektur aus. TP_RETINEX_CURVEEDITOR_MAP;L=f(L) TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Die Kurve kann entweder alleine, oder mit der Gaußschen- oder Waveletmaske angewendet werden.\nArtefakte beachten! +TP_RETINEX_EQUAL;Korrekturen TP_RETINEX_FREEGAMMA;Gamma TP_RETINEX_GAIN;Kontrast +TP_RETINEX_GAINOFFS;Verstärkung und Ausgleich (Helligkeit) +TP_RETINEX_GAINTRANSMISSION;Transmissionsverstärkung +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Ändert die Helligkeit durch Verstärken oder\nReduzieren der Transmissionskarte. TP_RETINEX_GAIN_TOOLTIP;Wirkt sich auf das verarbeitete Bild aus. Wird für schwarze oder weiße Pixel verwendet und hilft das Histogramm auszugleichen. TP_RETINEX_GAMMA;Gammakorrektur TP_RETINEX_GAMMA_FREE;Benutzerdefiniert @@ -1716,7 +1724,8 @@ TP_RETINEX_HIGHLIGHT;Spitzlichter Schwellenwert TP_RETINEX_HIGHLIGHT_TOOLTIP;Benötigt unter Umständen Korrekturen der Einstellungen "Benachbarte Pixel" und "Weißpunkt" unter dem Reiter "RAW". TP_RETINEX_HSLSPACE_LIN;HSL-Linear TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmisch -TP_RETINEX_ITER;Iterationen (Dynamikkompression) +TP_RETINEX_ITER;Iterationen +TP_RETINEX_ITERF;Dynamikkompression TP_RETINEX_ITER_TOOLTIP;Simuliert eine Dynamikkompression.\nHöhere Werte erhöhen die Prozessorzeit. TP_RETINEX_LABEL;Retinex (Bildschleier entfernen) TP_RETINEX_LABEL_MASK;Maske @@ -1728,7 +1737,7 @@ TP_RETINEX_MAP_MAPP;Schärfemaske (Teil-Wavelet) TP_RETINEX_MAP_MAPT;Schärfemaske (Wavelet) TP_RETINEX_MAP_METHOD_TOOLTIP;Keine: Wendet die Maske, die mit der gaußschen Funktion (Radius, Methode) erstellt wurde an, um Halos und Artefakte zu reduzieren.\n\nNur Kurve: Wendet eine diagonale Kontrastkurve auf die Maske an.\nArtefakte beachten.\n\nGaußschenmaske: Wendet eine gaußsche Unschärfe auf die originale Maske an.\n(Schnell)\n\nSchärfemaske: Wendet ein Wavelet auf die originale Maske an.\n(Langsam) TP_RETINEX_MAP_NONE;Keine -TP_RETINEX_MEDIAN;Transmission Medianfilter +TP_RETINEX_MEDIAN;Medianfilter TP_RETINEX_METHOD;Methode TP_RETINEX_METHOD_TOOLTIP;"Schatten" wirkt sich auf dunkle Bereiche aus.\n"Schatten & Lichter" wirkt sich auf dunkle und helle Bereiche aus.\n"Lichter" wirkt sich auf helle Bereiche aus.\n"Spitzlichter" wirkt sich auf sehr helle Bereiche aus und reduziert Magenta-Falschfarben. TP_RETINEX_MLABEL;Schleierreduzierung: Min=%1 Max=%2 @@ -1736,17 +1745,19 @@ TP_RETINEX_MLABEL_TOOLTIP;Sollte nahe bei Min=0 und Max=32768 sein TP_RETINEX_NEIGHBOR;Radius TP_RETINEX_NEUTRAL;Zurücksetzen TP_RETINEX_NEUTRAL_TIP;Setzt alle Regler und Kurven auf ihre Standardwerte zurück. -TP_RETINEX_OFFSET;Helligkeit +TP_RETINEX_OFFSET;Ausgleich (Helligkeit) TP_RETINEX_SCALES;Gaußscher Gradient TP_RETINEX_SCALES_TOOLTIP;Steht der Regler auf 0 sind alle Iterationen identisch.\nBei > 0 werden Skalierung und Radius reduziert und umgekehrt. TP_RETINEX_SETTINGS;Einstellungen +TP_RETINEX_SKAL;Skalierung TP_RETINEX_SLOPE;Gammasteigung TP_RETINEX_STRENGTH;Intensität -TP_RETINEX_THRESHOLD;Transmission Schwellenwert +TP_RETINEX_THRESHOLD;Schwellenwert TP_RETINEX_THRESHOLD_TOOLTIP;Limitiert den Bereich der Transmissionskurve. TP_RETINEX_TLABEL;T: Min=%1 Max=%2 Mittel=%3 Sigma=%4 TP_RETINEX_TLABEL2;T: Tmin=%1 Tmax=%2 TP_RETINEX_TLABEL_TOOLTIP;Ergebnis der Transmissionskurve: Min, Max, Mittel und Sigma\nMin und Max hat Einfluss auf die Abweichung.\n\nTmin = Kleinster Wert der Transmissionskurve\nTmax = Größter Wert der Transmissionskurve +TP_RETINEX_TRANF;Transmission TP_RETINEX_TRANSMISSION;Transmissionskurve TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission in Abhängigkeit der Transmission.\nx-Achse: Transmission negativer Werte (Min), Mittel und positiver Werte (Max).\ny-Achse: Verstärkung oder Reduzierung. TP_RETINEX_UNIFORM;Schatten & Lichter @@ -1951,7 +1962,7 @@ TP_WAVELET_NPHIGH;Hoch TP_WAVELET_NPLOW;Niedrig TP_WAVELET_NPNONE;Keine TP_WAVELET_NPTYPE;Benachbarte Pixel -TP_WAVELET_NPTYPE_TOOLTIP;Dieser Algorithmus verwendet einen Pixel und acht seiner Nachbarn. Sind die Unterschiede gering, werden die Kanten geschärft. +TP_WAVELET_NPTYPE_TOOLTIP;Dieser Algorithmus verwendet ein Pixel und acht seiner Nachbarn. Sind die Unterschiede gering, werden die Kanten geschärft. TP_WAVELET_OPACITY;Deckkraft Blau/Gelb TP_WAVELET_OPACITYW;Kontrastausgleichskurve TP_WAVELET_OPACITYWL;Lokale Kontrastkurve diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index d0979941b..f960286c8 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -295,6 +295,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_ABOUT;About !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before @@ -310,6 +311,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !GENERAL_NO;No !GENERAL_NONE;None !GENERAL_OK;OK +!GENERAL_OPEN;Open !GENERAL_PORTRAIT;Portrait !GENERAL_SAVE;Save !GENERAL_UNCHANGED;(Unchanged) @@ -469,7 +471,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -718,14 +720,14 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_420;Retinex - Histogram - HSL !HISTORY_MSG_421;Retinex - Gamma @@ -746,8 +748,10 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1384,11 +1388,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1429,12 +1434,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1444,7 +1449,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts !TP_DIRPYREQUALIZER_HUESKIN;Skin hue !TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. @@ -1679,8 +1683,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1700,6 +1708,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1719,10 +1728,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1730,6 +1740,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 677771240..f38615acd 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -200,6 +200,7 @@ !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_ABOUT;About !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before @@ -215,6 +216,7 @@ !GENERAL_NO;No !GENERAL_NONE;None !GENERAL_OK;OK +!GENERAL_OPEN;Open !GENERAL_PORTRAIT;Portrait !GENERAL_SAVE;Save !GENERAL_UNCHANGED;(Unchanged) @@ -380,7 +382,7 @@ !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -640,14 +642,14 @@ !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -669,8 +671,10 @@ !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1350,11 +1354,12 @@ !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1397,12 +1402,12 @@ !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1413,7 +1418,6 @@ !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1669,8 +1673,12 @@ !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1690,6 +1698,7 @@ !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1709,10 +1718,11 @@ !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1720,6 +1730,7 @@ !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index 7be7aa516..fc06babc8 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -421,7 +421,7 @@ HISTORY_MSG_145;Micro-contraste - Uniformidad HISTORY_MSG_146;Enfoque de bordes (EB) HISTORY_MSG_147;EB - Sólo luminancia HISTORY_MSG_148;Micro-contraste -HISTORY_MSG_149;Micro-contraste - matriz 3x3 +HISTORY_MSG_149;Micro-contraste - matriz 3×3 HISTORY_MSG_150;Reducción artefactos/ruido post interpolado HISTORY_MSG_151;Vibranza (Vib) HISTORY_MSG_152;Vib - Tonos pastel @@ -1162,10 +1162,6 @@ TP_DARKFRAME_LABEL;Toma Negra TP_DEFRINGE_LABEL;Quitar borde púrpura TP_DEFRINGE_RADIUS;Radio TP_DEFRINGE_THRESHOLD;Umbral -TP_DIRPYRDENOISE_33;3×3 fuerte -TP_DIRPYRDENOISE_55;5×5 fuerte -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (lento) TP_DIRPYRDENOISE_BLUE;Crominancia: Azul-Amarillo TP_DIRPYRDENOISE_CHROMA;Crominancia: Maestra TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modula la acción de eliminación de ruido 'de luminancia' @@ -1189,15 +1185,12 @@ TP_DIRPYRDENOISE_METHOD11;Calidad TP_DIRPYRDENOISE_METHOD11_TOOLTIP;La Calidad puede ser adaptada a un patrón de ruido. Al seleccionar "Alto" se incrementa el efecto de reducción de ruido a costa de prolongar el tiempo de procesamiento. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Para imágenes raw puede usar tanto el método RGB como el Lab.\n\nPara imágenes no raw el método Lab será usado de todas maneras, ignorando el método seleccionado. TP_DIRPYRDENOISE_METM_TOOLTIP;Cuando se utiliza "Sólo Luminancia" y los métodos "Lab", el filtro Median será aplicado inmediatamente después de cada proceso de toda la cadena de reducción de ruido.\nCuando se utiliza el modo "RGB", el filtro Median se aplicará al final de toda la cadena de procesos de reducción de ruido. -TP_DIRPYRDENOISE_MET_TOOLTIP;Aplicar el filtro Median al tamaño deseado. Cuanto mayor sea el tamaño, demandará más tiempo.\n\n3x3 suave: procesar 5 píxeles en un rango de 1 píxel.\n3x3: procesar 9 píxeles en un rango de 1 píxel.\n5x5 suave: procesar 13 píxeles en un rango de 2 píxeles.\n5x5: procesar 25 píxeles en un rango de 2 píxeles.\n7x7: procesar 49 píxeles en un rango 3 píxeles.\n\nAlgunas veces es posible lograr una mayor calidad ejecutando varias iteraciones con un rango pequeño, que con una sóla iteración con un rango amplio. TP_DIRPYRDENOISE_PASSES;Iteracciones Median -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Aplicar el filtro Median 3x3 con 3 iteraciones, a menudo produce mejores resultados que aplicar una sola vez 7x7. TP_DIRPYRDENOISE_RED;Crominancia: Rojo-Verde TP_DIRPYRDENOISE_RGB;RGB TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Estándar TP_DIRPYRDENOISE_SHALBI;Alto -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYREQUALIZER_ALGO;Rango de Color de Piel TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fino: cercano a los colores de la piel, minimizando la acción en otros colores\nAmplio: evita más elementos extraños. TP_DIRPYREQUALIZER_HUESKIN;Matiz de la piel @@ -1561,7 +1554,9 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_299;NR - Chrominance curve !HISTORY_MSG_300;- @@ -1674,14 +1669,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1703,8 +1698,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w @@ -1793,7 +1790,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1813,9 +1815,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail !TP_DIRPYRDENOISE_MAN;Manual !TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1853,8 +1857,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1874,6 +1882,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1893,10 +1902,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1904,6 +1914,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara index 251fa4673..1d4df36ae 100644 --- a/rtdata/languages/Euskara +++ b/rtdata/languages/Euskara @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 9aaac3fa3..fa622202c 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -376,7 +376,7 @@ HISTORY_MSG_145;Microcontraste - Uniformité HISTORY_MSG_146;Netteté des bords HISTORY_MSG_147;Bords - Luminance uniquement HISTORY_MSG_148;Microcontraste -HISTORY_MSG_149;Microcontraste - Matrice 3x3 +HISTORY_MSG_149;Microcontraste - Matrice 3×3 HISTORY_MSG_150;Réduction du bruit/artefact post-dématriçage HISTORY_MSG_151;Vibrance HISTORY_MSG_152;Vib. - Tons pastels @@ -1296,11 +1296,6 @@ TP_DARKFRAME_LABEL;Trame Noire TP_DEFRINGE_LABEL;Aberration chromatique TP_DEFRINGE_RADIUS;Rayon TP_DEFRINGE_THRESHOLD;Seuil -TP_DIRPYRDENOISE_33;3×3 fort -TP_DIRPYRDENOISE_55;5×5 fort -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (lent) -TP_DIRPYRDENOISE_99;9x9 (très lent) TP_DIRPYRDENOISE_ABM;Chroma uniquement TP_DIRPYRDENOISE_AUT;Global automatique TP_DIRPYRDENOISE_AUTO;Global automatique @@ -1343,12 +1338,10 @@ TP_DIRPYRDENOISE_METHOD11;Qualité TP_DIRPYRDENOISE_METHOD11_TOOLTIP;La qualité peut être adapté à la trame du bruit. Régler sur "haut" augmentera l'effet de la réduction de bruit au prix d'un temps de traitement plus long. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Pour les images raw, les méthodes RVB ou Lab peuvent être utilisées.\n\nPour les images non-raw la méthode Lab sera utilisée, indépendamment de ce qu'indique ce bouton. TP_DIRPYRDENOISE_METM_TOOLTIP;Lorsque vous utilisez les méthodes "Luminance seulement" et "Lab", un filtrage médian sera effectué juste après l'étape des ondelettes dans le pipeline de la réduction de bruit.\nEm mode "RVB", il sera effectué à la toute fin du pipeline de la réduction de bruit. -TP_DIRPYRDENOISE_MET_TOOLTIP;Applique un filtre médian de la taille souhaité. Plus il est large, plus cela prendra de temps.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. TP_DIRPYRDENOISE_NOISELABEL;Bruit de l'aperçu: Moyen=%1 Haut=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;Bruit de l'aperçu: Moyen= - Haut= - TP_DIRPYRDENOISE_NRESID_TOOLTIP;Affiche les niveaux de bruit résiduel de la partie de l'image visible dans l'aperçu après les ondelettes.\n\n>300 Très bruité\n100-300 Bruité\n50-100 Peu bruité\n<50 Très peu bruité\n\nAttention, les valeurs diffèreront entre le mode RVB et L*a*b*. Les valeurs RVB sont moins précises car le mode RVB ne séparent pas complètement la luminance et la chrominance. TP_DIRPYRDENOISE_PASSE;Itérations -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Appliquer 3 itération du filtre médian 3x3 donne de meilleurs résultats qu'appliquer une seule fois le filtre 7x7. TP_DIRPYRDENOISE_PON;Multi-zones auto TP_DIRPYRDENOISE_PRE;Aperçu multi-zones TP_DIRPYRDENOISE_PREV;Aperçu @@ -1359,7 +1352,6 @@ TP_DIRPYRDENOISE_RGBM;RVB TP_DIRPYRDENOISE_SHAL;Standard TP_DIRPYRDENOISE_SHALBI;Haut TP_DIRPYRDENOISE_SLI;Curseur -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;Taille des tuiles =%1, Centre: Tx=%2 Ty=%3 TP_DIRPYREQUALIZER_ALGO;Domaine des tons chairs TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fin: plus proche des tons chairs, minimisant l'actions sur les autres couleurs\nLarge: évite plus d'artéfacts @@ -1893,18 +1885,20 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !!!!!!!!!!!!!!!!!!!!!!!!! !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!GENERAL_APPLY;Apply +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1926,8 +1920,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_PRSHARPENING;Post-resize sharpening @@ -1944,7 +1940,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. !TP_COLORTONING_NEUTRAL;Reset sliders +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !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_PROFILEINTENT;Rendering Intent !TP_NEUTRAL;Reset @@ -1959,8 +1963,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1980,6 +1988,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1999,10 +2008,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -2010,6 +2020,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek index 61a6f844f..13d87c84c 100644 --- a/rtdata/languages/Greek +++ b/rtdata/languages/Greek @@ -579,12 +579,14 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -658,7 +660,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -918,14 +920,14 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -947,8 +949,10 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1425,11 +1429,12 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1472,12 +1477,12 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1488,7 +1493,6 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1710,8 +1714,12 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1731,6 +1739,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1750,10 +1759,11 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1761,6 +1771,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew index e007ebcd7..f91ac1f95 100644 --- a/rtdata/languages/Hebrew +++ b/rtdata/languages/Hebrew @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;מידת חום !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;מידת חום !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;מידת חום !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 82061c24d..eabb2ff60 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -365,7 +365,7 @@ HISTORY_MSG_145;Microcontrasto - Uniformità HISTORY_MSG_146;Nitidezza ai Bordi (ES) HISTORY_MSG_147;ES - Solo luminanza HISTORY_MSG_148;Microcontrasto -HISTORY_MSG_149;Microcontrasto - Matrice 3x3 +HISTORY_MSG_149;Microcontrasto - Matrice 3×3 HISTORY_MSG_150;Rid. rumore/artefatti di demosaic. HISTORY_MSG_151;Vividezza HISTORY_MSG_152;Vividezza - Toni Pastello @@ -1383,7 +1383,9 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_256;NR - Median type !HISTORY_MSG_257;Color Toning @@ -1539,14 +1541,14 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1568,8 +1570,10 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet @@ -1692,11 +1696,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1726,12 +1731,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_DIRPYRDENOISE_METHOD11;Quality !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1740,7 +1745,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts !TP_EPD_GAMMA;Gamma @@ -1794,8 +1798,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1815,6 +1823,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1834,10 +1843,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1845,6 +1855,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 78cfa3275..34211dbb3 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -409,7 +409,7 @@ HISTORY_MSG_145;マイクロコントラスト - 均等 HISTORY_MSG_146;エッジ シャープ化 HISTORY_MSG_147;エッジ シャープ化 - 輝度のみ HISTORY_MSG_148;マイクロコントラスト -HISTORY_MSG_149;マイクロコントラスト - 3x3 マトリクス +HISTORY_MSG_149;マイクロコントラスト - 3×3 マトリクス HISTORY_MSG_150;デモザイク後にアーティファクトとノイズを軽減 HISTORY_MSG_151;自然な彩度 HISTORY_MSG_152;自然な彩度 - 明清色トーン @@ -1329,11 +1329,6 @@ TP_DARKFRAME_LABEL;ダークフレーム TP_DEFRINGE_LABEL;フリンジ低減 TP_DEFRINGE_RADIUS;半径 TP_DEFRINGE_THRESHOLD;しきい値 -TP_DIRPYRDENOISE_33;強い3x3 -TP_DIRPYRDENOISE_55;強い5x5 -TP_DIRPYRDENOISE_55SOFT;5x5 -TP_DIRPYRDENOISE_77;7x7(遅い) -TP_DIRPYRDENOISE_99;9x9 (非常に遅い) TP_DIRPYRDENOISE_ABM;色ノイズだけ TP_DIRPYRDENOISE_AUT;自動(分割方式) TP_DIRPYRDENOISE_AUTO;自動(分割方式) @@ -1376,12 +1371,10 @@ TP_DIRPYRDENOISE_METHOD11;ノイズ低減の質 TP_DIRPYRDENOISE_METHOD11_TOOLTIP;ノイズの状態に応じて低減効果の質を選べます:1-標準 2-高い\n2の方がノイズ低減効果は高くなりますが、その分処理時間が増えます。 TP_DIRPYRDENOISE_METHOD_TOOLTIP;raw画像は、RGBまたはL*a*b*方式のいずれかを使用することができます。\n\nraw以外の画像は、選択にかかわらずL*a*b*方式が採用されます TP_DIRPYRDENOISE_METM_TOOLTIP;フィルタリングの方式で、"輝度のみ"と"L*a*b*"を選択した場合、メディアンフィルタリングはノイズ低減行程でウェーブレット変換が行われた直後に適用されます\n"RGB"モードの場合は、ノイズ低減行程の最後で適用されます -TP_DIRPYRDENOISE_MET_TOOLTIP;適用するメディアンフィルターのサイズを決めます。大きくするとその分処理時間が増えます。\n\nソフトな3x3:1ピクセル範囲で5ピクセルの処理を行います\n強い3x3:1ピクセル範囲で9ピクセルの処理を行います\nソフトな5x5:2ピクセル範囲で13ピクセルの処理を行います\n強い5x5:2ピクセル範囲で25ピクセルの処理を行います\n7x7:3ピクセル範囲で49ピクセルの処理を行います\n9x9:4ピクセル範囲で81ピクセルの処理を行います\n\n小さいフィルターを使って、繰り返し処理をした方が、大きいフィルターを1回使うより結果が良いこともあります。 TP_DIRPYRDENOISE_NOISELABEL;プレビューのノイズ: 中間色度=%1 高色度=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;プレビューのノイズ: 中間色度= - 高色度= - TP_DIRPYRDENOISE_NRESID_TOOLTIP;ウェーブレット変換後、プレビューで見える部分画像で残ったノイズのレベルを表示します\n\n>300以上 非常にノイズが多い\n100~300 ノイズが多い\n50~100 ノイズが少ない\n50以下 ノイズが非常に少ない\n\n算出値はRGBとL*a*b*モードでは異なります。RGBモードは輝度と色を完全に切り離すことが出来ないので、算出値の精度は劣ります。 TP_DIRPYRDENOISE_PASSES;フィルタリングの繰り返し回数 -TP_DIRPYRDENOISE_PASSES_TOOLTIP;3x3のメディアンフィルターを3回繰り返して適用する方が、7x7のフィルターを1回適用するより、良い結果を生むことが多いです TP_DIRPYRDENOISE_PON;自動(多分割方式) TP_DIRPYRDENOISE_PRE;自動(プレビュー方式) TP_DIRPYRDENOISE_PREV;プレビュー方式 @@ -1392,7 +1385,6 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;標準 TP_DIRPYRDENOISE_SHALBI;高い TP_DIRPYRDENOISE_SLI;スライダー -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;タイルのサイズ=%1, 中心位置: X座標=%2 Y座標=%3 TP_DIRPYREQUALIZER_ALGO;肌色の範囲 TP_DIRPYREQUALIZER_ALGO_TOOLTIP;ファイン:撮影の肌色に近い部分に働くアルゴリズム、他の色への影響を最小限に抑えます\n広範: アーティファクトの増加を避けるアルゴリズムです @@ -1923,18 +1915,20 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !!!!!!!!!!!!!!!!!!!!!!!!! !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!GENERAL_APPLY;Apply +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1956,8 +1950,10 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_PRSHARPENING;Post-resize sharpening @@ -1973,6 +1969,14 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_CBDL_BEF;Before Black-and-White !TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !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_PROFILEINTENT;Rendering Intent !TP_NEUTRAL;Reset @@ -1987,8 +1991,12 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -2008,6 +2016,7 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -2027,10 +2036,11 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -2038,6 +2048,7 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Latvian b/rtdata/languages/Latvian index 4d4415e58..8e93725bb 100644 --- a/rtdata/languages/Latvian +++ b/rtdata/languages/Latvian @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 9600eb0ce..dc4129b8f 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -328,7 +328,7 @@ HISTORY_MSG_145;Mikrokontraszt - egységesség HISTORY_MSG_146;Élek élesítése HISTORY_MSG_147;Élek élesítése - csak luminencia HISTORY_MSG_148;Mikrokontraszt -HISTORY_MSG_149;Mikrokontraszt - 3x3 mátrix +HISTORY_MSG_149;Mikrokontraszt - 3×3 mátrix HISTORY_MSG_150;Interpoláció utáni műtermék-/zajcsökkentés HISTORY_MSG_151;Vibrancia HISTORY_MSG_152;Vibrancia - Pastel tones @@ -951,9 +951,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_CLOSE;Close +!GENERAL_OPEN;Open !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. !HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. @@ -1200,14 +1202,14 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1229,8 +1231,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1572,11 +1576,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1615,12 +1620,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1631,7 +1636,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1773,8 +1777,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1794,6 +1802,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1813,10 +1822,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1824,6 +1834,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index fa1dbcd09..54e0a68e1 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -12,6 +12,7 @@ #12 2014-10-19 updated to rt4.1.92 by wim ter meer #13 2015-03-03 updated to rt4.2.102 by wim ter meer #14 2015-11-23 update by wim ter meer +#15 2016-07-21 update by wim ter meer ABOUT_TAB_BUILD;Versie ABOUT_TAB_CREDITS;Credits @@ -181,6 +182,7 @@ FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's\nSneltoets: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's\nSneltoets: 6 FILEBROWSER_SHOWEXIFINFO;Toon EXIF-info FILEBROWSER_SHOWNOTTRASHHINT;Toon alleen niet-verwijderde foto's. +FILEBROWSER_SHOWORIGINALHINT;Toon alleen originele afbeelding.\n\nAls er meerdere afbeeldingen zijn met dezelfde naam maar verschillende extensies, dan wordt de afbeelding waarvan de extensie het hoogst staat in de lijst met extensies in Voorkeuren > Bestandsnavigator > Extensies FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster.\nSneltoets: 1 FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren.\nSneltoets: 2 FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren.\nSneltoets: 3 @@ -389,7 +391,7 @@ HISTORY_MSG_145;Microcontrast - Uniformiteit HISTORY_MSG_146;Randen verscherpen HISTORY_MSG_147;RV - Luminantie HISTORY_MSG_148;Microcontrast -HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_149;Microcontrast - 3×3 matrix HISTORY_MSG_150;Nabewerking demozaïek HISTORY_MSG_151;Levendigheid HISTORY_MSG_152;LV - Pasteltinten @@ -406,6 +408,7 @@ HISTORY_MSG_162;Tonen koppelen HISTORY_MSG_163;RGB-curve - R HISTORY_MSG_164;RGB-curve - G HISTORY_MSG_165;RGB-curve - B +HISTORY_MSG_166;Belichting - Teruggezet HISTORY_MSG_167;Demozaïekmethode HISTORY_MSG_168;L*a*b* - CC curve HISTORY_MSG_169;L*a*b* - CH curve @@ -549,7 +552,7 @@ HISTORY_MSG_307;W Ch niveau HISTORY_MSG_308;W richting HISTORY_MSG_309;W tegels HISTORY_MSG_310;W Tinten lucht -HISTORY_MSG_311;W Max niveau's +HISTORY_MSG_311;W Max niveaus HISTORY_MSG_312;W Schaduwen drempel HISTORY_MSG_313;W Pastel Verzadigd HISTORY_MSG_314;W Artefacten blauwe lucht @@ -650,9 +653,11 @@ HISTORY_MSG_408;Retinex - Naburig HISTORY_MSG_409;Retinex - Verbeteren HISTORY_MSG_410;Retinex - Beginpunt HISTORY_MSG_411;Retinex - Sterkte +HISTORY_MSG_412;Retinex - Gaussiaans Verloop HISTORY_MSG_413;Retinex - Variantie HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmissie +HISTORY_MSG_416;Retinex HISTORY_MSG_417;Retinex - Transmissie mediaan HISTORY_MSG_418;Retinex - Drempel HISTORY_MSG_419;Retinex - Kleurruimte @@ -663,6 +668,19 @@ HISTORY_MSG_423;Retinex - Gamma helling HISTORY_MSG_424;Retinex - HL drempel HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Tint balans +HISTORY_MSG_427;Uitvoer rendering weergave +HISTORY_MSG_428;Monitor rendering weergave +HISTORY_MSG_429;Retinex - Herhalingen +HISTORY_MSG_430;Retinex - Transmissie Verloop +HISTORY_MSG_431;Retinex - Sterkte Verloop +HISTORY_MSG_432;Retinex - M - Hoge lichten +HISTORY_MSG_433;Retinex - M - Hoge lichten TW +HISTORY_MSG_434;Retinex - M - Schaduwen +HISTORY_MSG_435;Retinex - M - Schaduwen TW +HISTORY_MSG_436;Retinex - M - Straal +HISTORY_MSG_437;Retinex - M - Methode +HISTORY_MSG_438;Retinex - M - Mixer +HISTORY_MSG_440;DC - Methode HISTORY_NEWSNAPSHOT;Nieuw HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt-s HISTORY_SNAPSHOT;Nieuw @@ -710,11 +728,12 @@ IPTCPANEL_TRANSREFERENCE;Trans. Reference IPTCPANEL_TRANSREFERENCEHINT;Een code die de locatie van de oorspronkelijke transmissie representeert (Original Transmission Reference) MAIN_BUTTON_FULLSCREEN;Volledig scherm MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nSneltoets: Shift-F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 -MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nShortcut: Shift-F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nSneltoets: Shift-F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Editor om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB de miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) MAIN_BUTTON_PREFERENCES;Voorkeuren MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij.\nSneltoets: Ctrl+B MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto.\nSneltoets: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Bewerk afbeelding in externe editor MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma.\nSneltoets: Ctrl+E MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: m MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm @@ -779,6 +798,7 @@ MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift-L MAIN_TOOLTIP_THRESHOLD;Drempel MAIN_TOOLTIP_TOGGLE;Vergelijk origineel en bewerking +MONITOR_PROFILE_SYSTEM;Systeem standaardwaarde NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -838,6 +858,7 @@ PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dode pixels filter PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hete pixels filter PARTIALPASTE_PREPROCESS_LINEDENOISE;Lijnruisfilter +PARTIALPASTE_PRSHARPENING;Verscherp na verkleinen PARTIALPASTE_RAWCACORR_AUTO;Autom. C/A-correctie PARTIALPASTE_RAWCACORR_CABLUE;C/A Blauw PARTIALPASTE_RAWCACORR_CARED;C/A Rood @@ -915,7 +936,7 @@ PREFERENCES_DARKFRAMETEMPLATES;sjablonen PREFERENCES_DATEFORMAT;Datumformaat PREFERENCES_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is bijvoorbeeld:\n%d/%m/%y PREFERENCES_DAUB_LABEL;Gebruik Daubechies D6 wavelets in plaats van D4 -PREFERENCES_DAUB_TOOLTIP;De Ruisonderdrukking en Wavelet Niveau's gebruiken de Debauchies moeder wavelet. Als je D6 gebruikt in plaats van D4 vergroot het aantal orthogonale Daubechies coëfficiënten en dit verbeterd waarschijlijk de kwaliteit van de lage niveaus. +PREFERENCES_DAUB_TOOLTIP;De Ruisonderdrukking en Wavelet niveaus gebruiken de Debauchies moeder wavelet. Als je D6 gebruikt in plaats van D4 vergroot het aantal orthogonale Daubechies coëfficiënten en dit verbeterd waarschijnlijk de kwaliteit van de lage niveaus. PREFERENCES_DEFAULTLANG;Standaardtaal PREFERENCES_DEFAULTTHEME;Standaardthema PREFERENCES_DIRDARKFRAMES;Map met donkerframes @@ -986,6 +1007,8 @@ PREFERENCES_MENUGROUPRANK;Groepeer markering PREFERENCES_MENUOPTIONS;Menu-opties PREFERENCES_METADATA;Metadata PREFERENCES_MIN;Mini (100x115) +PREFERENCES_MONINTENT;Standaard monitor weergave +PREFERENCES_MONPROFILE;Standaard monitor profiel PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor PREFERENCES_NAVGUIDEBRUSH;Navigator randkleur @@ -1000,10 +1023,12 @@ PREFERENCES_OVERLAY_FILENAMES;Toon bestandsnamen over miniaturen PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Toon bestandsnaam over miniaturen in het Bewerkingsvenster PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande output-bestanden PREFERENCES_PANFACTORLABEL;Factor -PREFERENCES_PARSEDEXT;Toon extensies +PREFERENCES_PARSEDEXT;Extensies (verwerkingsvolgorde) PREFERENCES_PARSEDEXTADD;Voeg extensie toe PREFERENCES_PARSEDEXTADDHINT;Typ nieuwe extensie en druk op knop om aan lijst toe te voegen PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst +PREFERENCES_PARSEDEXTDOWNHINT;Verplaats extensie naar beneden +PREFERENCES_PARSEDEXTUPHINT;Verplaats extensie naar boven PREFERENCES_PREVDEMO;Voorbeeld Demozaïekmethode PREFERENCES_PREVDEMO_FAST;Snel PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: @@ -1014,6 +1039,7 @@ PREFERENCES_PROFILEPRCACHE;Profiel in cache PREFERENCES_PROFILEPRFILE;Profiel bij RAW-bestand PREFERENCES_PROFILESAVECACHE;Bewaar profiel in cache PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand +PREFERENCES_PROFILE_NONE;Geen PREFERENCES_PROPERTY;Eigenschap PREFERENCES_PSPATH;Installatiemap Adobe Photoshop PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom % en pan startpunt @@ -1061,7 +1087,7 @@ PREFERENCES_USESYSTEMTHEME; Gebruik systeemthema PREFERENCES_VIEW;Witbalans instelling van het uitvoerapparaat (monitor, TV, projector...) PREFERENCES_WAVLEV;Vergroot wavelet ninveau voor kwaliteit 'hoog' PREFERENCES_WLONE;Eén niveau -PREFERENCES_WLTWO;Twee niveau's +PREFERENCES_WLTWO;Twee niveaus PREFERENCES_WLZER;Nee PREFERENCES_WORKFLOW;Layout PROFILEPANEL_COPYPPASTE;Te kopiëren parameters @@ -1129,10 +1155,9 @@ TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: h TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtmaken / Kleine rotaties.\nSneltoets: s\n\nBepaal de vertikale of horizontale as door het trekken van een hulplijn over de afbeelding. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: w TP_BWMIX_ALGO;Algoritme OYCPM -TP_BWMIX_ALGO_LI;Linear +TP_BWMIX_ALGO_LI;Lineair TP_BWMIX_ALGO_SP;Speciale effecten -TP_BWMIX_ALGO_TOOLTIP;Linear: creëert een normale lineare response.\nSpeciale effecten: creëert speciale effecten door kanalen non-linearl te mixen. -TP_BWMIX_AUTOCH;Auto +TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire response.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen.TP_BWMIX_AUTOCH;Auto TP_BWMIX_AUTOCH_TIP;Bereken optimale waardes voor de kanaalmixer. TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM mode. @@ -1151,7 +1176,7 @@ TP_BWMIX_FILTER_NONE;Geen TP_BWMIX_FILTER_PURPLE;Paars TP_BWMIX_FILTER_RED;Rood TP_BWMIX_FILTER_REDYELLOW;Rood-Geel -TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beninvloeden de helderheid. Bv. een rood filter maak een blauwe lucht donkerder. +TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beïnvloeden de helderheid. Bv. een rood filter maak een blauwe lucht donkerder. TP_BWMIX_FILTER_YELLOW;Geel TP_BWMIX_GAMMA;Gamma Correctie TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB kanaal @@ -1184,13 +1209,17 @@ TP_BWMIX_SET_RGBREL;Relatieve RGB TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM TP_BWMIX_SET_ROYGCBPMREL;Relatieve ROYGCBPM TP_BWMIX_TCMODE_FILMLIKE;Z&W Film-achtig -TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadinging en Waarde menging +TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadiging en Waarde menging TP_BWMIX_TCMODE_STANDARD;Z-W Standaard TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen Standard TP_BWMIX_VAL;L TP_CACORRECTION_BLUE;Blauw TP_CACORRECTION_LABEL;Corrigeer chromatische aberratie TP_CACORRECTION_RED;Rood +TP_CBDL_AFT;Na Zwart-Wit +TP_CBDL_BEF;Voor Zwart-Wit +TP_CBDL_METHOD;Uitvoeren +TP_CBDL_METHOD_TOOLTIP;Kies of Detailcontrast moet worden uitgevoerd na de Zwart-Wit bewerking waardoor het werkt in L*a*b*, of voor de Zwart-Wit bewerking waardoor het werkt in RGB TP_CHMIXER_BLUE;Blauw TP_CHMIXER_GREEN;Groen TP_CHMIXER_LABEL;Kleurkanaal mixer @@ -1253,13 +1282,13 @@ TP_COLORAPP_RSTPRO_TOOLTIP;Rode en Huidtinten bescherming (schuifbalk en curven) TP_COLORAPP_SHARPCIE;Verscherpen, Detailcontrast, Microcontrast & Randen met Q/C TP_COLORAPP_SHARPCIE_TOOLTIP;Verscherpen, Detailcontrast, Microcontrast & Randen zullen CIECAM02 gebruiken wanneer dit is aangezet. TP_COLORAPP_SURROUND;Omgeving -TP_COLORAPP_SURROUND_AVER;Gemmideld +TP_COLORAPP_SURROUND_AVER;Gemmiddeld TP_COLORAPP_SURROUND_DARK;Donker TP_COLORAPP_SURROUND_DIM;Gedimd TP_COLORAPP_SURROUND_EXDARK;Duister TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden TP_COLORAPP_SURSOURCE;Donkere omgeving -TP_COLORAPP_SURSOURCE_TOOLTIP;Kan worden gebruikt als de fotos is gemaakt in een donkere omgeving +TP_COLORAPP_SURSOURCE_TOOLTIP;Kan worden gebruikt als de foto is gemaakt in een donkere omgeving TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid TP_COLORAPP_TCMODE_CHROMA;Chroma TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid @@ -1301,6 +1330,7 @@ TP_COLORTONING_SHADOWS;Schaduwen TP_COLORTONING_SPLITCO;Schaduwen/Midden tonen/Hoge lichten TP_COLORTONING_SPLITCOCO;Kleurbalans SMH TP_COLORTONING_SPLITLR;Verzadiging 2 kleuren +TP_COLORTONING_STR;Sterkte TP_COLORTONING_STRENGTH;Sterkte TP_COLORTONING_TWO2;Speciaal chroma '2 kleuren' TP_COLORTONING_TWOALL;Speciaal chroma @@ -1330,11 +1360,6 @@ TP_DARKFRAME_LABEL;Donkerframe TP_DEFRINGE_LABEL;Verzachten (Lab/CIECAM02) TP_DEFRINGE_RADIUS;Straal TP_DEFRINGE_THRESHOLD;Drempel -TP_DIRPYRDENOISE_33;3x3 sterk -TP_DIRPYRDENOISE_55;5x5 sterk -TP_DIRPYRDENOISE_55SOFT;5x5 -TP_DIRPYRDENOISE_77;7x7 (langzaaam) -TP_DIRPYRDENOISE_99;9x9 (erg langzaam) TP_DIRPYRDENOISE_ABM;Alleen chroma TP_DIRPYRDENOISE_AUT;Automatisch algemeen TP_DIRPYRDENOISE_AUTO;Automatisch algemeen @@ -1346,6 +1371,7 @@ TP_DIRPYRDENOISE_CHROMA;Chrominantie (master) TP_DIRPYRDENOISE_CHROMAFR;Chrominantie TP_DIRPYRDENOISE_CTYPE;Auto methode TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\n9 gebieden worden gebruikt om de chroma ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de "Voorbeeld" methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CUR;Curve TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Vergroot (vermenigvuldigt) de waarde van alle chrominantie schuifbalken.\nMet deze curve kun je de sterkte aanpassen van de chromatische ruisonderdrukking. Bijvoorbeeld door de werking te vergroten in gebieden met lage verzadiging en te verminderen in gebieden met hoge verzadiging. TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Luminantie ruisonderdrukking. Werkt niet lineair maar modulerend @@ -1354,6 +1380,7 @@ TP_DIRPYRDENOISE_ENH;Verbeteren TP_DIRPYRDENOISE_ENH_TOOLTIP;Verbetert de ruisonderdrukking, maar vergroot de verwerkingstijd met ongeveer 20% TP_DIRPYRDENOISE_GAMMA;Gamma TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten +TP_DIRPYRDENOISE_LAB;L*a*b* TP_DIRPYRDENOISE_LABEL;Ruisonderdrukking TP_DIRPYRDENOISE_LABM;L*a*b* TP_DIRPYRDENOISE_LCURVE;Luminantie curve @@ -1375,12 +1402,11 @@ TP_DIRPYRDENOISE_METHOD11;Kwaliteit TP_DIRPYRDENOISE_METHOD11_TOOLTIP;De kwaliteit kan worden aangepast aan de hoeveelheid ruis. \nHoog verbetert de ruisonderdrukking, maar verlengt de verwerkingstijd TP_DIRPYRDENOISE_METHOD_TOOLTIP;Voor raw afbeeldingen kan RGB of Lab methode worden gebruikt.\n\nVoor niet-raw afbeeldingen zal altijd de Lab methode worden gebruikt, ongeacht de geselecteerde methode. TP_DIRPYRDENOISE_METM_TOOLTIP;De "Alleen Luminantie" en "L*a*b*" methodes worden meteen na de wavelet stap uitgevoerd bij het onderdrukken van ruis.\nDe "RGB" methode, wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. -TP_DIRPYRDENOISE_MET_TOOLTIP;Mediaan filters. Hoe groter de omvang, hoe langer de verwerking.\n\n3x3: bewerkt 5 pixels in een 1-pixel reeks.\n3x3 sterk: bewerkt 9 pixels in een 1-pixel reeks.\n5x5 soft: bewerkt 13 pixels in een 2-pixel reeks.\n5x5: bewerkt 25 pixels in een 2-pixel reeks.\n7x7: bewerkt 49 pixels in een 3-pixel reeks.\n9x9: bewerkt 81 pixels in een 4-pixel reeks.\n\nSoms is het mogelijk om een beter resultaat te behalen door meerdere iteraties met een kleinere reeks uit te voeren dan 1 iteratie met een grotere reeks. TP_DIRPYRDENOISE_NOISELABEL;Voorbeeld ruis: Gemiddeld=%1 Hoog=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;Voorbeeld ruis: Gemiddeld= - Hoog= - -TP_DIRPYRDENOISE_NRESID_TOOLTIP;Toont de overgebleven ruisniveau's van het zichtbare deel van de afbeelding in het voorbeeld na wavelet.\n\n>300 Veel ruis\n100-300 Gemiddeld ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB en L*a*b* mode. De RGB waarden zijn minder accuraat omdat de RGB mode luminantie en chrominantie niet volledig scheidt. -TP_DIRPYRDENOISE_PASSE;Iteraties -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Een 3x3 filter met drie iteraties geeft meestal een beter resultaat dan eenmaal het 7x7 filter. +TP_DIRPYRDENOISE_NRESID_TOOLTIP;Toont de overgebleven ruisniveaus van het zichtbare deel van de afbeelding in het voorbeeld na wavelet.\n\n>300 Veel ruis\n100-300 Gemiddeld ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB en L*a*b* mode. De RGB waarden zijn minder accuraat omdat de RGB mode luminantie en chrominantie niet volledig scheidt. +TP_DIRPYRDENOISE_PASSE;Herhalingen +TP_DIRPYRDENOISE_PASSES;Mediaan herhalingen TP_DIRPYRDENOISE_PON;Auto multi-zone TP_DIRPYRDENOISE_PRE;Voorbeeld multi-zone TP_DIRPYRDENOISE_PREV;Voorbeeld @@ -1391,13 +1417,12 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standaard TP_DIRPYRDENOISE_SHALBI;Hoog TP_DIRPYRDENOISE_SLI;Schuifbalk -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;Tegel grootte=%1, Centrum: Tx=%2 Ty=%3 TP_DIRPYREQUALIZER_ALGO;Algoritme Huid TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de kleuren van de huid, minimaliseert de actie op andere kleuren\nGroot: vermijd artefacten TP_DIRPYREQUALIZER_ARTIF;Verminder artefacten TP_DIRPYREQUALIZER_HUESKIN;Huidtint -TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitie zone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigzins wijzigen om te voorkomen dat de rest van de afbeelding wordt beinvloed. +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitie zone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigzins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) TP_DIRPYREQUALIZER_LUMACOARSEST;grofste TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast- @@ -1440,13 +1465,14 @@ TP_EXPOSURE_TCMODE_FILMLIKE;Film-achtig TP_EXPOSURE_TCMODE_LABEL1;Curve modus 1 TP_EXPOSURE_TCMODE_LABEL2;Curve modus 2 TP_EXPOSURE_TCMODE_LUMINANCE;Luminantie -TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptuee +TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptueel TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Verzadiging en Waarde mengen TP_EXPOSURE_TCMODE_STANDARD;Standaard TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen Standaard TP_EXPOS_BLACKPOINT_LABEL;Raw Zwartpunten TP_EXPOS_WHITEPOINT_LABEL;Raw Witpunten TP_FILMSIMULATION_LABEL;Film Simuleren +TP_FILMSIMULATION_SLOWPARSEDIR;Map met Hald CLUT afbeeldingen. Deze worden gebruikt voor Film Simuleren.\nGa naar Voorkeuren > Beeldverwerking > Film Simuleren\nDe aanbeveling is om een map te gebruiken die alleen Hald CLUT afbeeldingen bevat.\n\nLees het Film Simuleren artikel in RawPedia voor meer informatie.\n\nWilt u de scan afbreken? TP_FILMSIMULATION_STRENGTH;Sterkte TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT map in Voorkeuren TP_FLATFIELD_AUTOSELECT;Automatische selectie @@ -1489,11 +1515,11 @@ TP_HSVEQUALIZER_LABEL;HSV-balans TP_HSVEQUALIZER_SAT;Verzadiging TP_HSVEQUALIZER_VAL;Waarde TP_ICM_APPLYBASELINEEXPOSUREOFFSET;DCP basis belichting -TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebede DCP basis belichting. De instelling is allen actief als de DCP een basis belichting heeft. +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebedde DCP basis belichting. De instelling is allen actief als de DCP een basis belichting heeft. TP_ICM_APPLYHUESATMAP;DCP basis tabel -TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebede DCP basis tabel (HueSatMap). De instelling is allen actief als de DCP een basis tabel heeft. +TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP basis tabel (HueSatMap). De instelling is allen actief als de DCP een basis tabel heeft. TP_ICM_APPLYLOOKTABLE;DCP 'look' tabel -TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebede DCP 'look' tabel. De instelling is allen actief als de DCP een looktable heeft. +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP 'look' tabel. De instelling is allen actief als de DCP een looktable heeft. TP_ICM_BLENDCMSMATRIX;Meng hoge lichten met matrix TP_ICM_BLENDCMSMATRIX_TOOLTIP;Activeer om uitgebeten hoge lichten te herstellen wanneer op LUT gebaseerde ICC-profielen worden gebruikt. TP_ICM_DCPILLUMINANT;Illuminant @@ -1514,10 +1540,11 @@ TP_ICM_INPUTPROFILE;Invoerprofiel TP_ICM_LABEL;Kleurbeheer TP_ICM_NOICM;Geen ICM: sRGB-uitvoer TP_ICM_OUTPUTPROFILE;Uitvoerprofiel +TP_ICM_PROFILEINTENT;Rendering weergave TP_ICM_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling TP_ICM_SAVEREFERENCE_APPLYWB;Toepassen witbalans TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Gebruik witbalans bij het opslaan van afbeeldingen voor het maken van ICC profielen. Gebruik geen witbalans bij het maken van DCP profielen. -TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineare TIFF afbeelding op voordat het invoer profiel is toegepast. Het resultaat kan worden gebruikt voor calibratie en het genereren van een camera profiel. +TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF afbeelding op voordat het invoer profiel is toegepast. Het resultaat kan worden gebruikt voor calibratie en het genereren van een camera profiel. TP_ICM_TONECURVE;Gebruik DCP's toon curve TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP toon curve. De instelling is alleen actief als de geselecteerd DCP een toon curve heeft. TP_ICM_WORKINGPROFILE;Werkprofiel @@ -1557,7 +1584,7 @@ TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens hue L=f(H) TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens luminantie L=f(L) TP_LABCURVE_LABEL;Lab TP_LABCURVE_LCREDSK;Beperkt LC tot Rode en Huidtinten -TP_LABCURVE_LCREDSK_TIP;Indien ingeschakeld, beinvloed de LC Curve alleen rode en huidtinten\nIndien uitgeschakeld, is het van toepassing op all tinten +TP_LABCURVE_LCREDSK_TIP;Indien ingeschakeld, beïnvloed de LC Curve alleen rode en huidtinten\nIndien uitgeschakeld, is het van toepassing op all tinten TP_LABCURVE_RSTPROTECTION;Rode en huidtinten Bescherming TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits schuifbalk en de CC curve. TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden @@ -1567,6 +1594,7 @@ TP_LENSPROFILE_LABEL;Lenscorrectie Profielen TP_LENSPROFILE_USECA;CA correctie TP_LENSPROFILE_USEDIST;Lensvervorming correctie TP_LENSPROFILE_USEVIGN;Vignettering correctie +TP_NEUTRAL;Terugzetten TP_NEUTRAL_TIP;Alle belichtingsinstellingen naar 0 TP_PCVIGNETTE_FEATHER;Straal TP_PCVIGNETTE_FEATHER_TOOLTIP;Straal: \n0=alleen hoeken \n50=halverwege tot het centrum \n100=tot aan het centrum @@ -1593,6 +1621,7 @@ TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen act TP_RAWCACORR_AUTO;Automatische CA-correctie TP_RAWCACORR_CABLUE;Blauw TP_RAWCACORR_CARED;Rood +TP_RAWCACORR_CASTR;Sterkte TP_RAWEXPOS_BLACKS;Zwartniveaus TP_RAWEXPOS_BLACK_0;Groen 1 (leidend) TP_RAWEXPOS_BLACK_1;Rood @@ -1637,34 +1666,58 @@ TP_RESIZE_WIDTH;Breedte TP_RETINEX_CONTEDIT_HSL;Histogram balans HSL TP_RETINEX_CONTEDIT_LAB;Histogram balans L*a*b* TP_RETINEX_CONTEDIT_LH;Tint balans +TP_RETINEX_CONTEDIT_MAP;Masker mixer TP_RETINEX_CURVEEDITOR_CD;L=f(L) TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminantie volgens luminantie L=f(L)\nCorrigeert ruwe data om halo's and artefacte te verminderen. TP_RETINEX_CURVEEDITOR_LH;Sterkte=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Sterkte volgens tint Sterkte=f(H)\nDeze curve wijzigt ook chroma wanneer de "Hooglicht" retinex methode wordt gebruikt. +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Deze curve kan zowel alleen worden gebruikt of in combinatie met een Gaussiaans masker of wavelet masker.\nHou rekening met artefacten! +TP_RETINEX_EQUAL;Mixer +TP_RETINEX_FREEGAMMA;Vrij gamma TP_RETINEX_GAIN;Verbeteren -TP_RETINEX_GAIN_TOOLTIP;Wijzigt de aangepaste afbeelding.\n\nDit wijkt af van de andere instellingen. Wordt gebruikt voor zwarte of witte pixels, en om het histogram te balanseren. +TP_RETINEX_GAIN_TOOLTIP;Wijzigt de aangepaste afbeelding.\n\nDit wijkt af van de andere instellingen. Wordt gebruikt voor zwarte of witte pixels, en om het histogram te balanceren. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Vrij TP_RETINEX_GAMMA_HIGH;Hoog TP_RETINEX_GAMMA_LOW;Laag TP_RETINEX_GAMMA_MID;Midden TP_RETINEX_GAMMA_NONE;Geen +TP_RETINEX_GAMMA_TOOLTIP;Hersteld tinten door gamma voor en na Retinex toe te passen. Verschilt van Retinex curves en andere curves (Lab, Exposure, etc.). +TP_RETINEX_GRAD;Transmissie verloop +TP_RETINEX_GRADS;Sterkte verloop +TP_RETINEX_GRADS_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Sterkte verminderd en herhaling vergroot, en omgekeerd. +TP_RETINEX_GRAD_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Variantie en Drempel worden verkleind als herhaling toeneemt, en omgekeerd. TP_RETINEX_HIGH;Hoog TP_RETINEX_HIGHLIG;Hooglicht TP_RETINEX_HIGHLIGHT;Drempel hooglicht TP_RETINEX_HIGHLIGHT_TOOLTIP;Versterkt de werking van de Hooglicht methode.\nMogelijk moet de "Naburige pixels" worden aangepast en moet de "Witpunt Correctie" in de Raw tab -> Raw Witpuntent worden vergroot. TP_RETINEX_HSLSPACE_LIN;HSL-Linear TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmisch +TP_RETINEX_ITER;Herhalingen (Tonemapping) +TP_RETINEX_ITERF;Tonemapping +TP_RETINEX_ITER_TOOLTIP;Simuleert tonemapping.\nHoge waarden verlengen de bewerkingstijd. TP_RETINEX_LABEL;Retinex +TP_RETINEX_LABEL_MASK;Masker TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Laag +TP_RETINEX_MAP;Masker methode +TP_RETINEX_MAP_GAUS;Gaussiaans masker +TP_RETINEX_MAP_MAPP;Verscherp masker (wavelet gedeeltelijk) +TP_RETINEX_MAP_MAPT;Verscherp masker (wavelet totaal) +TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en artefacten te verminderen.\n\nCurve: past een diagonale contrast curve toe op het masker.\nHou rekening met artefacten!\n\n Gausiaans: genereerd en gebruikt een ‘Gausiaanse blur’ op het masker.\nVerscherpen: genereert en gebruikt een ‘wavelet’ op het masker.\nLangzaam. +TP_RETINEX_MAP_NONE;Geen TP_RETINEX_MEDIAN;Transmissie mediaan filter TP_RETINEX_METHOD;Methode TP_RETINEX_METHOD_TOOLTIP;Laag = versterk lage lichten,\nUniform = gelijkmatig,\nHoog = versterk hoge lichten,\nHooglicht = verwijder magenta in hooglicht. +TP_RETINEX_MLABEL;Teruggeplaatst sluier-vrij Min=%1 Max=%2 +TP_RETINEX_MLABEL_TOOLTIP;Zou min=0 en max=32768 moeten benaderen\nTeruggeplaatste afbeelding zonder mixture. TP_RETINEX_NEIGHBOR;Naburige pixels -TP_RETINEX_NEUTRAL;Begingwaarde +TP_RETINEX_NEUTRAL;Beginwaarde TP_RETINEX_NEUTRAL_TIP;Zet alles terug naar de beginwaarde. TP_RETINEX_OFFSET;Beginpunt +TP_RETINEX_SCALES;Gaussiaans verloop +TP_RETINEX_SCALES_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Schaal en straal worden verkleind als herhaling toeneemt, en omgekeerd. TP_RETINEX_SETTINGS;Instellingen TP_RETINEX_SLOPE;Vrij gamma helling TP_RETINEX_STRENGTH;Sterkte @@ -1673,10 +1726,19 @@ TP_RETINEX_THRESHOLD_TOOLTIP;Beperkt in/uit.\nIn = afbeelding,\nUit = afbeelding TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sigma=%4 TP_RETINEX_TLABEL2;TM Tm=%1 TM=%2 TP_RETINEX_TLABEL_TOOLTIP;Transmissie resultaat.\nMin en Max worden gebruikt door Variantie.\nMeeste en Sigma\nTm=Min TM=Max van de transmissie. +TP_RETINEX_TRANF;Transmissie TP_RETINEX_TRANSMISSION;Transmissie plan +TP_RETINEX_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde, en positieve waarden (max).\nOrdinaat: versterken of verminderen. TP_RETINEX_UNIFORM;Uniform TP_RETINEX_VARIANCE;Variantie TP_RETINEX_VARIANCE_TOOLTIP;Lage variantie versterkt lokaal contrast en verzadiging, maar dit kan artefacten veroorzaken. +TP_RETINEX_VIEW;Proces +TP_RETINEX_VIEW_MASK;Masker +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standaard - Normale afbeelding.\nMasker - Toont het masker.\nOnscherp masker - Toont de afbeelding met een hoge straal.\nTransmissie - Auto/Vast - Toont de transmissie-map, voor enige actie op kontrast en helderheid.\n\nLet op: het masker komt niet overeen met de werkelijkheid, maar is versterkt om het effect beter zichtbaar te maken. +TP_RETINEX_VIEW_NONE;Standaard +TP_RETINEX_VIEW_TRAN;Transmissie - Auto +TP_RETINEX_VIEW_TRAN2;Transmissie - Vast +TP_RETINEX_VIEW_UNSHARP;Onscherpmasker TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Kanaal TP_RGBCURVES_GREEN;G @@ -1771,12 +1833,12 @@ TP_WAVELET_CBENAB;Kleurtint en kleurbalans TP_WAVELET_CCURVE;Lokaal contrast TP_WAVELET_CH1;Alle chroma's TP_WAVELET_CH2;Pastel - Verzadigd -TP_WAVELET_CH3;Koppel contrast niveau's +TP_WAVELET_CH3;Koppel contrast niveaus TP_WAVELET_CHCU;Curve TP_WAVELET_CHR;Koppel Chroma aan contrast TP_WAVELET_CHRO;Verzadigd - Pastel TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel -TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met Contrast niveau's +TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met Contrast niveaus TP_WAVELET_CHSL;Schuifbalken TP_WAVELET_CHTYPE;Chrominantie methode TP_WAVELET_COLORT;Dekking Rood-Groen Niveau @@ -1791,12 +1853,13 @@ TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRA_TOOLTIP;Wijzigt het contrast van de 'rest afbeelding'. TP_WAVELET_CTYPE;Chrominantie sterkte +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Wijzigt lokaal contrast als een functie van het oorspronkelijke lokale contrast (abscis).\nLage abscis waarden vertegenwoordigen klein lokaal contrast (werkelijke waarden rond 10..20).\n50% abscis vertegenwoordigd gemiddeld lokaal contrast (werkelijke waarden rond 100..300).\n66% abscis vertegenwoordigd standaard deviatie van lokaal contrast (werkelijke waarden rond 300..800).\n100% abscis vertegenwoordigd maximaal lokaal contrast (werkelijke waarden rond 3000..8000). TP_WAVELET_CURVEEDITOR_CH;Contrast niveau=f(Hue) TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Wijzigt het contrast van elk niveau als een functie van hue.\nZorg er voor dat de wijzigingen die zijn gemaakt bij de Gamut Hue toepassing niet worden overschreven.\nDe curve werkt alleen als de 'wavelet contrast niveau schuifbalken' groter dan nul zijn. TP_WAVELET_CURVEEDITOR_CL;L TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Contrast luminantie curve. Wordt uitgevoerd aan het einde van de wavelet niveau behandeling. TP_WAVELET_CURVEEDITOR_HH;HH -TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de rest van de afbeelding's tint als een functie van tint. +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de rest van de afbeelding 's tint als een functie van tint. TP_WAVELET_DALL;Alle richtingen TP_WAVELET_DAUB;Randen TP_WAVELET_DAUB2;D2 - laag @@ -1804,23 +1867,24 @@ TP_WAVELET_DAUB4;D4 - standaard TP_WAVELET_DAUB6;D6 - standaard plus TP_WAVELET_DAUB10;D10 - medium TP_WAVELET_DAUB14;D14 - hoog -TP_WAVELET_DAUB_TOOLTIP;Wijzigt Daubechies coëfficiënt:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere vewerkingstijd.\n\nBeinvloed zowel rand detectie als het algemen resultaat van de eerste niveau´s. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan varieeren per afbeelding en toepassing. +TP_WAVELET_DAUB_TOOLTIP;Wijzigt Daubechies coëfficiënt:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere verwerkingstijd.\n\nBeïnvloed zowel rand detectie als het algemen resultaat van de eerste niveau´s. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan variëren per afbeelding en toepassing. TP_WAVELET_DONE;Richting: Vertikaal TP_WAVELET_DTHR;Richting: Diagonaal TP_WAVELET_DTWO;Richting: Horizontaal TP_WAVELET_EDCU;Curve TP_WAVELET_EDGCONT;Lokaal contrast -TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen. Naar rechts schuiven vegroot het contrast.\nLinksbeneden, Linksboven, Rechtsboven, Rechtsbeneden vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev, maximum. +TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen. Naar rechts schuiven vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev, maximum. TP_WAVELET_EDGE;Randen verscherpen (Luminantie) TP_WAVELET_EDGEAMPLI;Basis versterking TP_WAVELET_EDGEDETECT;Gradiënt gevoeligheid TP_WAVELET_EDGEDETECTTHR;Drempel laag (ruis) TP_WAVELET_EDGEDETECTTHR2;Drempel hoog (detectie) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Wijzigt de rand detectie. Bijvoorbeeld om randverscherping te voorkomen bij fijne details zoals ruis in de lucht. TP_WAVELET_EDGEDETECT_TOOLTIP;Beweeg de schuifbalk naar rechts om de randgevoeligheid te vergroten. Dit wijzigt lokaal contrast, randscherpte en ruis. TP_WAVELET_EDGESENSI;Randgevoeligheid TP_WAVELET_EDGREINF_TOOLTIP;Versterk of verminder de aktie van het eerste niveau en doe het tegenovergestelde voor het tweede niveau en laat de rest ongewijzigd. TP_WAVELET_EDGTHRESH;Drempel -TP_WAVELET_EDGTHRESH_TOOLTIP;Wijzigt de interactie tussen de eerste niveau's en de andere niveau's. Hoe hoger de drempel hoe meer de actie is gecentreerd op de eerste niveau's. Wees voorzichtig met negatieve waarden. Deze versterken de hogere niveau's en kunnen artefacten veroorzaken. +TP_WAVELET_EDGTHRESH_TOOLTIP;Wijzigt de interactie tussen de eerste niveaus en de andere niveaus. Hoe hoger de drempel hoe meer de actie is gecentreerd op de eerste niveaus. Wees voorzichtig met negatieve waarden. Deze versterken de hogere niveaus en kunnen artefacten veroorzaken. TP_WAVELET_EDRAD;Straal TP_WAVELET_EDRAD_TOOLTIP;Deze straalaanpassing verschilt erg van die in de andere verscherpings tools. De waarde wordt vergeleken met elk niveau op basis van een complexe functie. In dit geval heeft zelfs een nul waarde effect. TP_WAVELET_EDSL;Drempel schuifbalk @@ -1832,25 +1896,28 @@ TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantie Reeks (0..100) TP_WAVELET_HS1;Alle luminanties TP_WAVELET_HS2;Hoge lichten/Schaduwen TP_WAVELET_HUESKIN;Tint reeks (huid) +TP_WAVELET_HUESKIN_TOOLTIP;De laagste punten vormen het begin van de transitie zone, en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. TP_WAVELET_HUESKY;Tint Reeks (lucht) +TP_WAVELET_HUESKY_TOOLTIP;De laagste punten vormen het begin van de transitie zone, en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. TP_WAVELET_ITER;Balans niveau -TP_WAVELET_ITER_TOOLTIP;Links: verhoog lage niveau's en verlaag hoge niveau's.\nRechts: verlaag lage niveau's en verhoog high hoge niveau's. -TP_WAVELET_LABEL;Wavelet niveau's +TP_WAVELET_ITER_TOOLTIP;Links: verhoog lage niveaus en verlaag hoge niveaus.\nRechts: verlaag lage niveaus en verhoog hoge niveaus. +TP_WAVELET_LABEL;Wavelet niveaus TP_WAVELET_LARGEST;grof TP_WAVELET_LEVCH;Chromaticiteit -TP_WAVELET_LEVDIR_ALL;Alle niveau's in alle richtingen +TP_WAVELET_LEVDIR_ALL;Alle niveaus in alle richtingen TP_WAVELET_LEVDIR_INF;Onder of gelijk aan het niveau -TP_WAVELET_LEVDIR_ONE;Een Niveau +TP_WAVELET_LEVDIR_ONE;Eén Niveau TP_WAVELET_LEVDIR_SUP;Boven het niveau -TP_WAVELET_LEVELS;Wavelet niveau's -TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detail niveau's. Meer niveau's vereisen meer RAM en de verwerking duurt langer. +TP_WAVELET_LEVELS;Wavelet niveaus +TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detail niveaus. Meer niveaus vereisen meer RAM en de verwerking duurt langer. TP_WAVELET_LEVF;Contrast -TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveau's=%1 +TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveaus=%1 TP_WAVELET_LEVONE;Niveau 2 TP_WAVELET_LEVTHRE;Niveau 4 TP_WAVELET_LEVTWO;Niveau 3 TP_WAVELET_LEVZERO;Niveau 1 TP_WAVELET_LINKEDG;Koppel met Randscherpte Waarde +TP_WAVELET_LIPST;Verbeterde methode TP_WAVELET_LOWLIGHT;Schaduwen: Luminantie Reeks (0..100) TP_WAVELET_MEDGREINF;Eerste Niveau TP_WAVELET_MEDI;Verminder artefacten in blauwe lucht @@ -1863,7 +1930,7 @@ TP_WAVELET_NPHIGH;Hoog TP_WAVELET_NPLOW;Laag TP_WAVELET_NPNONE;Geen TP_WAVELET_NPTYPE;Naburige pixels -TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan wordten rande verscherpt. +TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan worden randen verscherpt. TP_WAVELET_OPACITY;Dekking Blauw-Geel Niveau TP_WAVELET_OPACITYW;Contrast balans d/v-h curve TP_WAVELET_OPACITYWL;Finale lokaal contrast @@ -1883,15 +1950,16 @@ TP_WAVELET_SKIN;Huidtinten Wijzigen/Beschermen TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in de tint reeks\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... +TP_WAVELET_STREN;Sterkte TP_WAVELET_STRENGTH;Sterkte TP_WAVELET_SUP;Boven het niveau + overblijvend TP_WAVELET_SUPE;Extra TP_WAVELET_THR;Drempel Schaduwen TP_WAVELET_THRES;Max niveau -TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveau's (fijn naar grof - leidend) -TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveau's (grof naar fijn) -TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveau's tussen '9' en '9 minus gekozen waarde' worden behandeld als schaduwen\nDe andere niveau's worden volledig behandeld\nHet maximum niveau voor schaduwen wordt beperkt door het aantal Hoge lichten niveau's (9- hoge lichten niveau) -TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveau's boven de gekozen waarde worden behandeld als hoge lichten\nDe andere niveau's worden volledig behandeld +TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) +TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) +TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus tussen '9' en '9 minus gekozen waarde' worden behandeld als schaduwen\nDe andere niveaus worden volledig behandeld\nHet maximum niveau voor schaduwen wordt beperkt door het aantal Hoge lichten niveaus (9- hoge lichten niveau) +TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus boven de gekozen waarde worden behandeld als hoge lichten\nDe andere niveaus worden volledig behandeld TP_WAVELET_THRH;Drempel Hoge lichten TP_WAVELET_TILES;Tegel grootte (* 128) TP_WAVELET_TILESBIG;Grote Tegels @@ -1961,78 +2029,22 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!HISTORY_MSG_166;Exposure - Reset -!HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_416;Retinex -!HISTORY_MSG_427;Output rendering intent -!HISTORY_MSG_428;Monitor rendering intent -!HISTORY_MSG_429;Retinex - Iterations -!HISTORY_MSG_430;Retinex - Transmission Gradient -!HISTORY_MSG_431;Retinex - Strength Gradient -!HISTORY_MSG_432;Retinex - M - Highlights -!HISTORY_MSG_433;Retinex - M - Highlights TW -!HISTORY_MSG_434;Retinex - M - Shadows -!HISTORY_MSG_435;Retinex - M - Shadows TW -!HISTORY_MSG_436;Retinex - M - Radius -!HISTORY_MSG_437;Retinex - M - Method -!HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview -!HISTORY_MSG_440;CbDL - Method -!MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MONITOR_PROFILE_SYSTEM;System default -!PARTIALPASTE_PRSHARPENING;Post-resize sharpening -!PREFERENCES_MONINTENT;Default monitor intent -!PREFERENCES_MONPROFILE;Default monitor profile -!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. -!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. -!PREFERENCES_PROFILE_NONE;None -!TP_CBDL_AFT;After Black-and-White -!TP_CBDL_BEF;Before Black-and-White -!TP_CBDL_METHOD;Process located -!TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. -!TP_COLORTONING_STR;Strength -!TP_DIRPYRDENOISE_CUR;Curve -!TP_DIRPYRDENOISE_LAB;L*a*b* -!TP_DIRPYRDENOISE_PASSES;Median iterations -!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_PROFILEINTENT;Rendering Intent -!TP_NEUTRAL;Reset -!TP_RAWCACORR_CASTR;Strength -!TP_RETINEX_CONTEDIT_MAP;Mask equalizer -!TP_RETINEX_CURVEEDITOR_MAP;L=f(L) -!TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! -!TP_RETINEX_FREEGAMMA;Free gamma -!TP_RETINEX_GAMMA_TOOLTIP;Restore tones by applying gamma before and after Retinex. Different from Retinex curves or others curves (Lab, Exposure, etc.). -!TP_RETINEX_GRAD;Transmission gradient -!TP_RETINEX_GRADS;Strength gradient -!TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Strength is reduced when iterations increase, and conversely. -!TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Variance and Threshold are reduced when iterations increase, and conversely. -!TP_RETINEX_ITER;Iterations (Tone-mapping) -!TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. -!TP_RETINEX_LABEL_MASK;Mask -!TP_RETINEX_MAP;Mask method -!TP_RETINEX_MAP_GAUS;Gaussian mask -!TP_RETINEX_MAP_MAPP;Sharp mask (wavelet partial) -!TP_RETINEX_MAP_MAPT;Sharp mask (wavelet total) -!TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generated by the Gaussian function above (Radius, Method) to reduce halos and artifacts.\n\nCurve only: apply a diagonal contrast curve on the mask.\nBeware of artifacts!\n\nGaussian mask: generate and use a Gaussian blur of the original mask.\nQuick.\n\nSharp mask: generate and use a wavelet on the original mask.\nSlow. -!TP_RETINEX_MAP_NONE;None -!TP_RETINEX_MLABEL;Restored haze-free Min=%1 Max=%2 -!TP_RETINEX_MLABEL_TOOLTIP;Should be near min=0 max=32768\nRestored image with no mixture. -!TP_RETINEX_SCALES;Gaussian gradient -!TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. -!TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. -!TP_RETINEX_VIEW;Process -!TP_RETINEX_VIEW_MASK;Mask -!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_RETINEX_VIEW_NONE;Standard -!TP_RETINEX_VIEW_TRAN;Transmission - Auto -!TP_RETINEX_VIEW_TRAN2;Transmission - Fixed -!TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!GENERAL_APPLY;Apply +!GENERAL_OPEN;Open +!HISTORY_MSG_439;Retinex - Process +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale +!TP_BWMIX_AUTOCH;Auto +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. +!TP_RETINEX_SKAL;Scale !TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted -!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000). -!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. -!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. -!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. -!TP_WAVELET_LIPST;Enhanced algoritm -!TP_WAVELET_STREN;Strength diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM index 105277339..a3554ca16 100644 --- a/rtdata/languages/Norsk BM +++ b/rtdata/languages/Norsk BM @@ -579,12 +579,14 @@ TP_WBALANCE_TEMPERATURE;Temperatur !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -658,7 +660,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -918,14 +920,14 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -947,8 +949,10 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1425,11 +1429,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1472,12 +1477,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1488,7 +1493,6 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1710,8 +1714,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1731,6 +1739,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1750,10 +1759,11 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1761,6 +1771,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 5f3c30045..584409e96 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -369,7 +369,7 @@ HISTORY_MSG_145;Mikrokontrast - Jednolitość HISTORY_MSG_146;Wyostrzanie krawędzi HISTORY_MSG_147;Wyostrzanie krawędzi - tylko luminacja HISTORY_MSG_148;Mikrokontrast -HISTORY_MSG_149;Mikrokontrast - matryca 3x3 +HISTORY_MSG_149;Mikrokontrast - matryca 3×3 HISTORY_MSG_150;Redukcja szumu i artefaktów po demozaikowaniu HISTORY_MSG_151;Jaskrawość HISTORY_MSG_152;Jaskrawość - Ppastelowe @@ -1117,10 +1117,6 @@ TP_DARKFRAME_LABEL;Czarna klatka TP_DEFRINGE_LABEL;Usuwanie widma TP_DEFRINGE_RADIUS;Promień TP_DEFRINGE_THRESHOLD;Próg -TP_DIRPYRDENOISE_33;3×3 silne -TP_DIRPYRDENOISE_55;5×5 silne -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (wolne) TP_DIRPYRDENOISE_BLUE;Chrominancja - Błękit-żółć TP_DIRPYRDENOISE_CHROMA;Chrominancja - Główna TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Moduluje działanie usuwania szumów luminancji @@ -1144,15 +1140,12 @@ TP_DIRPYRDENOISE_METHOD11;Jakość TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Jakość może zostać dopasowana do wzoru szumów. Ustawienie "wysoka" ulepsza odszumianie około 20% wzrostu czasu przetwarzania. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazów raw można używać metody RGB oraz L*a*b*.\n\nDla obrazów nie-raw metoda L*a*b* zostanie użyta niezależnie od wyboru. TP_DIRPYRDENOISE_METM_TOOLTIP;Przy użyciu metod "tylko luminancja" oraz "L*a*b*", filtrowanie mediana zostanie wykonane prosto po funkcji falki w procesie odszumiania.\nW trybie "RGB" filtrowanie to zostanie wykonana pod koniec calego procesu. -TP_DIRPYRDENOISE_MET_TOOLTIP;Zasrosuj filtrowanie mediana o oknie pożądanego rozmiaru. Im większy rozmiar okna, tym dłużej przetwarzanie zajmie.\n\n3x3 miękki: użyje 5 pikseli w zasięgu 1 pikseli.\n3x3: użyje 9 pikseli w zasięgu 1 pikseli.\n5x5 miękki: użyje 13 pikseli w zasięgu 2 pikseli.\n5x5: użyje 25 pikseli w zasięgu 2 pikseli.\n7x7: użyje 49 pikseli w zasięgu 3 pikseli.\n\nCzasem można uzyskać wyższą jakość wielokrotnym powtórzeniem filtru przy użyciu małego okna niz przy jednokrotnym przetworzeniu przy użyciu dużego okna. TP_DIRPYRDENOISE_PASSES;Liczba powtórzeń mediana -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Trzykrotne powtórzenie filtru mediana przy użyciu okna o rozmiarze 3x3 często skutkuje wyższą jakością niż jednokrotne z oknem o rozmiarze 7x7. TP_DIRPYRDENOISE_RED;Chrominancja - Czerwień-zieleń TP_DIRPYRDENOISE_RGB;RGB TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standardowa TP_DIRPYRDENOISE_SHALBI;Wysoka -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYREQUALIZER_ALGO;Zakres odcieni skóry TP_DIRPYREQUALIZER_ALGO_TOOLTIP;- TP_DIRPYREQUALIZER_HUESKIN;Odcień skóry @@ -1518,7 +1511,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_299;NR - Chrominance curve !HISTORY_MSG_300;- @@ -1631,14 +1626,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1660,8 +1655,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet @@ -1741,7 +1738,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1761,9 +1763,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail !TP_DIRPYRDENOISE_MAN;Manual !TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1800,8 +1804,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1821,6 +1829,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1840,10 +1849,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1851,6 +1861,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) index 79bf35bea..5ff2cc31b 100644 --- a/rtdata/languages/Polish (Latin Characters) +++ b/rtdata/languages/Polish (Latin Characters) @@ -369,7 +369,7 @@ HISTORY_MSG_145;Mikrokontrast - Jednolitosc HISTORY_MSG_146;Wyostrzanie krawedzi HISTORY_MSG_147;Wyostrzanie krawedzi - tylko luminacja HISTORY_MSG_148;Mikrokontrast -HISTORY_MSG_149;Mikrokontrast - matryca 3x3 +HISTORY_MSG_149;Mikrokontrast - matryca 3×3 HISTORY_MSG_150;Redukcja szumu i artefaktow po demozaikowaniu HISTORY_MSG_151;Jaskrawosc HISTORY_MSG_152;Jaskrawosc - Ppastelowe @@ -1117,10 +1117,6 @@ TP_DARKFRAME_LABEL;Czarna klatka TP_DEFRINGE_LABEL;Usuwanie widma TP_DEFRINGE_RADIUS;Promien TP_DEFRINGE_THRESHOLD;Prog -TP_DIRPYRDENOISE_33;3×3 silne -TP_DIRPYRDENOISE_55;5×5 silne -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (wolne) TP_DIRPYRDENOISE_BLUE;Chrominancja - Blekit-zolc TP_DIRPYRDENOISE_CHROMA;Chrominancja - Glowna TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Moduluje dzialanie usuwania szumow luminancji @@ -1144,15 +1140,12 @@ TP_DIRPYRDENOISE_METHOD11;Jakosc TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Jakosc moze zostac dopasowana do wzoru szumow. Ustawienie "wysoka" ulepsza odszumianie okolo 20% wzrostu czasu przetwarzania. TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazow raw mozna uzywac metody RGB oraz L*a*b*.\n\nDla obrazow nie-raw metoda L*a*b* zostanie uzyta niezaleznie od wyboru. TP_DIRPYRDENOISE_METM_TOOLTIP;Przy uzyciu metod "tylko luminancja" oraz "L*a*b*", filtrowanie mediana zostanie wykonane prosto po funkcji falki w procesie odszumiania.\nW trybie "RGB" filtrowanie to zostanie wykonana pod koniec calego procesu. -TP_DIRPYRDENOISE_MET_TOOLTIP;Zasrosuj filtrowanie mediana o oknie pozadanego rozmiaru. Im wiekszy rozmiar okna, tym dluzej przetwarzanie zajmie.\n\n3x3 miekki: uzyje 5 pikseli w zasiegu 1 pikseli.\n3x3: uzyje 9 pikseli w zasiegu 1 pikseli.\n5x5 miekki: uzyje 13 pikseli w zasiegu 2 pikseli.\n5x5: uzyje 25 pikseli w zasiegu 2 pikseli.\n7x7: uzyje 49 pikseli w zasiegu 3 pikseli.\n\nCzasem mozna uzyskac wyzsza jakosc wielokrotnym powtorzeniem filtru przy uzyciu malego okna niz przy jednokrotnym przetworzeniu przy uzyciu duzego okna. TP_DIRPYRDENOISE_PASSES;Liczba powtorzen mediana -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Trzykrotne powtorzenie filtru mediana przy uzyciu okna o rozmiarze 3x3 czesto skutkuje wyzsza jakoscia niz jednokrotne z oknem o rozmiarze 7x7. TP_DIRPYRDENOISE_RED;Chrominancja - Czerwien-zielen TP_DIRPYRDENOISE_RGB;RGB TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standardowa TP_DIRPYRDENOISE_SHALBI;Wysoka -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYREQUALIZER_ALGO;Zakres odcieni skory TP_DIRPYREQUALIZER_ALGO_TOOLTIP;- TP_DIRPYREQUALIZER_HUESKIN;Odcien skory @@ -1518,7 +1511,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_299;NR - Chrominance curve !HISTORY_MSG_300;- @@ -1631,14 +1626,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1660,8 +1655,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet @@ -1741,7 +1738,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1761,9 +1763,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail !TP_DIRPYRDENOISE_MAN;Manual !TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1800,8 +1804,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1821,6 +1829,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1840,10 +1849,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1851,6 +1861,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index a665b17e4..9891c07b3 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;Temperatura !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;Temperatura !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;Temperatura !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 778500cbb..b792e92bc 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -364,7 +364,7 @@ HISTORY_MSG_145;Микроконтраст: Равномерность HISTORY_MSG_146;Резкость контуров HISTORY_MSG_147;РК: Только освещенность HISTORY_MSG_148;Микроконтраст -HISTORY_MSG_149;Микроконтраст: матрица 3x3 +HISTORY_MSG_149;Микроконтраст: матрица 3×3 HISTORY_MSG_150;Пост-демозаик шумоподавление HISTORY_MSG_151;Резонанс HISTORY_MSG_152;Рез: Пастельные тона @@ -1322,7 +1322,9 @@ ZOOMPANEL_ZOOMOUT;Удалить - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_252;CbDL - Skin tar/prot !HISTORY_MSG_253;CbDL - Reduce artifacts @@ -1482,14 +1484,14 @@ ZOOMPANEL_ZOOMOUT;Удалить - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1511,8 +1513,10 @@ ZOOMPANEL_ZOOMOUT;Удалить - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet @@ -1686,11 +1690,12 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1720,12 +1725,12 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_DIRPYRDENOISE_METHOD11;Quality !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1734,7 +1739,6 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1796,8 +1800,12 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1817,6 +1825,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1836,10 +1845,11 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1847,6 +1857,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index c48c5528f..5145322d2 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -3,14 +3,18 @@ ABOUT_TAB_BUILD;Издање ABOUT_TAB_CREDITS;Заслуге ABOUT_TAB_LICENSE;Лиценца +ABOUT_TAB_RELEASENOTES;Белешке о издању ABOUT_TAB_SPLASH;Увод ADJUSTER_RESET_TO_DEFAULT;Врати на подразумевано BATCHQUEUE_AUTOSTART;Сам започни +BATCHQUEUE_DESTFILENAME;Путања и име датотеке BATCH_PROCESSING;обрада CURVEEDITOR_CURVE;Кривуља CURVEEDITOR_CURVES;Кривуље CURVEEDITOR_CUSTOM;Произвољно CURVEEDITOR_DARKS;Тамно +CURVEEDITOR_FILEDLGFILTERANY;Све датотеке +CURVEEDITOR_FILEDLGFILTERCURVE;Датотеке са кривама CURVEEDITOR_HIGHLIGHTS;Пресветло CURVEEDITOR_LIGHTS;Светло CURVEEDITOR_LINEAR;Линеарно @@ -26,10 +30,10 @@ CURVEEDITOR_TOOLTIPLOAD;Учитава кривуљу из датотеке CURVEEDITOR_TOOLTIPPASTE;Убацује кривуљу из оставе CURVEEDITOR_TOOLTIPSAVE;Чува тренутну кривуљу CURVEEDITOR_TYPE;Врста: -DIRBROWSER_FOLDERS;Фасцикле EDITWINDOW_TITLE;Уређивање слике EXIFFILTER_APERTURE;Отвор бленде EXIFFILTER_CAMERA;Фото апарат +EXIFFILTER_EXPOSURECOMPENSATION;Компензација експозиције (ЕВ) EXIFFILTER_FILETYPE;Врста датотеке EXIFFILTER_FOCALLEN;Жижна даљина EXIFFILTER_ISO;ИСО @@ -50,6 +54,35 @@ EXIFPANEL_RESETALL;Врати све EXIFPANEL_RESETALLHINT;Враћа све ознаке на почетне вредности EXIFPANEL_RESETHINT;Враћа изабрану ознаку на почетну вредности EXIFPANEL_SUBDIRECTORY;Поддиректоријум +EXPORT_BYPASS_ALL;Изабери / поништи све +EXPORT_BYPASS_COLORDENOISE;Занемари уклањање колорног defriшума +EXPORT_BYPASS_DEFRINGE;Занемари уклањање ореола +EXPORT_BYPASS_DIRPYRDENOISE;Занемари уклањање шума +EXPORT_BYPASS_DIRPYREQUALIZER;Занемари детаљни ниво контраста +EXPORT_BYPASS_LUMADENOISE;Занемари уклањање шума луминасе +EXPORT_BYPASS_RAW_ALL_ENHANCE;Занемари уклањање артафакта/шума након расклапања +EXPORT_BYPASS_RAW_CA;Занемари [raw] исправљање хроматских аберација +EXPORT_BYPASS_RAW_CCSTEPS;Занемари [raw] пригушивање лажне боје +EXPORT_BYPASS_RAW_DCB_ENHANCE;Занемари [raw] ДЦБ побољшање +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Занемари [raw] број ДЦБ пролаза +EXPORT_BYPASS_RAW_DF;Занемари [raw] тамно поље +EXPORT_BYPASS_RAW_FF;Занемари [raw] равно поље +EXPORT_BYPASS_RAW_GREENTHRESH;Занемари [raw] калибрацију зелене боје +EXPORT_BYPASS_RAW_LINENOISE;Занемари [raw] линијски филтер шума +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Занемари [raw] ЛММСЕ кораке за побољшање +EXPORT_BYPASS_SHARPENEDGE;Занемари оштрење ивице +EXPORT_BYPASS_SHARPENING;Занемари оштрење +EXPORT_BYPASS_SHARPENMICRO;Занемари микроконтраст +EXPORT_BYPASS_SH_HQ;Занемари оштру маску за Сенке/Светло +EXPORT_FASTEXPORTOPTIONS;Опције за брз извоз +EXPORT_INSTRUCTIONS;Брз извоз омогућава да заобиђете неке од захтевних и споријих процеса приликом развијања слика и да закажете фотографије за брзо развијање. Овј метод је добар за брзо развијање слика у мањој резолуцији, када вам је битно да фотографије добијете што пре или када желите примените задовољавајуће параметре за развијање већег броја фотографија одједном без измене њихових профила. +EXPORT_MAXHEIGHT;Највећа висина: +EXPORT_MAXWIDTH;Највећа дужина: +EXPORT_PUTTOQUEUEFAST; Закажи за брз извоз +EXPORT_RAW_DMETHOD;Начин расклапања мозаика +EXPORT_RESIZEMETHOD;Начин промене величине +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;заказано-развијено FILEBROWSER_ADDDELTEMPLATE;Додај/уклони шаблоне... FILEBROWSER_APPLYPROFILE;Примени профил FILEBROWSER_APPLYPROFILE_PARTIAL;Примени профил (половично) @@ -61,6 +94,7 @@ FILEBROWSER_CACHE;Остава FILEBROWSER_CACHECLEARFROMFULL;Очисти из оставе — све FILEBROWSER_CACHECLEARFROMPARTIAL;Очисти из оставе — половично FILEBROWSER_CLEARPROFILE;Обриши профил +FILEBROWSER_COLORLABEL_TOOLTIP;Натпис у боји.\n\nКористите приложени мени или пречице:\nShift-Ctrl-0 Без боје\nShift-Ctrl-1 Црвена\nShift-Ctrl-2 Жута\nShift-Ctrl-3 Зелена\nShift-Ctrl-4 Плана\nShift-Ctrl-5 Љубичаста FILEBROWSER_COPYPROFILE;Умножи профил FILEBROWSER_CURRENT_NAME;Тренутно име: FILEBROWSER_DARKFRAME;Тамни кадар @@ -70,10 +104,12 @@ FILEBROWSER_DELETEDLGMSGINCLPROC;Да ли желите да обришете %1 FILEBROWSER_EMPTYTRASH;Избаци смеће FILEBROWSER_EMPTYTRASHHINT;Трајно брише датотеке из смећа FILEBROWSER_EXEC_CPB;Изгради почетни профил +FILEBROWSER_EXTPROGMENU;Отвори помоћу FILEBROWSER_FLATFIELD;Равно поље FILEBROWSER_MOVETODARKFDIR;Пребаци у фасциклу са тамним кадровима FILEBROWSER_MOVETOFLATFIELDDIR;Премести у фасцикли са равним пољима FILEBROWSER_NEW_NAME;Ново име: +FILEBROWSER_OPENDEFAULTVIEWER;Подразумевани приказ прозора (заказано-развијено) FILEBROWSER_PARTIALPASTEPROFILE;Делимично убаци FILEBROWSER_PASTEPROFILE;Убаци профил FILEBROWSER_POPUPCANCELJOB;Откажи задатак @@ -84,9 +120,10 @@ FILEBROWSER_POPUPMOVEEND;Премести на крај заказаних FILEBROWSER_POPUPMOVEHEAD;Премести на почетак заказаних FILEBROWSER_POPUPMOVETO;Премести у... FILEBROWSER_POPUPOPEN;Отвори -FILEBROWSER_POPUPOPENINEDITOR;Отвори у уреднику FILEBROWSER_POPUPPROCESS;Закажи за обраду +FILEBROWSER_POPUPPROCESSFAST;Додај у заказано (брзи извоз) FILEBROWSER_POPUPPROFILEOPERATIONS;Профил +FILEBROWSER_POPUPRANK;Оцена FILEBROWSER_POPUPREMOVE;Уклони из система датотека FILEBROWSER_POPUPREMOVEINCLPROC;Уклони из система датотека и заказаног FILEBROWSER_POPUPRENAME;Преименуј @@ -97,7 +134,13 @@ FILEBROWSER_POPUPUNTRASH;Уклони из смећа FILEBROWSER_QUERYBUTTONHINT;Очисти поље за претрагу FILEBROWSER_QUERYHINT;Унесите део имена датотеке за претрагу nCtrl-f поставља фокус (у Разгледачу датотека);nEnter претражује FILEBROWSER_QUERYLABEL; Тражи: +FILEBROWSER_RANK1_TOOLTIP;Оцена 1 *\nПречица: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Оцена 2 *\nПречица: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Оцена 3 *\nПречица: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Оцена 4 *\nПречица: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Оцена 5 *\nПречица: Shift-5 FILEBROWSER_RENAMEDLGLABEL;Преименуј датотеку +FILEBROWSER_RENAMEDLGMSG;Преименуј датотеку „%1“ у: FILEBROWSER_SELECTDARKFRAME;Изабери тамни кадар... FILEBROWSER_SELECTFLATFIELD;Изабери равно поље... FILEBROWSER_SHOWCOLORLABEL1HINT;Приказује слике означене црвеном Alt-1 @@ -125,12 +168,16 @@ FILEBROWSER_STOPPROCESSING;Заустави обраду FILEBROWSER_STOPPROCESSINGHINT;Зауставља обраду слика FILEBROWSER_THUMBSIZE;Преглед FILEBROWSER_TOOLTIP_STOPPROCESSING;Покреће обраду фотографија када их закажете +FILEBROWSER_UNRANK_TOOLTIP;Неоцењено.\nПречица: Shift-0 +FILEBROWSER_USETEMPLATE;Искористи шаблон: FILEBROWSER_ZOOMINHINT;Увећава преглед FILEBROWSER_ZOOMOUTHINT;Умањује преглед GENERAL_ABOUT;О програму GENERAL_AFTER;После +GENERAL_AUTO;Аутоматски GENERAL_BEFORE;Пре GENERAL_CANCEL;Откажи +GENERAL_CLOSE;Затвори GENERAL_DISABLE;Искључи GENERAL_DISABLED;Искључено GENERAL_ENABLE;Укључи @@ -144,8 +191,11 @@ GENERAL_OK;У реду GENERAL_PORTRAIT;Усправно GENERAL_SAVE;Сачувај GENERAL_UNCHANGED;(неизмењено) +GENERAL_WARNING;Упозорење HISTOGRAM_TOOLTIP_B;Приказује плави хистограм HISTOGRAM_TOOLTIP_BAR;Приказује/сакрива РГБ индикатор. Кликните десни тастер миша на умањени приказ да замрзнете +HISTOGRAM_TOOLTIP_CHRO;Прикажи/сакриј хистограм хроминансе. +HISTOGRAM_TOOLTIP_FULL;Укључује приказ потпуног или хистограма у размери. HISTOGRAM_TOOLTIP_G;Приказује зелени хистограм HISTOGRAM_TOOLTIP_L;Приказује ЦиеЛаб хитограм HISTOGRAM_TOOLTIP_R;Приказује црвени хистограм @@ -195,8 +245,8 @@ HISTORY_MSG_37;Појачање боја HISTORY_MSG_38;Начин балансирања беле HISTORY_MSG_39;Температура боје HISTORY_MSG_40;Заленило боје -HISTORY_MSG_41;Померај боје „А“ -HISTORY_MSG_42;Померај боје „Б“ +HISTORY_MSG_41;Померање боје „А“ +HISTORY_MSG_42;Померање боје „Б“ HISTORY_MSG_43;Уклањање светлосног шума HISTORY_MSG_44;Радијус укл. светлосног шума HISTORY_MSG_45;Толеранција ивице укл. с. шума @@ -303,11 +353,113 @@ HISTORY_MSG_145;Микроконтраст - уједначеност HISTORY_MSG_146;Оштрење ивица HISTORY_MSG_147;Оштрење ивица - само луминанса HISTORY_MSG_148;Микроконтраст -HISTORY_MSG_149;Микроконтраст - 3x3 матрица +HISTORY_MSG_149;Микроконтраст - 3×3 матрица HISTORY_MSG_150;Уклањање артефакта/шума након расклапања мозаика +HISTORY_MSG_151;Живост боја +HISTORY_MSG_152;Жив - Пастелни тонови +HISTORY_MSG_153;Жив - Засићени тонови +HISTORY_MSG_154;Жив - Заштити боју коже +HISTORY_MSG_155;Жив - Избегни померање боја +HISTORY_MSG_156;Жив - Повежи пастелно и засићено +HISTORY_MSG_157;Жив - П/С праг +HISTORY_MSG_158;МТ - Јачина +HISTORY_MSG_159;МТ - Заустављање ивице +HISTORY_MSG_160;МТ - Размера +HISTORY_MSG_161;МТ - Понављање премеравања +HISTORY_MSG_162;Мапирање тонова +HISTORY_MSG_163;РГБ криве - црвена +HISTORY_MSG_164;РГБ криве - зелена +HISTORY_MSG_165;РГБ криве - плава +HISTORY_MSG_166;Неутрални нивои +HISTORY_MSG_167;--неискоришћено-- +HISTORY_MSG_168;„CC“ крива +HISTORY_MSG_169;„CH“ крива +HISTORY_MSG_170;Жив - крива +HISTORY_MSG_171;„LC“ крива +HISTORY_MSG_172;Лаб - Забрани LC +HISTORY_MSG_173;УШ - Детаљи луминансе +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 адаптација +HISTORY_MSG_176;CAM02 - Околина приказа +HISTORY_MSG_177;CAM02 - Луминанса кадра +HISTORY_MSG_178;CAM02 - Луминанса приказа +HISTORY_MSG_179;CAM02 - Модел беле тачке +HISTORY_MSG_180;CAM02 - Светлина (J) +HISTORY_MSG_181;CAM02 - Боја (C) +HISTORY_MSG_182;CAM02 - Аутоматски CAT02 +HISTORY_MSG_183;CAM02 - Контраст (J) +HISTORY_MSG_184;CAM02 - Околина сцене +HISTORY_MSG_185;CAM02 - Контрола ширине тонова +HISTORY_MSG_186;CAM02 - Алгоритам +HISTORY_MSG_187;CAM02 - Заштита црвене и боје коже +HISTORY_MSG_188;CAM02 - Светлина (Q) +HISTORY_MSG_189;CAM02 - Контраст (Q) +HISTORY_MSG_190;CAM02 - Засићеност (S) +HISTORY_MSG_191;CAM02 - Живописност (M) +HISTORY_MSG_192;CAM02 - Нијанса (h) +HISTORY_MSG_193;CAM02 - Крива тонова 1 +HISTORY_MSG_194;CAM02 - Крива тонова 2 +HISTORY_MSG_195;CAM02 - Крива тонова 1 +HISTORY_MSG_196;CAM02 - Крива тонова 2 +HISTORY_MSG_197;CAM02 - Крива боје +HISTORY_MSG_198;CAM02 - Крива боје +HISTORY_MSG_199;CAM02 - Излазни хистограми +HISTORY_MSG_200;CAM02 - Мапирање тонова +HISTORY_MSG_201;УШ - Хроминанса Ц,З +HISTORY_MSG_202;УШ - Хроминанса П,Y +HISTORY_MSG_203;УШ - Начин +HISTORY_MSG_204;LMMSE кораци побољшања +HISTORY_MSG_205;CAM02 - Врући/лош пиксели +HISTORY_MSG_206;CAT02 - Аутоматска луминанса кадра +HISTORY_MSG_207;Уклањање ореола - крива нијансе +HISTORY_MSG_208;ББ - Баланс Ц и П +HISTORY_MSG_210;ФГ - Угао +HISTORY_MSG_211;Филтер градијента +HISTORY_MSG_212;ФВ - Јачина +HISTORY_MSG_213;Филтер вињетарења +HISTORY_MSG_214;Црно-бела слика +HISTORY_MSG_215;ЦБ - CM - Црвена +HISTORY_MSG_216;ЦБ - CM - Зелена +HISTORY_MSG_217;ЦБ - CM - Плава +HISTORY_MSG_218;ЦБ - Гама - Црвена +HISTORY_MSG_219;ЦБ - Гама - Зелена +HISTORY_MSG_220;ЦБ - Гама - Плана +HISTORY_MSG_221;ЦБ - Филтер боје +HISTORY_MSG_222;ЦБ - Предподешавања +HISTORY_MSG_223;ЦБ - CM - Наранџаста +HISTORY_MSG_224;ЦБ - CM - Жута +HISTORY_MSG_225;ЦБ - CM - Светло плава +HISTORY_MSG_226;ЦБ - CM - Светло љубичаста +HISTORY_MSG_227;ЦБ - CM - Љубичаста +HISTORY_MSG_228;ЦБ - Уједначење луминансе +HISTORY_MSG_229;ЦБ - Уједначење луминансе +HISTORY_MSG_230;ЦБ - Режим +HISTORY_MSG_231;ЦБ - Пре криве +HISTORY_MSG_232;ЦБ - Пре врсте криве +HISTORY_MSG_233;ЦБ - Након приве +HISTORY_MSG_234;ЦБ - Након врсте криве +HISTORY_MSG_235;ЦБ - Аутоматско мешање канала +HISTORY_MSG_236;--неискоришћено-- +HISTORY_MSG_237;ЦБ - Миксер +HISTORY_MSG_238;ФГ - Умекшање +HISTORY_MSG_239;ФГ - Јачина +HISTORY_MSG_240;ФГ - Центар +HISTORY_MSG_241;ФВ - Умекшање +HISTORY_MSG_242;ФВ - Кривоћа +HISTORY_MSG_243;ФВ - Пречник +HISTORY_MSG_244;ФВ - Јачина +HISTORY_MSG_245;ФВ - Центар +HISTORY_MSG_246;CL крива +HISTORY_MSG_247;LH крива +HISTORY_MSG_248;HH крива +HISTORY_MSG_249;CbDL - Праг +HISTORY_MSG_250;УШ - Побољшање +HISTORY_MSG_251;ЦБ - Алгоритам HISTORY_NEWSNAPSHOT;Додај +HISTORY_NEWSNAPSHOT_TOOLTIP;Пречица: Alt-s HISTORY_SNAPSHOT;Снимак HISTORY_SNAPSHOTS;Снимак +HRESHOLDSELECTOR_BL;Доле-лево IPTCPANEL_AUTHOR;Аутор IPTCPANEL_AUTHORSPOSITION;Звање аутора IPTCPANEL_AUTHORSPOSITIONHINT;Звање једног или више аутора (једно по реди). @@ -350,10 +502,14 @@ IPTCPANEL_TITLEHINT;Кратни назив слике (име објекта). IPTCPANEL_TRANSREFERENCE;Реф. преноса IPTCPANEL_TRANSREFERENCEHINT;Код којји представља место првобитног преноса (референца првог преноса). MAIN_BUTTON_FULLSCREEN;Цео екран +MAIN_BUTTON_NAVNEXT_TOOLTIP;Шаље вас на наредну слику у односу на отворену у прозору за уређивање.\nПречица: Shift-F4\n\nТакође, омогућа вам да идете на наредну слику у односу на тренутно изабрану у разгледачу или филмској траци.\nПречица: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Шаље вас на претходну слику у односу на отворену у прозору за уређивање.\nПречица: Shift-F3\n\nnТакође, омогућа вам да идете на наредну слику у односу на тренутно изабрану у разгледачу или филмској траци.\nПречица: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Усаглашава разгледач датотека или филмску траку са делом за уређивање ради умањеног приказа тренутно отворене слике и чисти све изабране филтере.\nПречица: x\n\nКао и претходна операција, али без чишћења изабраних филтера:\nПречица: y\n(Умањени приказ отворене слике неће бити приказан уколико је изфилтриран). MAIN_BUTTON_PREFERENCES;Поставке MAIN_BUTTON_PUTTOQUEUE;Закажи MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Додаје тренутну слику у заказане Ctrl+B MAIN_BUTTON_SAVE;Сачувај +MAIN_BUTTON_SAVEAS;Као... MAIN_BUTTON_SAVE_TOOLTIP;Чува тренутну слику Ctrl+С MAIN_BUTTON_SENDTOEDITOR;Уреди MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Уређује тренутну слику у спољном програму Ctrl+Е @@ -375,14 +531,20 @@ MAIN_MSG_CANNOTSAVE;Грешка при чувању датотеке MAIN_MSG_CANNOTSTARTEDITOR;Не могу да покренем програм за уређивање. MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Изаберите исправну путању у „Поставкама“. MAIN_MSG_EMPTYFILENAME;Није одређено име датотеке! +MAIN_MSG_IMAGEUNPROCESSED;Ова радња захтева да најпре ставите изабране слике у листу заказаних. MAIN_MSG_NAVIGATOR;Навигатор +MAIN_MSG_OPERATIONCANCELLED;Радња је отказана +MAIN_MSG_PATHDOESNTEXIST;Не постоји путања \n\n%1\n\n. Поставите исправну путањи из подешавања програма. MAIN_MSG_QOVERWRITE;Да ли желите да препишете? +MAIN_MSG_SETPATHFIRST;Морате изабрати циљну путању из подешавања програма\nкако би користили ову функцију! +MAIN_MSG_WRITEFAILED;Не могу да упишем\n\n"%1"\n\nПроверите да ли фасцикла постоји и да ли имате овлашћења за упис у њу. MAIN_TAB_COLOR;Боја MAIN_TAB_COLOR_TOOLTIP;Alt-c MAIN_TAB_DETAIL;Детаљи MAIN_TAB_DETAIL_TOOLTIP;Alt-d MAIN_TAB_DEVELOP;Развијање MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Брзи извоз MAIN_TAB_EXPOSURE;Светлост MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e MAIN_TAB_FILTER;Филтер @@ -391,21 +553,55 @@ MAIN_TAB_METADATA;Метаподаци MAIN_TAB_METADATA_TOOLTIP;Alt-m MAIN_TAB_RAW;RAW MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Ознаке MAIN_TAB_TRANSFORM;Исправке MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Боја позадине за преглед: На основу теме\nПречица: 9 +MAIN_TOOLTIP_BACKCOLOR1;Боја позадине за преглед: Црна\nПречица: 9 +MAIN_TOOLTIP_BACKCOLOR2;Боја позадине за преглед: Бела\nПречица: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Закључај / откључај пре приказа\n\nЗакључај: задржи претходни приказ.\nКорисно уколико желите да прикажете укупни ефекат више алата.\nПоређење се још може направити и за било које стање из Историје.\n\nОткључај: претходни приказ долази након приказа једног последњег корака, приказујући слику пре примене тренутног алата. MAIN_TOOLTIP_HIDEHP;Приказује/сакрива леву површ, заједно са историјатом (пречица: Х) MAIN_TOOLTIP_INDCLIPPEDH;Приказује исечене светле делове MAIN_TOOLTIP_INDCLIPPEDS;Приказује исечене тамне делове +MAIN_TOOLTIP_PREVIEWB;Преглед плавог каназа.\nПречица: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Приказује област у фокусу.\nПречица: Shift-f\n\nНа увећању прецизније ради са сликама које имају малу дубинску оштрину и мало шума.\n\nЗа прецизнији приказ код слика са шумом прегледајте фокус на мањем увећању од око 10-30%.\n\nПриказ фокусиране области ће успорити преглед фотографија. +MAIN_TOOLTIP_PREVIEWG;Преглед зеленог канала.\nПречица: g +MAIN_TOOLTIP_PREVIEWL;Преглед луминансе.\nПречица: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Преглед црвеног канала.\nПречица: r MAIN_TOOLTIP_QINFO;Основни подаци о слици И MAIN_TOOLTIP_SHOWHIDELP1;Приказује/сакрива леву површ l MAIN_TOOLTIP_SHOWHIDERP1;Приказује/сакрива десну површ Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Приказује/сакрива горњу површ Shift-L +MAIN_TOOLTIP_THRESHOLD;Праг MAIN_TOOLTIP_TOGGLE;Приказује слику пре и после обраде Б +NAVIGATOR_B_NA;П = ○ +NAVIGATOR_B_VALUE;П = %1 +NAVIGATOR_G_NA;З = ○ +NAVIGATOR_G_VALUE;З = %1 +NAVIGATOR_H_NA;Х = ○ +NAVIGATOR_H_VALUE;Х = %1 +NAVIGATOR_LAB_A_NA;А = ○ +NAVIGATOR_LAB_A_VALUE;А = %1 +NAVIGATOR_LAB_B_NA;Б = ○ +NAVIGATOR_LAB_B_VALUE;Б = %1 +NAVIGATOR_LAB_L_NA;Л = ○ +NAVIGATOR_LAB_L_VALUE;Л = %1 +NAVIGATOR_R_NA;Ц = ○ +NAVIGATOR_R_VALUE;Ц = %1 +NAVIGATOR_S_NA;С = ○ +NAVIGATOR_S_VALUE;С = %1 +NAVIGATOR_V_NA;В = ○ +NAVIGATOR_V_VALUE;В = %1 +NAVIGATOR_XY_FULL;Ширина = %1, Висина = %2 NAVIGATOR_XY_NA;x = ○, y = ○ +OPTIONS_DEFIMG_MISSING;Није пронађен или доступан подразумевани профил за слике које нису у сировом формату.\n\nПроверите фасциклу са профилима, можда не постоји или је оштећена.\n\nБиће коришћене подразумеване вредности. +OPTIONS_DEFRAW_MISSING;Није пронађен или доступан подразумевани профил за слике у сировом формату.\n\nПроверите фасциклу са профилима, можда не постоји или је оштећена.\n\nБиће коришћене подразумеване вредности. PARTIALPASTE_BASICGROUP;Основна подешавања PARTIALPASTE_CACORRECTION;Исправљање аберација PARTIALPASTE_CHANNELMIXER;Мешање канала +PARTIALPASTE_CHANNELMIXERBW;Црно-бела фотографија PARTIALPASTE_COARSETRANS;Ротација за 90˚ / извртање +PARTIALPASTE_COLORAPP;CIECAM 2002 модел изгледа боја PARTIALPASTE_COLORGROUP;Подешавање боја PARTIALPASTE_COMMONTRANSFORMPARAMS;Сам попуни PARTIALPASTE_COMPOSITIONGROUP;Подешавање композиције @@ -418,6 +614,7 @@ PARTIALPASTE_DIALOGLABEL;Делимочно убацује профил за о PARTIALPASTE_DIRPYRDENOISE;Уклањање шума PARTIALPASTE_DIRPYREQUALIZER;Контраст нивоима детаља PARTIALPASTE_DISTORTION;Исправљање изобличења +PARTIALPASTE_EPD;Мапирање тонова PARTIALPASTE_EVERYTHING;Све PARTIALPASTE_EXIFCHANGES;Измене exif података PARTIALPASTE_EXPOSURE;Експозиција @@ -425,15 +622,21 @@ PARTIALPASTE_FLATFIELDAUTOSELECT;Аутоматски избор РК PARTIALPASTE_FLATFIELDBLURRADIUS;Полупречник замућења РК PARTIALPASTE_FLATFIELDBLURTYPE;Начин замућења РК PARTIALPASTE_FLATFIELDFILE;Датотека за равни кадар +PARTIALPASTE_GRADIENT;Филтер градијента PARTIALPASTE_HSVEQUALIZER;Уједначење ХСВ +PARTIALPASTE_ICMGAMMA;Излазна гама PARTIALPASTE_ICMSETTINGS;ИЦМ подешавања PARTIALPASTE_IMPULSEDENOISE;Импулсно уклањање шума PARTIALPASTE_IPTCINFO;ИПТЦ подави PARTIALPASTE_LABCURVE;Лаб крива PARTIALPASTE_LENSGROUP;Подешавања објектива -PARTIALPASTE_METAGROUP;Метаподаци +PARTIALPASTE_LENSPROFILE;Профил за исправке објектива +PARTIALPASTE_LUMACURVE;Крива луминасе +PARTIALPASTE_METAICMGROUP;Метаподаци/ИЦМ подешавања +PARTIALPASTE_PCVIGNETTE;Филтер вињетарења PARTIALPASTE_PERSPECTIVE;Перспектива PARTIALPASTE_PREPROCESS_GREENEQUIL;Уједначавање зелене +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Филтер врелих/мртвих пиксела PARTIALPASTE_PREPROCESS_LINEDENOISE;Линијски филтер шума PARTIALPASTE_RAWCACORR_AUTO;Ауто хроматске аберације PARTIALPASTE_RAWCACORR_CABLUE;Плава хроминанса @@ -442,39 +645,68 @@ PARTIALPASTE_RAWEXPOS_BLACK;Ниво црне PARTIALPASTE_RAWEXPOS_LINEAR;Линеарни фактор исправке RAW беле тачке PARTIALPASTE_RAWEXPOS_PRESER;Raw тачка беле уз очување светлих делова PARTIALPASTE_RAWGROUP;Raw подешавања +PARTIALPASTE_RAW_ALLENHANCE;Уклони шум након расклапања мозаика PARTIALPASTE_RAW_DCBENHANCE;Примени корак ДЦБ побољшања PARTIALPASTE_RAW_DCBITERATIONS;Број ДЦБ понављања PARTIALPASTE_RAW_DMETHOD;Начин расклапања мозаика PARTIALPASTE_RAW_FALSECOLOR;Кораци пригушења лажне боје при расклапању мозаика +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE кораци побољшања PARTIALPASTE_RESIZE;Промена величине +PARTIALPASTE_RGBCURVES;РГБ криве PARTIALPASTE_ROTATION;Ротација PARTIALPASTE_SHADOWSHIGHLIGHTS;Сенке/Светлост PARTIALPASTE_SHARPENEDGE;Ивице PARTIALPASTE_SHARPENING;Оштрење PARTIALPASTE_SHARPENMICRO;Микроконтраст +PARTIALPASTE_VIBRANCE;Живост боја PARTIALPASTE_VIGNETTING;Исправљање вињетарења PARTIALPASTE_WHITEBALANCE;Баланс беле +POPUPBUTTON_SELECTOPTIONHINT;РМБ за измену опције PREFERENCES_ADD;Додај PREFERENCES_APPLNEXTSTARTUP;примењује се након поновног покретања PREFERENCES_AUTOMONPROFILE;Сам примени профиле монитора из оперативног система PREFERENCES_BATCH_PROCESSING;Обрада закзаног +PREFERENCES_BEHADDALL;Све у „Додај“ +PREFERENCES_BEHADDALLHINT;Поставља све параметре у режим Додај.\nЊихово подешавање помоћу алата из панела за заказано ће бити разлике сачуваних вредности. PREFERENCES_BEHAVIOR;Понашање +PREFERENCES_BEHSETALL;Све у „Постави“ +PREFERENCES_BEHSETALLHINT;Поставља све параметре у режим Постави.\nЊихово подешавање помоћу алата из панела за заказано ће бити апсолутне вредности као што су и изабране. +PREFERENCES_BLACKBODY;Обична сијалица +PREFERENCES_BLINKCLIPPED;Покажи претамне/пресветле делове PREFERENCES_CACHECLEARALL;Обриши све PREFERENCES_CACHECLEARPROFILES;Обриши профиле PREFERENCES_CACHECLEARTHUMBS;Обриши приказе +PREFERENCES_CACHEFORMAT1;Власнички (брже и боље) +PREFERENCES_CACHEFORMAT2;JPEG (мање места на диску) PREFERENCES_CACHEMAXENTRIES;Највећи број мест у остави PREFERENCES_CACHEOPTS;Подешавање оставе +PREFERENCES_CACHETHUMBFORM;Формат умањених приказа PREFERENCES_CACHETHUMBHEIGHT;Највећа висина приказа +PREFERENCES_CIEART;CIECAM02 оптимизација +PREFERENCES_CIEART_LABEL;Једнострука тачност уместо двоструке +PREFERENCES_CIEART_TOOLTIP;Уколико је омогућено, ради CIECAM02 рачунања са једноструком тачношћу уместо са двоструком. Ово даје мало повећање брзине уз неизоставан губитак на квалитету. +PREFERENCES_CLEARDLG_LINE1;Чишћење оставе +PREFERENCES_CLEARDLG_LINE2;Ово може да потраје неколико секунди. +PREFERENCES_CLEARDLG_TITLE;Сачекајте PREFERENCES_CLIPPINGIND;Показивачи одсечених делова +PREFERENCES_CMETRICINTENT;Колориметријска намера PREFERENCES_CUSTPROFBUILD;Изградња произвољног почетног профила слике PREFERENCES_CUSTPROFBUILDHINT;Извршна датотека (или скрипта) која се позива када изграђујете нови почетни профил за слику.nПрихвата параметре из командне линије ради прављења .pp3 датотеке на основу неких правила:n[Путања до RAW/JPG] [Путања подразумеваног профила] [Бленда] [Експозиција у s] [Жижна дужина mm] [ИСО] [Објектив] [Фото-апарат] +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Кључни формати +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Назив +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;БрОзнаке PREFERENCES_CUSTPROFBUILDPATH;Извршна путања PREFERENCES_CUTOVERLAYBRUSH;Маска исецања боје/провидног +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K PREFERENCES_DARKFRAME;Тамни кадар PREFERENCES_DARKFRAMEFOUND;Нађен PREFERENCES_DARKFRAMESHOTS;снимака PREFERENCES_DARKFRAMETEMPLATES;шаблони PREFERENCES_DATEFORMAT;Формат датума +PREFERENCES_DATEFORMATFRAME;Формат PREFERENCES_DATEFORMATHINT;Можете задати следеће формате:\n%y :година\n%m : месец\n%d : дан\n\nУ Србији се највише користи:\n%d.%m.%y PREFERENCES_DEFAULTLANG;Језик програма PREFERENCES_DEFAULTTHEME;Тема програма @@ -495,9 +727,21 @@ PREFERENCES_FLATFIELDFOUND;Нађено PREFERENCES_FLATFIELDSDIR;Директоријум за равна поља PREFERENCES_FLATFIELDSHOTS;снимака PREFERENCES_FLATFIELDTEMPLATES;шаблони +PREFERENCES_FLUOF2;Флоресцентна F2 +PREFERENCES_FLUOF7;Флоресцентна F7 +PREFERENCES_FLUOF11;Флоресцентна F11 PREFERENCES_FORIMAGE;За датотеке са сликама PREFERENCES_FORRAW;За RAW датотеке PREFERENCES_GIMPPATH;Директоријум са инсталираним Гимпом +PREFERENCES_GREY;Yb луминанса излазног уређаја (%) +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;Yb=18 CIE L#50 +PREFERENCES_GREY23;Yb=23 CIE L#55 +PREFERENCES_GREY30;Yb=30 CIE L#60 +PREFERENCES_GREY40;Yb=40 CIE L#70 +PREFERENCES_GTKTHEME;ГТК тема PREFERENCES_HISTOGRAMPOSITIONLEFT;Хистограм у левој површи PREFERENCES_HLTHRESHOLD;Праг за одсечене светле делове PREFERENCES_ICCDIR;ИЦЦ директоријум @@ -508,12 +752,14 @@ PREFERENCES_INTENT_RELATIVE;Релативно колориметријски PREFERENCES_INTENT_SATURATION;Засићени приказ PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Користи угњежђени RAW приказ до измене PREFERENCES_LANGAUTODETECT;Сам откриј +PREFERENCES_MENUGROUPEXTPROGS;Групиши "Отвори са" PREFERENCES_MENUGROUPFILEOPERATIONS;Групиши радње над датотекама PREFERENCES_MENUGROUPLABEL;Групиши обележавање PREFERENCES_MENUGROUPPROFILEOPERATIONS;Групиши радње са профилима PREFERENCES_MENUGROUPRANK;Групиши оцењивање PREFERENCES_MENUOPTIONS;Опције менија PREFERENCES_METADATA;Метаподаци +PREFERENCES_MONITORICC;Профил монитора PREFERENCES_MULTITAB;Режим у више листова PREFERENCES_MULTITABDUALMON;Режим у више листова, на другом монитору PREFERENCES_OUTDIR;Излазни директоријум @@ -523,6 +769,7 @@ PREFERENCES_OUTDIRTEMPLATE;Употреби шаблон PREFERENCES_OUTDIRTEMPLATEHINT;Можете да задате следеће скраћенице за форматирање:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nОви знакови за форматирање се односе на директоријуме, подпутање путања до raw датотеке.\n\nНа пример, уколико је отворена слика /home/ivan/слике/02.09.2010/dsc0012.nef, скраћенице означавају:\n%f=dsc0012, %d1=02.09.2010, %d2=слике, ...\n%p1=/home/ivan/слике/02.09.2010, %p2=/home/ivan/слике, %p3=/home/ivan, ...\n\nУколико желите да сачувате развијену слику поред оригинала, унесите:\n%p1/%f\n\nУколико желите да сачувате излазну слику у директоријум „развијене“ који се налази где и оригинална слика, унесите:\n%p1/развијене/%f\n\nУколико желите да сачувате развијену слику у директоријум „/home/ivan/развијене“, а да структура поддиректоријума остане очувана, унесите:\n%p2/развијене/%d1/%f PREFERENCES_OVERLAY_FILENAMES;Постави преко умањеног приказа PREFERENCES_OVERWRITEOUTPUTFILE;Препиши постојеће излазне датотеке +PREFERENCES_PANFACTORFRAME;Убрзање при померању платна PREFERENCES_PANFACTORLABEL;Фактор PREFERENCES_PARSEDEXT;Екстензије за приказ PREFERENCES_PARSEDEXTADD;Додај екстензију @@ -536,12 +783,16 @@ PREFERENCES_PROFILESAVECACHE;Сачувај параметре обраде у PREFERENCES_PROFILESAVEINPUT;Сачувај парамтре обраде поред улазне датотеке PREFERENCES_PROPERTY;Особина PREFERENCES_PSPATH;Директоријум са инсталираним Адобе Фотошопом +PREFERENCES_RGBDTL_LABEL;Највећи број нири приликом уклањања шума +PREFERENCES_RGBDTL_TOOLTIP;Уклањање шума захтева око 128MB РАМ меморије за слику од 10 мегапиксела или 512MB за слику од 40 мегапиксела, уз додатних 128MB меморије по свакој нити. Што више нити се извршавају заједно то ће брже бити рачунање. Оставите ову вредност на „0“ како би програм аутоматски доделило што је више нитова могуће. PREFERENCES_SELECTFONT;Изаберите фонт PREFERENCES_SELECTLANG;Језик PREFERENCES_SELECTTHEME;Тема PREFERENCES_SET;Постави PREFERENCES_SHOWBASICEXIF;Прикажи основне Exif податке PREFERENCES_SHOWDATETIME;Прикажи датум и време +PREFERENCES_SHOWEXPOSURECOMPENSATION;Додај компензацију експозиције +PREFERENCES_SHOWPROFILESELECTOR;Прикажи избор профила PREFERENCES_SHTHRESHOLD;Праг за одсечене тамне делове PREFERENCES_SINGLETAB;Режим у једном листу PREFERENCES_SINGLETABVERTAB;Режим у једном листу, вертикални листови @@ -550,21 +801,38 @@ PREFERENCES_SND_BATCHQUEUEDONE;Обрађене су заказане датот PREFERENCES_SND_HELP;Унесите путању до датотеке или оставите празно уколико не желите звук. На Windows-у можете да користите „SystemDefault“, „SystemAsterisk“ за системске звуке. PREFERENCES_SND_LNGEDITPROCDONE;Уредник је завршио обраду PREFERENCES_SND_TRESHOLDSECS;бр. секунди +PREFERENCES_SQUAREDETAILWINDOW;Коцкаст прозор са детаљима (брже) PREFERENCES_STARTUPIMDIR;Директоријум по покретању PREFERENCES_TAB_BROWSER;Преглед датотека PREFERENCES_TAB_COLORMGR;Управљање бојама PREFERENCES_TAB_GENERAL;Опште PREFERENCES_TAB_IMPROC;Обрада сликe +PREFERENCES_TAB_PERFORMANCE;Перформанса PREFERENCES_TAB_SOUND;Звуци +PREFERENCES_TP_LABEL;Површ алата: +PREFERENCES_TP_USEICONORTEXT;Користи иконице језичка уместо текста PREFERENCES_TP_VSCROLLBAR;Сакриј клизаче у области са алаткама +PREFERENCES_TUNNELMETADATA;Копирај неизмењене IPTC/XMP (када је слика означена другим програмом) +PREFERENCES_USEBUNDLEDPROFILES;Користи профиле који долазе уз програм PREFERENCES_USESYSTEMTHEME; Користи системску тему +PREFERENCES_VIEW;Баланс беле излазног уређаја (монитор, ТВ, пројакетор и др.) PREFERENCES_WORKFLOW;Ток обраде +PROFILEPANEL_COPYPPASTE;Параметри за копирање +PROFILEPANEL_FILEDLGFILTERANY;Све датотеке +PROFILEPANEL_FILEDLGFILTERPP;Профили за обраду +PROFILEPANEL_GLOBALPROFILES;Профили из програма PROFILEPANEL_LABEL;Профили обраде PROFILEPANEL_LOADDLGLABEL;Учитај профил за обраду... +PROFILEPANEL_LOADPPASTE;Параметри за учитавање +PROFILEPANEL_MODE_TIP;Начин допуне профила који се користи за обраду.\n\nПритиснута дугмад: делимични профили се преводе у потпуне профиле, а недостајуће вредносоти се мењају подразумеваним вредностим.\n\nПуштена дугмад: профили ће бити примењени какви јесу, уз измени само оних вредности које садржи профил. +PROFILEPANEL_MYPROFILES;Моји профили +PROFILEPANEL_PASTEPPASTE;Параметри за убацивање PROFILEPANEL_PCUSTOM;Произвољно PROFILEPANEL_PFILE;Из датотеке +PROFILEPANEL_PINTERNAL;Неутрално PROFILEPANEL_PLASTSAVED;Од последњег чувања PROFILEPANEL_SAVEDLGLABEL;Чува параметре за обраду... +PROFILEPANEL_SAVEPPASTE;Параметри за чување PROFILEPANEL_TOOLTIPCOPY;Копира тренутни профил у оставу PROFILEPANEL_TOOLTIPLOAD;Учитава профил из датотеке PROFILEPANEL_TOOLTIPPASTE; Учитава профил из @@ -574,29 +842,115 @@ PROGRESSBAR_LOADINGTHUMBS;Учитавам приказе... PROGRESSBAR_LOADJPEG;Учитавам JPEG датотеку... PROGRESSBAR_LOADPNG;Учитавам PNG датотеку... PROGRESSBAR_LOADTIFF;Учитавам TIFF датотеку... +PROGRESSBAR_NOIMAGES;Нису пронађене слике PROGRESSBAR_PROCESSING;Обрађујем слику... +PROGRESSBAR_PROCESSING_PROFILESAVED;Обрађујем сачувани профил PROGRESSBAR_READY;Чекам PROGRESSBAR_SAVEJPEG;Чувам JPEG датотеку... PROGRESSBAR_SAVEPNG;Чувам PNG датотеку... PROGRESSBAR_SAVETIFF;Чувам TIFF датотеку... +PROGRESSBAR_SNAPSHOT_ADDED;Додат је снимак +PROGRESSDLG_LOADING;Учитавам датотеку... +PROGRESSDLG_PROCESSING;Обрађујем слику... PROGRESSDLG_PROFILECHANGEDINBROWSER;Профил измењен у разгледачу +PROGRESSDLG_SAVING;Чувам датотеку... P_GAMMA_CURV;гама QINFO_ISO;ИСО QINFO_NOEXIF;Нису доступни Exif подаци. SAVEDLG_AUTOSUFFIX;Сам додај суфикс уколико датотека већ постоји SAVEDLG_FILEFORMAT;Формат датотеке +SAVEDLG_FORCEFORMATOPTS;Приморај могућности за чување SAVEDLG_JPEGQUAL;JPEG квалитет +SAVEDLG_JPGFILTER;JPEG датотеке SAVEDLG_PNGCOMPR;PNG паковање SAVEDLG_PUTTOQUEUE;Заказује слику за обраду SAVEDLG_PUTTOQUEUEHEAD;Премешта слику на почетак заказаних SAVEDLG_PUTTOQUEUETAIL;Премешта слику на крај заказаних SAVEDLG_SAVEIMMEDIATELY;Одмах сачувај SAVEDLG_SAVESPP;Сачувај параметре обраде уз слику +SAVEDLG_SUBSAMP;Подузорковање +SAVEDLG_SUBSAMP_1;Најбоља компресија +SAVEDLG_SUBSAMP_2;Балансирано +SAVEDLG_SUBSAMP_3;Најбољи квалитет +SAVEDLG_SUBSAMP_TOOLTIP;Најбоља компресија: 4:1:1\nБалансирано: 4:2:2\nНајбољи квалитет: 4:4:4 +SAVEDLG_TIFFFILTER;TIFF датотеке SAVEDLG_TIFFUNCOMPRESSED;Незапаковани TIFF +SAVEDLG_WARNFILENAME;Датотека ће бити названа +SHCSELECTOR_TOOLTIP;Кликните десно дугме миша да поново вратите позицију ова три клизача. +THRESHOLDSELECTOR_B;Доле +THRESHOLDSELECTOR_BR;Доле-десно +THRESHOLDSELECTOR_HINT;Притисните дугме Shift за померање појединачних тачака. +THRESHOLDSELECTOR_T;Горе +THRESHOLDSELECTOR_TL;Горе-лево +THRESHOLDSELECTOR_TR;Горе-десно TOOLBAR_TOOLTIP_CROP;Поставља оквир за исецање (пречица: Ц) TOOLBAR_TOOLTIP_HAND;Алат за померање (пречица: Н) TOOLBAR_TOOLTIP_STRAIGHTEN;Исправља линију хоризонта (пречица: С) TOOLBAR_TOOLTIP_WB;Одређује баланс беле из тачке (пречица: W) +TP_BWMIX_ALGO;OYCPM алгоритам +TP_BWMIX_ALGO_LI;Линеарно +TP_BWMIX_ALGO_SP;Специјални ефекти +TP_BWMIX_ALGO_TOOLTIP;Линеарно: производи нормални линеарни одговор.\nСпецијални ефекти: производи специјалне ефекте мешајући канале нелинеарно. +TP_BWMIX_AUTOCH;Ауто +TP_BWMIX_AUTOCH_TIP;Израчунај вредности тако да оптимизује мешање канала. +TP_BWMIX_BLUE;Плава +TP_BWMIX_CC_ENABLED;Подеси комплементарну боју +TP_BWMIX_CC_TOOLTIP;Омогући за аутоматско подешавање комплементарне боје у ROYGCBPM режиму. +TP_BWMIX_CHANNEL;Уједначавање луминансе +TP_BWMIX_CURVEEDITOR1;„Пре“ кривуље +TP_BWMIX_CURVEEDITOR2;„Након“ кривуље +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Крива тонова након ЦБ превођења, на крају третмана. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Крива тонова, тик пред ЦБ превођење.\nМоже да узме у обзир и компоненте боје. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Луминанса на основу нијансе L=f(H).\nОбратите пажњу на екстремне вредности пошто оне могу да направе нежељене ефекте. +TP_BWMIX_CYAN;Светло-плава +TP_BWMIX_FILTER;Филтер боја +TP_BWMIX_FILTER_BLUE;Плава +TP_BWMIX_FILTER_BLUEGREEN;Плаво-зелена +TP_BWMIX_FILTER_GREEN;Зелена +TP_BWMIX_FILTER_GREENYELLOW;Зелено-жута +TP_BWMIX_FILTER_NONE;Ни једна +TP_BWMIX_FILTER_PURPLE;Љубичаста +TP_BWMIX_FILTER_RED;Црвена +TP_BWMIX_FILTER_REDYELLOW;Црвено-Жута +TP_BWMIX_GREEN;Зелена +TP_BWMIX_LABEL;Црна и бела +TP_BWMIX_MAGENTA;Љубичаста +TP_BWMIX_MET;Начин +TP_BWMIX_MET_CHANMIX;Мешање канала +TP_BWMIX_MET_DESAT;Уклањање боје +TP_BWMIX_MET_LUMEQUAL;Уједначавање луминансе +TP_BWMIX_MIXC;Мешање +TP_BWMIX_NEUTRAL;Врати мешање +TP_BWMIX_NEUTRAL_TIP;Врати све вреднсоти (филтер боје, мешање канала) на подразумеване. +TP_BWMIX_ORANGE;Наранџаста +TP_BWMIX_PURPLE;Љубичаста +TP_BWMIX_RED;Црвена +TP_BWMIX_RGBLABEL;Р: %1%% Г: %2%% Б: %3%% Укупно: %4%% +TP_BWMIX_RGBLABEL_HINT;Коначни РГБ фактори који се брину о опцијама за мешање.\n„Укупно“ приказује збир РГБ вредности:\n- у 100% у релативном режиму\n- више (светлије) или мање (тамније) од 100% у апсолутном режиму. +TP_BWMIX_RGB_TOOLTIP;Мешање РГБ канала. Користите постојеће преподешене параметре као водиљу.\nОбратите пажњу на негативне вреднсти које могу да направе грешке унутар слике или изазову неправилно понашање. +TP_BWMIX_SETTING;Преподешено +TP_BWMIX_SETTING_TOOLTIP;Различите подешене вредности (филм, пејзаж и др.) или ручно подешене вредности мешања канала. +TP_BWMIX_SET_HIGHCONTAST;Велики контраст +TP_BWMIX_SET_HIGHSENSIT;Велика осетљивост +TP_BWMIX_SET_HYPERPANCHRO;Јако панхроматски +TP_BWMIX_SET_INFRARED;Инфрацрвено +TP_BWMIX_SET_LANDSCAPE;Пејзаж +TP_BWMIX_SET_LOWSENSIT;Ниска осетљивост +TP_BWMIX_SET_LUMINANCE;Луминанса +TP_BWMIX_SET_NORMCONTAST;Нормални контраст +TP_BWMIX_SET_ORTHOCHRO;Ортохроматски +TP_BWMIX_SET_PANCHRO;Панхроматски +TP_BWMIX_SET_PORTRAIT;Портрет +TP_BWMIX_SET_RGBABS;Апсолутни РГБ мешања канала +TP_BWMIX_SET_RGBREL;Релативни РГБ мешања канала +TP_BWMIX_SET_ROYGCBPMABS;Апсолутни ROYGCBPM мешања канала +TP_BWMIX_SET_ROYGCBPMREL;Релативни ROYGCBPM мешања канала +TP_BWMIX_TCMODE_FILMLIKE;Црно-бело, налик филму +TP_BWMIX_TCMODE_SATANDVALBLENDING;Црно-бели, стапање засићености и вредности +TP_BWMIX_TCMODE_STANDARD;Црно-бели, уобичајени +TP_BWMIX_TCMODE_WEIGHTEDSTD;Црно-бели, мерени стандард +TP_BWMIX_VAL;L +TP_BWMIX_YELLOW;Жута TP_CACORRECTION_BLUE;Плава TP_CACORRECTION_LABEL;Хроматке аберације TP_CACORRECTION_RED;Црвена @@ -605,13 +959,109 @@ TP_CHMIXER_GREEN;Зелена TP_CHMIXER_LABEL;Мешање канала TP_CHMIXER_RED;Црвена TP_CHROMATABERR_LABEL;Хроматске аберације +TP_COARSETRAF_DEGREE;степени: TP_COARSETRAF_TOOLTIP_HFLIP;Изврће слику хоризонтално TP_COARSETRAF_TOOLTIP_ROTLEFT;Окреће слику улево TP_COARSETRAF_TOOLTIP_ROTRIGHT;Окреће слику удесно TP_COARSETRAF_TOOLTIP_VFLIP;Изврће слику вертикално +TP_COLORAPP_ADAPTSCENE;Луминозност сцене +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Апосолутна луминозност окружења сцене (cd/m²).\n1) Рачуна се из Exif података:\nБрзина затварача - ИСО вредност - отвор бленде - корекција експозиције камере.\n2) Рачуна се из беле тачке сирове слике унутар дела програма за компензацију експозиције. +TP_COLORAPP_ADAPTVIEWING;Луминозност за преглед (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Апсолутна луминозност окружења за преглед\n(обично 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Уколико је штиклирано (препоручено), програм рачуна оптималне вредности на основу Exif података.\nЗа ручно постављање ових вредности, одштиклирајте ово поље. +TP_COLORAPP_ALGO;Алгоритам +TP_COLORAPP_ALGO_ALL;Све +TP_COLORAPP_ALGO_JC;Светлина + Боја (JC) +TP_COLORAPP_ALGO_JS;Светлина + Хроминанса (JS) +TP_COLORAPP_ALGO_QM;Осветљеност + Живост боја (QM) +TP_COLORAPP_ALGO_TOOLTIP;Омогућава избор између подскупа параметара или свих параметара. +TP_COLORAPP_BADPIXSL;Филтер врућих/лоших пиксела +TP_COLORAPP_BADPIXSL_TOOLTIP;Потискивање врућих/лоших (пресветло обојених) пиксела.\n0 = без ефекта\n1 = медијан\n2 = гаузијан.\n\nОве грешке се јављају услед CIECAM02 ограничења. Други начин за избегавање грешака је да подесите слику тако да избегнете веома тамне сенке. +TP_COLORAPP_BRIGHT;Осветљеност (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Осветљеност у CIECAM02 систему узима у обзир луминансу беле и разликује се у односу на Лаб и РГБ осветљеност. +TP_COLORAPP_CHROMA;Хрома (C) +TP_COLORAPP_CHROMA_M;Живост боја (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Живост боја у CIECAM02 систему се разликује у односу на Лаб и РГБ осветљеност. +TP_COLORAPP_CHROMA_S;Засићеност (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Засићеност у CIECAM02 систему се разликује у односу на Лаб и РГБ осветљеност. +TP_COLORAPP_CHROMA_TOOLTIP;Хрома у CIECAM02 систему се разликује у односу на Лаб и РГБ осветљеност. +TP_COLORAPP_CIECAT_DEGREE;прилагођавање за CAT02 +TP_COLORAPP_CONTRAST;Контраст (J) +TP_COLORAPP_CONTRAST_Q;Контраст (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Контраст у CIECAM02 систему за Q клизач; разликује се од Лаб и РГБ контраста. +TP_COLORAPP_CONTRAST_TOOLTIP;Контраст у CIECAM02 систему за J клизач; разликује се од Лаб и РГБ контраста. +TP_COLORAPP_CURVEEDITOR1;Крива тонова 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Приказује хистограм за L (Лаб) пре CIECAM02.\nУколико је омогућено „CIECAM02 излазни хистограм у кривуљама“, приказујер хистограм за J или Q након CIECAM02.\n\nJ и Q се не приказују у главној површи хистограма.\n\nЗа конаачни изла погледајте главну површ хистограма. +TP_COLORAPP_CURVEEDITOR2;Крива тонова 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Користи се на исти начин као и друга крива тонова експозиције. +TP_COLORAPP_CURVEEDITOR3;Крива боја +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Подешава било хрому, засићеност или живост боја.\n\nПриказује хистограм хроматисе (Лаб) пре CIECAM02.\nУколико је омогућено „CIECAM02 излазни хистограм у кривуљама“, приказује хистограм за C, s или M након CIECAM02.\n\nC, s и M се не приказују у главној површи за хистограм.\nЗа конаачни изла погледајте главну површ хистограма. +TP_COLORAPP_DATACIE;CIECAM02 излазни хистограм у кривуљама +TP_COLORAPP_DATACIE_TOOLTIP;Када је омогућено, хистограми у CIECAM02 кривим приказују приближне вредности/опсеге за J или Q, и C, s или M након CIECAM02 подешавања.\nОвај избор не утиче на приказ у главној површи за хистограм.\n\nКада је искључено, хистограми у CIECAM02 кривим приказују Лаб вредности пре CIECAM02 подешавања. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Уколико је штиклирано (препоручено), програм рачина оптималне вредности, које се затим користе за CAT02, а такође за читав CIECAM02.\nДа би поставили вредности ручне, одштиклирајте ово поље (препоручене су вредности изнад 65). +TP_COLORAPP_DEGREE_TOOLTIP;Количина преображаја CIE хроматске адаптације2002. +TP_COLORAPP_GAMUT;Контрола гамута (Лаб) +TP_COLORAPP_GAMUT_TOOLTIP;Омогућава контролу гамута у Лаб режиму. +TP_COLORAPP_HUE;Нијанса (h) +TP_COLORAPP_HUE_TOOLTIP;Нијанса (h) - угао између 0° и 360°. +TP_COLORAPP_LABEL;CIECAM 2002 модел изгледа боја +TP_COLORAPP_LABEL_CAM02;Подешавања слике +TP_COLORAPP_LABEL_SCENE;Услови сцене +TP_COLORAPP_LABEL_VIEWING;Услови за преглед +TP_COLORAPP_LIGHT;Светлина (J) +TP_COLORAPP_LIGHT_TOOLTIP;Светлина у CIECAM02 се разликује од Лаб или РГБ светлине. +TP_COLORAPP_MODEL;WP модел +TP_COLORAPP_MODEL_TOOLTIP;Модел беле-тачке.\n\nБаланс беле [RT] + [излаз]: баланс беле из програма се користи за кадар, CIECAM02 се поставља на D50, а баланс беле излазног уређаја се одређује из Подешавања > Управљање бојама.\n\nБаланс беле [RT+CAT02] + [излаз]: подешавања баланса беле из програма се користе од стране CAT02, а баланс беле излазног уређаја се одређује из Подешавања - Управљање бојама. +TP_COLORAPP_RSTPRO;Заштита црвене и боје коже +TP_COLORAPP_RSTPRO_TOOLTIP;Заштита црвене боје и боје коже (клизачи и криве). +TP_COLORAPP_SHARPCIE;--не користи се-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--не користи се-- +TP_COLORAPP_SURROUND;Окружено +TP_COLORAPP_SURROUND_AVER;Просечно +TP_COLORAPP_SURROUND_DARK;Тамно +TP_COLORAPP_SURROUND_DIM;Затамњено +TP_COLORAPP_SURROUND_EXDARK;Јако тамно +TP_COLORAPP_SURROUND_TOOLTIP;Мења тонове и боје како би се прилагодило условима уређаја за приказ.\n\nПросечно: Просечно осветљено окружење (уобичајено). Слика неће бити измењена.\n\nЗатамњено: Затамњено окружење (ТВ). Слика ће постати за нијансу тамнија.\n\nТамно: Тамно окружење (пројектор). Слика ће постати још више тамна.\n\nЈако тамно: Екстрамно тамно окружење (cutsheet). Слика ће постати изузетно тамна. +TP_COLORAPP_SURSOURCE;Тамно окружење +TP_COLORAPP_SURSOURCE_TOOLTIP;Може да се користи уколико слика има тамне ивице. +TP_COLORAPP_TCMODE_BRIGHTNESS;Освтљеност +TP_COLORAPP_TCMODE_CHROMA;Хрома +TP_COLORAPP_TCMODE_COLORF;Живост боја +TP_COLORAPP_TCMODE_LABEL1;Режим криве 1 +TP_COLORAPP_TCMODE_LABEL2;Режим криве 2 +TP_COLORAPP_TCMODE_LABEL3;Крива у хром режиму +TP_COLORAPP_TCMODE_LIGHTNESS;Светлина +TP_COLORAPP_TCMODE_SATUR;Засићеност +TP_COLORAPP_TONECIE;Мапирање тонова у CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Уколико је искључена ова опција, мапирање тонова се врши у Лаб окружењу.\nУколико је укључена, мапирање се врши помоћу CIECAM02.\nМорате користити алат за мапирање тонова како би ова опција била примењена. +TP_COLORAPP_WBCAM;Баланс беле [RT+CAT02] + [излаз] +TP_COLORAPP_WBRT;Баланс беле [RT] + [излаз] +TP_COLORBOOST_ACHANNEL;Канал „а“ +TP_COLORBOOST_AMOUNT;Количина +TP_COLORBOOST_AVOIDCOLORCLIP;Избегни одсецање боја +TP_COLORBOOST_BCHANNEL;Канал „б“ +TP_COLORBOOST_CHANNEL;Канал +TP_COLORBOOST_CHSEPARATE;раздвоји +TP_COLORBOOST_ENABLESATLIMITER;Омогући ограничење засићености +TP_COLORBOOST_LABEL;Појачање боја +TP_COLORBOOST_SATLIMIT;Граница за засићеност +TP_COLORDENOISE_EDGESENSITIVE;Осетљиво на ивице +TP_COLORDENOISE_EDGETOLERANCE;Толеранција ивице +TP_COLORDENOISE_LABEL;Уклаљање колорног шума +TP_COLORDENOISE_RADIUS;Полупречник +TP_COLORSHIFT_BLUEYELLOW;Плава-Жута +TP_COLORSHIFT_GREENMAGENTA;Зелена-Љубичаста +TP_COLORSHIFT_LABEL;Померање боја +TP_CROP_DPI;ТПИ= TP_CROP_FIXRATIO;Сразмерно: TP_CROP_GTDIAGONALS;Правило дијагонала +TP_CROP_GTEPASSPORT;Биометријски пасош +TP_CROP_GTFRAME;Оквир TP_CROP_GTGRID;Мрежа +TP_CROP_GTHARMMEANS1;Златни пресек 1 +TP_CROP_GTHARMMEANS2;Златни пресек 2 +TP_CROP_GTHARMMEANS3;Златни пресек 3 +TP_CROP_GTHARMMEANS4;Златни пресек 4 TP_CROP_GTNONE;Ништа TP_CROP_GTRULETHIRDS;Правило трећина TP_CROP_GUIDETYPE;Вођицe: @@ -627,10 +1077,22 @@ TP_DARKFRAME_LABEL;Тамни кадар TP_DEFRINGE_LABEL;Уклаљање ореола TP_DEFRINGE_RADIUS;Полупречник TP_DEFRINGE_THRESHOLD;Праг +TP_DETAIL_AMOUNT;Количина +TP_DIRPYRDENOISE_BLUE;Хроминанса: Плава-Жута TP_DIRPYRDENOISE_CHROMA;Боја +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Може се употребити за raw или не-raw слике.\n\nЗа слике које нису у raw формату уклањање шума луминансе зависи од гаме улазног профила боја. Подразумева се употреба sRGB профила, па ће ефекат уклањања шума луминансе бити различит уколико се користи профил боја са другом вредношћу гаме. +TP_DIRPYRDENOISE_ENH;Побољшани режим +TP_DIRPYRDENOISE_ENH_TOOLTIP;Повећава квалитет уклањања шума на уштрб око 20% времена за обраду. TP_DIRPYRDENOISE_GAMMA;Гама +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Гама утиче на јачину уклањања шума преко опсег тонова. Мања вредност ће утицати на сенке, већа ће повећати овај ефекат и на светлије тонове. TP_DIRPYRDENOISE_LABEL;Дирекционо пирамидно уклањање шума +TP_DIRPYRDENOISE_LDETAIL;Детаљи луминансе TP_DIRPYRDENOISE_LUMA;Луминанса +TP_DIRPYRDENOISE_METHOD;Начин +TP_DIRPYRDENOISE_METHOD_TOOLTIP;За рав слике можете користити РГБ или Лаб режиме.\n\nЗа остале слике се користи Лаб, без обзира на избор. +TP_DIRPYRDENOISE_PERF;РГБ режим (raw слике) +TP_DIRPYRDENOISE_RED;Хроминанса - црвена-зелена +TP_DIRPYRDENOISE_RGB;РГБ TP_DIRPYREQUALIZER_LABEL;Детаљни ниво контраста TP_DIRPYREQUALIZER_LUMACOARSEST;грубо TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Контраст- @@ -642,18 +1104,43 @@ TP_DISTORTION_AMOUNT;Количина TP_DISTORTION_AUTO;Сам исправи изобличења TP_DISTORTION_AUTO_TIP;(Експериментално) Аутоматски исправља изобличења неких апарата (М4/3, неки компакти, и др.) TP_DISTORTION_LABEL;Изобличења +TP_EPD_EDGESTOPPING;Изоштравање ивице +TP_EPD_LABEL;Мапирање тонова +TP_EPD_REWEIGHTINGITERATES;Број поновних мерења +TP_EPD_SCALE;Размера +TP_EPD_STRENGTH;Јачина +TP_EPD_TOOLTIP;Мапирање тонова је могуће у Лаб (стандардном) или CIECAM02 режиму.\n\nЗа рад у CIECAM02 режиму укључите:\n1. CIECAM02\n2. Алгоритам="Осветљење + живописност (QM)"\n3. "Мапирање тонова у CIECAM02 осветљењу (Q)" +TP_EQUALIZER_CONTRAST_MINUS;Контраст - +TP_EQUALIZER_CONTRAST_PLUS;Контраст + +TP_EQUALIZER_FINEST;најфиније +TP_EQUALIZER_LABEL;Таласно уједначење +TP_EQUALIZER_LARGEST;најгрубље +TP_EQUALIZER_NEUTRAL;Неутрално +TP_EXPOSCORR_LABEL;Raw бела тачка TP_EXPOSURE_AUTOLEVELS;Ауто-нивои +TP_EXPOSURE_AUTOLEVELS_TIP;Омогућава аутоматско одређивање нивоа, који подешава клизаче експозиције на основу податка о самој слици.\nУкључује чупање светлих делова уколико је неопходно. TP_EXPOSURE_BLACKLEVEL;Црна TP_EXPOSURE_BRIGHTNESS;Осветљеност TP_EXPOSURE_CLIP;Одсеци +TP_EXPOSURE_CLIP_TIP;Део пиксела које ће бити одсечени применом аутоматских нивоа. TP_EXPOSURE_COMPRHIGHLIGHTS;Сабијање светлог TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Праг за чупање светлих делова TP_EXPOSURE_COMPRSHADOWS;Сабијање сенки TP_EXPOSURE_CONTRAST;Контраст TP_EXPOSURE_CURVEEDITOR;Крива нијанси +TP_EXPOSURE_CURVEEDITOR1;Крива тонова 1 +TP_EXPOSURE_CURVEEDITOR2;Крива тонова 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Погледајте „Експозиција > Криве тонова“ унутар чланка на сајту RawPedia како би научили како се постижу најбољи резучтати успотребом две криве тонова. TP_EXPOSURE_EXPCOMP;Компензација TP_EXPOSURE_LABEL;Експозиција TP_EXPOSURE_SATURATION;Засићеност +TP_EXPOSURE_TCMODE_FILMLIKE;Налик фото-филму +TP_EXPOSURE_TCMODE_LABEL1;1. режим криве +TP_EXPOSURE_TCMODE_LABEL2;2. режим криве +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Утапање засићености и вредности +TP_EXPOSURE_TCMODE_STANDARD;Стандард +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Уравнотежени стандард +TP_EXPO_AFTER; Пре интерполације (пре превода у РГБ) TP_FLATFIELD_AUTOSELECT;Сам изабери TP_FLATFIELD_BLURRADIUS;Полупречник замућења TP_FLATFIELD_BLURTYPE;Замути @@ -662,63 +1149,178 @@ TP_FLATFIELD_BT_HORIZONTAL;Хоризонтално TP_FLATFIELD_BT_VERTHORIZ;Хориз. и вертик. TP_FLATFIELD_BT_VERTICAL;Вертикално TP_FLATFIELD_LABEL;Равно поље +TP_GAMMA_COMMENT;(онемогућен је излазни профил, осим „default“) +TP_GAMMA_CURV;Гама TP_GAMMA_FREE;Гама слобода TP_GAMMA_OUTPUT;Излазна гама TP_GAMMA_SLOP;нагиб (линеарни) +TP_GENERAL_11SCALE_TOOLTIP;Ефект овог алата или његових опција се види само у размери 1:1. +TP_GRADIENT_CENTER;Центар +TP_GRADIENT_CENTER_X;Центар X +TP_GRADIENT_CENTER_X_TOOLTIP;Помера градијент улево (негативне вредности) или удесно (позитивне вредности). +TP_GRADIENT_CENTER_Y;Центар Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Помера градијент на горе (негативне вредности) или на доле (позитивне вредности). +TP_GRADIENT_DEGREE;Угао +TP_GRADIENT_DEGREE_TOOLTIP;Окреће угао градијента за одабрани број степени. +TP_GRADIENT_FEATHER;Умекшавање +TP_GRADIENT_FEATHER_TOOLTIP;Ширина градијента у процентима дијагонале слике. +TP_GRADIENT_LABEL;Филтер градијента +TP_GRADIENT_STRENGTH;Јачина +TP_GRADIENT_STRENGTH_TOOLTIP;Јачина филтера у броју тачака прекида. TP_HLREC_BLEND;Утапање TP_HLREC_CIELAB;ЦиеЛаб стапање TP_HLREC_COLOR;Пропагинација боје +TP_HLREC_ENA_TOOLTIP;Може се активирати опцијом „Ауто-нивои“. TP_HLREC_LABEL;Чупање светлих делова TP_HLREC_LUMINANCE;Извлачење луминансе TP_HLREC_METHOD;Начин: +TP_HSVEQUALIZER1;Црвена +TP_HSVEQUALIZER2;Жута +TP_HSVEQUALIZER3;Лимун +TP_HSVEQUALIZER4;Зелена +TP_HSVEQUALIZER5;Водена +TP_HSVEQUALIZER6;Плава +TP_HSVEQUALIZER7;Љубичаста +TP_HSVEQUALIZER8;Магнета TP_HSVEQUALIZER_CHANNEL;ХСВ канал TP_HSVEQUALIZER_HUE;Нијанса TP_HSVEQUALIZER_LABEL;Уједначење ХСВ канала TP_HSVEQUALIZER_SAT;Засићеност TP_HSVEQUALIZER_VAL;Вредност TP_ICM_BLENDCMSMATRIX;Утопи светле делове у матрицу +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Омогућите како би повратили преосветљене делове уколико користите LUT ICC профиле. +TP_ICM_DCPILLUMINANT;Илуминантно +TP_ICM_DCPILLUMINANT_INTERPOLATED;Интерполирано +TP_ICM_FILEDLGFILTERANY;Било која датотека +TP_ICM_FILEDLGFILTERICM;ИЦЦ профили +TP_ICM_GAMMABEFOREINPUT;Профил за примену Гаме TP_ICM_INPUTCAMERA;Подразумевано из апарата TP_ICM_INPUTCAMERAICC;Фото-апарат или стандардни ИЦЦ +TP_ICM_INPUTCAMERA_TOOLTIP;Користи просту матрицу боја из програма dcraw, унапређену RawTherapee верзију (која год да је доступна за ваш модел фото-апарата) или неки од уграђених DNG профила. TP_ICM_INPUTCUSTOM;Произвољно +TP_ICM_INPUTCUSTOM_TOOLTIP;Изаберите жељени DCP/ICC профил боја за фото-апарат. TP_ICM_INPUTDLGLABEL;Изаберите улазни ИЦЦ профил... TP_ICM_INPUTEMBEDDED;Угњежђено, уколико је могуће +TP_ICM_INPUTEMBEDDED_TOOLTIP;Користи профил боја који је уграђен у не-raw датотеке. TP_ICM_INPUTNONE;Нема профила +TP_ICM_INPUTNONE_TOOLTIP;Уопште не користи улазни профил боја.\nПримењује се само у посебним околностима. TP_ICM_INPUTPROFILE;Улазни профил TP_ICM_LABEL;ИЦМ TP_ICM_NOICM;No ICM: sRGB излаз TP_ICM_OUTPUTPROFILE;Излазни профил TP_ICM_SAVEREFERENCE;Сачувај слику као референцу за профил +TP_ICM_SAVEREFERENCE_TOOLTIP;Сачувај линеарну TIFF слику пре примене улазног профила. Резултат може да се користи за калибрацију и израду профила фото-апарата. +TP_ICM_TONECURVE;Користи DCP криву тонова +TP_ICM_TONECURVE_TOOLTIP;Употребљава уграђену DCP криву тонова. Ово подешавање је омогућено само ако изабрани DCP има криву тонова. TP_ICM_WORKINGPROFILE;Радни профил TP_IMPULSEDENOISE_LABEL;Импулсно уклањање шума TP_IMPULSEDENOISE_THRESH;Праг +TP_LABCURVE_AVOIDCOLORCLIP;Онемогући одсецање боје +TP_LABCURVE_AVOIDCOLORSHIFT;Избегни померање боја +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Поставља боје у опсег тренутног радног простора боја и примењује Мунселову корекцију. TP_LABCURVE_BRIGHTNESS;Осветљеност +TP_LABCURVE_CHROMATICITY;Боје +TP_LABCURVE_CHROMA_TOOLTIP;To apply ЦБ toning, set Chromaticity to -100. TP_LABCURVE_CONTRAST;Контраст TP_LABCURVE_CURVEEDITOR;Крива светлости +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Засићена зелена +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Пастелна зелена +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Пастелна црвена +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Засићена црвена +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Засићена плава +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Пастелна плава +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Пастелна жута +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Засићена жута +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Неутрално +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Испрано +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Пастелно +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Засићено +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Боја као функција боје C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Боја као функција нијансе C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Хроминанса на основу луминансе C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Нијанса као функција нијансе H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Светност као функција боје L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Светлост као функција нијансе L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Светлост као функција светлости L=f(L) +TP_LABCURVE_ENABLESATLIMITER;Укључи граничник засићености TP_LABCURVE_LABEL;Лаб крива +TP_LABCURVE_LCREDSK;Ограничи LC на црвену и боју коже +TP_LABCURVE_LCREDSK_TIP;Уколико је укључено, LC крива ће утицати само на црвену и боју коже.\nУ супротном се примењује на све тонове. +TP_LABCURVE_RSTPROTECTION;Заштита црвене и боје коже +TP_LABCURVE_RSTPRO_TOOLTIP;Може се користити са клизачем за Хроминансу и CC кривом. +TP_LABCURVE_SATLIMIT;Граничник засићености +TP_LABCURVE_SATURATION;Засићеност TP_LENSGEOM_AUTOCROP;Сам исеци TP_LENSGEOM_FILL;Сам попуни TP_LENSGEOM_LABEL;Објектив и геометрија +TP_LENSPROFILE_FILEDLGFILTERLCP;Фајлови са изобличењима објектива +TP_LENSPROFILE_LABEL;Профили за исправљање изобличења објектива +TP_LENSPROFILE_USECA;Исправљање хром. аберација +TP_LENSPROFILE_USEDIST;Исправљање изобличења +TP_LENSPROFILE_USEVIGN;Исправљање вињетарења +TP_LUMACURVE_BLACKLEVEL;Црна +TP_LUMACURVE_BRIGHTNESS;Осветљење +TP_LUMACURVE_COMPRHIGHLIGHTS;Сабијање светлог +TP_LUMACURVE_COMPRSHADOWS;Сабијање сенки +TP_LUMACURVE_CONTRAST;Контраст +TP_LUMACURVE_CURVEEDITOR;Крива лиминансе +TP_LUMACURVE_LABEL;Крива луминансе +TP_NEUTRAL;Неутрално +TP_NEUTRAL_TIP;Враћа клизаче експозиције на неутралне вредности.\nПримењује се на исте контроле као у Ауто нивои, без обзира на то да ли сте користили Ауто нивое или не. +TP_PCVIGNETTE_FEATHER;Умекшавање +TP_PCVIGNETTE_FEATHER_TOOLTIP;Умекшавање:\n0 = само углове,\n50 = на половину од центра,\n100 = центар. +TP_PCVIGNETTE_LABEL;Филтер вињетарења +TP_PCVIGNETTE_ROUNDNESS;Заокругљеност +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Заокругљеност:\n0 = квадрат,\n50 = прелаз од квадрата ка кругу,\n100 = круг. +TP_PCVIGNETTE_STRENGTH;Јачина +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Јачина филтера у прекидима (који се достижу на угловима). TP_PERSPECTIVE_HORIZONTAL;Хоризонтална TP_PERSPECTIVE_LABEL;Перспектива TP_PERSPECTIVE_VERTICAL;Вертикална +TP_PFCURVE_CURVEEDITOR_CH;Нијанса +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Одређује јачину уклаљања боје.\nВишље = више,\nНиже = мање. TP_PREPROCESS_GREENEQUIL;Калибрација зелене боје +TP_PREPROCESS_HOTDEADPIXFILT;Избаци прегореле и мртве пикселе +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Покушава да уклони вруће и мртве пикселе. TP_PREPROCESS_LABEL;Предобрада TP_PREPROCESS_LINEDENOISE;Линијски филтер шума TP_PREPROCESS_NO_FOUND;Није пронађено TP_RAWCACORR_AUTO;Исправи хроматске аберације TP_RAWCACORR_CABLUE;Плава TP_RAWCACORR_CARED;Црвена +TP_RAWEXPOS_BLACKONE;Ниво црне: Црвена TP_RAWEXPOS_BLACKS;Ниво црне +TP_RAWEXPOS_BLACKTHREE;Ниво црне: Зелена 2 +TP_RAWEXPOS_BLACKTWO;Ниво црне: Плава +TP_RAWEXPOS_BLACKZERO;Ниво црне: Зелена 1 (водећа) TP_RAWEXPOS_LINEAR;Линеарни фактор корекције TP_RAWEXPOS_PRESER;Очување светлих делова TP_RAWEXPOS_TWOGREEN;Обе зелене +TP_RAW_ALLENHANCE;Уклони артафакте/шум након расклапања TP_RAW_DCBENHANCE;Примени ДЦБ побољшање TP_RAW_DCBITERATIONS;Број ДЦБ пролаза TP_RAW_DMETHOD;Начин +TP_RAW_DMETHOD_PROGRESSBAR;%1 расклапам мозаик... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Побољшавам мозаик... +TP_RAW_DMETHOD_TOOLTIP;Примедба: IGV и LMMSE служе код великих ИСО вредности слике и служе за испомоћ при уклањање шума како не би дошло до ефекта постеризације или испраног излгеда. TP_RAW_FALSECOLOR;Кораци за пригушивање лажне боје TP_RAW_LABEL;Расклапање мозаика +TP_RAW_LMMSEITERATIONS;Кораци LMMSE побољшања +TP_RAW_LMMSE_TOOLTIP;Додаје гаму (корак 1), медијан (кораци 2-4) и побољшања (кораци 5-6) како би смањио неисправности и побољшао однос сигнал-према-шум. TP_RESIZE_APPLIESTO;Примени на: +TP_RESIZE_BICUBIC;Бикубично +TP_RESIZE_BICUBICSF;Бикубично (мекше) +TP_RESIZE_BICUBICSH;Бикубично (оштрије) +TP_RESIZE_BILINEAR;Билинеарно TP_RESIZE_CROPPEDAREA;Исечену област +TP_RESIZE_DOWNSCALEB;Смањење размере (боље) +TP_RESIZE_DOWNSCALEF;Смањење размере (брже) TP_RESIZE_FITBOX;Ширину и висину TP_RESIZE_FULLIMAGE;Целу слику TP_RESIZE_H;В: @@ -731,15 +1333,26 @@ TP_RESIZE_SCALE;Умањење TP_RESIZE_SPECIFY;Изабери: TP_RESIZE_W;Ш: TP_RESIZE_WIDTH;Ширину +TP_RGBCURVES_BLUE;П +TP_RGBCURVES_CHANNEL;Канал +TP_RGBCURVES_GREEN;З +TP_RGBCURVES_LABEL;РГБ криве +TP_RGBCURVES_LUMAMODE;Режим луминансе +TP_RGBCURVES_LUMAMODE_TOOLTIP;Режим лиминансе омогућава да мењате удео црвеног, зеленог и плавог канала из луминансе слике што не утиче на промену боје фотографије. +TP_RGBCURVES_RED;Ц +TP_ROTATE_AUTOCROP;Сам исеци TP_ROTATE_DEGREE;Степени: +TP_ROTATE_FILL;Попуни TP_ROTATE_LABEL;Ротација TP_ROTATE_SELECTLINE; Постави праву линију +TP_SAVEDIALOG_OK_TIP;Пречица: Ctrl-Enter TP_SHADOWSHLIGHTS_HIGHLIGHTS;Светло TP_SHADOWSHLIGHTS_HLTONALW;Ширина тонова TP_SHADOWSHLIGHTS_LABEL;Сенке/Светло TP_SHADOWSHLIGHTS_LOCALCONTR;Локални контраст TP_SHADOWSHLIGHTS_RADIUS;Полупречник TP_SHADOWSHLIGHTS_SHADOWS;Сенке +TP_SHADOWSHLIGHTS_SHARPMASK;Оштра маска TP_SHADOWSHLIGHTS_SHTONALW;Ширина тонова TP_SHARPENEDGE_AMOUNT;Количина TP_SHARPENEDGE_LABEL;Ивице @@ -759,11 +1372,29 @@ TP_SHARPENING_RLD_AMOUNT;Количина TP_SHARPENING_RLD_DAMPING;Пригушивање TP_SHARPENING_RLD_ITERATIONS;Понављања TP_SHARPENING_THRESHOLD;Праг +TP_SHARPENING_TOOLTIP;Очекујте нешто другачији ефекат када користите CIECAM02. Уколико приметите разлике, подесите их по свом укусу. TP_SHARPENING_USM;Оштрина маске TP_SHARPENMICRO_AMOUNT;Количина TP_SHARPENMICRO_LABEL;Микроконттраст TP_SHARPENMICRO_MATRIX;3×3 матрица уместо 5×5 TP_SHARPENMICRO_UNIFORMITY;Уједначеност +TP_VIBRANCE_AVOIDCOLORSHIFT;Избегни померање боја +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Боја коже +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Црвена/љубичаста +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Црвена +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Црвена/жута +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Жута +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Нијанса на основу HUE H=f(H) +TP_VIBRANCE_LABEL;Живост боја +TP_VIBRANCE_PASTELS;Пастелне боје +TP_VIBRANCE_PASTSATTOG;Повежи засићене и пастелне боје +TP_VIBRANCE_PROTECTSKINS;Очувај боју коже +TP_VIBRANCE_PSTHRESHOLD;Праг за пастелне/засићене боје +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Праг за засићене боје +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Вертикална оса садржи пастелне тонове при дну и засићене тонове на врху.\nХоризонтална оса представља опсег засићења. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Тежина прелаза пастелних/засићених боја +TP_VIBRANCE_SATURATED;Засићене боје TP_VIGNETTING_AMOUNT;Количина TP_VIGNETTING_CENTER;Центар TP_VIGNETTING_CENTER_X;Центар X @@ -773,13 +1404,50 @@ TP_VIGNETTING_RADIUS;Полупречник TP_VIGNETTING_STRENGTH;Јачина TP_WBALANCE_AUTO;Сам одреди TP_WBALANCE_CAMERA;Из апарата +TP_WBALANCE_CLOUDY;Облачно време TP_WBALANCE_CUSTOM;Произвољно +TP_WBALANCE_DAYLIGHT;Дневно светло (сунчано) +TP_WBALANCE_EQBLUERED;Баланс црвене и плаве +TP_WBALANCE_EQBLUERED_TOOLTIP;Дозвољава нестандардно подешавање баланса беле помоћу баланса плаве и црвене боје.\nОво је корисно када:\nа) сликате у нестандардним условима светла (нпр. под водом),\nб) су услови далеко другачији од оних у којима је извршена калибрација,\nв) су матрице или ИЦЦ профили неодговарајући. +TP_WBALANCE_FLASH55;Леика +TP_WBALANCE_FLASH60;Стандардни, Кенон, Пентакс, Олимпус +TP_WBALANCE_FLASH65;Никон, Панасоник, Сони, Минолта +TP_WBALANCE_FLASH_HEADER;Блиц +TP_WBALANCE_FLUO1;F1 - Дневно светло +TP_WBALANCE_FLUO2;F2 - Хладно светло +TP_WBALANCE_FLUO3;F3 - Бело светло +TP_WBALANCE_FLUO4;F4 - Топло-бело светло +TP_WBALANCE_FLUO5;F5 - Дневно светло +TP_WBALANCE_FLUO6;F6 - Светло-бело светло +TP_WBALANCE_FLUO7;F7 - D65 симулатор дневне светлости +TP_WBALANCE_FLUO8;F8 - D50 / Силванија F40 дизајн +TP_WBALANCE_FLUO9;F9 - Хладна, делукс-бела +TP_WBALANCE_FLUO10;F10 - Филипс TL85 +TP_WBALANCE_FLUO11;F11 - Филипс TL84 +TP_WBALANCE_FLUO12;F12 - Филипс TL83 +TP_WBALANCE_FLUO_HEADER;Неонско светло TP_WBALANCE_GREEN;Зеленило +TP_WBALANCE_GTI;ГеТеИ +TP_WBALANCE_HMI;ХаЕмИ +TP_WBALANCE_JUDGEIII;ЏудIII TP_WBALANCE_LABEL;Баланс беле +TP_WBALANCE_LAMP_HEADER;Лампа +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;ЛЕД осветљење +TP_WBALANCE_LED_LSI;LSI Лумелекс 2040 TP_WBALANCE_METHOD;Начин: +TP_WBALANCE_SHADE;У сенци TP_WBALANCE_SIZE;Величина: +TP_WBALANCE_SOLUX35;Солукс 3500K +TP_WBALANCE_SOLUX41;Солукс 4100K +TP_WBALANCE_SOLUX47;Солукс 4700K (произвођач) +TP_WBALANCE_SOLUX47_NG;Солукс 4700K (Нац. галерија) TP_WBALANCE_SPOTWB;Из тачке TP_WBALANCE_TEMPERATURE;Температура +TP_WBALANCE_TUNGSTEN;Обична сијалица +TP_WBALANCE_WATER1;Подводна фотографија 1 +TP_WBALANCE_WATER2;Подводна фотографија 2 +TP_WBALANCE_WATER_HEADER;Подводна фотографија ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;Отвара нови прозор са детаљима ZOOMPANEL_ZOOM100;Повећава преглед на 100% z @@ -791,67 +1459,30 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!ABOUT_TAB_RELEASENOTES;Release Notes -!BATCHQUEUE_DESTFILENAME;Path and file name !CURVEEDITOR_AXIS_IN;I: !CURVEEDITOR_AXIS_LEFT_TAN;LT: !CURVEEDITOR_AXIS_OUT;O: !CURVEEDITOR_AXIS_RIGHT_TAN;RT: !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!DIRBROWSER_FOLDERS;Folders !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. -!EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) -!EXPORT_BYPASS_ALL;Select / Unselect All -!EXPORT_BYPASS_DEFRINGE;Bypass Defringe -!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction -!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels -!EXPORT_BYPASS_RAW_CA;Bypass [raw] Chromatic Aberration Correction -!EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Color Suppression -!EXPORT_BYPASS_RAW_DCB_ENHANCE;Bypass [raw] DCB Enhancement Steps -!EXPORT_BYPASS_RAW_DCB_ITERATIONS;Bypass [raw] DCB Iterations -!EXPORT_BYPASS_RAW_DF;Bypass [raw] Dark-Frame -!EXPORT_BYPASS_RAW_FF;Bypass [raw] Flat-Field -!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration -!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter -!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps -!EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening -!EXPORT_BYPASS_SHARPENING;Bypass Sharpening -!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast -!EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights -!EXPORT_FASTEXPORTOPTIONS;Fast Export Options -!EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters. -!EXPORT_MAXHEIGHT;Maximum height: -!EXPORT_MAXWIDTH;Maximum width: -!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export -!EXPORT_RAW_DMETHOD;Demosaic method -!EXTPROGTARGET_1;raw -!EXTPROGTARGET_2;queue-processed -!FILEBROWSER_COLORLABEL_TOOLTIP;Color label.\n\nUse dropdown menu or shortcuts:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Red\nShift-Ctrl-2 Yellow\nShift-Ctrl-3 Green\nShift-Ctrl-4 Blue\nShift-Ctrl-5 Purple -!FILEBROWSER_EXTPROGMENU;Open with -!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) !FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green !FILEBROWSER_POPUPCOLORLABEL4;Label: Blue !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple -!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) -!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPOPENINEDITOR;Open in Editor !FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** !FILEBROWSER_POPUPRANK4;Rank 4 **** !FILEBROWSER_POPUPRANK5;Rank 5 ***** -!FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 -!FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 -!FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 -!FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 -!FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -859,112 +1490,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image -!GENERAL_AUTO;Automatic -!GENERAL_CLOSE;Close -!GENERAL_WARNING;Warning -!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. -!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. -!HISTORY_MSG_151;Vibrance -!HISTORY_MSG_152;Vib - Pastel tones -!HISTORY_MSG_153;Vib - Saturated tones -!HISTORY_MSG_154;Vib - Protect skin-tones -!HISTORY_MSG_155;Vib - Avoid color shift -!HISTORY_MSG_156;Vib - Link pastel/saturated -!HISTORY_MSG_157;Vib - P/S threshold -!HISTORY_MSG_158;TM - Strength -!HISTORY_MSG_159;TM - Edge stopping -!HISTORY_MSG_160;TM - Scale -!HISTORY_MSG_161;TM - Reweighting iterates -!HISTORY_MSG_162;Tone Mapping -!HISTORY_MSG_163;RGB Curves - Red -!HISTORY_MSG_164;RGB Curves - Green -!HISTORY_MSG_165;RGB Curves - Blue -!HISTORY_MSG_166;Exposure - Reset -!HISTORY_MSG_167;Demosaicing method -!HISTORY_MSG_168;L*a*b* - CC curve -!HISTORY_MSG_169;L*a*b* - CH curve -!HISTORY_MSG_170;Vibrance - HH curve -!HISTORY_MSG_171;L*a*b* - LC curve -!HISTORY_MSG_172;L*a*b* - Restrict LC -!HISTORY_MSG_173;NR - Luminance detail -!HISTORY_MSG_174;CIECAM02 -!HISTORY_MSG_175;CAM02 - CAT02 adaptation -!HISTORY_MSG_176;CAM02 - Viewing surround -!HISTORY_MSG_177;CAM02 - Scene luminosity -!HISTORY_MSG_178;CAM02 - Viewing luminosity -!HISTORY_MSG_179;CAM02 - White-point model -!HISTORY_MSG_180;CAM02 - Lightness (J) -!HISTORY_MSG_181;CAM02 - Chroma (C) -!HISTORY_MSG_182;CAM02 - Automatic CAT02 -!HISTORY_MSG_183;CAM02 - Contrast (J) -!HISTORY_MSG_184;CAM02 - Scene surround -!HISTORY_MSG_185;CAM02 - Gamut control -!HISTORY_MSG_186;CAM02 - Algorithm -!HISTORY_MSG_187;CAM02 - Red/skin prot. -!HISTORY_MSG_188;CAM02 - Brightness (Q) -!HISTORY_MSG_189;CAM02 - Contrast (Q) -!HISTORY_MSG_190;CAM02 - Saturation (S) -!HISTORY_MSG_191;CAM02 - Colorfulness (M) -!HISTORY_MSG_192;CAM02 - Hue (h) -!HISTORY_MSG_193;CAM02 - Tone curve 1 -!HISTORY_MSG_194;CAM02 - Tone curve 2 -!HISTORY_MSG_195;CAM02 - Tone curve 1 -!HISTORY_MSG_196;CAM02 - Tone curve 2 -!HISTORY_MSG_197;CAM02 - Color curve -!HISTORY_MSG_198;CAM02 - Color curve -!HISTORY_MSG_199;CAM02 - Output histograms -!HISTORY_MSG_200;CAM02 - Tone mapping -!HISTORY_MSG_201;NR - Chrominance - R&G -!HISTORY_MSG_202;NR - Chrominance - B&Y -!HISTORY_MSG_203;NR - Method -!HISTORY_MSG_204;LMMSE enhancement steps -!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter -!HISTORY_MSG_206;CAT02 - Auto scene luminosity -!HISTORY_MSG_207;Defringe - Hue curve -!HISTORY_MSG_208;WB - B/R equalizer -!HISTORY_MSG_210;GF - Angle -!HISTORY_MSG_211;Graduated Filter -!HISTORY_MSG_212;VF - Strength -!HISTORY_MSG_213;Vignette Filter -!HISTORY_MSG_214;Black-and-White -!HISTORY_MSG_215;B&W - CM - Red -!HISTORY_MSG_216;B&W - CM - Green -!HISTORY_MSG_217;B&W - CM - Blue -!HISTORY_MSG_218;B&W - Gamma - Red -!HISTORY_MSG_219;B&W - Gamma - Green -!HISTORY_MSG_220;B&W - Gamma - Blue -!HISTORY_MSG_221;B&W - Color filter -!HISTORY_MSG_222;B&W - Presets -!HISTORY_MSG_223;B&W - CM - Orange -!HISTORY_MSG_224;B&W - CM - Yellow -!HISTORY_MSG_225;B&W - CM - Cyan -!HISTORY_MSG_226;B&W - CM - Magenta -!HISTORY_MSG_227;B&W - CM - Purple -!HISTORY_MSG_228;B&W - Luminance equalizer -!HISTORY_MSG_229;B&W - Luminance equalizer -!HISTORY_MSG_230;B&W - Mode -!HISTORY_MSG_231;B&W - 'Before' curve -!HISTORY_MSG_232;B&W - 'Before' curve type -!HISTORY_MSG_233;B&W - 'After' curve -!HISTORY_MSG_234;B&W - 'After' curve type -!HISTORY_MSG_235;B&W - Auto channel mixer -!HISTORY_MSG_236;--unused-- -!HISTORY_MSG_237;B&W - Mixer -!HISTORY_MSG_238;GF - Feather -!HISTORY_MSG_239;GF - Strength -!HISTORY_MSG_240;GF - Center -!HISTORY_MSG_241;VF - Feather -!HISTORY_MSG_242;VF - Roundness -!HISTORY_MSG_243;VC - Radius -!HISTORY_MSG_244;VC - Strength -!HISTORY_MSG_245;VC - Center -!HISTORY_MSG_246;L*a*b* - CL curve -!HISTORY_MSG_247;L*a*b* - LH curve -!HISTORY_MSG_248;L*a*b* - HH curve -!HISTORY_MSG_249;CbDL - Threshold -!HISTORY_MSG_250;NR - Enhanced -!HISTORY_MSG_251;B&W - Algorithm +!GENERAL_OPEN;Open !HISTORY_MSG_252;CbDL - Skin tar/prot !HISTORY_MSG_253;CbDL - Reduce artifacts !HISTORY_MSG_254;CbDL - Skin hue @@ -1123,14 +1651,14 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1152,31 +1680,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method -!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s -!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 -!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 -!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). -!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. -!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled -!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. -!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! -!MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. -!MAIN_TAB_EXPORT; Fast Export +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w -!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 -!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 -!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\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_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.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. -!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g -!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B -!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r -!MAIN_TOOLTIP_THRESHOLD;Threshold !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1188,26 +1698,15 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !NAVIGATOR_R;R: !NAVIGATOR_S;S: !NAVIGATOR_V;V: -!NAVIGATOR_XY_FULL;Width: %1, Height: %2 -!OPTIONS_DEFIMG_MISSING;The default profile for non-raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. -!OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. -!PARTIALPASTE_CHANNELMIXERBW;Black-and-white -!PARTIALPASTE_COLORAPP;CIECAM02 !PARTIALPASTE_COLORTONING;Color toning -!PARTIALPASTE_EPD;Tone mapping !PARTIALPASTE_EQUALIZER;Wavelet levels !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_GRADIENT;Graduated filter -!PARTIALPASTE_LENSPROFILE;Lens correction profile -!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_METAGROUP;Metadata !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter !PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter !PARTIALPASTE_PRSHARPENING;Post-resize sharpening -!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps !PARTIALPASTE_RETINEX;Retinex -!PARTIALPASTE_RGBCURVES;RGB curves -!PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles @@ -1215,15 +1714,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTSTD;Standard -!PREFERENCES_BEHADDALL;All to 'Add' -!PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. -!PREFERENCES_BEHSETALL;All to 'Set' -!PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. -!PREFERENCES_BLACKBODY;Tungsten -!PREFERENCES_CIEART;CIECAM02 optimization !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings -!PREFERENCES_CIEART_LABEL;Use float precision instead of double -!PREFERENCES_CIEART_TOOLTIP;If enabled, CIECAM02 calculations are performed in the single-precision floating-point format instead of the double-precision one. This provides a small increase in speed at the expense of a negligible loss of quality. !PREFERENCES_CLUTSCACHE;HaldCLUT Cache !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory @@ -1232,30 +1723,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_CURVEBBOXPOS_BELOW;Below !PREFERENCES_CURVEBBOXPOS_LEFT;Left !PREFERENCES_CURVEBBOXPOS_RIGHT;Right -!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID -!PREFERENCES_D50;5000K -!PREFERENCES_D55;5500K -!PREFERENCES_D60;6000K -!PREFERENCES_D65;6500K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLUOF2;Fluorescent F2 -!PREFERENCES_FLUOF7;Fluorescent F7 -!PREFERENCES_FLUOF11;Fluorescent F11 !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel and the File Browser !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Having separate thumbnail size will require more processing time each time you'll switch between the single Editor tab and the File Browser. -!PREFERENCES_GREY;Output device's Yb luminance (%) -!PREFERENCES_GREY05;Yb=05 CIE L#30 -!PREFERENCES_GREY10;Yb=10 CIE L#40 -!PREFERENCES_GREY15;Yb=15 CIE L#45 -!PREFERENCES_GREY18;Yb=18 CIE L#50 -!PREFERENCES_GREY23;Yb=23 CIE L#55 -!PREFERENCES_GREY30;Yb=30 CIE L#60 -!PREFERENCES_GREY40;Yb=40 CIE L#70 !PREFERENCES_GREYSC;Scene Yb luminance (%) !PREFERENCES_GREYSC18;Yb=18 CIE L#50 !PREFERENCES_GREYSCA;Automatic @@ -1271,7 +1744,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_MAX;Maxi (Tile) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MED;Medium (Tile/2) -!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" !PREFERENCES_MIN;Mini (100x115) !PREFERENCES_MONINTENT;Default monitor intent !PREFERENCES_MONPROFILE;Default monitor profile @@ -1288,191 +1760,29 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_PROFILE_NONE;None !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in "Single Editor Tab Mode" and when "Demosaicing method used for the preview at <100% zoom" is set to "As in PP3". -!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels -!PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;When working with folders full of uncompressed tiff files enabling this option can increase performance of thumb generation. -!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar !PREFERENCES_SIMPLAUT;Tool mode !PREFERENCES_SMA;Small (250x287) !PREFERENCES_STDAUT;Standard -!PREFERENCES_TAB_PERFORMANCE;Performance & Quality !PREFERENCES_TIMAX;High !PREFERENCES_TINB;Number of tiles !PREFERENCES_TISTD;Standard -!PREFERENCES_TP_LABEL;Tool panel: -!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text -!PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file -!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_VIEW;Output device's white balance (monitor, TV, projector, viewing, etc.) !PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' !PREFERENCES_WLONE;One level !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No -!PROFILEPANEL_COPYPPASTE;Parameters to copy -!PROFILEPANEL_GLOBALPROFILES;Bundled profiles -!PROFILEPANEL_LOADPPASTE;Parameters to load -!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. -!PROFILEPANEL_MYPROFILES;My profiles -!PROFILEPANEL_PASTEPPASTE;Parameters to paste -!PROFILEPANEL_PINTERNAL;Neutral -!PROFILEPANEL_SAVEPPASTE;Parameters to save -!PROGRESSBAR_NOIMAGES;No images found -!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved -!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added -!SAVEDLG_FORCEFORMATOPTS;Force saving options -!SAVEDLG_SUBSAMP;Subsampling -!SAVEDLG_SUBSAMP_1;Best compression -!SAVEDLG_SUBSAMP_2;Balanced -!SAVEDLG_SUBSAMP_3;Best quality -!SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. -!SAVEDLG_WARNFILENAME;File will be named -!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left -!THRESHOLDSELECTOR_BR;Bottom-right -!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. -!THRESHOLDSELECTOR_T;Top -!THRESHOLDSELECTOR_TL;Top-left -!THRESHOLDSELECTOR_TR;Top-right -!TP_BWMIX_ALGO;Algorithm OYCPM -!TP_BWMIX_ALGO_LI;Linear -!TP_BWMIX_ALGO_SP;Special effects -!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. -!TP_BWMIX_AUTOCH;Auto -!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. -!TP_BWMIX_CC_ENABLED;Adjust complementary color -!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. -!TP_BWMIX_CHANNEL;Luminance equalizer -!TP_BWMIX_CURVEEDITOR1;'Before' curve -!TP_BWMIX_CURVEEDITOR2;'After' curve -!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. -!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. -!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. -!TP_BWMIX_FILTER;Color Filter -!TP_BWMIX_FILTER_BLUE;Blue -!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green -!TP_BWMIX_FILTER_GREEN;Green -!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow -!TP_BWMIX_FILTER_NONE;None -!TP_BWMIX_FILTER_PURPLE;Purple -!TP_BWMIX_FILTER_RED;Red -!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow !TP_BWMIX_FILTER_TOOLTIP;The color filter simulates shots taken with a colored filter placed in front of the lens. Colored filters reduce the transmission of specific color ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. !TP_BWMIX_FILTER_YELLOW;Yellow !TP_BWMIX_GAMMA;Gamma Correction !TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. -!TP_BWMIX_LABEL;Black-and-White -!TP_BWMIX_MET;Method -!TP_BWMIX_MET_CHANMIX;Channel Mixer -!TP_BWMIX_MET_DESAT;Desaturation -!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer -!TP_BWMIX_MIXC;Mixer -!TP_BWMIX_NEUTRAL;Reset mixer -!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. -!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% -!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. -!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. -!TP_BWMIX_SETTING;Presets -!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. -!TP_BWMIX_SET_HIGHCONTAST;High contrast -!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity -!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic -!TP_BWMIX_SET_INFRARED;Infrared -!TP_BWMIX_SET_LANDSCAPE;Landscape -!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity -!TP_BWMIX_SET_LUMINANCE;Luminance -!TP_BWMIX_SET_NORMCONTAST;Normal Contrast -!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic -!TP_BWMIX_SET_PANCHRO;Panchromatic -!TP_BWMIX_SET_PORTRAIT;Portrait -!TP_BWMIX_SET_RGBABS;Absolute RGB -!TP_BWMIX_SET_RGBREL;Relative RGB -!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM -!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM -!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like -!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending -!TP_BWMIX_TCMODE_STANDARD;B&W Standard -!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard -!TP_BWMIX_VAL;L !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White !TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. -!TP_COLORAPP_ADAPTSCENE;Scene luminosity -!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. -!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) -!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). -!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. -!TP_COLORAPP_ALGO;Algorithm -!TP_COLORAPP_ALGO_ALL;All -!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) -!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) -!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) -!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. -!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter -!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. -!TP_COLORAPP_BRIGHT;Brightness (Q) -!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. -!TP_COLORAPP_CHROMA;Chroma (C) -!TP_COLORAPP_CHROMA_M;Colorfulnes (M) -!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. -!TP_COLORAPP_CHROMA_S;Saturation (S) -!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. -!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation -!TP_COLORAPP_CONTRAST;Contrast (J) -!TP_COLORAPP_CONTRAST_Q;Contrast (Q) -!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. -!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. -!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 -!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. -!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 -!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. -!TP_COLORAPP_CURVEEDITOR3;Color curve -!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. -!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves -!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. -!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). -!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. -!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) -!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. -!TP_COLORAPP_HUE;Hue (h) -!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. -!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 -!TP_COLORAPP_LABEL_CAM02;Image Adjustments -!TP_COLORAPP_LABEL_SCENE;Scene Conditions -!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions -!TP_COLORAPP_LIGHT;Lightness (J) -!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. -!TP_COLORAPP_MODEL;WP Model -!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. -!TP_COLORAPP_RSTPRO;Red & skin-tones protection -!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. -!TP_COLORAPP_SHARPCIE;--unused-- -!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- -!TP_COLORAPP_SURROUND;Surround -!TP_COLORAPP_SURROUND_AVER;Average -!TP_COLORAPP_SURROUND_DARK;Dark -!TP_COLORAPP_SURROUND_DIM;Dim -!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) -!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. -!TP_COLORAPP_SURSOURCE;Dark surround -!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. -!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness -!TP_COLORAPP_TCMODE_CHROMA;Chroma -!TP_COLORAPP_TCMODE_COLORF;Colorfulness -!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 -!TP_COLORAPP_TCMODE_LABEL2;Curve mode 2 -!TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode -!TP_COLORAPP_TCMODE_LIGHTNESS;Lightness -!TP_COLORAPP_TCMODE_SATUR;Saturation -!TP_COLORAPP_TONECIE;Tone mapping using CIECAM02 -!TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. -!TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] -!TP_COLORAPP_WBRT;WB [RT] + [output] !TP_COLORTONING_AB;o C/L !TP_COLORTONING_AUTOSAT;Automatic !TP_COLORTONING_BALANCE;Balance @@ -1509,21 +1819,19 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_COLORTONING_TWOBY;Special a* and b* !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_GTEPASSPORT;Biometric Passport -!TP_CROP_GTFRAME;Frame !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global !TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! -!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow !TP_DIRPYRDENOISE_C2TYPE_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. !TP_DIRPYRDENOISE_CCCURVE;Chrominance curve !TP_DIRPYRDENOISE_CHROMAFR;Chrominance @@ -1533,14 +1841,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma !TP_DIRPYRDENOISE_CURVEEDITOR_CC_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_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise -!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. -!TP_DIRPYRDENOISE_ENH;Enhanced mode -!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. -!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. !TP_DIRPYRDENOISE_LAB;L*a*b* !TP_DIRPYRDENOISE_LABM;L*a*b* !TP_DIRPYRDENOISE_LCURVE;Luminance curve -!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail !TP_DIRPYRDENOISE_LM;Luminance only !TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) !TP_DIRPYRDENOISE_LTYPE;Luminance control @@ -1552,28 +1855,23 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_DIRPYRDENOISE_MEDMETHOD;Median method !TP_DIRPYRDENOISE_MEDTYPE;Median type !TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising -!TP_DIRPYRDENOISE_METHOD;Method !TP_DIRPYRDENOISE_METHOD11;Quality !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. -!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview !TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 -!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green -!TP_DIRPYRDENOISE_RGB;RGB !TP_DIRPYRDENOISE_RGBM;RGB !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1583,26 +1881,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_DIRPYREQUALIZER_SKIN;Skin targetting/protection !TP_DIRPYREQUALIZER_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. !TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. -!TP_EPD_EDGESTOPPING;Edge stopping !TP_EPD_GAMMA;Gamma -!TP_EPD_LABEL;Tone Mapping -!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates -!TP_EPD_SCALE;Scale -!TP_EPD_STRENGTH;Strength -!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" -!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. -!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. -!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 -!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 -!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. -!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like -!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 -!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual -!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending -!TP_EXPOSURE_TCMODE_STANDARD;Standard -!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMSIMULATION_LABEL;Film Simulation @@ -1611,90 +1892,17 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_GAMMA_CURV;Gamma -!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 -!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). -!TP_GRADIENT_CENTER_Y;Center Y -!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). -!TP_GRADIENT_DEGREE;Angle -!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. -!TP_GRADIENT_FEATHER;Feather -!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. -!TP_GRADIENT_LABEL;Graduated Filter -!TP_GRADIENT_STRENGTH;Strength -!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. -!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only enabled if the selected DCP has any. !TP_ICM_APPLYHUESATMAP;Base table !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only enabled if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only enabled if the selected DCP has one. -!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. -!TP_ICM_DCPILLUMINANT;Illuminant -!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. !TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. -!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. -!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. -!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. -!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. !TP_ICM_PROFILEINTENT;Rendering Intent !TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. -!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. -!TP_ICM_TONECURVE;Tone curve -!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. -!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift -!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. -!TP_LABCURVE_CHROMATICITY;Chromaticity -!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. -!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated -!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel -!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel -!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated -!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated -!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel -!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel -!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated -!TP_LABCURVE_CURVEEDITOR_CC;CC -!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral -!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull -!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel -!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated -!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) -!TP_LABCURVE_CURVEEDITOR_CH;CH -!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) -!TP_LABCURVE_CURVEEDITOR_CL;CL -!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) -!TP_LABCURVE_CURVEEDITOR_HH;HH -!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) -!TP_LABCURVE_CURVEEDITOR_LC;LC -!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) -!TP_LABCURVE_CURVEEDITOR_LH;LH -!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) -!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) -!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones -!TP_LABCURVE_LCREDSK_TIP;If enabled, the LC Curve affects only red and skin-tones.\nIf disabled, it applies to all tones. -!TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection -!TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. -!TP_LENSPROFILE_LABEL;Lens Correction Profile -!TP_LENSPROFILE_USECA;Chromatic aberration correction -!TP_LENSPROFILE_USEDIST;Distortion correction -!TP_LENSPROFILE_USEVIGN;Vignetting correction -!TP_NEUTRAL;Reset -!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;Feather -!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. -!TP_PCVIGNETTE_LABEL;Vignette Filter -!TP_PCVIGNETTE_ROUNDNESS;Roundness -!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_PFCURVE_CURVEEDITOR_CH;Hue -!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter !TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. !TP_PREPROCESS_HOTPIXFILT;Hot pixel filter @@ -1710,13 +1918,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RAWEXPOS_BLACK_GREEN;Green !TP_RAWEXPOS_BLACK_RED;Red !TP_RAWEXPOS_RGB;Red, Green, Blue -!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... -!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... -!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. !TP_RAW_HD;Threshold !TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. -!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. !TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix !TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. !TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix @@ -1730,8 +1933,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1751,6 +1958,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1770,10 +1978,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1781,6 +1990,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform @@ -1793,33 +2003,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask -!TP_RGBCURVES_BLUE;B -!TP_RGBCURVES_CHANNEL;Channel -!TP_RGBCURVES_GREEN;G -!TP_RGBCURVES_LABEL;RGB Curves -!TP_RGBCURVES_LUMAMODE;Luminosity mode -!TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminosity mode allows to vary the contribution of R, G and B channels to the luminosity of the image, without altering image color. -!TP_RGBCURVES_RED;R -!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter -!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask -!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. -!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift -!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) -!TP_VIBRANCE_LABEL;Vibrance -!TP_VIBRANCE_PASTELS;Pastel Tones -!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones -!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones -!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold -!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold -!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. -!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting -!TP_VIBRANCE_SATURATED;Saturated Tones !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 @@ -1983,41 +2166,4 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. !TP_WAVELET_TMTYPE;Compression method !TP_WAVELET_TON;Toning -!TP_WBALANCE_CLOUDY;Cloudy -!TP_WBALANCE_DAYLIGHT;Daylight (sunny) -!TP_WBALANCE_EQBLUERED;Blue/Red equalizer -!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. -!TP_WBALANCE_FLASH55;Leica -!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus -!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta -!TP_WBALANCE_FLASH_HEADER;Flash -!TP_WBALANCE_FLUO1;F1 - Daylight -!TP_WBALANCE_FLUO2;F2 - Cool White -!TP_WBALANCE_FLUO3;F3 - White -!TP_WBALANCE_FLUO4;F4 - Warm White -!TP_WBALANCE_FLUO5;F5 - Daylight -!TP_WBALANCE_FLUO6;F6 - Lite White -!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator -!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design -!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe -!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_GTI;GTI -!TP_WBALANCE_HMI;HMI -!TP_WBALANCE_JUDGEIII;JudgeIII -!TP_WBALANCE_LAMP_HEADER;Lamp -!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 -!TP_WBALANCE_LED_HEADER;LED -!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 -!TP_WBALANCE_SHADE;Shade -!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_TUNGSTEN;Tungsten -!TP_WBALANCE_WATER1;UnderWater 1 -!TP_WBALANCE_WATER2;UnderWater 2 -!TP_WBALANCE_WATER_HEADER;UnderWater !ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) index ee2df3cdf..c770ad345 100644 --- a/rtdata/languages/Serbian (Latin Characters) +++ b/rtdata/languages/Serbian (Latin Characters) @@ -3,14 +3,18 @@ ABOUT_TAB_BUILD;Izdanje ABOUT_TAB_CREDITS;Zasluge ABOUT_TAB_LICENSE;Licenca +ABOUT_TAB_RELEASENOTES;Beleške o izdanju ABOUT_TAB_SPLASH;Uvod ADJUSTER_RESET_TO_DEFAULT;Vrati na podrazumevano BATCHQUEUE_AUTOSTART;Sam započni +BATCHQUEUE_DESTFILENAME;Putanja i ime datoteke BATCH_PROCESSING;obrada CURVEEDITOR_CURVE;Krivulja CURVEEDITOR_CURVES;Krivulje CURVEEDITOR_CUSTOM;Proizvoljno CURVEEDITOR_DARKS;Tamno +CURVEEDITOR_FILEDLGFILTERANY;Sve datoteke +CURVEEDITOR_FILEDLGFILTERCURVE;Datoteke sa krivama CURVEEDITOR_HIGHLIGHTS;Presvetlo CURVEEDITOR_LIGHTS;Svetlo CURVEEDITOR_LINEAR;Linearno @@ -26,10 +30,10 @@ CURVEEDITOR_TOOLTIPLOAD;Učitava krivulju iz datoteke CURVEEDITOR_TOOLTIPPASTE;Ubacuje krivulju iz ostave CURVEEDITOR_TOOLTIPSAVE;Čuva trenutnu krivulju CURVEEDITOR_TYPE;Vrsta: -DIRBROWSER_FOLDERS;Fascikle EDITWINDOW_TITLE;Uređivanje slike EXIFFILTER_APERTURE;Otvor blende EXIFFILTER_CAMERA;Foto aparat +EXIFFILTER_EXPOSURECOMPENSATION;Kompenzacija ekspozicije (EV) EXIFFILTER_FILETYPE;Vrsta datoteke EXIFFILTER_FOCALLEN;Žižna daljina EXIFFILTER_ISO;ISO @@ -50,6 +54,35 @@ EXIFPANEL_RESETALL;Vrati sve EXIFPANEL_RESETALLHINT;Vraća sve oznake na početne vrednosti EXIFPANEL_RESETHINT;Vraća izabranu oznaku na početnu vrednosti EXIFPANEL_SUBDIRECTORY;Poddirektorijum +EXPORT_BYPASS_ALL;Izaberi / poništi sve +EXPORT_BYPASS_COLORDENOISE;Zanemari uklanjanje kolornog defrišuma +EXPORT_BYPASS_DEFRINGE;Zanemari uklanjanje oreola +EXPORT_BYPASS_DIRPYRDENOISE;Zanemari uklanjanje šuma +EXPORT_BYPASS_DIRPYREQUALIZER;Zanemari detaljni nivo kontrasta +EXPORT_BYPASS_LUMADENOISE;Zanemari uklanjanje šuma luminase +EXPORT_BYPASS_RAW_ALL_ENHANCE;Zanemari uklanjanje artafakta/šuma nakon rasklapanja +EXPORT_BYPASS_RAW_CA;Zanemari [raw] ispravljanje hromatskih aberacija +EXPORT_BYPASS_RAW_CCSTEPS;Zanemari [raw] prigušivanje lažne boje +EXPORT_BYPASS_RAW_DCB_ENHANCE;Zanemari [raw] DCB poboljšanje +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Zanemari [raw] broj DCB prolaza +EXPORT_BYPASS_RAW_DF;Zanemari [raw] tamno polje +EXPORT_BYPASS_RAW_FF;Zanemari [raw] ravno polje +EXPORT_BYPASS_RAW_GREENTHRESH;Zanemari [raw] kalibraciju zelene boje +EXPORT_BYPASS_RAW_LINENOISE;Zanemari [raw] linijski filter šuma +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Zanemari [raw] LMMSE korake za poboljšanje +EXPORT_BYPASS_SHARPENEDGE;Zanemari oštrenje ivice +EXPORT_BYPASS_SHARPENING;Zanemari oštrenje +EXPORT_BYPASS_SHARPENMICRO;Zanemari mikrokontrast +EXPORT_BYPASS_SH_HQ;Zanemari oštru masku za Senke/Svetlo +EXPORT_FASTEXPORTOPTIONS;Opcije za brz izvoz +EXPORT_INSTRUCTIONS;Brz izvoz omogućava da zaobiđete neke od zahtevnih i sporijih procesa prilikom razvijanja slika i da zakažete fotografije za brzo razvijanje. Ovj metod je dobar za brzo razvijanje slika u manjoj rezoluciji, kada vam je bitno da fotografije dobijete što pre ili kada želite primenite zadovoljavajuće parametre za razvijanje većeg broja fotografija odjednom bez izmene njihovih profila. +EXPORT_MAXHEIGHT;Najveća visina: +EXPORT_MAXWIDTH;Najveća dužina: +EXPORT_PUTTOQUEUEFAST; Zakaži za brz izvoz +EXPORT_RAW_DMETHOD;Način rasklapanja mozaika +EXPORT_RESIZEMETHOD;Način promene veličine +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;zakazano-razvijeno FILEBROWSER_ADDDELTEMPLATE;Dodaj/ukloni šablone... FILEBROWSER_APPLYPROFILE;Primeni profil FILEBROWSER_APPLYPROFILE_PARTIAL;Primeni profil (polovično) @@ -61,6 +94,7 @@ FILEBROWSER_CACHE;Ostava FILEBROWSER_CACHECLEARFROMFULL;Očisti iz ostave — sve FILEBROWSER_CACHECLEARFROMPARTIAL;Očisti iz ostave — polovično FILEBROWSER_CLEARPROFILE;Obriši profil +FILEBROWSER_COLORLABEL_TOOLTIP;Natpis u boji.\n\nKoristite priloženi meni ili prečice:\nShift-Ctrl-0 Bez boje\nShift-Ctrl-1 Crvena\nShift-Ctrl-2 Žuta\nShift-Ctrl-3 Zelena\nShift-Ctrl-4 Plana\nShift-Ctrl-5 Ljubičasta FILEBROWSER_COPYPROFILE;Umnoži profil FILEBROWSER_CURRENT_NAME;Trenutno ime: FILEBROWSER_DARKFRAME;Tamni kadar @@ -70,10 +104,12 @@ FILEBROWSER_DELETEDLGMSGINCLPROC;Da li želite da obrišete %1 izabranih datotek FILEBROWSER_EMPTYTRASH;Izbaci smeće FILEBROWSER_EMPTYTRASHHINT;Trajno briše datoteke iz smeća FILEBROWSER_EXEC_CPB;Izgradi početni profil +FILEBROWSER_EXTPROGMENU;Otvori pomoću FILEBROWSER_FLATFIELD;Ravno polje FILEBROWSER_MOVETODARKFDIR;Prebaci u fasciklu sa tamnim kadrovima FILEBROWSER_MOVETOFLATFIELDDIR;Premesti u fascikli sa ravnim poljima FILEBROWSER_NEW_NAME;Novo ime: +FILEBROWSER_OPENDEFAULTVIEWER;Podrazumevani prikaz prozora (zakazano-razvijeno) FILEBROWSER_PARTIALPASTEPROFILE;Delimično ubaci FILEBROWSER_PASTEPROFILE;Ubaci profil FILEBROWSER_POPUPCANCELJOB;Otkaži zadatak @@ -84,9 +120,10 @@ FILEBROWSER_POPUPMOVEEND;Premesti na kraj zakazanih FILEBROWSER_POPUPMOVEHEAD;Premesti na početak zakazanih FILEBROWSER_POPUPMOVETO;Premesti u... FILEBROWSER_POPUPOPEN;Otvori -FILEBROWSER_POPUPOPENINEDITOR;Otvori u Uredniku FILEBROWSER_POPUPPROCESS;Zakaži za obradu +FILEBROWSER_POPUPPROCESSFAST;Dodaj u zakazano (brzi izvoz) FILEBROWSER_POPUPPROFILEOPERATIONS;Profil +FILEBROWSER_POPUPRANK;Ocena FILEBROWSER_POPUPREMOVE;Ukloni iz sistema datoteka FILEBROWSER_POPUPREMOVEINCLPROC;Ukloni iz sistema datoteka i zakazanog FILEBROWSER_POPUPRENAME;Preimenuj @@ -97,7 +134,13 @@ FILEBROWSER_POPUPUNTRASH;Ukloni iz smeća FILEBROWSER_QUERYBUTTONHINT;Očisti polje za pretragu FILEBROWSER_QUERYHINT;Unesite deo imena datoteke za pretragu nCtrl-f postavlja fokus (u Razgledaču datoteka);nEnter pretražuje FILEBROWSER_QUERYLABEL; Traži: +FILEBROWSER_RANK1_TOOLTIP;Ocena 1 *\nPrečica: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Ocena 2 *\nPrečica: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Ocena 3 *\nPrečica: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Ocena 4 *\nPrečica: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Ocena 5 *\nPrečica: Shift-5 FILEBROWSER_RENAMEDLGLABEL;Preimenuj datoteku +FILEBROWSER_RENAMEDLGMSG;Preimenuj datoteku „%1“ u: FILEBROWSER_SELECTDARKFRAME;Izaberi tamni kadar... FILEBROWSER_SELECTFLATFIELD;Izaberi ravno polje... FILEBROWSER_SHOWCOLORLABEL1HINT;Prikazuje slike označene crvenom Alt-1 @@ -125,12 +168,16 @@ FILEBROWSER_STOPPROCESSING;Zaustavi obradu FILEBROWSER_STOPPROCESSINGHINT;Zaustavlja obradu slika FILEBROWSER_THUMBSIZE;Pregled FILEBROWSER_TOOLTIP_STOPPROCESSING;Pokreće obradu fotografija kada ih zakažete +FILEBROWSER_UNRANK_TOOLTIP;Neocenjeno.\nPrečica: Shift-0 +FILEBROWSER_USETEMPLATE;Iskoristi šablon: FILEBROWSER_ZOOMINHINT;Uvećava pregled FILEBROWSER_ZOOMOUTHINT;Umanjuje pregled GENERAL_ABOUT;O programu GENERAL_AFTER;Posle +GENERAL_AUTO;Automatski GENERAL_BEFORE;Pre GENERAL_CANCEL;Otkaži +GENERAL_CLOSE;Zatvori GENERAL_DISABLE;Isključi GENERAL_DISABLED;Isključeno GENERAL_ENABLE;Uključi @@ -144,8 +191,11 @@ GENERAL_OK;U redu GENERAL_PORTRAIT;Uspravno GENERAL_SAVE;Sačuvaj GENERAL_UNCHANGED;(neizmenjeno) +GENERAL_WARNING;Upozorenje HISTOGRAM_TOOLTIP_B;Prikazuje plavi histogram HISTOGRAM_TOOLTIP_BAR;Prikazuje/sakriva RGB indikator. Kliknite desni taster miša na umanjeni prikaz da zamrznete +HISTOGRAM_TOOLTIP_CHRO;Prikaži/sakrij histogram hrominanse. +HISTOGRAM_TOOLTIP_FULL;Uključuje prikaz potpunog ili histograma u razmeri. HISTOGRAM_TOOLTIP_G;Prikazuje zeleni histogram HISTOGRAM_TOOLTIP_L;Prikazuje CieLab hitogram HISTOGRAM_TOOLTIP_R;Prikazuje crveni histogram @@ -195,8 +245,8 @@ HISTORY_MSG_37;Pojačanje boja HISTORY_MSG_38;Način balansiranja bele HISTORY_MSG_39;Temperatura boje HISTORY_MSG_40;Zalenilo boje -HISTORY_MSG_41;Pomeraj boje „A“ -HISTORY_MSG_42;Pomeraj boje „B“ +HISTORY_MSG_41;Pomeranje boje „A“ +HISTORY_MSG_42;Pomeranje boje „B“ HISTORY_MSG_43;Uklanjanje svetlosnog šuma HISTORY_MSG_44;Radijus ukl. svetlosnog šuma HISTORY_MSG_45;Tolerancija ivice ukl. s. šuma @@ -303,11 +353,113 @@ HISTORY_MSG_145;Mikrokontrast - ujednačenost HISTORY_MSG_146;Oštrenje ivica HISTORY_MSG_147;Oštrenje ivica - samo luminansa HISTORY_MSG_148;Mikrokontrast -HISTORY_MSG_149;Mikrokontrast - 3x3 matrica +HISTORY_MSG_149;Mikrokontrast - 3×3 matrica HISTORY_MSG_150;Uklanjanje artefakta/šuma nakon rasklapanja mozaika +HISTORY_MSG_151;Živost boja +HISTORY_MSG_152;Živ - Pastelni tonovi +HISTORY_MSG_153;Živ - Zasićeni tonovi +HISTORY_MSG_154;Živ - Zaštiti boju kože +HISTORY_MSG_155;Živ - Izbegni pomeranje boja +HISTORY_MSG_156;Živ - Poveži pastelno i zasićeno +HISTORY_MSG_157;Živ - P/S prag +HISTORY_MSG_158;MT - Jačina +HISTORY_MSG_159;MT - Zaustavljanje ivice +HISTORY_MSG_160;MT - Razmera +HISTORY_MSG_161;MT - Ponavljanje premeravanja +HISTORY_MSG_162;Mapiranje tonova +HISTORY_MSG_163;RGB krive - crvena +HISTORY_MSG_164;RGB krive - zelena +HISTORY_MSG_165;RGB krive - plava +HISTORY_MSG_166;Neutralni nivoi +HISTORY_MSG_167;--neiskorišćeno-- +HISTORY_MSG_168;„CC“ kriva +HISTORY_MSG_169;„CH“ kriva +HISTORY_MSG_170;Živ - kriva +HISTORY_MSG_171;„LC“ kriva +HISTORY_MSG_172;Lab - Zabrani LC +HISTORY_MSG_173;UŠ - Detalji luminanse +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 adaptacija +HISTORY_MSG_176;CAM02 - Okolina prikaza +HISTORY_MSG_177;CAM02 - Luminansa kadra +HISTORY_MSG_178;CAM02 - Luminansa prikaza +HISTORY_MSG_179;CAM02 - Model bele tačke +HISTORY_MSG_180;CAM02 - Svetlina (J) +HISTORY_MSG_181;CAM02 - Boja (C) +HISTORY_MSG_182;CAM02 - Automatski CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Okolina scene +HISTORY_MSG_185;CAM02 - Kontrola širine tonova +HISTORY_MSG_186;CAM02 - Algoritam +HISTORY_MSG_187;CAM02 - Zaštita crvene i boje kože +HISTORY_MSG_188;CAM02 - Svetlina (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Zasićenost (S) +HISTORY_MSG_191;CAM02 - Živopisnost (M) +HISTORY_MSG_192;CAM02 - Nijansa (h) +HISTORY_MSG_193;CAM02 - Kriva tonova 1 +HISTORY_MSG_194;CAM02 - Kriva tonova 2 +HISTORY_MSG_195;CAM02 - Kriva tonova 1 +HISTORY_MSG_196;CAM02 - Kriva tonova 2 +HISTORY_MSG_197;CAM02 - Kriva boje +HISTORY_MSG_198;CAM02 - Kriva boje +HISTORY_MSG_199;CAM02 - Izlazni histogrami +HISTORY_MSG_200;CAM02 - Mapiranje tonova +HISTORY_MSG_201;UŠ - Hrominansa C,Z +HISTORY_MSG_202;UŠ - Hrominansa P,Y +HISTORY_MSG_203;UŠ - Način +HISTORY_MSG_204;LMMSE koraci poboljšanja +HISTORY_MSG_205;CAM02 - Vrući/loš pikseli +HISTORY_MSG_206;CAT02 - Automatska luminansa kadra +HISTORY_MSG_207;Uklanjanje oreola - kriva nijanse +HISTORY_MSG_208;BB - Balans C i P +HISTORY_MSG_210;FG - Ugao +HISTORY_MSG_211;Filter gradijenta +HISTORY_MSG_212;FV - Jačina +HISTORY_MSG_213;Filter vinjetarenja +HISTORY_MSG_214;Crno-bela slika +HISTORY_MSG_215;CB - CM - Crvena +HISTORY_MSG_216;CB - CM - Zelena +HISTORY_MSG_217;CB - CM - Plava +HISTORY_MSG_218;CB - Gama - Crvena +HISTORY_MSG_219;CB - Gama - Zelena +HISTORY_MSG_220;CB - Gama - Plana +HISTORY_MSG_221;CB - Filter boje +HISTORY_MSG_222;CB - Predpodešavanja +HISTORY_MSG_223;CB - CM - Narandžasta +HISTORY_MSG_224;CB - CM - Žuta +HISTORY_MSG_225;CB - CM - Svetlo plava +HISTORY_MSG_226;CB - CM - Svetlo ljubičasta +HISTORY_MSG_227;CB - CM - Ljubičasta +HISTORY_MSG_228;CB - Ujednačenje luminanse +HISTORY_MSG_229;CB - Ujednačenje luminanse +HISTORY_MSG_230;CB - Režim +HISTORY_MSG_231;CB - Pre krive +HISTORY_MSG_232;CB - Pre vrste krive +HISTORY_MSG_233;CB - Nakon prive +HISTORY_MSG_234;CB - Nakon vrste krive +HISTORY_MSG_235;CB - Automatsko mešanje kanala +HISTORY_MSG_236;--neiskorišćeno-- +HISTORY_MSG_237;CB - Mikser +HISTORY_MSG_238;FG - Umekšanje +HISTORY_MSG_239;FG - Jačina +HISTORY_MSG_240;FG - Centar +HISTORY_MSG_241;FV - Umekšanje +HISTORY_MSG_242;FV - Krivoća +HISTORY_MSG_243;FV - Prečnik +HISTORY_MSG_244;FV - Jačina +HISTORY_MSG_245;FV - Centar +HISTORY_MSG_246;CL kriva +HISTORY_MSG_247;LH kriva +HISTORY_MSG_248;HH kriva +HISTORY_MSG_249;CbDL - Prag +HISTORY_MSG_250;UŠ - Poboljšanje +HISTORY_MSG_251;CB - Algoritam HISTORY_NEWSNAPSHOT;Dodaj +HISTORY_NEWSNAPSHOT_TOOLTIP;Prečica: Alt-s HISTORY_SNAPSHOT;Snimak HISTORY_SNAPSHOTS;Snimak +HRESHOLDSELECTOR_BL;Dole-levo IPTCPANEL_AUTHOR;Autor IPTCPANEL_AUTHORSPOSITION;Zvanje autora IPTCPANEL_AUTHORSPOSITIONHINT;Zvanje jednog ili više autora (jedno po redi). @@ -350,10 +502,14 @@ IPTCPANEL_TITLEHINT;Kratni naziv slike (ime objekta). IPTCPANEL_TRANSREFERENCE;Ref. prenosa IPTCPANEL_TRANSREFERENCEHINT;Kod kojji predstavlja mesto prvobitnog prenosa (referenca prvog prenosa). MAIN_BUTTON_FULLSCREEN;Ceo ekran +MAIN_BUTTON_NAVNEXT_TOOLTIP;Šalje vas na narednu sliku u odnosu na otvorenu u prozoru za uređivanje.\nPrečica: Shift-F4\n\nTakođe, omoguća vam da idete na narednu sliku u odnosu na trenutno izabranu u razgledaču ili filmskoj traci.\nPrečica: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Šalje vas na prethodnu sliku u odnosu na otvorenu u prozoru za uređivanje.\nPrečica: Shift-F3\n\nnTakođe, omoguća vam da idete na narednu sliku u odnosu na trenutno izabranu u razgledaču ili filmskoj traci.\nPrečica: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Usaglašava razgledač datoteka ili filmsku traku sa delom za uređivanje radi umanjenog prikaza trenutno otvorene slike i čisti sve izabrane filtere.\nPrečica: x\n\nKao i prethodna operacija, ali bez čišćenja izabranih filtera:\nPrečica: y\n(Umanjeni prikaz otvorene slike neće biti prikazan ukoliko je izfiltriran). MAIN_BUTTON_PREFERENCES;Postavke MAIN_BUTTON_PUTTOQUEUE;Zakaži MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaje trenutnu sliku u zakazane Ctrl+B MAIN_BUTTON_SAVE;Sačuvaj +MAIN_BUTTON_SAVEAS;Kao... MAIN_BUTTON_SAVE_TOOLTIP;Čuva trenutnu sliku Ctrl+S MAIN_BUTTON_SENDTOEDITOR;Uredi MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Uređuje trenutnu sliku u spoljnom programu Ctrl+E @@ -375,14 +531,20 @@ MAIN_MSG_CANNOTSAVE;Greška pri čuvanju datoteke MAIN_MSG_CANNOTSTARTEDITOR;Ne mogu da pokrenem program za uređivanje. MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Izaberite ispravnu putanju u „Postavkama“. MAIN_MSG_EMPTYFILENAME;Nije određeno ime datoteke! +MAIN_MSG_IMAGEUNPROCESSED;Ova radnja zahteva da najpre stavite izabrane slike u listu zakazanih. MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_OPERATIONCANCELLED;Radnja je otkazana +MAIN_MSG_PATHDOESNTEXIST;Ne postoji putanja \n\n%1\n\n. Postavite ispravnu putanji iz podešavanja programa. MAIN_MSG_QOVERWRITE;Da li želite da prepišete? +MAIN_MSG_SETPATHFIRST;Morate izabrati ciljnu putanju iz podešavanja programa\nkako bi koristili ovu funkciju! +MAIN_MSG_WRITEFAILED;Ne mogu da upišem\n\n"%1"\n\nProverite da li fascikla postoji i da li imate ovlašćenja za upis u nju. MAIN_TAB_COLOR;Boja MAIN_TAB_COLOR_TOOLTIP;Alt-c MAIN_TAB_DETAIL;Detalji MAIN_TAB_DETAIL_TOOLTIP;Alt-d MAIN_TAB_DEVELOP;Razvijanje MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Brzi izvoz MAIN_TAB_EXPOSURE;Svetlost MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e MAIN_TAB_FILTER;Filter @@ -391,21 +553,55 @@ MAIN_TAB_METADATA;Metapodaci MAIN_TAB_METADATA_TOOLTIP;Alt-m MAIN_TAB_RAW;RAW MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TAGGING;Oznake MAIN_TAB_TRANSFORM;Ispravke MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Boja pozadine za pregled: Na osnovu teme\nPrečica: 9 +MAIN_TOOLTIP_BACKCOLOR1;Boja pozadine za pregled: Crna\nPrečica: 9 +MAIN_TOOLTIP_BACKCOLOR2;Boja pozadine za pregled: Bela\nPrečica: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zaključaj / otključaj pre prikaza\n\nZaključaj: zadrži prethodni prikaz.\nKorisno ukoliko želite da prikažete ukupni efekat više alata.\nPoređenje se još može napraviti i za bilo koje stanje iz Istorije.\n\nOtključaj: prethodni prikaz dolazi nakon prikaza jednog poslednjeg koraka, prikazujući sliku pre primene trenutnog alata. MAIN_TOOLTIP_HIDEHP;Prikazuje/sakriva levu površ, zajedno sa istorijatom (prečica: H) MAIN_TOOLTIP_INDCLIPPEDH;Prikazuje isečene svetle delove MAIN_TOOLTIP_INDCLIPPEDS;Prikazuje isečene tamne delove +MAIN_TOOLTIP_PREVIEWB;Pregled plavog kanaza.\nPrečica: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Prikazuje oblast u fokusu.\nPrečica: Shift-f\n\nNa uvećanju preciznije radi sa slikama koje imaju malu dubinsku oštrinu i malo šuma.\n\nZa precizniji prikaz kod slika sa šumom pregledajte fokus na manjem uvećanju od oko 10-30%.\n\nPrikaz fokusirane oblasti će usporiti pregled fotografija. +MAIN_TOOLTIP_PREVIEWG;Pregled zelenog kanala.\nPrečica: g +MAIN_TOOLTIP_PREVIEWL;Pregled luminanse.\nPrečica: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Pregled crvenog kanala.\nPrečica: r MAIN_TOOLTIP_QINFO;Osnovni podaci o slici I MAIN_TOOLTIP_SHOWHIDELP1;Prikazuje/sakriva levu površ l MAIN_TOOLTIP_SHOWHIDERP1;Prikazuje/sakriva desnu površ Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Prikazuje/sakriva gornju površ Shift-L +MAIN_TOOLTIP_THRESHOLD;Prag MAIN_TOOLTIP_TOGGLE;Prikazuje sliku pre i posle obrade B +NAVIGATOR_B_NA;P = ○ +NAVIGATOR_B_VALUE;P = %1 +NAVIGATOR_G_NA;Z = ○ +NAVIGATOR_G_VALUE;Z = %1 +NAVIGATOR_H_NA;H = ○ +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_LAB_A_NA;A = ○ +NAVIGATOR_LAB_A_VALUE;A = %1 +NAVIGATOR_LAB_B_NA;B = ○ +NAVIGATOR_LAB_B_VALUE;B = %1 +NAVIGATOR_LAB_L_NA;L = ○ +NAVIGATOR_LAB_L_VALUE;L = %1 +NAVIGATOR_R_NA;C = ○ +NAVIGATOR_R_VALUE;C = %1 +NAVIGATOR_S_NA;S = ○ +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_NA;V = ○ +NAVIGATOR_V_VALUE;V = %1 +NAVIGATOR_XY_FULL;Širina = %1, Visina = %2 NAVIGATOR_XY_NA;x = ○, y = ○ +OPTIONS_DEFIMG_MISSING;Nije pronađen ili dostupan podrazumevani profil za slike koje nisu u sirovom formatu.\n\nProverite fasciklu sa profilima, možda ne postoji ili je oštećena.\n\nBiće korišćene podrazumevane vrednosti. +OPTIONS_DEFRAW_MISSING;Nije pronađen ili dostupan podrazumevani profil za slike u sirovom formatu.\n\nProverite fasciklu sa profilima, možda ne postoji ili je oštećena.\n\nBiće korišćene podrazumevane vrednosti. PARTIALPASTE_BASICGROUP;Osnovna podešavanja PARTIALPASTE_CACORRECTION;Ispravljanje aberacija PARTIALPASTE_CHANNELMIXER;Mešanje kanala +PARTIALPASTE_CHANNELMIXERBW;Crno-bela fotografija PARTIALPASTE_COARSETRANS;Rotacija za 90˚ / izvrtanje +PARTIALPASTE_COLORAPP;CIECAM 2002 model izgleda boja PARTIALPASTE_COLORGROUP;Podešavanje boja PARTIALPASTE_COMMONTRANSFORMPARAMS;Sam popuni PARTIALPASTE_COMPOSITIONGROUP;Podešavanje kompozicije @@ -418,6 +614,7 @@ PARTIALPASTE_DIALOGLABEL;Delimočno ubacuje profil za obradu PARTIALPASTE_DIRPYRDENOISE;Uklanjanje šuma PARTIALPASTE_DIRPYREQUALIZER;Kontrast nivoima detalja PARTIALPASTE_DISTORTION;Ispravljanje izobličenja +PARTIALPASTE_EPD;Mapiranje tonova PARTIALPASTE_EVERYTHING;Sve PARTIALPASTE_EXIFCHANGES;Izmene exif podataka PARTIALPASTE_EXPOSURE;Ekspozicija @@ -425,15 +622,21 @@ PARTIALPASTE_FLATFIELDAUTOSELECT;Automatski izbor RK PARTIALPASTE_FLATFIELDBLURRADIUS;Poluprečnik zamućenja RK PARTIALPASTE_FLATFIELDBLURTYPE;Način zamućenja RK PARTIALPASTE_FLATFIELDFILE;Datoteka za ravni kadar +PARTIALPASTE_GRADIENT;Filter gradijenta PARTIALPASTE_HSVEQUALIZER;Ujednačenje HSV +PARTIALPASTE_ICMGAMMA;Izlazna gama PARTIALPASTE_ICMSETTINGS;ICM podešavanja PARTIALPASTE_IMPULSEDENOISE;Impulsno uklanjanje šuma PARTIALPASTE_IPTCINFO;IPTC podavi PARTIALPASTE_LABCURVE;Lab kriva PARTIALPASTE_LENSGROUP;Podešavanja objektiva -PARTIALPASTE_METAGROUP;Metapodaci +PARTIALPASTE_LENSPROFILE;Profil za ispravke objektiva +PARTIALPASTE_LUMACURVE;Kriva luminase +PARTIALPASTE_METAICMGROUP;Metapodaci/ICM podešavanja +PARTIALPASTE_PCVIGNETTE;Filter vinjetarenja PARTIALPASTE_PERSPECTIVE;Perspektiva PARTIALPASTE_PREPROCESS_GREENEQUIL;Ujednačavanje zelene +PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filter vrelih/mrtvih piksela PARTIALPASTE_PREPROCESS_LINEDENOISE;Linijski filter šuma PARTIALPASTE_RAWCACORR_AUTO;Auto hromatske aberacije PARTIALPASTE_RAWCACORR_CABLUE;Plava hrominansa @@ -442,39 +645,68 @@ PARTIALPASTE_RAWEXPOS_BLACK;Nivo crne PARTIALPASTE_RAWEXPOS_LINEAR;Linearni faktor ispravke RAW bele tačke PARTIALPASTE_RAWEXPOS_PRESER;Raw tačka bele uz očuvanje svetlih delova PARTIALPASTE_RAWGROUP;Raw podešavanja +PARTIALPASTE_RAW_ALLENHANCE;Ukloni šum nakon rasklapanja mozaika PARTIALPASTE_RAW_DCBENHANCE;Primeni korak DCB poboljšanja PARTIALPASTE_RAW_DCBITERATIONS;Broj DCB ponavljanja PARTIALPASTE_RAW_DMETHOD;Način rasklapanja mozaika PARTIALPASTE_RAW_FALSECOLOR;Koraci prigušenja lažne boje pri rasklapanju mozaika +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE koraci poboljšanja PARTIALPASTE_RESIZE;Promena veličine +PARTIALPASTE_RGBCURVES;RGB krive PARTIALPASTE_ROTATION;Rotacija PARTIALPASTE_SHADOWSHIGHLIGHTS;Senke/Svetlost PARTIALPASTE_SHARPENEDGE;Ivice PARTIALPASTE_SHARPENING;Oštrenje PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Živost boja PARTIALPASTE_VIGNETTING;Ispravljanje vinjetarenja PARTIALPASTE_WHITEBALANCE;Balans bele +POPUPBUTTON_SELECTOPTIONHINT;RMB za izmenu opcije PREFERENCES_ADD;Dodaj PREFERENCES_APPLNEXTSTARTUP;primenjuje se nakon ponovnog pokretanja PREFERENCES_AUTOMONPROFILE;Sam primeni profile monitora iz operativnog sistema PREFERENCES_BATCH_PROCESSING;Obrada zakzanog +PREFERENCES_BEHADDALL;Sve u „Dodaj“ +PREFERENCES_BEHADDALLHINT;Postavlja sve parametre u režim Dodaj.\nNjihovo podešavanje pomoću alata iz panela za zakazano će biti razlike sačuvanih vrednosti. PREFERENCES_BEHAVIOR;Ponašanje +PREFERENCES_BEHSETALL;Sve u „Postavi“ +PREFERENCES_BEHSETALLHINT;Postavlja sve parametre u režim Postavi.\nNjihovo podešavanje pomoću alata iz panela za zakazano će biti apsolutne vrednosti kao što su i izabrane. +PREFERENCES_BLACKBODY;Obična sijalica +PREFERENCES_BLINKCLIPPED;Pokaži pretamne/presvetle delove PREFERENCES_CACHECLEARALL;Obriši sve PREFERENCES_CACHECLEARPROFILES;Obriši profile PREFERENCES_CACHECLEARTHUMBS;Obriši prikaze +PREFERENCES_CACHEFORMAT1;Vlasnički (brže i bolje) +PREFERENCES_CACHEFORMAT2;JPEG (manje mesta na disku) PREFERENCES_CACHEMAXENTRIES;Najveći broj mest u ostavi PREFERENCES_CACHEOPTS;Podešavanje ostave +PREFERENCES_CACHETHUMBFORM;Format umanjenih prikaza PREFERENCES_CACHETHUMBHEIGHT;Najveća visina prikaza +PREFERENCES_CIEART;CIECAM02 optimizacija +PREFERENCES_CIEART_LABEL;Jednostruka tačnost umesto dvostruke +PREFERENCES_CIEART_TOOLTIP;Ukoliko je omogućeno, radi CIECAM02 računanja sa jednostrukom tačnošću umesto sa dvostrukom. Ovo daje malo povećanje brzine uz neizostavan gubitak na kvalitetu. +PREFERENCES_CLEARDLG_LINE1;Čišćenje ostave +PREFERENCES_CLEARDLG_LINE2;Ovo može da potraje nekoliko sekundi. +PREFERENCES_CLEARDLG_TITLE;Sačekajte PREFERENCES_CLIPPINGIND;Pokazivači odsečenih delova +PREFERENCES_CMETRICINTENT;Kolorimetrijska namera PREFERENCES_CUSTPROFBUILD;Izgradnja proizvoljnog početnog profila slike PREFERENCES_CUSTPROFBUILDHINT;Izvršna datoteka (ili skripta) koja se poziva kada izgrađujete novi početni profil za sliku.nPrihvata parametre iz komandne linije radi pravljenja .pp3 datoteke na osnovu nekih pravila:n[Putanja do RAW/JPG] [Putanja podrazumevanog profila] [Blenda] [Ekspozicija u s] [Žižna dužina mm] [ISO] [Objektiv] [Foto-aparat] +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Ključni formati +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Naziv +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;BrOznake PREFERENCES_CUSTPROFBUILDPATH;Izvršna putanja PREFERENCES_CUTOVERLAYBRUSH;Maska isecanja boje/providnog +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K PREFERENCES_DARKFRAME;Tamni kadar PREFERENCES_DARKFRAMEFOUND;Nađen PREFERENCES_DARKFRAMESHOTS;snimaka PREFERENCES_DARKFRAMETEMPLATES;šabloni PREFERENCES_DATEFORMAT;Format datuma +PREFERENCES_DATEFORMATFRAME;Format PREFERENCES_DATEFORMATHINT;Možete zadati sledeće formate:\n%y :godina\n%m : mesec\n%d : dan\n\nU Srbiji se najviše koristi:\n%d.%m.%y PREFERENCES_DEFAULTLANG;Jezik programa PREFERENCES_DEFAULTTHEME;Tema programa @@ -495,9 +727,21 @@ PREFERENCES_FLATFIELDFOUND;Nađeno PREFERENCES_FLATFIELDSDIR;Direktorijum za ravna polja PREFERENCES_FLATFIELDSHOTS;snimaka PREFERENCES_FLATFIELDTEMPLATES;šabloni +PREFERENCES_FLUOF2;Florescentna F2 +PREFERENCES_FLUOF7;Florescentna F7 +PREFERENCES_FLUOF11;Florescentna F11 PREFERENCES_FORIMAGE;Za datoteke sa slikama PREFERENCES_FORRAW;Za RAW datoteke PREFERENCES_GIMPPATH;Direktorijum sa instaliranim Gimpom +PREFERENCES_GREY;Yb luminansa izlaznog uređaja (%) +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;Yb=18 CIE L#50 +PREFERENCES_GREY23;Yb=23 CIE L#55 +PREFERENCES_GREY30;Yb=30 CIE L#60 +PREFERENCES_GREY40;Yb=40 CIE L#70 +PREFERENCES_GTKTHEME;GTK tema PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram u levoj površi PREFERENCES_HLTHRESHOLD;Prag za odsečene svetle delove PREFERENCES_ICCDIR;ICC direktorijum @@ -508,12 +752,14 @@ PREFERENCES_INTENT_RELATIVE;Relativno kolorimetrijski PREFERENCES_INTENT_SATURATION;Zasićeni prikaz PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Koristi ugnježđeni RAW prikaz do izmene PREFERENCES_LANGAUTODETECT;Sam otkrij +PREFERENCES_MENUGROUPEXTPROGS;Grupiši "Otvori sa" PREFERENCES_MENUGROUPFILEOPERATIONS;Grupiši radnje nad datotekama PREFERENCES_MENUGROUPLABEL;Grupiši obeležavanje PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupiši radnje sa profilima PREFERENCES_MENUGROUPRANK;Grupiši ocenjivanje PREFERENCES_MENUOPTIONS;Opcije menija PREFERENCES_METADATA;Metapodaci +PREFERENCES_MONITORICC;Profil monitora PREFERENCES_MULTITAB;Režim u više listova PREFERENCES_MULTITABDUALMON;Režim u više listova, na drugom monitoru PREFERENCES_OUTDIR;Izlazni direktorijum @@ -523,6 +769,7 @@ PREFERENCES_OUTDIRTEMPLATE;Upotrebi šablon PREFERENCES_OUTDIRTEMPLATEHINT;Možete da zadate sledeće skraćenice za formatiranje:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nOvi znakovi za formatiranje se odnose na direktorijume, podputanje putanja do raw datoteke.\n\nNa primer, ukoliko je otvorena slika /home/ivan/slike/02.09.2010/dsc0012.nef, skraćenice označavaju:\n%f=dsc0012, %d1=02.09.2010, %d2=slike, ...\n%p1=/home/ivan/slike/02.09.2010, %p2=/home/ivan/slike, %p3=/home/ivan, ...\n\nUkoliko želite da sačuvate razvijenu sliku pored originala, unesite:\n%p1/%f\n\nUkoliko želite da sačuvate izlaznu sliku u direktorijum „razvijene“ koji se nalazi gde i originalna slika, unesite:\n%p1/razvijene/%f\n\nUkoliko želite da sačuvate razvijenu sliku u direktorijum „/home/ivan/razvijene“, a da struktura poddirektorijuma ostane očuvana, unesite:\n%p2/razvijene/%d1/%f PREFERENCES_OVERLAY_FILENAMES;Postavi preko umanjenog prikaza PREFERENCES_OVERWRITEOUTPUTFILE;Prepiši postojeće izlazne datoteke +PREFERENCES_PANFACTORFRAME;Ubrzanje pri pomeranju platna PREFERENCES_PANFACTORLABEL;Faktor PREFERENCES_PARSEDEXT;Ekstenzije za prikaz PREFERENCES_PARSEDEXTADD;Dodaj ekstenziju @@ -536,12 +783,16 @@ PREFERENCES_PROFILESAVECACHE;Sačuvaj parametre obrade u ostavu PREFERENCES_PROFILESAVEINPUT;Sačuvaj paramtre obrade pored ulazne datoteke PREFERENCES_PROPERTY;Osobina PREFERENCES_PSPATH;Direktorijum sa instaliranim Adobe Fotošopom +PREFERENCES_RGBDTL_LABEL;Najveći broj niri prilikom uklanjanja šuma +PREFERENCES_RGBDTL_TOOLTIP;Uklanjanje šuma zahteva oko 128MB RAM memorije za sliku od 10 megapiksela ili 512MB za sliku od 40 megapiksela, uz dodatnih 128MB memorije po svakoj niti. Što više niti se izvršavaju zajedno to će brže biti računanje. Ostavite ovu vrednost na „0“ kako bi program automatski dodelilo što je više nitova moguće. PREFERENCES_SELECTFONT;Izaberite font PREFERENCES_SELECTLANG;Jezik PREFERENCES_SELECTTHEME;Tema PREFERENCES_SET;Postavi PREFERENCES_SHOWBASICEXIF;Prikaži osnovne Exif podatke PREFERENCES_SHOWDATETIME;Prikaži datum i vreme +PREFERENCES_SHOWEXPOSURECOMPENSATION;Dodaj kompenzaciju ekspozicije +PREFERENCES_SHOWPROFILESELECTOR;Prikaži izbor profila PREFERENCES_SHTHRESHOLD;Prag za odsečene tamne delove PREFERENCES_SINGLETAB;Režim u jednom listu PREFERENCES_SINGLETABVERTAB;Režim u jednom listu, vertikalni listovi @@ -550,21 +801,38 @@ PREFERENCES_SND_BATCHQUEUEDONE;Obrađene su zakazane datoteke PREFERENCES_SND_HELP;Unesite putanju do datoteke ili ostavite prazno ukoliko ne želite zvuk. Na Windows-u možete da koristite „SystemDefault“, „SystemAsterisk“ za sistemske zvuke. PREFERENCES_SND_LNGEDITPROCDONE;Urednik je završio obradu PREFERENCES_SND_TRESHOLDSECS;br. sekundi +PREFERENCES_SQUAREDETAILWINDOW;Kockast prozor sa detaljima (brže) PREFERENCES_STARTUPIMDIR;Direktorijum po pokretanju PREFERENCES_TAB_BROWSER;Pregled datoteka PREFERENCES_TAB_COLORMGR;Upravljanje bojama PREFERENCES_TAB_GENERAL;Opšte PREFERENCES_TAB_IMPROC;Obrada slike +PREFERENCES_TAB_PERFORMANCE;Performansa PREFERENCES_TAB_SOUND;Zvuci +PREFERENCES_TP_LABEL;Površ alata: +PREFERENCES_TP_USEICONORTEXT;Koristi ikonice jezička umesto teksta PREFERENCES_TP_VSCROLLBAR;Sakrij klizače u oblasti sa alatkama +PREFERENCES_TUNNELMETADATA;Kopiraj neizmenjene IPTC/XMP (kada je slika označena drugim programom) +PREFERENCES_USEBUNDLEDPROFILES;Koristi profile koji dolaze uz program PREFERENCES_USESYSTEMTHEME; Koristi sistemsku temu +PREFERENCES_VIEW;Balans bele izlaznog uređaja (monitor, TV, projaketor i dr.) PREFERENCES_WORKFLOW;Tok obrade +PROFILEPANEL_COPYPPASTE;Parametri za kopiranje +PROFILEPANEL_FILEDLGFILTERANY;Sve datoteke +PROFILEPANEL_FILEDLGFILTERPP;Profili za obradu +PROFILEPANEL_GLOBALPROFILES;Profili iz programa PROFILEPANEL_LABEL;Profili obrade PROFILEPANEL_LOADDLGLABEL;Učitaj profil za obradu... +PROFILEPANEL_LOADPPASTE;Parametri za učitavanje +PROFILEPANEL_MODE_TIP;Način dopune profila koji se koristi za obradu.\n\nPritisnuta dugmad: delimični profili se prevode u potpune profile, a nedostajuće vrednosoti se menjaju podrazumevanim vrednostim.\n\nPuštena dugmad: profili će biti primenjeni kakvi jesu, uz izmeni samo onih vrednosti koje sadrži profil. +PROFILEPANEL_MYPROFILES;Moji profili +PROFILEPANEL_PASTEPPASTE;Parametri za ubacivanje PROFILEPANEL_PCUSTOM;Proizvoljno PROFILEPANEL_PFILE;Iz datoteke +PROFILEPANEL_PINTERNAL;Neutralno PROFILEPANEL_PLASTSAVED;Od poslednjeg čuvanja PROFILEPANEL_SAVEDLGLABEL;Čuva parametre za obradu... +PROFILEPANEL_SAVEPPASTE;Parametri za čuvanje PROFILEPANEL_TOOLTIPCOPY;Kopira trenutni profil u ostavu PROFILEPANEL_TOOLTIPLOAD;Učitava profil iz datoteke PROFILEPANEL_TOOLTIPPASTE; Učitava profil iz @@ -574,29 +842,115 @@ PROGRESSBAR_LOADINGTHUMBS;Učitavam prikaze... PROGRESSBAR_LOADJPEG;Učitavam JPEG datoteku... PROGRESSBAR_LOADPNG;Učitavam PNG datoteku... PROGRESSBAR_LOADTIFF;Učitavam TIFF datoteku... +PROGRESSBAR_NOIMAGES;Nisu pronađene slike PROGRESSBAR_PROCESSING;Obrađujem sliku... +PROGRESSBAR_PROCESSING_PROFILESAVED;Obrađujem sačuvani profil PROGRESSBAR_READY;Čekam PROGRESSBAR_SAVEJPEG;Čuvam JPEG datoteku... PROGRESSBAR_SAVEPNG;Čuvam PNG datoteku... PROGRESSBAR_SAVETIFF;Čuvam TIFF datoteku... +PROGRESSBAR_SNAPSHOT_ADDED;Dodat je snimak +PROGRESSDLG_LOADING;Učitavam datoteku... +PROGRESSDLG_PROCESSING;Obrađujem sliku... PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil izmenjen u razgledaču +PROGRESSDLG_SAVING;Čuvam datoteku... P_GAMMA_CURV;gama QINFO_ISO;ISO QINFO_NOEXIF;Nisu dostupni Exif podaci. SAVEDLG_AUTOSUFFIX;Sam dodaj sufiks ukoliko datoteka već postoji SAVEDLG_FILEFORMAT;Format datoteke +SAVEDLG_FORCEFORMATOPTS;Primoraj mogućnosti za čuvanje SAVEDLG_JPEGQUAL;JPEG kvalitet +SAVEDLG_JPGFILTER;JPEG datoteke SAVEDLG_PNGCOMPR;PNG pakovanje SAVEDLG_PUTTOQUEUE;Zakazuje sliku za obradu SAVEDLG_PUTTOQUEUEHEAD;Premešta sliku na početak zakazanih SAVEDLG_PUTTOQUEUETAIL;Premešta sliku na kraj zakazanih SAVEDLG_SAVEIMMEDIATELY;Odmah sačuvaj SAVEDLG_SAVESPP;Sačuvaj parametre obrade uz sliku +SAVEDLG_SUBSAMP;Poduzorkovanje +SAVEDLG_SUBSAMP_1;Najbolja kompresija +SAVEDLG_SUBSAMP_2;Balansirano +SAVEDLG_SUBSAMP_3;Najbolji kvalitet +SAVEDLG_SUBSAMP_TOOLTIP;Najbolja kompresija: 4:1:1\nBalansirano: 4:2:2\nNajbolji kvalitet: 4:4:4 +SAVEDLG_TIFFFILTER;TIFF datoteke SAVEDLG_TIFFUNCOMPRESSED;Nezapakovani TIFF +SAVEDLG_WARNFILENAME;Datoteka će biti nazvana +SHCSELECTOR_TOOLTIP;Kliknite desno dugme miša da ponovo vratite poziciju ova tri klizača. +THRESHOLDSELECTOR_B;Dole +THRESHOLDSELECTOR_BR;Dole-desno +THRESHOLDSELECTOR_HINT;Pritisnite dugme Shift za pomeranje pojedinačnih tačaka. +THRESHOLDSELECTOR_T;Gore +THRESHOLDSELECTOR_TL;Gore-levo +THRESHOLDSELECTOR_TR;Gore-desno TOOLBAR_TOOLTIP_CROP;Postavlja okvir za isecanje (prečica: C) TOOLBAR_TOOLTIP_HAND;Alat za pomeranje (prečica: N) TOOLBAR_TOOLTIP_STRAIGHTEN;Ispravlja liniju horizonta (prečica: S) TOOLBAR_TOOLTIP_WB;Određuje balans bele iz tačke (prečica: W) +TP_BWMIX_ALGO;OYCPM algoritam +TP_BWMIX_ALGO_LI;Linearno +TP_BWMIX_ALGO_SP;Specijalni efekti +TP_BWMIX_ALGO_TOOLTIP;Linearno: proizvodi normalni linearni odgovor.\nSpecijalni efekti: proizvodi specijalne efekte mešajući kanale nelinearno. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Izračunaj vrednosti tako da optimizuje mešanje kanala. +TP_BWMIX_BLUE;Plava +TP_BWMIX_CC_ENABLED;Podesi komplementarnu boju +TP_BWMIX_CC_TOOLTIP;Omogući za automatsko podešavanje komplementarne boje u ROYGCBPM režimu. +TP_BWMIX_CHANNEL;Ujednačavanje luminanse +TP_BWMIX_CURVEEDITOR1;„Pre“ krivulje +TP_BWMIX_CURVEEDITOR2;„Nakon“ krivulje +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Kriva tonova nakon CB prevođenja, na kraju tretmana. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Kriva tonova, tik pred CB prevođenje.\nMože da uzme u obzir i komponente boje. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminansa na osnovu nijanse L=f(H).\nObratite pažnju na ekstremne vrednosti pošto one mogu da naprave neželjene efekte. +TP_BWMIX_CYAN;Svetlo-plava +TP_BWMIX_FILTER;Filter boja +TP_BWMIX_FILTER_BLUE;Plava +TP_BWMIX_FILTER_BLUEGREEN;Plavo-zelena +TP_BWMIX_FILTER_GREEN;Zelena +TP_BWMIX_FILTER_GREENYELLOW;Zeleno-žuta +TP_BWMIX_FILTER_NONE;Ni jedna +TP_BWMIX_FILTER_PURPLE;Ljubičasta +TP_BWMIX_FILTER_RED;Crvena +TP_BWMIX_FILTER_REDYELLOW;Crveno-Žuta +TP_BWMIX_GREEN;Zelena +TP_BWMIX_LABEL;Crna i bela +TP_BWMIX_MAGENTA;Ljubičasta +TP_BWMIX_MET;Način +TP_BWMIX_MET_CHANMIX;Mešanje kanala +TP_BWMIX_MET_DESAT;Uklanjanje boje +TP_BWMIX_MET_LUMEQUAL;Ujednačavanje luminanse +TP_BWMIX_MIXC;Mešanje +TP_BWMIX_NEUTRAL;Vrati mešanje +TP_BWMIX_NEUTRAL_TIP;Vrati sve vrednsoti (filter boje, mešanje kanala) na podrazumevane. +TP_BWMIX_ORANGE;Narandžasta +TP_BWMIX_PURPLE;Ljubičasta +TP_BWMIX_RED;Crvena +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Ukupno: %4%% +TP_BWMIX_RGBLABEL_HINT;Konačni RGB faktori koji se brinu o opcijama za mešanje.\n„Ukupno“ prikazuje zbir RGB vrednosti:\n- u 100% u relativnom režimu\n- više (svetlije) ili manje (tamnije) od 100% u apsolutnom režimu. +TP_BWMIX_RGB_TOOLTIP;Mešanje RGB kanala. Koristite postojeće prepodešene parametre kao vodilju.\nObratite pažnju na negativne vrednsti koje mogu da naprave greške unutar slike ili izazovu nepravilno ponašanje. +TP_BWMIX_SETTING;Prepodešeno +TP_BWMIX_SETTING_TOOLTIP;Različite podešene vrednosti (film, pejzaž i dr.) ili ručno podešene vrednosti mešanja kanala. +TP_BWMIX_SET_HIGHCONTAST;Veliki kontrast +TP_BWMIX_SET_HIGHSENSIT;Velika osetljivost +TP_BWMIX_SET_HYPERPANCHRO;Jako panhromatski +TP_BWMIX_SET_INFRARED;Infracrveno +TP_BWMIX_SET_LANDSCAPE;Pejzaž +TP_BWMIX_SET_LOWSENSIT;Niska osetljivost +TP_BWMIX_SET_LUMINANCE;Luminansa +TP_BWMIX_SET_NORMCONTAST;Normalni kontrast +TP_BWMIX_SET_ORTHOCHRO;Ortohromatski +TP_BWMIX_SET_PANCHRO;Panhromatski +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;Apsolutni RGB mešanja kanala +TP_BWMIX_SET_RGBREL;Relativni RGB mešanja kanala +TP_BWMIX_SET_ROYGCBPMABS;Apsolutni ROYGCBPM mešanja kanala +TP_BWMIX_SET_ROYGCBPMREL;Relativni ROYGCBPM mešanja kanala +TP_BWMIX_TCMODE_FILMLIKE;Crno-belo, nalik filmu +TP_BWMIX_TCMODE_SATANDVALBLENDING;Crno-beli, stapanje zasićenosti i vrednosti +TP_BWMIX_TCMODE_STANDARD;Crno-beli, uobičajeni +TP_BWMIX_TCMODE_WEIGHTEDSTD;Crno-beli, mereni standard +TP_BWMIX_VAL;L +TP_BWMIX_YELLOW;Žuta TP_CACORRECTION_BLUE;Plava TP_CACORRECTION_LABEL;Hromatke aberacije TP_CACORRECTION_RED;Crvena @@ -605,13 +959,109 @@ TP_CHMIXER_GREEN;Zelena TP_CHMIXER_LABEL;Mešanje kanala TP_CHMIXER_RED;Crvena TP_CHROMATABERR_LABEL;Hromatske aberacije +TP_COARSETRAF_DEGREE;stepeni: TP_COARSETRAF_TOOLTIP_HFLIP;Izvrće sliku horizontalno TP_COARSETRAF_TOOLTIP_ROTLEFT;Okreće sliku ulevo TP_COARSETRAF_TOOLTIP_ROTRIGHT;Okreće sliku udesno TP_COARSETRAF_TOOLTIP_VFLIP;Izvrće sliku vertikalno +TP_COLORAPP_ADAPTSCENE;Luminoznost scene +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Aposolutna luminoznost okruženja scene (cd/m²).\n1) Računa se iz Exif podataka:\nBrzina zatvarača - ISO vrednost - otvor blende - korekcija ekspozicije kamere.\n2) Računa se iz bele tačke sirove slike unutar dela programa za kompenzaciju ekspozicije. +TP_COLORAPP_ADAPTVIEWING;Luminoznost za pregled (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Apsolutna luminoznost okruženja za pregled\n(obično 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Ukoliko je štiklirano (preporučeno), program računa optimalne vrednosti na osnovu Exif podataka.\nZa ručno postavljanje ovih vrednosti, odštiklirajte ovo polje. +TP_COLORAPP_ALGO;Algoritam +TP_COLORAPP_ALGO_ALL;Sve +TP_COLORAPP_ALGO_JC;Svetlina + Boja (JC) +TP_COLORAPP_ALGO_JS;Svetlina + Hrominansa (JS) +TP_COLORAPP_ALGO_QM;Osvetljenost + Živost boja (QM) +TP_COLORAPP_ALGO_TOOLTIP;Omogućava izbor između podskupa parametara ili svih parametara. +TP_COLORAPP_BADPIXSL;Filter vrućih/loših piksela +TP_COLORAPP_BADPIXSL_TOOLTIP;Potiskivanje vrućih/loših (presvetlo obojenih) piksela.\n0 = bez efekta\n1 = medijan\n2 = gauzijan.\n\nOve greške se javljaju usled CIECAM02 ograničenja. Drugi način za izbegavanje grešaka je da podesite sliku tako da izbegnete veoma tamne senke. +TP_COLORAPP_BRIGHT;Osvetljenost (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Osvetljenost u CIECAM02 sistemu uzima u obzir luminansu bele i razlikuje se u odnosu na Lab i RGB osvetljenost. +TP_COLORAPP_CHROMA;Hroma (C) +TP_COLORAPP_CHROMA_M;Živost boja (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Živost boja u CIECAM02 sistemu se razlikuje u odnosu na Lab i RGB osvetljenost. +TP_COLORAPP_CHROMA_S;Zasićenost (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Zasićenost u CIECAM02 sistemu se razlikuje u odnosu na Lab i RGB osvetljenost. +TP_COLORAPP_CHROMA_TOOLTIP;Hroma u CIECAM02 sistemu se razlikuje u odnosu na Lab i RGB osvetljenost. +TP_COLORAPP_CIECAT_DEGREE;prilagođavanje za CAT02 +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast u CIECAM02 sistemu za Q klizač; razlikuje se od Lab i RGB kontrasta. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast u CIECAM02 sistemu za J klizač; razlikuje se od Lab i RGB kontrasta. +TP_COLORAPP_CURVEEDITOR1;Kriva tonova 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Prikazuje histogram za L (Lab) pre CIECAM02.\nUkoliko je omogućeno „CIECAM02 izlazni histogram u krivuljama“, prikazujer histogram za J ili Q nakon CIECAM02.\n\nJ i Q se ne prikazuju u glavnoj površi histograma.\n\nZa konaačni izla pogledajte glavnu površ histograma. +TP_COLORAPP_CURVEEDITOR2;Kriva tonova 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Koristi se na isti način kao i druga kriva tonova ekspozicije. +TP_COLORAPP_CURVEEDITOR3;Kriva boja +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Podešava bilo hromu, zasićenost ili živost boja.\n\nPrikazuje histogram hromatise (Lab) pre CIECAM02.\nUkoliko je omogućeno „CIECAM02 izlazni histogram u krivuljama“, prikazuje histogram za C, s ili M nakon CIECAM02.\n\nC, s i M se ne prikazuju u glavnoj površi za histogram.\nZa konaačni izla pogledajte glavnu površ histograma. +TP_COLORAPP_DATACIE;CIECAM02 izlazni histogram u krivuljama +TP_COLORAPP_DATACIE_TOOLTIP;Kada je omogućeno, histogrami u CIECAM02 krivim prikazuju približne vrednosti/opsege za J ili Q, i C, s ili M nakon CIECAM02 podešavanja.\nOvaj izbor ne utiče na prikaz u glavnoj površi za histogram.\n\nKada je isključeno, histogrami u CIECAM02 krivim prikazuju Lab vrednosti pre CIECAM02 podešavanja. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Ukoliko je štiklirano (preporučeno), program račina optimalne vrednosti, koje se zatim koriste za CAT02, a takođe za čitav CIECAM02.\nDa bi postavili vrednosti ručne, odštiklirajte ovo polje (preporučene su vrednosti iznad 65). +TP_COLORAPP_DEGREE_TOOLTIP;Količina preobražaja CIE hromatske adaptacije2002. +TP_COLORAPP_GAMUT;Kontrola gamuta (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Omogućava kontrolu gamuta u Lab režimu. +TP_COLORAPP_HUE;Nijansa (h) +TP_COLORAPP_HUE_TOOLTIP;Nijansa (h) - ugao između 0° i 360°. +TP_COLORAPP_LABEL;CIECAM 2002 model izgleda boja +TP_COLORAPP_LABEL_CAM02;Podešavanja slike +TP_COLORAPP_LABEL_SCENE;Uslovi scene +TP_COLORAPP_LABEL_VIEWING;Uslovi za pregled +TP_COLORAPP_LIGHT;Svetlina (J) +TP_COLORAPP_LIGHT_TOOLTIP;Svetlina u CIECAM02 se razlikuje od Lab ili RGB svetline. +TP_COLORAPP_MODEL;WP model +TP_COLORAPP_MODEL_TOOLTIP;Model bele-tačke.\n\nBalans bele [RT] + [izlaz]: balans bele iz programa se koristi za kadar, CIECAM02 se postavlja na D50, a balans bele izlaznog uređaja se određuje iz Podešavanja > Upravljanje bojama.\n\nBalans bele [RT+CAT02] + [izlaz]: podešavanja balansa bele iz programa se koriste od strane CAT02, a balans bele izlaznog uređaja se određuje iz Podešavanja - Upravljanje bojama. +TP_COLORAPP_RSTPRO;Zaštita crvene i boje kože +TP_COLORAPP_RSTPRO_TOOLTIP;Zaštita crvene boje i boje kože (klizači i krive). +TP_COLORAPP_SHARPCIE;--ne koristi se-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--ne koristi se-- +TP_COLORAPP_SURROUND;Okruženo +TP_COLORAPP_SURROUND_AVER;Prosečno +TP_COLORAPP_SURROUND_DARK;Tamno +TP_COLORAPP_SURROUND_DIM;Zatamnjeno +TP_COLORAPP_SURROUND_EXDARK;Jako tamno +TP_COLORAPP_SURROUND_TOOLTIP;Menja tonove i boje kako bi se prilagodilo uslovima uređaja za prikaz.\n\nProsečno: Prosečno osvetljeno okruženje (uobičajeno). Slika neće biti izmenjena.\n\nZatamnjeno: Zatamnjeno okruženje (TV). Slika će postati za nijansu tamnija.\n\nTamno: Tamno okruženje (projektor). Slika će postati još više tamna.\n\nJako tamno: Ekstramno tamno okruženje (cutsheet). Slika će postati izuzetno tamna. +TP_COLORAPP_SURSOURCE;Tamno okruženje +TP_COLORAPP_SURSOURCE_TOOLTIP;Može da se koristi ukoliko slika ima tamne ivice. +TP_COLORAPP_TCMODE_BRIGHTNESS;Osvtljenost +TP_COLORAPP_TCMODE_CHROMA;Hroma +TP_COLORAPP_TCMODE_COLORF;Živost boja +TP_COLORAPP_TCMODE_LABEL1;Režim krive 1 +TP_COLORAPP_TCMODE_LABEL2;Režim krive 2 +TP_COLORAPP_TCMODE_LABEL3;Kriva u hrom režimu +TP_COLORAPP_TCMODE_LIGHTNESS;Svetlina +TP_COLORAPP_TCMODE_SATUR;Zasićenost +TP_COLORAPP_TONECIE;Mapiranje tonova u CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Ukoliko je isključena ova opcija, mapiranje tonova se vrši u Lab okruženju.\nUkoliko je uključena, mapiranje se vrši pomoću CIECAM02.\nMorate koristiti alat za mapiranje tonova kako bi ova opcija bila primenjena. +TP_COLORAPP_WBCAM;Balans bele [RT+CAT02] + [izlaz] +TP_COLORAPP_WBRT;Balans bele [RT] + [izlaz] +TP_COLORBOOST_ACHANNEL;Kanal „a“ +TP_COLORBOOST_AMOUNT;Količina +TP_COLORBOOST_AVOIDCOLORCLIP;Izbegni odsecanje boja +TP_COLORBOOST_BCHANNEL;Kanal „b“ +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;razdvoji +TP_COLORBOOST_ENABLESATLIMITER;Omogući ograničenje zasićenosti +TP_COLORBOOST_LABEL;Pojačanje boja +TP_COLORBOOST_SATLIMIT;Granica za zasićenost +TP_COLORDENOISE_EDGESENSITIVE;Osetljivo na ivice +TP_COLORDENOISE_EDGETOLERANCE;Tolerancija ivice +TP_COLORDENOISE_LABEL;Uklaljanje kolornog šuma +TP_COLORDENOISE_RADIUS;Poluprečnik +TP_COLORSHIFT_BLUEYELLOW;Plava-Žuta +TP_COLORSHIFT_GREENMAGENTA;Zelena-Ljubičasta +TP_COLORSHIFT_LABEL;Pomeranje boja +TP_CROP_DPI;TPI= TP_CROP_FIXRATIO;Srazmerno: TP_CROP_GTDIAGONALS;Pravilo dijagonala +TP_CROP_GTEPASSPORT;Biometrijski pasoš +TP_CROP_GTFRAME;Okvir TP_CROP_GTGRID;Mreža +TP_CROP_GTHARMMEANS1;Zlatni presek 1 +TP_CROP_GTHARMMEANS2;Zlatni presek 2 +TP_CROP_GTHARMMEANS3;Zlatni presek 3 +TP_CROP_GTHARMMEANS4;Zlatni presek 4 TP_CROP_GTNONE;Ništa TP_CROP_GTRULETHIRDS;Pravilo trećina TP_CROP_GUIDETYPE;Vođice: @@ -627,10 +1077,22 @@ TP_DARKFRAME_LABEL;Tamni kadar TP_DEFRINGE_LABEL;Uklaljanje oreola TP_DEFRINGE_RADIUS;Poluprečnik TP_DEFRINGE_THRESHOLD;Prag +TP_DETAIL_AMOUNT;Količina +TP_DIRPYRDENOISE_BLUE;Hrominansa: Plava-Žuta TP_DIRPYRDENOISE_CHROMA;Boja +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Može se upotrebiti za raw ili ne-raw slike.\n\nZa slike koje nisu u raw formatu uklanjanje šuma luminanse zavisi od game ulaznog profila boja. Podrazumeva se upotreba sRGB profila, pa će efekat uklanjanja šuma luminanse biti različit ukoliko se koristi profil boja sa drugom vrednošću game. +TP_DIRPYRDENOISE_ENH;Poboljšani režim +TP_DIRPYRDENOISE_ENH_TOOLTIP;Povećava kvalitet uklanjanja šuma na uštrb oko 20% vremena za obradu. TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gama utiče na jačinu uklanjanja šuma preko opseg tonova. Manja vrednost će uticati na senke, veća će povećati ovaj efekat i na svetlije tonove. TP_DIRPYRDENOISE_LABEL;Direkciono piramidno uklanjanje šuma +TP_DIRPYRDENOISE_LDETAIL;Detalji luminanse TP_DIRPYRDENOISE_LUMA;Luminansa +TP_DIRPYRDENOISE_METHOD;Način +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Za rav slike možete koristiti RGB ili Lab režime.\n\nZa ostale slike se koristi Lab, bez obzira na izbor. +TP_DIRPYRDENOISE_PERF;RGB režim (raw slike) +TP_DIRPYRDENOISE_RED;Hrominansa - crvena-zelena +TP_DIRPYRDENOISE_RGB;RGB TP_DIRPYREQUALIZER_LABEL;Detaljni nivo kontrasta TP_DIRPYREQUALIZER_LUMACOARSEST;grubo TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- @@ -642,18 +1104,43 @@ TP_DISTORTION_AMOUNT;Količina TP_DISTORTION_AUTO;Sam ispravi izobličenja TP_DISTORTION_AUTO_TIP;(Eksperimentalno) Automatski ispravlja izobličenja nekih aparata (M4/3, neki kompakti, i dr.) TP_DISTORTION_LABEL;Izobličenja +TP_EPD_EDGESTOPPING;Izoštravanje ivice +TP_EPD_LABEL;Mapiranje tonova +TP_EPD_REWEIGHTINGITERATES;Broj ponovnih merenja +TP_EPD_SCALE;Razmera +TP_EPD_STRENGTH;Jačina +TP_EPD_TOOLTIP;Mapiranje tonova je moguće u Lab (standardnom) ili CIECAM02 režimu.\n\nZa rad u CIECAM02 režimu uključite:\n1. CIECAM02\n2. Algoritam="Osvetljenje + živopisnost (QM)"\n3. "Mapiranje tonova u CIECAM02 osvetljenju (Q)" +TP_EQUALIZER_CONTRAST_MINUS;Kontrast - +TP_EQUALIZER_CONTRAST_PLUS;Kontrast + +TP_EQUALIZER_FINEST;najfinije +TP_EQUALIZER_LABEL;Talasno ujednačenje +TP_EQUALIZER_LARGEST;najgrublje +TP_EQUALIZER_NEUTRAL;Neutralno +TP_EXPOSCORR_LABEL;Raw bela tačka TP_EXPOSURE_AUTOLEVELS;Auto-nivoi +TP_EXPOSURE_AUTOLEVELS_TIP;Omogućava automatsko određivanje nivoa, koji podešava klizače ekspozicije na osnovu podatka o samoj slici.\nUključuje čupanje svetlih delova ukoliko je neophodno. TP_EXPOSURE_BLACKLEVEL;Crna TP_EXPOSURE_BRIGHTNESS;Osvetljenost TP_EXPOSURE_CLIP;Odseci +TP_EXPOSURE_CLIP_TIP;Deo piksela koje će biti odsečeni primenom automatskih nivoa. TP_EXPOSURE_COMPRHIGHLIGHTS;Sabijanje svetlog TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Prag za čupanje svetlih delova TP_EXPOSURE_COMPRSHADOWS;Sabijanje senki TP_EXPOSURE_CONTRAST;Kontrast TP_EXPOSURE_CURVEEDITOR;Kriva nijansi +TP_EXPOSURE_CURVEEDITOR1;Kriva tonova 1 +TP_EXPOSURE_CURVEEDITOR2;Kriva tonova 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Pogledajte „Ekspozicija > Krive tonova“ unutar članka na sajtu RawPedia kako bi naučili kako se postižu najbolji rezučtati uspotrebom dve krive tonova. TP_EXPOSURE_EXPCOMP;Kompenzacija TP_EXPOSURE_LABEL;Ekspozicija TP_EXPOSURE_SATURATION;Zasićenost +TP_EXPOSURE_TCMODE_FILMLIKE;Nalik foto-filmu +TP_EXPOSURE_TCMODE_LABEL1;1. režim krive +TP_EXPOSURE_TCMODE_LABEL2;2. režim krive +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Utapanje zasićenosti i vrednosti +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Uravnoteženi standard +TP_EXPO_AFTER; Pre interpolacije (pre prevoda u RGB) TP_FLATFIELD_AUTOSELECT;Sam izaberi TP_FLATFIELD_BLURRADIUS;Poluprečnik zamućenja TP_FLATFIELD_BLURTYPE;Zamuti @@ -662,63 +1149,178 @@ TP_FLATFIELD_BT_HORIZONTAL;Horizontalno TP_FLATFIELD_BT_VERTHORIZ;Horiz. i vertik. TP_FLATFIELD_BT_VERTICAL;Vertikalno TP_FLATFIELD_LABEL;Ravno polje +TP_GAMMA_COMMENT;(onemogućen je izlazni profil, osim „default“) +TP_GAMMA_CURV;Gama TP_GAMMA_FREE;Gama sloboda TP_GAMMA_OUTPUT;Izlazna gama TP_GAMMA_SLOP;nagib (linearni) +TP_GENERAL_11SCALE_TOOLTIP;Efekt ovog alata ili njegovih opcija se vidi samo u razmeri 1:1. +TP_GRADIENT_CENTER;Centar +TP_GRADIENT_CENTER_X;Centar X +TP_GRADIENT_CENTER_X_TOOLTIP;Pomera gradijent ulevo (negativne vrednosti) ili udesno (pozitivne vrednosti). +TP_GRADIENT_CENTER_Y;Centar Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Pomera gradijent na gore (negativne vrednosti) ili na dole (pozitivne vrednosti). +TP_GRADIENT_DEGREE;Ugao +TP_GRADIENT_DEGREE_TOOLTIP;Okreće ugao gradijenta za odabrani broj stepeni. +TP_GRADIENT_FEATHER;Umekšavanje +TP_GRADIENT_FEATHER_TOOLTIP;Širina gradijenta u procentima dijagonale slike. +TP_GRADIENT_LABEL;Filter gradijenta +TP_GRADIENT_STRENGTH;Jačina +TP_GRADIENT_STRENGTH_TOOLTIP;Jačina filtera u broju tačaka prekida. TP_HLREC_BLEND;Utapanje TP_HLREC_CIELAB;CieLab stapanje TP_HLREC_COLOR;Propaginacija boje +TP_HLREC_ENA_TOOLTIP;Može se aktivirati opcijom „Auto-nivoi“. TP_HLREC_LABEL;Čupanje svetlih delova TP_HLREC_LUMINANCE;Izvlačenje luminanse TP_HLREC_METHOD;Način: +TP_HSVEQUALIZER1;Crvena +TP_HSVEQUALIZER2;Žuta +TP_HSVEQUALIZER3;Limun +TP_HSVEQUALIZER4;Zelena +TP_HSVEQUALIZER5;Vodena +TP_HSVEQUALIZER6;Plava +TP_HSVEQUALIZER7;Ljubičasta +TP_HSVEQUALIZER8;Magneta TP_HSVEQUALIZER_CHANNEL;HSV kanal TP_HSVEQUALIZER_HUE;Nijansa TP_HSVEQUALIZER_LABEL;Ujednačenje HSV kanala TP_HSVEQUALIZER_SAT;Zasićenost TP_HSVEQUALIZER_VAL;Vrednost TP_ICM_BLENDCMSMATRIX;Utopi svetle delove u matricu +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Omogućite kako bi povratili preosvetljene delove ukoliko koristite LUT ICC profile. +TP_ICM_DCPILLUMINANT;Iluminantno +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolirano +TP_ICM_FILEDLGFILTERANY;Bilo koja datoteka +TP_ICM_FILEDLGFILTERICM;ICC profili +TP_ICM_GAMMABEFOREINPUT;Profil za primenu Game TP_ICM_INPUTCAMERA;Podrazumevano iz aparata TP_ICM_INPUTCAMERAICC;Foto-aparat ili standardni ICC +TP_ICM_INPUTCAMERA_TOOLTIP;Koristi prostu matricu boja iz programa dcraw, unapređenu RawTherapee verziju (koja god da je dostupna za vaš model foto-aparata) ili neki od ugrađenih DNG profila. TP_ICM_INPUTCUSTOM;Proizvoljno +TP_ICM_INPUTCUSTOM_TOOLTIP;Izaberite željeni DCP/ICC profil boja za foto-aparat. TP_ICM_INPUTDLGLABEL;Izaberite ulazni ICC profil... TP_ICM_INPUTEMBEDDED;Ugnježđeno, ukoliko je moguće +TP_ICM_INPUTEMBEDDED_TOOLTIP;Koristi profil boja koji je ugrađen u ne-raw datoteke. TP_ICM_INPUTNONE;Nema profila +TP_ICM_INPUTNONE_TOOLTIP;Uopšte ne koristi ulazni profil boja.\nPrimenjuje se samo u posebnim okolnostima. TP_ICM_INPUTPROFILE;Ulazni profil TP_ICM_LABEL;ICM TP_ICM_NOICM;No ICM: sRGB izlaz TP_ICM_OUTPUTPROFILE;Izlazni profil TP_ICM_SAVEREFERENCE;Sačuvaj sliku kao referencu za profil +TP_ICM_SAVEREFERENCE_TOOLTIP;Sačuvaj linearnu TIFF sliku pre primene ulaznog profila. Rezultat može da se koristi za kalibraciju i izradu profila foto-aparata. +TP_ICM_TONECURVE;Koristi DCP krivu tonova +TP_ICM_TONECURVE_TOOLTIP;Upotrebljava ugrađenu DCP krivu tonova. Ovo podešavanje je omogućeno samo ako izabrani DCP ima krivu tonova. TP_ICM_WORKINGPROFILE;Radni profil TP_IMPULSEDENOISE_LABEL;Impulsno uklanjanje šuma TP_IMPULSEDENOISE_THRESH;Prag +TP_LABCURVE_AVOIDCOLORCLIP;Onemogući odsecanje boje +TP_LABCURVE_AVOIDCOLORSHIFT;Izbegni pomeranje boja +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Postavlja boje u opseg trenutnog radnog prostora boja i primenjuje Munselovu korekciju. TP_LABCURVE_BRIGHTNESS;Osvetljenost +TP_LABCURVE_CHROMATICITY;Boje +TP_LABCURVE_CHROMA_TOOLTIP;To apply CB toning, set Chromaticity to -100. TP_LABCURVE_CONTRAST;Kontrast TP_LABCURVE_CURVEEDITOR;Kriva svetlosti +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Zasićena zelena +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Pastelna zelena +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Pastelna crvena +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Zasićena crvena +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Zasićena plava +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Pastelna plava +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Pastelna žuta +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Zasićena žuta +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutralno +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Isprano +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastelno +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Zasićeno +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Boja kao funkcija boje C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Boja kao funkcija nijanse C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Hrominansa na osnovu luminanse C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Nijansa kao funkcija nijanse H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Svetnost kao funkcija boje L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Svetlost kao funkcija nijanse L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Svetlost kao funkcija svetlosti L=f(L) +TP_LABCURVE_ENABLESATLIMITER;Uključi graničnik zasićenosti TP_LABCURVE_LABEL;Lab kriva +TP_LABCURVE_LCREDSK;Ograniči LC na crvenu i boju kože +TP_LABCURVE_LCREDSK_TIP;Ukoliko je uključeno, LC kriva će uticati samo na crvenu i boju kože.\nU suprotnom se primenjuje na sve tonove. +TP_LABCURVE_RSTPROTECTION;Zaštita crvene i boje kože +TP_LABCURVE_RSTPRO_TOOLTIP;Može se koristiti sa klizačem za Hrominansu i CC krivom. +TP_LABCURVE_SATLIMIT;Graničnik zasićenosti +TP_LABCURVE_SATURATION;Zasićenost TP_LENSGEOM_AUTOCROP;Sam iseci TP_LENSGEOM_FILL;Sam popuni TP_LENSGEOM_LABEL;Objektiv i geometrija +TP_LENSPROFILE_FILEDLGFILTERLCP;Fajlovi sa izobličenjima objektiva +TP_LENSPROFILE_LABEL;Profili za ispravljanje izobličenja objektiva +TP_LENSPROFILE_USECA;Ispravljanje hrom. aberacija +TP_LENSPROFILE_USEDIST;Ispravljanje izobličenja +TP_LENSPROFILE_USEVIGN;Ispravljanje vinjetarenja +TP_LUMACURVE_BLACKLEVEL;Crna +TP_LUMACURVE_BRIGHTNESS;Osvetljenje +TP_LUMACURVE_COMPRHIGHLIGHTS;Sabijanje svetlog +TP_LUMACURVE_COMPRSHADOWS;Sabijanje senki +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Kriva liminanse +TP_LUMACURVE_LABEL;Kriva luminanse +TP_NEUTRAL;Neutralno +TP_NEUTRAL_TIP;Vraća klizače ekspozicije na neutralne vrednosti.\nPrimenjuje se na iste kontrole kao u Auto nivoi, bez obzira na to da li ste koristili Auto nivoe ili ne. +TP_PCVIGNETTE_FEATHER;Umekšavanje +TP_PCVIGNETTE_FEATHER_TOOLTIP;Umekšavanje:\n0 = samo uglove,\n50 = na polovinu od centra,\n100 = centar. +TP_PCVIGNETTE_LABEL;Filter vinjetarenja +TP_PCVIGNETTE_ROUNDNESS;Zaokrugljenost +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Zaokrugljenost:\n0 = kvadrat,\n50 = prelaz od kvadrata ka krugu,\n100 = krug. +TP_PCVIGNETTE_STRENGTH;Jačina +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Jačina filtera u prekidima (koji se dostižu na uglovima). TP_PERSPECTIVE_HORIZONTAL;Horizontalna TP_PERSPECTIVE_LABEL;Perspektiva TP_PERSPECTIVE_VERTICAL;Vertikalna +TP_PFCURVE_CURVEEDITOR_CH;Nijansa +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Određuje jačinu uklaljanja boje.\nVišlje = više,\nNiže = manje. TP_PREPROCESS_GREENEQUIL;Kalibracija zelene boje +TP_PREPROCESS_HOTDEADPIXFILT;Izbaci pregorele i mrtve piksele +TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Pokušava da ukloni vruće i mrtve piksele. TP_PREPROCESS_LABEL;Predobrada TP_PREPROCESS_LINEDENOISE;Linijski filter šuma TP_PREPROCESS_NO_FOUND;Nije pronađeno TP_RAWCACORR_AUTO;Ispravi hromatske aberacije TP_RAWCACORR_CABLUE;Plava TP_RAWCACORR_CARED;Crvena +TP_RAWEXPOS_BLACKONE;Nivo crne: Crvena TP_RAWEXPOS_BLACKS;Nivo crne +TP_RAWEXPOS_BLACKTHREE;Nivo crne: Zelena 2 +TP_RAWEXPOS_BLACKTWO;Nivo crne: Plava +TP_RAWEXPOS_BLACKZERO;Nivo crne: Zelena 1 (vodeća) TP_RAWEXPOS_LINEAR;Linearni faktor korekcije TP_RAWEXPOS_PRESER;Očuvanje svetlih delova TP_RAWEXPOS_TWOGREEN;Obe zelene +TP_RAW_ALLENHANCE;Ukloni artafakte/šum nakon rasklapanja TP_RAW_DCBENHANCE;Primeni DCB poboljšanje TP_RAW_DCBITERATIONS;Broj DCB prolaza TP_RAW_DMETHOD;Način +TP_RAW_DMETHOD_PROGRESSBAR;%1 rasklapam mozaik... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Poboljšavam mozaik... +TP_RAW_DMETHOD_TOOLTIP;Primedba: IGV i LMMSE služe kod velikih ISO vrednosti slike i služe za ispomoć pri uklanjanje šuma kako ne bi došlo do efekta posterizacije ili ispranog izlgeda. TP_RAW_FALSECOLOR;Koraci za prigušivanje lažne boje TP_RAW_LABEL;Rasklapanje mozaika +TP_RAW_LMMSEITERATIONS;Koraci LMMSE poboljšanja +TP_RAW_LMMSE_TOOLTIP;Dodaje gamu (korak 1), medijan (koraci 2-4) i poboljšanja (koraci 5-6) kako bi smanjio neispravnosti i poboljšao odnos signal-prema-šum. TP_RESIZE_APPLIESTO;Primeni na: +TP_RESIZE_BICUBIC;Bikubično +TP_RESIZE_BICUBICSF;Bikubično (mekše) +TP_RESIZE_BICUBICSH;Bikubično (oštrije) +TP_RESIZE_BILINEAR;Bilinearno TP_RESIZE_CROPPEDAREA;Isečenu oblast +TP_RESIZE_DOWNSCALEB;Smanjenje razmere (bolje) +TP_RESIZE_DOWNSCALEF;Smanjenje razmere (brže) TP_RESIZE_FITBOX;Širinu i visinu TP_RESIZE_FULLIMAGE;Celu sliku TP_RESIZE_H;V: @@ -731,15 +1333,26 @@ TP_RESIZE_SCALE;Umanjenje TP_RESIZE_SPECIFY;Izaberi: TP_RESIZE_W;Š: TP_RESIZE_WIDTH;Širinu +TP_RGBCURVES_BLUE;P +TP_RGBCURVES_CHANNEL;Kanal +TP_RGBCURVES_GREEN;Z +TP_RGBCURVES_LABEL;RGB krive +TP_RGBCURVES_LUMAMODE;Režim luminanse +TP_RGBCURVES_LUMAMODE_TOOLTIP;Režim liminanse omogućava da menjate udeo crvenog, zelenog i plavog kanala iz luminanse slike što ne utiče na promenu boje fotografije. +TP_RGBCURVES_RED;C +TP_ROTATE_AUTOCROP;Sam iseci TP_ROTATE_DEGREE;Stepeni: +TP_ROTATE_FILL;Popuni TP_ROTATE_LABEL;Rotacija TP_ROTATE_SELECTLINE; Postavi pravu liniju +TP_SAVEDIALOG_OK_TIP;Prečica: Ctrl-Enter TP_SHADOWSHLIGHTS_HIGHLIGHTS;Svetlo TP_SHADOWSHLIGHTS_HLTONALW;Širina tonova TP_SHADOWSHLIGHTS_LABEL;Senke/Svetlo TP_SHADOWSHLIGHTS_LOCALCONTR;Lokalni kontrast TP_SHADOWSHLIGHTS_RADIUS;Poluprečnik TP_SHADOWSHLIGHTS_SHADOWS;Senke +TP_SHADOWSHLIGHTS_SHARPMASK;Oštra maska TP_SHADOWSHLIGHTS_SHTONALW;Širina tonova TP_SHARPENEDGE_AMOUNT;Količina TP_SHARPENEDGE_LABEL;Ivice @@ -759,11 +1372,29 @@ TP_SHARPENING_RLD_AMOUNT;Količina TP_SHARPENING_RLD_DAMPING;Prigušivanje TP_SHARPENING_RLD_ITERATIONS;Ponavljanja TP_SHARPENING_THRESHOLD;Prag +TP_SHARPENING_TOOLTIP;Očekujte nešto drugačiji efekat kada koristite CIECAM02. Ukoliko primetite razlike, podesite ih po svom ukusu. TP_SHARPENING_USM;Oštrina maske TP_SHARPENMICRO_AMOUNT;Količina TP_SHARPENMICRO_LABEL;Mikrokonttrast TP_SHARPENMICRO_MATRIX;3×3 matrica umesto 5×5 TP_SHARPENMICRO_UNIFORMITY;Ujednačenost +TP_VIBRANCE_AVOIDCOLORSHIFT;Izbegni pomeranje boja +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Boja kože +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Crvena/ljubičasta +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Crvena +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Crvena/žuta +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Žuta +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Nijansa na osnovu HUE H=f(H) +TP_VIBRANCE_LABEL;Živost boja +TP_VIBRANCE_PASTELS;Pastelne boje +TP_VIBRANCE_PASTSATTOG;Poveži zasićene i pastelne boje +TP_VIBRANCE_PROTECTSKINS;Očuvaj boju kože +TP_VIBRANCE_PSTHRESHOLD;Prag za pastelne/zasićene boje +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Prag za zasićene boje +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Vertikalna osa sadrži pastelne tonove pri dnu i zasićene tonove na vrhu.\nHorizontalna osa predstavlja opseg zasićenja. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Težina prelaza pastelnih/zasićenih boja +TP_VIBRANCE_SATURATED;Zasićene boje TP_VIGNETTING_AMOUNT;Količina TP_VIGNETTING_CENTER;Centar TP_VIGNETTING_CENTER_X;Centar X @@ -773,17 +1404,54 @@ TP_VIGNETTING_RADIUS;Poluprečnik TP_VIGNETTING_STRENGTH;Jačina TP_WBALANCE_AUTO;Sam odredi TP_WBALANCE_CAMERA;Iz aparata +TP_WBALANCE_CLOUDY;Oblačno vreme TP_WBALANCE_CUSTOM;Proizvoljno +TP_WBALANCE_DAYLIGHT;Dnevno svetlo (sunčano) +TP_WBALANCE_EQBLUERED;Balans crvene i plave +TP_WBALANCE_EQBLUERED_TOOLTIP;Dozvoljava nestandardno podešavanje balansa bele pomoću balansa plave i crvene boje.\nOvo je korisno kada:\na) slikate u nestandardnim uslovima svetla (npr. pod vodom),\nb) su uslovi daleko drugačiji od onih u kojima je izvršena kalibracija,\nv) su matrice ili ICC profili neodgovarajući. +TP_WBALANCE_FLASH55;Leika +TP_WBALANCE_FLASH60;Standardni, Kenon, Pentaks, Olimpus +TP_WBALANCE_FLASH65;Nikon, Panasonik, Soni, Minolta +TP_WBALANCE_FLASH_HEADER;Blic +TP_WBALANCE_FLUO1;F1 - Dnevno svetlo +TP_WBALANCE_FLUO2;F2 - Hladno svetlo +TP_WBALANCE_FLUO3;F3 - Belo svetlo +TP_WBALANCE_FLUO4;F4 - Toplo-belo svetlo +TP_WBALANCE_FLUO5;F5 - Dnevno svetlo +TP_WBALANCE_FLUO6;F6 - Svetlo-belo svetlo +TP_WBALANCE_FLUO7;F7 - D65 simulator dnevne svetlosti +TP_WBALANCE_FLUO8;F8 - D50 / Silvanija F40 dizajn +TP_WBALANCE_FLUO9;F9 - Hladna, deluks-bela +TP_WBALANCE_FLUO10;F10 - Filips TL85 +TP_WBALANCE_FLUO11;F11 - Filips TL84 +TP_WBALANCE_FLUO12;F12 - Filips TL83 +TP_WBALANCE_FLUO_HEADER;Neonsko svetlo TP_WBALANCE_GREEN;Zelenilo +TP_WBALANCE_GTI;GeTeI +TP_WBALANCE_HMI;HaEmI +TP_WBALANCE_JUDGEIII;DžudIII TP_WBALANCE_LABEL;Balans bele +TP_WBALANCE_LAMP_HEADER;Lampa +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED osvetljenje +TP_WBALANCE_LED_LSI;LSI Lumeleks 2040 TP_WBALANCE_METHOD;Način: +TP_WBALANCE_SHADE;U senci TP_WBALANCE_SIZE;Veličina: +TP_WBALANCE_SOLUX35;Soluks 3500K +TP_WBALANCE_SOLUX41;Soluks 4100K +TP_WBALANCE_SOLUX47;Soluks 4700K (proizvođač) +TP_WBALANCE_SOLUX47_NG;Soluks 4700K (Nac. galerija) TP_WBALANCE_SPOTWB;Iz tačke TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Obična sijalica +TP_WBALANCE_WATER1;Podvodna fotografija 1 +TP_WBALANCE_WATER2;Podvodna fotografija 2 +TP_WBALANCE_WATER_HEADER;Podvodna fotografija ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;Otvara novi prozor sa detaljima ZOOMPANEL_ZOOM100;Povećava pregled na 100% z -ZOOMPANEL_ZOOMFITSCREEN;Uklapa sliku u veličinu prozora f +ZOOMPANEL_ZOOMFITSCREEN;Uklapa sliku u veličinu prozora F ZOOMPANEL_ZOOMIN;Uvećava prikaz slike + ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - @@ -791,67 +1459,30 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!ABOUT_TAB_RELEASENOTES;Release Notes -!BATCHQUEUE_DESTFILENAME;Path and file name !CURVEEDITOR_AXIS_IN;I: !CURVEEDITOR_AXIS_LEFT_TAN;LT: !CURVEEDITOR_AXIS_OUT;O: !CURVEEDITOR_AXIS_RIGHT_TAN;RT: !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!DIRBROWSER_FOLDERS;Folders !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. -!EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) -!EXPORT_BYPASS_ALL;Select / Unselect All -!EXPORT_BYPASS_DEFRINGE;Bypass Defringe -!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction -!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels -!EXPORT_BYPASS_RAW_CA;Bypass [raw] Chromatic Aberration Correction -!EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Color Suppression -!EXPORT_BYPASS_RAW_DCB_ENHANCE;Bypass [raw] DCB Enhancement Steps -!EXPORT_BYPASS_RAW_DCB_ITERATIONS;Bypass [raw] DCB Iterations -!EXPORT_BYPASS_RAW_DF;Bypass [raw] Dark-Frame -!EXPORT_BYPASS_RAW_FF;Bypass [raw] Flat-Field -!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration -!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter -!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps -!EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening -!EXPORT_BYPASS_SHARPENING;Bypass Sharpening -!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast -!EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights -!EXPORT_FASTEXPORTOPTIONS;Fast Export Options -!EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters. -!EXPORT_MAXHEIGHT;Maximum height: -!EXPORT_MAXWIDTH;Maximum width: -!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export -!EXPORT_RAW_DMETHOD;Demosaic method -!EXTPROGTARGET_1;raw -!EXTPROGTARGET_2;queue-processed -!FILEBROWSER_COLORLABEL_TOOLTIP;Color label.\n\nUse dropdown menu or shortcuts:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Red\nShift-Ctrl-2 Yellow\nShift-Ctrl-3 Green\nShift-Ctrl-4 Blue\nShift-Ctrl-5 Purple -!FILEBROWSER_EXTPROGMENU;Open with -!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) !FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green !FILEBROWSER_POPUPCOLORLABEL4;Label: Blue !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple -!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) -!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPOPENINEDITOR;Open in Editor !FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** !FILEBROWSER_POPUPRANK4;Rank 4 **** !FILEBROWSER_POPUPRANK5;Rank 5 ***** -!FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 -!FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 -!FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 -!FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 -!FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -859,112 +1490,9 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image -!GENERAL_AUTO;Automatic -!GENERAL_CLOSE;Close -!GENERAL_WARNING;Warning -!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. -!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. -!HISTORY_MSG_151;Vibrance -!HISTORY_MSG_152;Vib - Pastel tones -!HISTORY_MSG_153;Vib - Saturated tones -!HISTORY_MSG_154;Vib - Protect skin-tones -!HISTORY_MSG_155;Vib - Avoid color shift -!HISTORY_MSG_156;Vib - Link pastel/saturated -!HISTORY_MSG_157;Vib - P/S threshold -!HISTORY_MSG_158;TM - Strength -!HISTORY_MSG_159;TM - Edge stopping -!HISTORY_MSG_160;TM - Scale -!HISTORY_MSG_161;TM - Reweighting iterates -!HISTORY_MSG_162;Tone Mapping -!HISTORY_MSG_163;RGB Curves - Red -!HISTORY_MSG_164;RGB Curves - Green -!HISTORY_MSG_165;RGB Curves - Blue -!HISTORY_MSG_166;Exposure - Reset -!HISTORY_MSG_167;Demosaicing method -!HISTORY_MSG_168;L*a*b* - CC curve -!HISTORY_MSG_169;L*a*b* - CH curve -!HISTORY_MSG_170;Vibrance - HH curve -!HISTORY_MSG_171;L*a*b* - LC curve -!HISTORY_MSG_172;L*a*b* - Restrict LC -!HISTORY_MSG_173;NR - Luminance detail -!HISTORY_MSG_174;CIECAM02 -!HISTORY_MSG_175;CAM02 - CAT02 adaptation -!HISTORY_MSG_176;CAM02 - Viewing surround -!HISTORY_MSG_177;CAM02 - Scene luminosity -!HISTORY_MSG_178;CAM02 - Viewing luminosity -!HISTORY_MSG_179;CAM02 - White-point model -!HISTORY_MSG_180;CAM02 - Lightness (J) -!HISTORY_MSG_181;CAM02 - Chroma (C) -!HISTORY_MSG_182;CAM02 - Automatic CAT02 -!HISTORY_MSG_183;CAM02 - Contrast (J) -!HISTORY_MSG_184;CAM02 - Scene surround -!HISTORY_MSG_185;CAM02 - Gamut control -!HISTORY_MSG_186;CAM02 - Algorithm -!HISTORY_MSG_187;CAM02 - Red/skin prot. -!HISTORY_MSG_188;CAM02 - Brightness (Q) -!HISTORY_MSG_189;CAM02 - Contrast (Q) -!HISTORY_MSG_190;CAM02 - Saturation (S) -!HISTORY_MSG_191;CAM02 - Colorfulness (M) -!HISTORY_MSG_192;CAM02 - Hue (h) -!HISTORY_MSG_193;CAM02 - Tone curve 1 -!HISTORY_MSG_194;CAM02 - Tone curve 2 -!HISTORY_MSG_195;CAM02 - Tone curve 1 -!HISTORY_MSG_196;CAM02 - Tone curve 2 -!HISTORY_MSG_197;CAM02 - Color curve -!HISTORY_MSG_198;CAM02 - Color curve -!HISTORY_MSG_199;CAM02 - Output histograms -!HISTORY_MSG_200;CAM02 - Tone mapping -!HISTORY_MSG_201;NR - Chrominance - R&G -!HISTORY_MSG_202;NR - Chrominance - B&Y -!HISTORY_MSG_203;NR - Method -!HISTORY_MSG_204;LMMSE enhancement steps -!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter -!HISTORY_MSG_206;CAT02 - Auto scene luminosity -!HISTORY_MSG_207;Defringe - Hue curve -!HISTORY_MSG_208;WB - B/R equalizer -!HISTORY_MSG_210;GF - Angle -!HISTORY_MSG_211;Graduated Filter -!HISTORY_MSG_212;VF - Strength -!HISTORY_MSG_213;Vignette Filter -!HISTORY_MSG_214;Black-and-White -!HISTORY_MSG_215;B&W - CM - Red -!HISTORY_MSG_216;B&W - CM - Green -!HISTORY_MSG_217;B&W - CM - Blue -!HISTORY_MSG_218;B&W - Gamma - Red -!HISTORY_MSG_219;B&W - Gamma - Green -!HISTORY_MSG_220;B&W - Gamma - Blue -!HISTORY_MSG_221;B&W - Color filter -!HISTORY_MSG_222;B&W - Presets -!HISTORY_MSG_223;B&W - CM - Orange -!HISTORY_MSG_224;B&W - CM - Yellow -!HISTORY_MSG_225;B&W - CM - Cyan -!HISTORY_MSG_226;B&W - CM - Magenta -!HISTORY_MSG_227;B&W - CM - Purple -!HISTORY_MSG_228;B&W - Luminance equalizer -!HISTORY_MSG_229;B&W - Luminance equalizer -!HISTORY_MSG_230;B&W - Mode -!HISTORY_MSG_231;B&W - 'Before' curve -!HISTORY_MSG_232;B&W - 'Before' curve type -!HISTORY_MSG_233;B&W - 'After' curve -!HISTORY_MSG_234;B&W - 'After' curve type -!HISTORY_MSG_235;B&W - Auto channel mixer -!HISTORY_MSG_236;--unused-- -!HISTORY_MSG_237;B&W - Mixer -!HISTORY_MSG_238;GF - Feather -!HISTORY_MSG_239;GF - Strength -!HISTORY_MSG_240;GF - Center -!HISTORY_MSG_241;VF - Feather -!HISTORY_MSG_242;VF - Roundness -!HISTORY_MSG_243;VC - Radius -!HISTORY_MSG_244;VC - Strength -!HISTORY_MSG_245;VC - Center -!HISTORY_MSG_246;L*a*b* - CL curve -!HISTORY_MSG_247;L*a*b* - LH curve -!HISTORY_MSG_248;L*a*b* - HH curve -!HISTORY_MSG_249;CbDL - Threshold -!HISTORY_MSG_250;NR - Enhanced -!HISTORY_MSG_251;B&W - Algorithm +!GENERAL_OPEN;Open !HISTORY_MSG_252;CbDL - Skin tar/prot !HISTORY_MSG_253;CbDL - Reduce artifacts !HISTORY_MSG_254;CbDL - Skin hue @@ -1123,14 +1651,14 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1152,31 +1680,13 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method -!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s -!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 -!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 -!MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). -!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. -!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled -!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. -!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! -!MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. -!MAIN_TAB_EXPORT; Fast Export +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w -!MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 -!MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 -!MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\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_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.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. -!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g -!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B -!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r -!MAIN_TOOLTIP_THRESHOLD;Threshold !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1188,26 +1698,15 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !NAVIGATOR_R;R: !NAVIGATOR_S;S: !NAVIGATOR_V;V: -!NAVIGATOR_XY_FULL;Width: %1, Height: %2 -!OPTIONS_DEFIMG_MISSING;The default profile for non-raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. -!OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. -!PARTIALPASTE_CHANNELMIXERBW;Black-and-white -!PARTIALPASTE_COLORAPP;CIECAM02 !PARTIALPASTE_COLORTONING;Color toning -!PARTIALPASTE_EPD;Tone mapping !PARTIALPASTE_EQUALIZER;Wavelet levels !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_GRADIENT;Graduated filter -!PARTIALPASTE_LENSPROFILE;Lens correction profile -!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_METAGROUP;Metadata !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter !PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter !PARTIALPASTE_PRSHARPENING;Post-resize sharpening -!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps !PARTIALPASTE_RETINEX;Retinex -!PARTIALPASTE_RGBCURVES;RGB curves -!PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles @@ -1215,15 +1714,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTSTD;Standard -!PREFERENCES_BEHADDALL;All to 'Add' -!PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. -!PREFERENCES_BEHSETALL;All to 'Set' -!PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. -!PREFERENCES_BLACKBODY;Tungsten -!PREFERENCES_CIEART;CIECAM02 optimization !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings -!PREFERENCES_CIEART_LABEL;Use float precision instead of double -!PREFERENCES_CIEART_TOOLTIP;If enabled, CIECAM02 calculations are performed in the single-precision floating-point format instead of the double-precision one. This provides a small increase in speed at the expense of a negligible loss of quality. !PREFERENCES_CLUTSCACHE;HaldCLUT Cache !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory @@ -1232,30 +1723,12 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_CURVEBBOXPOS_BELOW;Below !PREFERENCES_CURVEBBOXPOS_LEFT;Left !PREFERENCES_CURVEBBOXPOS_RIGHT;Right -!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID -!PREFERENCES_D50;5000K -!PREFERENCES_D55;5500K -!PREFERENCES_D60;6000K -!PREFERENCES_D65;6500K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLUOF2;Fluorescent F2 -!PREFERENCES_FLUOF7;Fluorescent F7 -!PREFERENCES_FLUOF11;Fluorescent F11 !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel and the File Browser !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Having separate thumbnail size will require more processing time each time you'll switch between the single Editor tab and the File Browser. -!PREFERENCES_GREY;Output device's Yb luminance (%) -!PREFERENCES_GREY05;Yb=05 CIE L#30 -!PREFERENCES_GREY10;Yb=10 CIE L#40 -!PREFERENCES_GREY15;Yb=15 CIE L#45 -!PREFERENCES_GREY18;Yb=18 CIE L#50 -!PREFERENCES_GREY23;Yb=23 CIE L#55 -!PREFERENCES_GREY30;Yb=30 CIE L#60 -!PREFERENCES_GREY40;Yb=40 CIE L#70 !PREFERENCES_GREYSC;Scene Yb luminance (%) !PREFERENCES_GREYSC18;Yb=18 CIE L#50 !PREFERENCES_GREYSCA;Automatic @@ -1271,7 +1744,6 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_MAX;Maxi (Tile) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MED;Medium (Tile/2) -!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" !PREFERENCES_MIN;Mini (100x115) !PREFERENCES_MONINTENT;Default monitor intent !PREFERENCES_MONPROFILE;Default monitor profile @@ -1288,191 +1760,29 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_PROFILE_NONE;None !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in "Single Editor Tab Mode" and when "Demosaicing method used for the preview at <100% zoom" is set to "As in PP3". -!PREFERENCES_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels -!PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;When working with folders full of uncompressed tiff files enabling this option can increase performance of thumb generation. -!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar !PREFERENCES_SIMPLAUT;Tool mode !PREFERENCES_SMA;Small (250x287) !PREFERENCES_STDAUT;Standard -!PREFERENCES_TAB_PERFORMANCE;Performance & Quality !PREFERENCES_TIMAX;High !PREFERENCES_TINB;Number of tiles !PREFERENCES_TISTD;Standard -!PREFERENCES_TP_LABEL;Tool panel: -!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text -!PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file -!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_VIEW;Output device's white balance (monitor, TV, projector, viewing, etc.) !PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' !PREFERENCES_WLONE;One level !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No -!PROFILEPANEL_COPYPPASTE;Parameters to copy -!PROFILEPANEL_GLOBALPROFILES;Bundled profiles -!PROFILEPANEL_LOADPPASTE;Parameters to load -!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. -!PROFILEPANEL_MYPROFILES;My profiles -!PROFILEPANEL_PASTEPPASTE;Parameters to paste -!PROFILEPANEL_PINTERNAL;Neutral -!PROFILEPANEL_SAVEPPASTE;Parameters to save -!PROGRESSBAR_NOIMAGES;No images found -!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved -!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added -!SAVEDLG_FORCEFORMATOPTS;Force saving options -!SAVEDLG_SUBSAMP;Subsampling -!SAVEDLG_SUBSAMP_1;Best compression -!SAVEDLG_SUBSAMP_2;Balanced -!SAVEDLG_SUBSAMP_3;Best quality -!SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. -!SAVEDLG_WARNFILENAME;File will be named -!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left -!THRESHOLDSELECTOR_BR;Bottom-right -!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. -!THRESHOLDSELECTOR_T;Top -!THRESHOLDSELECTOR_TL;Top-left -!THRESHOLDSELECTOR_TR;Top-right -!TP_BWMIX_ALGO;Algorithm OYCPM -!TP_BWMIX_ALGO_LI;Linear -!TP_BWMIX_ALGO_SP;Special effects -!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. -!TP_BWMIX_AUTOCH;Auto -!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. -!TP_BWMIX_CC_ENABLED;Adjust complementary color -!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. -!TP_BWMIX_CHANNEL;Luminance equalizer -!TP_BWMIX_CURVEEDITOR1;'Before' curve -!TP_BWMIX_CURVEEDITOR2;'After' curve -!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. -!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. -!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. -!TP_BWMIX_FILTER;Color Filter -!TP_BWMIX_FILTER_BLUE;Blue -!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green -!TP_BWMIX_FILTER_GREEN;Green -!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow -!TP_BWMIX_FILTER_NONE;None -!TP_BWMIX_FILTER_PURPLE;Purple -!TP_BWMIX_FILTER_RED;Red -!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow !TP_BWMIX_FILTER_TOOLTIP;The color filter simulates shots taken with a colored filter placed in front of the lens. Colored filters reduce the transmission of specific color ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. !TP_BWMIX_FILTER_YELLOW;Yellow !TP_BWMIX_GAMMA;Gamma Correction !TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. -!TP_BWMIX_LABEL;Black-and-White -!TP_BWMIX_MET;Method -!TP_BWMIX_MET_CHANMIX;Channel Mixer -!TP_BWMIX_MET_DESAT;Desaturation -!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer -!TP_BWMIX_MIXC;Mixer -!TP_BWMIX_NEUTRAL;Reset mixer -!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. -!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% -!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. -!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. -!TP_BWMIX_SETTING;Presets -!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. -!TP_BWMIX_SET_HIGHCONTAST;High contrast -!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity -!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic -!TP_BWMIX_SET_INFRARED;Infrared -!TP_BWMIX_SET_LANDSCAPE;Landscape -!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity -!TP_BWMIX_SET_LUMINANCE;Luminance -!TP_BWMIX_SET_NORMCONTAST;Normal Contrast -!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic -!TP_BWMIX_SET_PANCHRO;Panchromatic -!TP_BWMIX_SET_PORTRAIT;Portrait -!TP_BWMIX_SET_RGBABS;Absolute RGB -!TP_BWMIX_SET_RGBREL;Relative RGB -!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM -!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM -!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like -!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending -!TP_BWMIX_TCMODE_STANDARD;B&W Standard -!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard -!TP_BWMIX_VAL;L !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White !TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. -!TP_COLORAPP_ADAPTSCENE;Scene luminosity -!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. -!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) -!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). -!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. -!TP_COLORAPP_ALGO;Algorithm -!TP_COLORAPP_ALGO_ALL;All -!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) -!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) -!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) -!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. -!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter -!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. -!TP_COLORAPP_BRIGHT;Brightness (Q) -!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. -!TP_COLORAPP_CHROMA;Chroma (C) -!TP_COLORAPP_CHROMA_M;Colorfulnes (M) -!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. -!TP_COLORAPP_CHROMA_S;Saturation (S) -!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. -!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation -!TP_COLORAPP_CONTRAST;Contrast (J) -!TP_COLORAPP_CONTRAST_Q;Contrast (Q) -!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. -!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. -!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 -!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. -!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 -!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. -!TP_COLORAPP_CURVEEDITOR3;Color curve -!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. -!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves -!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. -!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). -!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. -!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) -!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. -!TP_COLORAPP_HUE;Hue (h) -!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. -!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 -!TP_COLORAPP_LABEL_CAM02;Image Adjustments -!TP_COLORAPP_LABEL_SCENE;Scene Conditions -!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions -!TP_COLORAPP_LIGHT;Lightness (J) -!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. -!TP_COLORAPP_MODEL;WP Model -!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. -!TP_COLORAPP_RSTPRO;Red & skin-tones protection -!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. -!TP_COLORAPP_SHARPCIE;--unused-- -!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- -!TP_COLORAPP_SURROUND;Surround -!TP_COLORAPP_SURROUND_AVER;Average -!TP_COLORAPP_SURROUND_DARK;Dark -!TP_COLORAPP_SURROUND_DIM;Dim -!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) -!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. -!TP_COLORAPP_SURSOURCE;Dark surround -!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. -!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness -!TP_COLORAPP_TCMODE_CHROMA;Chroma -!TP_COLORAPP_TCMODE_COLORF;Colorfulness -!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 -!TP_COLORAPP_TCMODE_LABEL2;Curve mode 2 -!TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode -!TP_COLORAPP_TCMODE_LIGHTNESS;Lightness -!TP_COLORAPP_TCMODE_SATUR;Saturation -!TP_COLORAPP_TONECIE;Tone mapping using CIECAM02 -!TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. -!TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] -!TP_COLORAPP_WBRT;WB [RT] + [output] !TP_COLORTONING_AB;o C/L !TP_COLORTONING_AUTOSAT;Automatic !TP_COLORTONING_BALANCE;Balance @@ -1509,21 +1819,19 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_COLORTONING_TWOBY;Special a* and b* !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_GTEPASSPORT;Biometric Passport -!TP_CROP_GTFRAME;Frame !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global !TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! -!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow !TP_DIRPYRDENOISE_C2TYPE_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. !TP_DIRPYRDENOISE_CCCURVE;Chrominance curve !TP_DIRPYRDENOISE_CHROMAFR;Chrominance @@ -1533,14 +1841,9 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma !TP_DIRPYRDENOISE_CURVEEDITOR_CC_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_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise -!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. -!TP_DIRPYRDENOISE_ENH;Enhanced mode -!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. -!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. !TP_DIRPYRDENOISE_LAB;L*a*b* !TP_DIRPYRDENOISE_LABM;L*a*b* !TP_DIRPYRDENOISE_LCURVE;Luminance curve -!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail !TP_DIRPYRDENOISE_LM;Luminance only !TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) !TP_DIRPYRDENOISE_LTYPE;Luminance control @@ -1552,28 +1855,23 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_DIRPYRDENOISE_MEDMETHOD;Median method !TP_DIRPYRDENOISE_MEDTYPE;Median type !TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising -!TP_DIRPYRDENOISE_METHOD;Method !TP_DIRPYRDENOISE_METHOD11;Quality !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. -!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview !TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 -!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green -!TP_DIRPYRDENOISE_RGB;RGB !TP_DIRPYRDENOISE_RGBM;RGB !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1583,26 +1881,9 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_DIRPYREQUALIZER_SKIN;Skin targetting/protection !TP_DIRPYREQUALIZER_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. !TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. -!TP_EPD_EDGESTOPPING;Edge stopping !TP_EPD_GAMMA;Gamma -!TP_EPD_LABEL;Tone Mapping -!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates -!TP_EPD_SCALE;Scale -!TP_EPD_STRENGTH;Strength -!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" -!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. -!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. -!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 -!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 -!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. -!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like -!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 -!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual -!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending -!TP_EXPOSURE_TCMODE_STANDARD;Standard -!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMSIMULATION_LABEL;Film Simulation @@ -1611,90 +1892,17 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !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_GAMMA_CURV;Gamma -!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 -!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). -!TP_GRADIENT_CENTER_Y;Center Y -!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). -!TP_GRADIENT_DEGREE;Angle -!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. -!TP_GRADIENT_FEATHER;Feather -!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. -!TP_GRADIENT_LABEL;Graduated Filter -!TP_GRADIENT_STRENGTH;Strength -!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. -!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only enabled if the selected DCP has any. !TP_ICM_APPLYHUESATMAP;Base table !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only enabled if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only enabled if the selected DCP has one. -!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. -!TP_ICM_DCPILLUMINANT;Illuminant -!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. !TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. -!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. -!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. -!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. -!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. !TP_ICM_PROFILEINTENT;Rendering Intent !TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. -!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. -!TP_ICM_TONECURVE;Tone curve -!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. -!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift -!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. -!TP_LABCURVE_CHROMATICITY;Chromaticity -!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. -!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated -!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel -!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel -!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated -!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated -!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel -!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel -!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated -!TP_LABCURVE_CURVEEDITOR_CC;CC -!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral -!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull -!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel -!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated -!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) -!TP_LABCURVE_CURVEEDITOR_CH;CH -!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) -!TP_LABCURVE_CURVEEDITOR_CL;CL -!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) -!TP_LABCURVE_CURVEEDITOR_HH;HH -!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) -!TP_LABCURVE_CURVEEDITOR_LC;LC -!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) -!TP_LABCURVE_CURVEEDITOR_LH;LH -!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) -!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) -!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones -!TP_LABCURVE_LCREDSK_TIP;If enabled, the LC Curve affects only red and skin-tones.\nIf disabled, it applies to all tones. -!TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection -!TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. -!TP_LENSPROFILE_LABEL;Lens Correction Profile -!TP_LENSPROFILE_USECA;Chromatic aberration correction -!TP_LENSPROFILE_USEDIST;Distortion correction -!TP_LENSPROFILE_USEVIGN;Vignetting correction -!TP_NEUTRAL;Reset -!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;Feather -!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. -!TP_PCVIGNETTE_LABEL;Vignette Filter -!TP_PCVIGNETTE_ROUNDNESS;Roundness -!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_PFCURVE_CURVEEDITOR_CH;Hue -!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. !TP_PREPROCESS_DEADPIXFILT;Dead pixel filter !TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. !TP_PREPROCESS_HOTPIXFILT;Hot pixel filter @@ -1710,13 +1918,8 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RAWEXPOS_BLACK_GREEN;Green !TP_RAWEXPOS_BLACK_RED;Red !TP_RAWEXPOS_RGB;Red, Green, Blue -!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... -!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... -!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. !TP_RAW_HD;Threshold !TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. -!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. !TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix !TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. !TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix @@ -1730,8 +1933,12 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1751,6 +1958,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1770,10 +1978,11 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1781,6 +1990,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform @@ -1793,33 +2003,6 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask -!TP_RGBCURVES_BLUE;B -!TP_RGBCURVES_CHANNEL;Channel -!TP_RGBCURVES_GREEN;G -!TP_RGBCURVES_LABEL;RGB Curves -!TP_RGBCURVES_LUMAMODE;Luminosity mode -!TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminosity mode allows to vary the contribution of R, G and B channels to the luminosity of the image, without altering image color. -!TP_RGBCURVES_RED;R -!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter -!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask -!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. -!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift -!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow -!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) -!TP_VIBRANCE_LABEL;Vibrance -!TP_VIBRANCE_PASTELS;Pastel Tones -!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones -!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones -!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold -!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold -!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. -!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting -!TP_VIBRANCE_SATURATED;Saturated Tones !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 @@ -1983,41 +2166,4 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. !TP_WAVELET_TMTYPE;Compression method !TP_WAVELET_TON;Toning -!TP_WBALANCE_CLOUDY;Cloudy -!TP_WBALANCE_DAYLIGHT;Daylight (sunny) -!TP_WBALANCE_EQBLUERED;Blue/Red equalizer -!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. -!TP_WBALANCE_FLASH55;Leica -!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus -!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta -!TP_WBALANCE_FLASH_HEADER;Flash -!TP_WBALANCE_FLUO1;F1 - Daylight -!TP_WBALANCE_FLUO2;F2 - Cool White -!TP_WBALANCE_FLUO3;F3 - White -!TP_WBALANCE_FLUO4;F4 - Warm White -!TP_WBALANCE_FLUO5;F5 - Daylight -!TP_WBALANCE_FLUO6;F6 - Lite White -!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator -!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design -!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe -!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_GTI;GTI -!TP_WBALANCE_HMI;HMI -!TP_WBALANCE_JUDGEIII;JudgeIII -!TP_WBALANCE_LAMP_HEADER;Lamp -!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 -!TP_WBALANCE_LED_HEADER;LED -!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 -!TP_WBALANCE_SHADE;Shade -!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_TUNGSTEN;Tungsten -!TP_WBALANCE_WATER1;UnderWater 1 -!TP_WBALANCE_WATER2;UnderWater 2 -!TP_WBALANCE_WATER_HEADER;UnderWater !ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak index 7ea5ead8a..90eef3409 100644 --- a/rtdata/languages/Slovak +++ b/rtdata/languages/Slovak @@ -655,11 +655,13 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. @@ -722,7 +724,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -982,14 +984,14 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1011,8 +1013,10 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1465,11 +1469,12 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1508,12 +1513,12 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1524,7 +1529,6 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1719,8 +1723,12 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1740,6 +1748,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1759,10 +1768,11 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1770,6 +1780,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi index 5017c2066..612df257d 100644 --- a/rtdata/languages/Suomi +++ b/rtdata/languages/Suomi @@ -581,12 +581,14 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -660,7 +662,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -920,14 +922,14 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -949,8 +951,10 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1426,11 +1430,12 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1473,12 +1478,12 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1489,7 +1494,6 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1711,8 +1715,12 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1732,6 +1740,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1751,10 +1760,11 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1762,6 +1772,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 3f979abaf..fbdb4c3ae 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -374,7 +374,7 @@ HISTORY_MSG_145;Mikrokontrast - Enhetlighet HISTORY_MSG_146;Kantskärpning HISTORY_MSG_147;Kantskärpning - Endast luminans HISTORY_MSG_148;Mikrokontrast -HISTORY_MSG_149;Mikrokontrast - 3x3-matris +HISTORY_MSG_149;Mikrokontrast - 3×3-matris HISTORY_MSG_150;Reducering av artefakter och brus e. demosaicing HISTORY_MSG_151;Lyster HISTORY_MSG_152;Lyster - Pastelltoner @@ -1240,11 +1240,6 @@ TP_DARKFRAME_LABEL;Svartbild TP_DEFRINGE_LABEL;Fyll ut överstrålning TP_DEFRINGE_RADIUS;Radie TP_DEFRINGE_THRESHOLD;Tröskelvärde -TP_DIRPYRDENOISE_33;3×3 kraftig -TP_DIRPYRDENOISE_55;5×5 kraftig -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (långsam) -TP_DIRPYRDENOISE_99;9x9 (mycket långsam) TP_DIRPYRDENOISE_ABM;Endast chroma TP_DIRPYRDENOISE_AUTO_TOOLTIP;Försök att utvärdera chroma-bruset\nVar försiktig, den här beräkningen görs på genomsnittet och är tämligen subjektiv! TP_DIRPYRDENOISE_BLUE;Krominans - Blå-Gul @@ -1278,7 +1273,6 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standard TP_DIRPYRDENOISE_SHALBI;Hög TP_DIRPYRDENOISE_SLI;Reglage -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYREQUALIZER_ALGO;Algoritm för hudtoner TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fin: närmre hudens färger, minimerar inverkan på andra färger\nStor: undvik än mer artefakter TP_DIRPYREQUALIZER_ARTIF;Reducera artefakter @@ -1722,6 +1716,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!GENERAL_APPLY;Apply +!GENERAL_OPEN;Open !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_256;NR - Median type !HISTORY_MSG_257;Color Toning @@ -1758,14 +1754,14 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -1787,8 +1783,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_COLORTONING;Color toning @@ -1828,6 +1826,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_COLORTONING_TWOALL;Special chroma !TP_COLORTONING_TWOBY;Special a* and b* !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_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global !TP_DIRPYRDENOISE_C2TYPE_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. @@ -1844,12 +1848,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 @@ -1881,8 +1885,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1902,6 +1910,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1921,10 +1930,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1932,6 +1942,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish index d7f6fa405..0af0611d5 100644 --- a/rtdata/languages/Turkish +++ b/rtdata/languages/Turkish @@ -580,12 +580,14 @@ TP_WBALANCE_TEMPERATURE;Isı !FILECHOOSER_FILTER_SAME;Same format as current photo !FILECHOOSER_FILTER_TIFF;TIFF files !GENERAL_AFTER;After +!GENERAL_APPLY;Apply !GENERAL_ASIMAGE;As Image !GENERAL_AUTO;Automatic !GENERAL_BEFORE;Before !GENERAL_CLOSE;Close !GENERAL_FILE;File !GENERAL_NONE;None +!GENERAL_OPEN;Open !GENERAL_UNCHANGED;(Unchanged) !GENERAL_WARNING;Warning !HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. @@ -659,7 +661,7 @@ TP_WBALANCE_TEMPERATURE;Isı !HISTORY_MSG_146;Edge sharpening !HISTORY_MSG_147;ES - Luminance only !HISTORY_MSG_148;Microcontrast -!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_149;Microcontrast - 3×3 matrix !HISTORY_MSG_150;Post-demosaic artifact/noise red. !HISTORY_MSG_151;Vibrance !HISTORY_MSG_152;Vib - Pastel tones @@ -919,14 +921,14 @@ TP_WBALANCE_TEMPERATURE;Isı !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Radius !HISTORY_MSG_409;Retinex - Contrast -!HISTORY_MSG_410;Retinex - Brightness +!HISTORY_MSG_410;Retinex - Offset !HISTORY_MSG_411;Retinex - Strength !HISTORY_MSG_412;Retinex - Gaussian Gradient -!HISTORY_MSG_413;Retinex - Variance +!HISTORY_MSG_413;Retinex - Contrast !HISTORY_MSG_414;Retinex - Histogram - Lab !HISTORY_MSG_415;Retinex - Transmission !HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median +!HISTORY_MSG_417;Retinex - Transmission Median !HISTORY_MSG_418;Retinex - Threshold !HISTORY_MSG_419;Retinex - Color space !HISTORY_MSG_420;Retinex - Histogram - HSL @@ -948,8 +950,10 @@ TP_WBALANCE_TEMPERATURE;Isı !HISTORY_MSG_436;Retinex - M - Radius !HISTORY_MSG_437;Retinex - M - Method !HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Preview +!HISTORY_MSG_439;Retinex - Process !HISTORY_MSG_440;CbDL - Method +!HISTORY_MSG_441;Retinex - Gain transmission +!HISTORY_MSG_442;Retinex - Scale !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 @@ -1425,11 +1429,12 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_DEFRINGE_LABEL;Defringe !TP_DEFRINGE_RADIUS;Radius !TP_DEFRINGE_THRESHOLD;Threshold -!TP_DIRPYRDENOISE_33;3×3 strong -!TP_DIRPYRDENOISE_55;5×5 strong -!TP_DIRPYRDENOISE_55SOFT;5×5 -!TP_DIRPYRDENOISE_77;7×7 (slow) -!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_3X3;3×3 +!TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +!TP_DIRPYRDENOISE_5X5;5×5 +!TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +!TP_DIRPYRDENOISE_7X7;7×7 +!TP_DIRPYRDENOISE_9X9;9×9 !TP_DIRPYRDENOISE_ABM;Chroma only !TP_DIRPYRDENOISE_AUT;Automatic global !TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1472,12 +1477,12 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. !TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. !TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. !TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 !TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - !TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. !TP_DIRPYRDENOISE_PASSES;Median iterations -!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_PON;Auto multi-zones !TP_DIRPYRDENOISE_PRE;Preview multi-zones !TP_DIRPYRDENOISE_PREV;Preview @@ -1488,7 +1493,6 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_DIRPYRDENOISE_SHAL;Standard !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider -!TP_DIRPYRDENOISE_SOFT;3x3 !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 !TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1710,8 +1714,12 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. !TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +!TP_RETINEX_EQUAL;Equalizer !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAIN;Gain +!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +!TP_RETINEX_GAINTRANSMISSION;Gain transmission +!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. !TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. !TP_RETINEX_GAMMA;Gamma !TP_RETINEX_GAMMA_FREE;Free @@ -1731,6 +1739,7 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_RETINEX_HSLSPACE_LIN;HSL-Linear !TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) +!TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. !TP_RETINEX_LABEL;Retinex !TP_RETINEX_LABEL_MASK;Mask @@ -1750,10 +1759,11 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_RETINEX_NEIGHBOR;Radius !TP_RETINEX_NEUTRAL;Reset !TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Brightness +!TP_RETINEX_OFFSET;Offset (brightness) !TP_RETINEX_SCALES;Gaussian gradient !TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. !TP_RETINEX_SETTINGS;Settings +!TP_RETINEX_SKAL;Scale !TP_RETINEX_SLOPE;Free gamma slope !TP_RETINEX_STRENGTH;Strength !TP_RETINEX_THRESHOLD;Threshold @@ -1761,6 +1771,7 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission !TP_RETINEX_TRANSMISSION;Transmission map !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_UNIFORM;Uniform diff --git a/rtdata/languages/default b/rtdata/languages/default index 53efbf5eb..f349ebd56 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1,6 +1,6 @@ #00 default translation file #01 Developers should add translations to this file and then run the 'generateTranslationDiffs' Bash script to update other locales. -#02 Translators please append a comment with the date of translation and your name(s) as used in the RawTherapee forum or Google Code project to the top of your translation, e.g.: +#02 Translators please append a comment here with the current date and your name(s) as used in the RawTherapee forum or GitHub page, e.g.: #03 2525-12-24 Zager and Evans ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Credits @@ -199,6 +199,7 @@ FILECHOOSER_FILTER_SAME;Same format as current photo FILECHOOSER_FILTER_TIFF;TIFF files GENERAL_ABOUT;About GENERAL_AFTER;After +GENERAL_APPLY;Apply GENERAL_ASIMAGE;As Image GENERAL_AUTO;Automatic GENERAL_BEFORE;Before @@ -214,6 +215,7 @@ GENERAL_NA;n/a GENERAL_NO;No GENERAL_NONE;None GENERAL_OK;OK +GENERAL_OPEN;Open GENERAL_PORTRAIT;Portrait GENERAL_SAVE;Save GENERAL_UNCHANGED;(Unchanged) @@ -379,7 +381,7 @@ HISTORY_MSG_145;Microcontrast - Uniformity HISTORY_MSG_146;Edge sharpening HISTORY_MSG_147;ES - Luminance only HISTORY_MSG_148;Microcontrast -HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_149;Microcontrast - 3×3 matrix HISTORY_MSG_150;Post-demosaic artifact/noise red. HISTORY_MSG_151;Vibrance HISTORY_MSG_152;Vib - Pastel tones @@ -639,14 +641,14 @@ HISTORY_MSG_406;W - ES - Neighboring pixels HISTORY_MSG_407;Retinex - Method HISTORY_MSG_408;Retinex - Radius HISTORY_MSG_409;Retinex - Contrast -HISTORY_MSG_410;Retinex - Brightness +HISTORY_MSG_410;Retinex - Offset HISTORY_MSG_411;Retinex - Strength HISTORY_MSG_412;Retinex - Gaussian Gradient -HISTORY_MSG_413;Retinex - Variance +HISTORY_MSG_413;Retinex - Contrast HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmission HISTORY_MSG_416;Retinex -HISTORY_MSG_417;Retinex - Transmission median +HISTORY_MSG_417;Retinex - Transmission Median HISTORY_MSG_418;Retinex - Threshold HISTORY_MSG_419;Retinex - Color space HISTORY_MSG_420;Retinex - Histogram - HSL @@ -668,9 +670,11 @@ HISTORY_MSG_435;Retinex - M - Shadows TW HISTORY_MSG_436;Retinex - M - Radius HISTORY_MSG_437;Retinex - M - Method HISTORY_MSG_438;Retinex - M - Equalizer -HISTORY_MSG_439;Retinex - Preview +HISTORY_MSG_439;Retinex - Process HISTORY_MSG_440;CbDL - Method -HISTORY_MSG_441;Spot removal +HISTORY_MSG_441;Retinex - Gain transmission +HISTORY_MSG_442;Retinex - Scale +HISTORY_MSG_443;Spot removal HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1350,11 +1354,12 @@ TP_DARKFRAME_LABEL;Dark-Frame TP_DEFRINGE_LABEL;Defringe TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Threshold -TP_DIRPYRDENOISE_33;3×3 strong -TP_DIRPYRDENOISE_55;5×5 strong -TP_DIRPYRDENOISE_55SOFT;5×5 -TP_DIRPYRDENOISE_77;7×7 (slow) -TP_DIRPYRDENOISE_99;9x9 (very slow) +TP_DIRPYRDENOISE_3X3;3×3 +TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft +TP_DIRPYRDENOISE_5X5;5×5 +TP_DIRPYRDENOISE_5X5_SOFT;5×5 soft +TP_DIRPYRDENOISE_7X7;7×7 +TP_DIRPYRDENOISE_9X9;9×9 TP_DIRPYRDENOISE_ABM;Chroma only TP_DIRPYRDENOISE_AUT;Automatic global TP_DIRPYRDENOISE_AUTO;Automatic global @@ -1397,12 +1402,12 @@ TP_DIRPYRDENOISE_METHOD11;Quality TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. -TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. TP_DIRPYRDENOISE_PASSES;Median iterations -TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. TP_DIRPYRDENOISE_PON;Auto multi-zones TP_DIRPYRDENOISE_PRE;Preview multi-zones TP_DIRPYRDENOISE_PREV;Preview @@ -1413,7 +1418,6 @@ TP_DIRPYRDENOISE_RGBM;RGB TP_DIRPYRDENOISE_SHAL;Standard TP_DIRPYRDENOISE_SHALBI;High TP_DIRPYRDENOISE_SLI;Slider -TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 TP_DIRPYREQUALIZER_ALGO;Skin Color Range TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. @@ -1669,8 +1673,12 @@ TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. TP_RETINEX_CURVEEDITOR_MAP;L=f(L) TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! +TP_RETINEX_EQUAL;Equalizer TP_RETINEX_FREEGAMMA;Free gamma TP_RETINEX_GAIN;Gain +TP_RETINEX_GAINOFFS;Gain and Offset (brightness) +TP_RETINEX_GAINTRANSMISSION;Gain transmission +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Free @@ -1690,6 +1698,7 @@ TP_RETINEX_HIGHLIGHT_TOOLTIP;Increase action of High algorithm.\nMay require you TP_RETINEX_HSLSPACE_LIN;HSL-Linear TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic TP_RETINEX_ITER;Iterations (Tone-mapping) +TP_RETINEX_ITERF;Tone mapping TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. TP_RETINEX_LABEL;Retinex TP_RETINEX_LABEL_MASK;Mask @@ -1709,10 +1718,11 @@ TP_RETINEX_MLABEL_TOOLTIP;Should be near min=0 max=32768\nRestored image with no TP_RETINEX_NEIGHBOR;Radius TP_RETINEX_NEUTRAL;Reset TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -TP_RETINEX_OFFSET;Brightness +TP_RETINEX_OFFSET;Offset (brightness) TP_RETINEX_SCALES;Gaussian gradient TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. TP_RETINEX_SETTINGS;Settings +TP_RETINEX_SKAL;Scale TP_RETINEX_SLOPE;Free gamma slope TP_RETINEX_STRENGTH;Strength TP_RETINEX_THRESHOLD;Threshold @@ -1720,6 +1730,7 @@ TP_RETINEX_THRESHOLD_TOOLTIP;Limits in/out.\nIn = image source,\nOut = image gau TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Mean=%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;Transmission TP_RETINEX_TRANSMISSION;Transmission map TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. TP_RETINEX_UNIFORM;Uniform diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index ab0b95a27..64bb19113 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -26,6 +26,7 @@ #include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" +#include "median.h" namespace { @@ -106,14 +107,6 @@ bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) //end of linear equation solver //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -inline void pixSort(float &a, float &b) { - if (a > b) { - float temp = a; - a = b; - b = temp; - } -} - } using namespace std; @@ -630,36 +623,18 @@ void RawImageSource::CA_correct_RT(const double cared, const double cablue, cons float bstemp[2]; for (int dir = 0; dir < 2; dir++) { //temporary storage for median filter - float p[9]; - p[0] = blockshifts[(vblock - 1) * hblsz + hblock - 1][c][dir]; - p[1] = blockshifts[(vblock - 1) * hblsz + hblock][c][dir]; - p[2] = blockshifts[(vblock - 1) * hblsz + hblock + 1][c][dir]; - p[3] = blockshifts[(vblock) * hblsz + hblock - 1][c][dir]; - p[4] = blockshifts[(vblock) * hblsz + hblock][c][dir]; - p[5] = blockshifts[(vblock) * hblsz + hblock + 1][c][dir]; - p[6] = blockshifts[(vblock + 1) * hblsz + hblock - 1][c][dir]; - p[7] = blockshifts[(vblock + 1) * hblsz + hblock][c][dir]; - p[8] = blockshifts[(vblock + 1) * hblsz + hblock + 1][c][dir]; - pixSort(p[1], p[2]); - pixSort(p[4], p[5]); - pixSort(p[7], p[8]); - pixSort(p[0], p[1]); - pixSort(p[3], p[4]); - pixSort(p[6], p[7]); - pixSort(p[1], p[2]); - pixSort(p[4], p[5]); - pixSort(p[7], p[8]); - pixSort(p[0], p[3]); - pixSort(p[5], p[8]); - pixSort(p[4], p[7]); - pixSort(p[3], p[6]); - pixSort(p[1], p[4]); - pixSort(p[2], p[5]); - pixSort(p[4], p[7]); - pixSort(p[4], p[2]); - pixSort(p[6], p[4]); - pixSort(p[4], p[2]); - bstemp[dir] = p[4]; + const std::array p = { + blockshifts[(vblock - 1) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock - 1) * hblsz + hblock][c][dir], + blockshifts[(vblock - 1) * hblsz + hblock + 1][c][dir], + blockshifts[(vblock) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock) * hblsz + hblock][c][dir], + blockshifts[(vblock) * hblsz + hblock + 1][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock + 1][c][dir] + }; + bstemp[dir] = median(p); } //now prepare coefficient matrix; use only data points within caautostrength/2 std devs of zero diff --git a/rtengine/EdgePreservingDecomposition.h b/rtengine/EdgePreservingDecomposition.h index 558caa5db..04ebfe3b6 100644 --- a/rtengine/EdgePreservingDecomposition.h +++ b/rtengine/EdgePreservingDecomposition.h @@ -1,47 +1,64 @@ #pragma once /* -The EdgePreservingDecomposition files contain standard C++ (standard except the first line) code for creating and, to a -limited extent (create your own uses!), messing with multi scale edge preserving decompositions of a 32 bit single channel -image. As a byproduct it contains a lot of linear algebra which can be useful for optimization problems that -you want to solve in rectangles on rectangular grids. +The EdgePreservingDecomposition files contain standard C++ (standard except the +first line) code for creating and, to a limited extent (create your own uses!), +messing with multi scale edge preserving decompositions of a 32 bit single +channel image. As a byproduct it contains a lot of linear algebra which can be +useful for optimization problems that you want to solve in rectangles on +rectangular grids. -Anyway. Basically, this is an implementation of what's presented in the following papers: - Edge-Preserving Decompositions for Multi-Scale Tone and Detail Manipulation - An Iterative Solution Method for Linear Systems of Which the Coefficient Matrix is a Symetric M-Matrix - Color correction for tone mapping - Wikipedia, the free encyclopedia +Anyway. Basically, this is an implementation of what's presented in the +following papers: +- Edge-Preserving Decompositions for Multi-Scale Tone and Detail Manipulation +- An Iterative Solution Method for Linear Systems of Which the Coefficient + Matrix is a Symetric M-Matrix +- Color correction for tone mapping +- Wikipedia, the free encyclopedia -First one is most of what matters, next two are details, last everything else. I did a few things differently, especially: - Reformulated the minimization with finite elements instead of finite differences. This results in better conditioning, - slightly better accuracy (less artifacts), the possibility of a better picked edge stopping function, but more memory consumption. - - A single rotationally invariant edge stopping function is used instead of two non-invariant ones. - - Incomplete Cholseky factorization instead of Szeliski's LAHBF. Slower, but not subject to any patents. - - For tone mapping, original images are decomposed instead of their logarithms, and just one decomposition is made; - I find that this way works plenty good (theirs isn't better or worse... just different) and is simpler. +First one is most of what matters, next two are details, last everything else. +I did a few things differently, especially: +- Reformulated the minimization with finite elements instead of finite + differences. This results in better conditioning, slightly better accuracy + (less artifacts), the possibility of a better picked edge stopping function, + but more memory consumption. +- A single rotationally invariant edge stopping function is used instead of two + non-invariant ones. +- Incomplete Cholseky factorization instead of Szeliski's LAHBF. Slower, but + not subject to any patents. +- For tone mapping, original images are decomposed instead of their logarithms, + and just one decomposition is made; +- I find that this way works plenty good (theirs isn't better or worse... just + different) and is simpler. Written by ben_pcc in Portland, Oregon, USA. Some history: - Late April 2010, I develop interest in this stuff because photos of my ceramics lack local contrast. - Mid 2010, it works but is too slow to be useful. - Fall 2010, various unsuccessful attempts at speeding up are tried. - Early December 2010, I get off the path of least resistance and write a matrix storage class with incomplete Cholesky decomposition. - 31 December 2010, the FEM reformulation works very well. - 1 January 2011, I'm cleaning up this file and readying it for initial release. - 12 - 14 November 2011, further cleanup, improvements, bug fixes, integration into Raw Therapee. +- Late April 2010, I develop interest in this stuff because photos of my + ceramics lack local contrast. +- Mid 2010, it works but is too slow to be useful. +- Fall 2010, various unsuccessful attempts at speeding up are tried. +- Early December 2010, I get off the path of least resistance and write a + matrix storage class with incomplete Cholesky decomposition. +- 31 December 2010, the FEM reformulation works very well. +- 1 January 2011, I'm cleaning up this file and readying it for initial release. +- 12 - 14 November 2011, further cleanup, improvements, bug fixes, integration + into Raw Therapee. -It's likely that I'll take apart and rerelease contents of this file (in the distant future) as most of it isn't edge preserving decomposition -and rather supporting material. SparseConjugateGradient alone is a workhorse I and a few others have been exploiting for a few years. +It's likely that I'll take apart and rerelease contents of this file (in the +distant future) as most of it isn't edge preserving decomposition and rather +supporting material. SparseConjugateGradient alone is a workhorse I and a few +others have been exploiting for a few years. -EdgePreservingDecomposition.h and EdgePreservingDecomposition.cpp are released under the following licence: - � It's free. - � You may not incorporate this code as part of proprietary or commercial software, but via freeware you may use its output for profit. - � You may modify and redistribute, but keep this big comment block intact and not for profit in any way unless I give specific permission. - � If you're unsure about anything else, treat as public domain. - � Don't be a dick. +EdgePreservingDecomposition.h and EdgePreservingDecomposition.cpp are released +under the following licence: +- It's free. +- You may not incorporate this code as part of proprietary or commercial + software, but via freeware you may use its output for profit. +- You may modify and redistribute, but keep this big comment block intact and + not for profit in any way unless I give specific permission. +- If you're unsure about anything else, treat as public domain. +- Don't be a dick. -My email address is my screen name followed by @yahoo.com. I'm also known as ben_s or nonbasketless. Enjoy! +My email address is my screen name followed by @yahoo.com. I'm also known as +ben_s or nonbasketless. Enjoy! */ diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 71c65cfb0..ba7ae693e 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -22,7 +22,7 @@ // //////////////////////////////////////////////////////////////// -#include +#include #include #include "../rtgui/threadutils.h" #include "rtengine.h" @@ -36,7 +36,7 @@ #include "sleef.c" #include "opthelper.h" #include "cplx_wavelet_dec.h" - +#include "median.h" #ifdef _OPENMP #include #endif @@ -48,52 +48,6 @@ #define epsilon 0.001f/(TS*TS) //tolerance -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - -#define med5(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; pp[9]=a9; pp[10]=a10; pp[11]=a11; pp[12]=a12; \ -pp[13]=a13; pp[14]=a14; pp[15]=a15; pp[16]=a16; pp[17]=a17; pp[18]=a18; pp[19]=a19; pp[20]=a20; pp[21]=a21; pp[22]=a22; pp[23]=a23; pp[24]=a24; \ -PIX_SORT(pp[0], pp[1]) ; PIX_SORT(pp[3], pp[4]) ; PIX_SORT(pp[2], pp[4]) ;\ -PIX_SORT(pp[2], pp[3]) ; PIX_SORT(pp[6], pp[7]) ; PIX_SORT(pp[5], pp[7]) ;\ -PIX_SORT(pp[5], pp[6]) ; PIX_SORT(pp[9], pp[10]) ; PIX_SORT(pp[8], pp[10]) ;\ -PIX_SORT(pp[8], pp[9]) ; PIX_SORT(pp[12], pp[13]) ; PIX_SORT(pp[11], pp[13]) ;\ -PIX_SORT(pp[11], pp[12]) ; PIX_SORT(pp[15], pp[16]) ; PIX_SORT(pp[14], pp[16]) ;\ -PIX_SORT(pp[14], pp[15]) ; PIX_SORT(pp[18], pp[19]) ; PIX_SORT(pp[17], pp[19]) ;\ -PIX_SORT(pp[17], pp[18]) ; PIX_SORT(pp[21], pp[22]) ; PIX_SORT(pp[20], pp[22]) ;\ -PIX_SORT(pp[20], pp[21]) ; PIX_SORT(pp[23], pp[24]) ; PIX_SORT(pp[2], pp[5]) ;\ -PIX_SORT(pp[3], pp[6]) ; PIX_SORT(pp[0], pp[6]) ; PIX_SORT(pp[0], pp[3]) ;\ -PIX_SORT(pp[4], pp[7]) ; PIX_SORT(pp[1], pp[7]) ; PIX_SORT(pp[1], pp[4]) ;\ -PIX_SORT(pp[11], pp[14]) ; PIX_SORT(pp[8], pp[14]) ; PIX_SORT(pp[8], pp[11]) ;\ -PIX_SORT(pp[12], pp[15]) ; PIX_SORT(pp[9], pp[15]) ; PIX_SORT(pp[9], pp[12]) ;\ -PIX_SORT(pp[13], pp[16]) ; PIX_SORT(pp[10], pp[16]) ; PIX_SORT(pp[10], pp[13]) ;\ -PIX_SORT(pp[20], pp[23]) ; PIX_SORT(pp[17], pp[23]) ; PIX_SORT(pp[17], pp[20]) ;\ -PIX_SORT(pp[21], pp[24]) ; PIX_SORT(pp[18], pp[24]) ; PIX_SORT(pp[18], pp[21]) ;\ -PIX_SORT(pp[19], pp[22]) ; PIX_SORT(pp[8], pp[17]) ; PIX_SORT(pp[9], pp[18]) ;\ -PIX_SORT(pp[0], pp[18]) ; PIX_SORT(pp[0], pp[9]) ; PIX_SORT(pp[10], pp[19]) ;\ -PIX_SORT(pp[1], pp[19]) ; PIX_SORT(pp[1], pp[10]) ; PIX_SORT(pp[11], pp[20]) ;\ -PIX_SORT(pp[2], pp[20]) ; PIX_SORT(pp[2], pp[11]) ; PIX_SORT(pp[12], pp[21]) ;\ -PIX_SORT(pp[3], pp[21]) ; PIX_SORT(pp[3], pp[12]) ; PIX_SORT(pp[13], pp[22]) ;\ -PIX_SORT(pp[4], pp[22]) ; PIX_SORT(pp[4], pp[13]) ; PIX_SORT(pp[14], pp[23]) ;\ -PIX_SORT(pp[5], pp[23]) ; PIX_SORT(pp[5], pp[14]) ; PIX_SORT(pp[15], pp[24]) ;\ -PIX_SORT(pp[6], pp[24]) ; PIX_SORT(pp[6], pp[15]) ; PIX_SORT(pp[7], pp[16]) ;\ -PIX_SORT(pp[7], pp[19]) ; PIX_SORT(pp[13], pp[21]) ; PIX_SORT(pp[15], pp[23]) ;\ -PIX_SORT(pp[7], pp[13]) ; PIX_SORT(pp[7], pp[15]) ; PIX_SORT(pp[1], pp[9]) ;\ -PIX_SORT(pp[3], pp[11]) ; PIX_SORT(pp[5], pp[17]) ; PIX_SORT(pp[11], pp[17]) ;\ -PIX_SORT(pp[9], pp[17]) ; PIX_SORT(pp[4], pp[10]) ; PIX_SORT(pp[6], pp[12]) ;\ -PIX_SORT(pp[7], pp[14]) ; PIX_SORT(pp[4], pp[6]) ; PIX_SORT(pp[4], pp[7]) ;\ -PIX_SORT(pp[12], pp[14]) ; PIX_SORT(pp[10], pp[14]) ; PIX_SORT(pp[6], pp[7]) ;\ -PIX_SORT(pp[10], pp[12]) ; PIX_SORT(pp[6], pp[10]) ; PIX_SORT(pp[6], pp[17]) ;\ -PIX_SORT(pp[12], pp[17]) ; PIX_SORT(pp[7], pp[17]) ; PIX_SORT(pp[7], pp[10]) ;\ -PIX_SORT(pp[12], pp[18]) ; PIX_SORT(pp[7], pp[12]) ; PIX_SORT(pp[10], pp[18]) ;\ -PIX_SORT(pp[12], pp[20]) ; PIX_SORT(pp[10], pp[20]) ; PIX_SORT(pp[10], pp[12]) ;\ -median=pp[12];} - -#define ELEM_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } - namespace rtengine { @@ -117,135 +71,48 @@ namespace rtengine extern const Settings* settings; -// Median calculation using quicksort -float fq_sort2(float arr[], int n) +void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, const int height, const Median medianType, const int iterations, const int numThreads, float **buffer) { - int low = 0; - int high = n - 1; - int median = (low + high) / 2; + int border = 1; - for (;;) { - if (high <= low) { - return arr[median] ; + switch (medianType) { + case Median::TYPE_3X3_SOFT: + case Median::TYPE_3X3_STRONG: { + border = 1; + break; } - if (high == low + 1) { - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; - } - - return arr[median] ; + case Median::TYPE_5X5_SOFT: { + border = 2; + break; } - int middle = (low + high) / 2; - - if (arr[middle] > arr[high]) { - ELEM_FLOAT_SWAP(arr[middle], arr[high]) ; + case Median::TYPE_5X5_STRONG: { + border = 2; + break; } - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + case Median::TYPE_7X7: { + border = 3; + break; } - if (arr[middle] > arr[low]) { - ELEM_FLOAT_SWAP(arr[middle], arr[low]) ; - } - - ELEM_FLOAT_SWAP(arr[middle], arr[low + 1]) ; - int ll = low + 1; - int hh = high; - - for (;;) { - do { - ll++; - } while (arr[low] > arr[ll]) ; - - do { - hh--; - } while (arr[hh] > arr[low]) ; - - if (hh < ll) { - break; - } - - ELEM_FLOAT_SWAP(arr[ll], arr[hh]) ; - } - - ELEM_FLOAT_SWAP(arr[low], arr[hh]) ; - - if (hh <= median) { - low = ll; - } - - if (hh >= median) { - high = hh - 1; + case Median::TYPE_9X9: { + border = 4; + break; } } -} -float media(float *elements, int N) -{ - - // Order elements (only half of them) - for (int i = 0; i < (N >> 1) + 1; ++i) { - // Find position of minimum element - int min = i; - - for (int j = i + 1; j < N; ++j) - if (elements[j] < elements[min]) { - min = j; - } - - // Put found minimum element in its place - float temp = elements[i]; - elements[i] = elements[min]; - elements[min] = temp; - } - - // Get result - the middle element - return elements[N >> 1]; -} - -void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, const int height, const mediantype medianType, const int iterations, const int numThreads, float **buffer) -{ - int border = 1, numElements, middleElement; - - switch(medianType) { - case MED_3X3SOFT: - case MED_3X3STRONG: - border = 1; - break; - - case MED_5X5SOFT: - border = 2; - break; - - case MED_5X5STRONG: - border = 2; - break; - - case MED_7X7: - border = 3; - numElements = 49; - middleElement = 24; - break; - - default: // includes MED_9X9 - border = 4; - numElements = 81; - middleElement = 40; - } - - float **allocBuffer = NULL; + float **allocBuffer = nullptr; float **medBuffer[2]; medBuffer[0] = src; // we need a buffer if src == dst or if (src != dst && iterations > 1) - if(src == dst || (src != dst && iterations > 1)) { - if(buffer == NULL) { // we didn't get a buufer => create one + if (src == dst || (src != dst && iterations > 1)) { + if (buffer == nullptr) { // we didn't get a buufer => create one allocBuffer = new float*[height]; - for (int i = 0; i < height; i++) { + for (int i = 0; i < height; ++i) { allocBuffer[i] = new float[width]; } @@ -260,151 +127,252 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, float ** medianIn, ** medianOut; int BufferIndex = 0; - for(int iteration = 1; iteration <= iterations; iteration++) { + for (int iteration = 1; iteration <= iterations; ++iteration) { medianIn = medBuffer[BufferIndex]; medianOut = medBuffer[BufferIndex ^ 1]; - if(iteration == 1) { // upper border - for (int i = 0; i < border; i++) - for (int j = 0; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } - -#ifdef _OPENMP - #pragma omp parallel for num_threads(numThreads) if(numThreads>1) -#endif - - for (int i = border; i < height - border; i++) { - if(medianType == MED_3X3SOFT) { - float pp[5], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med2(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1], medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_3X3STRONG) { - float pp[9], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med3(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_5X5SOFT) { - float pp[13]; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - pp[0] = medianIn[i][j]; - pp[1] = medianIn[i - 1][j]; - pp[2] = medianIn[i + 1][j]; - pp[3] = medianIn[i][j + 1]; - pp[4] = medianIn[i][j - 1]; - pp[5] = medianIn[i - 1][j - 1]; - pp[6] = medianIn[i - 1][j + 1]; - pp[7] = medianIn[i + 1][j - 1]; - pp[8] = medianIn[i + 1][j + 1]; - pp[9] = medianIn[i + 2][j]; - pp[10] = medianIn[i - 2][j]; - pp[11] = medianIn[i][j + 2]; - pp[12] = medianIn[i][j - 2]; - fq_sort2(pp, 13); - medianOut[i][j] = pp[6]; - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_5X5STRONG) { - float pp[25], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med5(medianIn[i][j], medianIn[i - 1][j], medianIn[i + 1][j], medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], - medianIn[i - 2][j], medianIn[i + 2][j], medianIn[i][j + 2], medianIn[i][j - 2], medianIn[i - 2][j - 2], medianIn[i - 2][j + 2], medianIn[i + 2][j - 2], medianIn[i + 2][j + 2], - medianIn[i - 2][j + 1], medianIn[i + 2][j + 1], medianIn[i - 1][j + 2], medianIn[i - 1][j - 2], medianIn[i - 2][j - 1], medianIn[i + 2][j - 1], medianIn[i + 1][j + 2], medianIn[i + 1][j - 2], - medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else {// includes MED_7X7 and MED_9X9 - float pp[81]; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - int kk = 0; - - for (int ii = -border; ii <= border; ii++) { - for (int jj = -border; jj <= border; jj++) { - kk++; - pp[kk] = medianIn[i + ii][j + jj]; - } - } - - fq_sort2(pp, numElements); - medianOut[i][j] = pp[middleElement]; - } - - for(; j < width; j++) { + if (iteration == 1) { // upper border + for (int i = 0; i < border; ++i) { + for (int j = 0; j < width; ++j) { medianOut[i][j] = medianIn[i][j]; } } } - if(iteration == 1) { // lower border - for (int i = height - border; i < height; i++) - for (int j = 0; j < width; j++) { +#ifdef _OPENMP + #pragma omp parallel for num_threads(numThreads) if (numThreads>1) schedule(dynamic,16) +#endif + + for (int i = border; i < height - border; ++i) { + int j = 0; + + for (; j < border; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + + switch (medianType) { + case Median::TYPE_3X3_SOFT: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 1][j], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j] + ); + } + + break; + } + + case Median::TYPE_3X3_STRONG: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1] + ); + } + + break; + } + + case Median::TYPE_5X5_SOFT: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 2][j], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 2][j] + ); + } + + break; + } + + case Median::TYPE_5X5_STRONG: { +#ifdef __SSE2__ + + for (; j < width - border - 3; j += 4) { + STVFU( + medianOut[i][j], + median( + LVFU(medianIn[i - 2][j - 2]), + LVFU(medianIn[i - 2][j - 1]), + LVFU(medianIn[i - 2][j]), + LVFU(medianIn[i - 2][j + 1]), + LVFU(medianIn[i - 2][j + 2]), + LVFU(medianIn[i - 1][j - 2]), + LVFU(medianIn[i - 1][j - 1]), + LVFU(medianIn[i - 1][j]), + LVFU(medianIn[i - 1][j + 1]), + LVFU(medianIn[i - 1][j + 2]), + LVFU(medianIn[i][j - 2]), + LVFU(medianIn[i][j - 1]), + LVFU(medianIn[i][j]), + LVFU(medianIn[i][j + 1]), + LVFU(medianIn[i][j + 2]), + LVFU(medianIn[i + 1][j - 2]), + LVFU(medianIn[i + 1][j - 1]), + LVFU(medianIn[i + 1][j]), + LVFU(medianIn[i + 1][j + 1]), + LVFU(medianIn[i + 1][j + 2]), + LVFU(medianIn[i + 2][j - 2]), + LVFU(medianIn[i + 2][j - 1]), + LVFU(medianIn[i + 2][j]), + LVFU(medianIn[i + 2][j + 1]), + LVFU(medianIn[i + 2][j + 2]) + ) + ); + } + +#endif + + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 2][j - 2], + medianIn[i - 2][j - 1], + medianIn[i - 2][j], + medianIn[i - 2][j + 1], + medianIn[i - 2][j + 2], + medianIn[i - 1][j - 2], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i - 1][j + 2], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 1][j + 2], + medianIn[i + 2][j - 2], + medianIn[i + 2][j - 1], + medianIn[i + 2][j], + medianIn[i + 2][j + 1], + medianIn[i + 2][j + 2] + ); + } + + break; + } + + case Median::TYPE_7X7: { +#ifdef __SSE2__ + std::array vpp ALIGNED16; + + for (; j < width - border - 3; j += 4) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + vpp[kk] = LVFU(medianIn[i + ii][j + jj]); + } + } + + STVFU(medianOut[i][j], median(vpp)); + } + +#endif + + std::array pp; + + for (; j < width - border; ++j) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } + } + + medianOut[i][j] = median(pp); + } + + break; + } + + case Median::TYPE_9X9: { +#ifdef __SSE2__ + std::array vpp ALIGNED16; + + for (; j < width - border - 3; j += 4) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + vpp[kk] = LVFU(medianIn[i + ii][j + jj]); + } + } + + STVFU(medianOut[i][j], median(vpp)); + } + +#endif + + std::array pp; + + for (; j < width - border; ++j) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } + } + + medianOut[i][j] = median(pp); + } + + for (; j < width; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + + break; + } + } + + for (; j < width; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + } + + if (iteration == 1) { // lower border + for (int i = height - border; i < height; ++i) { + for (int j = 0; j < width; ++j) { medianOut[i][j] = medianIn[i][j]; } + } } BufferIndex ^= 1; // swap buffers } - if(medianOut != dst) { + if (medianOut != dst) { #ifdef _OPENMP - #pragma omp parallel for num_threads(numThreads) if(numThreads>1) + #pragma omp parallel for num_threads(numThreads) if (numThreads>1) #endif - for(int i = border; i < height - border; i++ ) { - for(int j = border; j < width - border; j++) { + for (int i = border; i < height - border; ++i) { + for (int j = border; j < width - border; ++j) { dst[i][j] = medianOut[i][j]; } } } - if(allocBuffer != NULL) { // we allocated memory, so let's free it now - for (int i = 0; i < height; i++) { + if (allocBuffer != nullptr) { // we allocated memory, so let's free it now + for (int i = 0; i < height; ++i) { delete[] allocBuffer[i]; } @@ -412,18 +380,18 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } } -void ImProcFunctions::Tile_calc (int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip) +void ImProcFunctions::Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip) { - if(kall == 2) { + if (kall == 2) { if (imwidth < tilesize) { numtiles_W = 1; tileWskip = imwidth; tilewidth = imwidth; } else { - numtiles_W = ceil(((float)(imwidth)) / (tilesize - overlap)); - tilewidth = ceil(((float)(imwidth)) / (numtiles_W)) + overlap; + numtiles_W = ceil((static_cast(imwidth)) / (tilesize - overlap)); + tilewidth = ceil((static_cast(imwidth)) / (numtiles_W)) + overlap; tilewidth += (tilewidth & 1); tileWskip = tilewidth - overlap; } @@ -433,14 +401,14 @@ void ImProcFunctions::Tile_calc (int tilesize, int overlap, int kall, int imwidt tileHskip = imheight; tileheight = imheight; } else { - numtiles_H = ceil(((float)(imheight)) / (tilesize - overlap)); - tileheight = ceil(((float)(imheight)) / (numtiles_H)) + overlap; + numtiles_H = ceil((static_cast(imheight)) / (tilesize - overlap)); + tileheight = ceil((static_cast(imheight)) / (numtiles_H)) + overlap; tileheight += (tileheight & 1); tileHskip = tileheight - overlap; } } - if(kall == 0) { + if (kall == 0) { numtiles_W = 1; tileWskip = imwidth; tilewidth = imwidth; @@ -464,13 +432,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //#endif if (dnparams.luma == 0 && dnparams.chroma == 0 && !dnparams.median && !noiseLCurve && !noiseCCurve) { //nothing to do; copy src to dst or do nothing in case src == dst - if(src != dst) { + if (src != dst) { src->copyData(dst); } - if(calclum) { + if (calclum) { delete calclum; - calclum = NULL; + calclum = nullptr; } return; @@ -480,9 +448,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef MyMutex::MyLock lock(FftwMutex); const nrquality nrQuality = (dnparams.smethod == "shal") ? QUALITY_STANDARD : QUALITY_HIGH;//shrink method - const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f / (float) settings->nrhigh : 1.0f; - const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f ); - const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f ); + const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f / static_cast( settings->nrhigh) : 1.0f; + const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f); + const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f); const bool autoch = (settings->leveldnautsimpl == 1 && (dnparams.Cmethod == "AUT" || dnparams.Cmethod == "PRE")) || (settings->leveldnautsimpl == 0 && (dnparams.C2method == "AUTO" || dnparams.C2method == "PREV")); float** lumcalc; @@ -493,39 +461,39 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef bool ponder = false; float ponderCC = 1.f; - if(settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PON") { + if (settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PON") { ponder = true; ponderCC = 0.5f; } - if(settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PRE") { + if (settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PRE") { ponderCC = 0.5f; } - if(settings->leveldnautsimpl == 0 && params->dirpyrDenoise.Cmethod == "PREV") { + if (settings->leveldnautsimpl == 0 && params->dirpyrDenoise.Cmethod == "PREV") { ponderCC = 0.5f; } int metchoice = 0; - if(dnparams.methodmed == "Lonly") { + if (dnparams.methodmed == "Lonly") { metchoice = 1; - } else if(dnparams.methodmed == "Lab") { + } else if (dnparams.methodmed == "Lab") { metchoice = 2; - } else if(dnparams.methodmed == "ab") { + } else if (dnparams.methodmed == "ab") { metchoice = 3; - } else if(dnparams.methodmed == "Lpab") { + } else if (dnparams.methodmed == "Lpab") { metchoice = 4; } const bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); // init luma noisevarL - const float noiseluma = (float) dnparams.luma; - const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : (float) (SQR((noiseluma / 125.0) * (1.0 + noiseluma / 25.0))); + const float noiseluma = static_cast( dnparams.luma); + const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? static_cast (SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : static_cast (SQR((noiseluma / 125.0) * (1.0 + noiseluma / 25.0))); const bool denoiseLuminance = (noisevarL > 0.00001f); //printf("NL=%f \n",noisevarL); - if(useNoiseLCurve || useNoiseCCurve) { + if (useNoiseLCurve || useNoiseCCurve) { int hei = calclum->height; int wid = calclum->width; TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); @@ -538,20 +506,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef lumcalcBuffer = new float[hei * wid]; lumcalc = new float*[(hei)]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { lumcalc[i] = lumcalcBuffer + (i * wid); } ccalcBuffer = new float[hei * wid]; ccalc = new float*[(hei)]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { ccalc[i] = ccalcBuffer + (i * wid); } float cn100Precalc; - if(useNoiseCCurve) { + if (useNoiseCCurve) { cn100Precalc = SQR(1.f + ponderCC * (4.f * noiseCCurve[100.f / 60.f])); } @@ -559,8 +527,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for schedule(dynamic,16) #endif - for(int ii = 0; ii < hei; ii++) { - for(int jj = 0; jj < wid; jj++) { + for (int ii = 0; ii < hei; ++ii) { + for (int jj = 0; jj < wid; ++jj) { float LLum, AAum, BBum; float RL = calclum->r(ii, jj); @@ -571,14 +539,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef Color::rgbxyz(RL, GL, BL, XL, YL, ZL, wpi); Color::XYZ2Lab(XL, YL, ZL, LLum, AAum, BBum); - if(useNoiseLCurve) { + if (useNoiseLCurve) { float epsi = 0.01f; - if(LLum < 2.f) { + if (LLum < 2.f) { LLum = 2.f; //avoid divided by zero } - if(LLum > 32768.f) { + if (LLum > 32768.f) { LLum = 32768.f; // not strictly necessary } @@ -588,10 +556,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef lumcalc[ii][jj] = SQR((kinterm / 125.f) * (1.f + kinterm / 25.f)); } - if(useNoiseCCurve) { + if (useNoiseCCurve) { float cN = sqrtf(SQR(AAum) + SQR(BBum)); - if(cN > 100) { + if (cN > 100) { ccalc[ii][jj] = SQR(1.f + ponderCC * (4.f * noiseCCurve[cN / 60.f])); } else { ccalc[ii][jj] = cn100Precalc; @@ -601,36 +569,32 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } delete calclum; - calclum = NULL; + calclum = nullptr; } const short int imheight = src->height, imwidth = src->width; - if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly" ) { + if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly") { // gamma transform for input data float gam = dnparams.gamma; float gamthresh = 0.001f; - if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG - if(gam < 1.9f) { + if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG + if (gam < 1.9f) { gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7 } else if (gam >= 1.9f && gam <= 3.f) { gam = (1.4f / 1.1f) * gam - 1.41818f; } } - float gamslope = exp(log((double)gamthresh) / gam) / gamthresh; LUTf gamcurve(65536, LUT_CLIP_BELOW); + float gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; - } + if (denoiseMethodRgb) { + Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f); } else { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamman((double)i / 65535.0, gam)) * 32768.0f; - } + Color::gammanf2lut(gamcurve, gam, 65535.f, 32768.f); } // inverse gamma transform for output data @@ -640,61 +604,27 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef LUTf igamcurve(65536, LUT_CLIP_BELOW); - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - igamcurve[i] = (Color::gamma((float)i / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - } + if (denoiseMethodRgb) { + Color::gammaf2lut(igamcurve, igam, igamthresh, igamslope, 32768.f, 65535.f); } else { - for (int i = 0; i < 65536; i++) { - igamcurve[i] = (Color::gamman((float)i / 32768.0f, igam) * 65535.0f); - } + Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f); } const float gain = pow (2.0f, float(expcomp)); - float noisevar_Ldetail = SQR((float)(SQR(100. - dnparams.Ldetail) + 50.*(100. - dnparams.Ldetail)) * TS * 0.5f); - - if(settings->verbose) { - printf("Denoise Lab=%i\n", settings->denoiselabgamma); - } - - // To avoid branches in loops we access the gammatabs by pointers - // modify arbitrary data for Lab..I have test : nothing, gamma 2.6 11 - gamma 4 5 - gamma 5.5 10 - // we can put other as gamma g=2.6 slope=11, etc. - // but noting to do with real gamma !!!: it's only for data Lab # data RGB - // finally I opted fot gamma55 and with options we can change - - LUTf *denoisegamtab; - LUTf *denoiseigamtab; - - switch(settings->denoiselabgamma) { - case 0: - denoisegamtab = &(Color::gammatab_26_11); - denoiseigamtab = &(Color::igammatab_26_11); - break; - - case 1: - denoisegamtab = &(Color::gammatab_4); - denoiseigamtab = &(Color::igammatab_4); - break; - - default: - denoisegamtab = &(Color::gammatab_55); - denoiseigamtab = &(Color::igammatab_55); - break; - } + float noisevar_Ldetail = SQR(static_cast(SQR(100. - dnparams.Ldetail) + 50.*(100. - dnparams.Ldetail)) * TS * 0.5f); array2D tilemask_in(TS, TS); array2D tilemask_out(TS, TS); - if(denoiseLuminance) { + if (denoiseLuminance) { const int border = MAX(2, TS / 16); - for (int i = 0; i < TS; i++) { + for (int i = 0; i < TS; ++i) { float i1 = abs((i > TS / 2 ? i - TS + 1 : i)); float vmask = (i1 < border ? SQR(sin((M_PI * i1) / (2 * border))) : 1.0f); float vmask2 = (i1 < 2 * border ? SQR(sin((M_PI * i1) / (2 * border))) : 1.0f); - for (int j = 0; j < TS; j++) { + for (int j = 0; j < TS; ++j) { float j1 = abs((j > TS / 2 ? j - TS + 1 : j)); tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((M_PI * j1) / (2 * border))) : 1.0f)) + epsilon; tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((M_PI * j1) / (2 * border))) : 1.0f)) + epsilon; @@ -706,28 +636,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int tilesize; int overlap; - if(settings->leveldnti == 0) { + if (settings->leveldnti == 0) { tilesize = 1024; overlap = 128; } - if(settings->leveldnti == 1) { + if (settings->leveldnti == 1) { tilesize = 768; overlap = 96; } int numTries = 0; - if(ponder) { + if (ponder) { printf("Tiled denoise processing caused by Automatic Multizone mode\n"); } bool memoryAllocationFailed = false; do { - numTries++; + ++numTries; - if(numTries == 2) { + if (numTries == 2) { printf("1st denoise pass failed due to insufficient memory, starting 2nd (tiled) pass now...\n"); } @@ -740,7 +670,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //output buffer Imagefloat * dsttmp; - if(numtiles == 1) { + if (numtiles == 1) { dsttmp = dst; } else { dsttmp = new Imagefloat(imwidth, imheight); @@ -748,12 +678,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for #endif - for(int i = 0; i < imheight; i++) - for(int j = 0; j < imwidth; j++) { + for (int i = 0; i < imheight; ++i) { + for (int j = 0; j < imwidth; ++j) { dsttmp->r(i, j) = 0.f; dsttmp->g(i, j) = 0.f; dsttmp->b(i, j) = 0.f; } + } } //now we have tile dimensions, overlaps @@ -763,17 +694,17 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // outside the parallel region and use them inside the parallel region. // calculate max size of numblox_W. - int max_numblox_W = ceil(((float)(MIN(imwidth, tilewidth))) / (offset)) + 2 * blkrad; + int max_numblox_W = ceil((static_cast(MIN(imwidth, tilewidth))) / (offset)) + 2 * blkrad; // calculate min size of numblox_W. - int min_numblox_W = ceil(((float)((MIN(imwidth, ((numtiles_W - 1) * tileWskip) + tilewidth) ) - ((numtiles_W - 1) * tileWskip))) / (offset)) + 2 * blkrad; + int min_numblox_W = ceil((static_cast((MIN(imwidth, ((numtiles_W - 1) * tileWskip) + tilewidth)) - ((numtiles_W - 1) * tileWskip))) / (offset)) + 2 * blkrad; // these are needed only for creation of the plans and will be freed before entering the parallel loop fftwf_plan plan_forward_blox[2]; fftwf_plan plan_backward_blox[2]; - if(denoiseLuminance) { - float *Lbloxtmp = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof (float)); - float *fLbloxtmp = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof (float)); + if (denoiseLuminance) { + float *Lbloxtmp = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof (float))); + float *fLbloxtmp = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof (float))); int nfwd[2] = {TS, TS}; @@ -782,12 +713,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; // Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit - plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS * TS, fLbloxtmp, NULL, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS * TS, Lbloxtmp, NULL, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS * TS, fLbloxtmp, NULL, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS * TS, Lbloxtmp, NULL, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - fftwf_free ( Lbloxtmp ); - fftwf_free ( fLbloxtmp ); + plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, nullptr, 1, TS * TS, fLbloxtmp, nullptr, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, nullptr, 1, TS * TS, Lbloxtmp, nullptr, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, nullptr, 1, TS * TS, fLbloxtmp, nullptr, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, nullptr, 1, TS * TS, Lbloxtmp, nullptr, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + fftwf_free (Lbloxtmp); + fftwf_free (fLbloxtmp); } #ifndef _OPENMP @@ -796,7 +727,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles int numthreads = MIN(numtiles, omp_get_max_threads()); - if(options.rgbDenoiseThreadLimit > 0) { + if (options.rgbDenoiseThreadLimit > 0) { numthreads = MIN(numthreads, options.rgbDenoiseThreadLimit); } @@ -804,20 +735,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef denoiseNestedLevels = omp_get_max_threads() / numthreads; bool oldNested = omp_get_nested(); - if(denoiseNestedLevels < 2) { + if (denoiseNestedLevels < 2) { denoiseNestedLevels = 1; } else { omp_set_nested(true); } - if(options.rgbDenoiseThreadLimit > 0) + if (options.rgbDenoiseThreadLimit > 0) while(denoiseNestedLevels * numthreads > options.rgbDenoiseThreadLimit) { denoiseNestedLevels--; } #endif - if(settings->verbose) { + if (settings->verbose) { printf("RGB_denoise uses %d main thread(s) and up to %d nested thread(s) for each main thread\n", numthreads, denoiseNestedLevels); } @@ -825,11 +756,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float *LbloxArray[denoiseNestedLevels * numthreads]; float *fLbloxArray[denoiseNestedLevels * numthreads]; - if(numtiles > 1 && denoiseLuminance) - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { - LbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); - fLbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); + if (numtiles > 1 && denoiseLuminance) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { + LbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); + fLbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); } + } TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); //inverse matrix user select @@ -847,17 +779,16 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} }; - // begin tile processing of image #ifdef _OPENMP - #pragma omp parallel num_threads(numthreads) if(numthreads>1) + #pragma omp parallel num_threads(numthreads) if (numthreads>1) #endif { int pos; float* noisevarlum; float* noisevarchrom; - if(numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) { + if (numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) { noisevarlum = lumcalcBuffer; noisevarchrom = ccalcBuffer; } else { @@ -879,28 +810,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int height = tilebottom - tiletop; int width2 = (width + 1) / 2; float realred, realblue; - float interm_med = (float) dnparams.chroma / 10.0; + float interm_med = static_cast( dnparams.chroma) / 10.0; float intermred, intermblue; - if(dnparams.redchro > 0.) { + if (dnparams.redchro > 0.) { intermred = (dnparams.redchro / 10.); } else { - intermred = (float) dnparams.redchro / 7.0; //increase slower than linear for more sensit + intermred = static_cast( dnparams.redchro) / 7.0; //increase slower than linear for more sensit } - if(dnparams.bluechro > 0.) { + if (dnparams.bluechro > 0.) { intermblue = (dnparams.bluechro / 10.); } else { - intermblue = (float) dnparams.bluechro / 7.0; //increase slower than linear for more sensit + intermblue = static_cast( dnparams.bluechro) / 7.0; //increase slower than linear for more sensit } - if(ponder && kall == 2) { + if (ponder && kall == 2) { interm_med = ch_M[pos] / 10.f; intermred = max_r[pos] / 10.f; intermblue = max_b[pos] / 10.f; } - if(ponder && kall == 0) { + if (ponder && kall == 0) { interm_med = 0.01f; intermred = 0.f; intermblue = 0.f; @@ -908,13 +839,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef realred = interm_med + intermred; - if (realred < 0.f) { + if (realred <= 0.f) { realred = 0.001f; } realblue = interm_med + intermblue; - if (realblue < 0.f) { + if (realblue <= 0.f) { realblue = 0.001f; } @@ -931,29 +862,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef if (isRAW) {//image is raw; use channel differences for chroma channels - if(!denoiseMethodRgb) { //lab mode + if (!denoiseMethodRgb) { //lab mode //modification Jacques feb 2013 and july 2014 #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float R_ = gain * src->r(i, j); float G_ = gain * src->g(i, j); float B_ = gain * src->b(i, j); - R_ = (*denoiseigamtab)[R_]; - G_ = (*denoiseigamtab)[G_]; - B_ = (*denoiseigamtab)[B_]; + R_ = Color::denoiseIGammaTab[R_]; + G_ = Color::denoiseIGammaTab[G_]; + B_ = Color::denoiseIGammaTab[B_]; //apply gamma noise standard (slider) - R_ = R_ < 65535.0f ? gamcurve[R_] : (Color::gammanf(R_ / 65535.f, gam) * 32768.0f); - G_ = G_ < 65535.0f ? gamcurve[G_] : (Color::gammanf(G_ / 65535.f, gam) * 32768.0f); - B_ = B_ < 65535.0f ? gamcurve[B_] : (Color::gammanf(B_ / 65535.f, gam) * 32768.0f); + R_ = R_ < 65535.f ? gamcurve[R_] : (Color::gammanf(R_ / 65535.f, gam) * 32768.f); + G_ = G_ < 65535.f ? gamcurve[G_] : (Color::gammanf(G_ / 65535.f, gam) * 32768.f); + B_ = B_ < 65535.f ? gamcurve[B_] : (Color::gammanf(B_ / 65535.f, gam) * 32768.f); //true conversion xyz=>Lab float X, Y, Z; @@ -967,8 +898,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef labdn->a[i1][j1] = a; labdn->b[i1][j1] = b; - if(((i1 | j1) & 1) == 0) { - if(numTries == 1) { + if (((i1 | j1) & 1) == 0) { + if (numTries == 1) { noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseLCurve ? lumcalc[i >> 1][j >> 1] : noisevarL; noisevarchrom[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseCCurve ? maxNoiseVarab * ccalc[i >> 1][j >> 1] : 1.f; } else { @@ -982,29 +913,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } } else {//RGB mode #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float X = gain * src->r(i, j); float Y = gain * src->g(i, j); float Z = gain * src->b(i, j); //conversion colorspace to determine luminance with no gamma - X = X < 65535.0f ? gamcurve[X] : (Color::gamma((double)X / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma((double)Y / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma((double)Z / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + X = X < 65535.f ? gamcurve[X] : (Color::gammaf(X / 65535.f, gam, gamthresh, gamslope) * 32768.f); + Y = Y < 65535.f ? gamcurve[Y] : (Color::gammaf(Y / 65535.f, gam, gamthresh, gamslope) * 32768.f); + Z = Z < 65535.f ? gamcurve[Z] : (Color::gammaf(Z / 65535.f, gam, gamthresh, gamslope) * 32768.f); //end chroma labdn->L[i1][j1] = Y; labdn->a[i1][j1] = (X - Y); labdn->b[i1][j1] = (Y - Z); - if(((i1 | j1) & 1) == 0) { - if(numTries == 1) { + if (((i1 | j1) & 1) == 0) { + if (numTries == 1) { noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseLCurve ? lumcalc[i >> 1][j >> 1] : noisevarL; noisevarchrom[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseCCurve ? maxNoiseVarab * ccalc[i >> 1][j >> 1] : 1.f; } else { @@ -1017,13 +948,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } } else {//image is not raw; use Lab parametrization #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float L, a, b; float rLum = src->r(i, j) ; //for denoise curves @@ -1038,9 +969,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float btmp = Color::igammatab_srgb[ src->b(i, j) ]; //modification Jacques feb 2013 // gamma slider different from raw - rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp / 65535.0, gam) * 32768.0f); - gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp / 65535.0, gam) * 32768.0f); - btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp / 65535.0, gam) * 32768.0f); + rtmp = rtmp < 65535.f ? gamcurve[rtmp] : (Color::gammanf(rtmp / 65535.f, gam) * 32768.f); + gtmp = gtmp < 65535.f ? gamcurve[gtmp] : (Color::gammanf(gtmp / 65535.f, gam) * 32768.f); + btmp = btmp < 65535.f ? gamcurve[btmp] : (Color::gammanf(btmp / 65535.f, gam) * 32768.f); float X, Y, Z; Color::rgbxyz(rtmp, gtmp, btmp, X, Y, Z, wp); @@ -1051,24 +982,24 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef labdn->a[i1][j1] = a; labdn->b[i1][j1] = b; - if(((i1 | j1) & 1) == 0) { + if (((i1 | j1) & 1) == 0) { float Llum, alum, blum; - if(useNoiseLCurve || useNoiseCCurve) { + if (useNoiseLCurve || useNoiseCCurve) { float XL, YL, ZL; Color::rgbxyz(rLum, gLum, bLum, XL, YL, ZL, wp); Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); } - if(useNoiseLCurve) { + if (useNoiseLCurve) { float kN = Llum; float epsi = 0.01f; - if(kN < 2.f) { + if (kN < 2.f) { kN = 2.f; } - if(kN > 32768.f) { + if (kN > 32768.f) { kN = 32768.f; } @@ -1080,12 +1011,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = noisevarL; } - if(useNoiseCCurve) { + if (useNoiseCCurve) { float aN = alum; float bN = blum; float cN = sqrtf(SQR(aN) + SQR(bN)); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero ??? } @@ -1105,23 +1036,23 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample //the first level only, 7 means subsample the first three levels, etc. //actual implementation only works with subsampling set to 1 - float interm_medT = (float) dnparams.chroma / 10.0; + float interm_medT = static_cast( dnparams.chroma) / 10.0; bool execwavelet = true; - if(!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) { + if (!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) { execwavelet = false; //do not exec wavelet if sliders luminance and chroma are very small and median need } //we considered user don't want wavelet - if(settings->leveldnautsimpl == 1 && dnparams.Cmethod != "MAN") { + if (settings->leveldnautsimpl == 1 && dnparams.Cmethod != "MAN") { execwavelet = true; } - if(settings->leveldnautsimpl == 0 && dnparams.C2method != "MANU") { + if (settings->leveldnautsimpl == 0 && dnparams.C2method != "MANU") { execwavelet = true; } - if(execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 + if (execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 wavelet_decomposition* Ldecomp; wavelet_decomposition* adecomp; @@ -1129,66 +1060,66 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float maxreal = max(realred, realblue); //increase the level of wavelet if user increase much or very much sliders - if( maxreal < 8.f) { + if (maxreal < 8.f) { levwav = 5; - } else if( maxreal < 10.f) { + } else if (maxreal < 10.f) { levwav = 6; - } else if( maxreal < 15.f) { + } else if (maxreal < 15.f) { levwav = 7; } else { levwav = 8; //maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 } - if(nrQuality == QUALITY_HIGH) { + if (nrQuality == QUALITY_HIGH) { levwav += settings->nrwavlevel; //increase level for enhanced mode } - if(levwav > 8) { + if (levwav > 8) { levwav = 8; } int minsizetile = min(tilewidth, tileheight); int maxlev2 = 8; - if(minsizetile < 256) { + if (minsizetile < 256) { maxlev2 = 7; } - if(minsizetile < 128) { + if (minsizetile < 128) { maxlev2 = 6; } - if(minsizetile < 64) { + if (minsizetile < 64) { maxlev2 = 5; } levwav = min(maxlev2, levwav); - // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); + // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b); Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(Ldecomp->memoryAllocationFailed) { + if (Ldecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } float madL[8][3]; - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { // precalculate madL, because it's used in adecomp and bdecomp int maxlvl = Ldecomp->maxlevel(); #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_L = Ldecomp->level_W(lvl); int Hlvl_L = Ldecomp->level_H(lvl); float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); } else { madL[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); @@ -1204,29 +1135,30 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef adecomp = new wavelet_decomposition (labdn->a[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(adecomp->memoryAllocationFailed) { + if (adecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + if (!memoryAllocationFailed) { + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { memoryAllocationFailed = true; } + } } } - if(!memoryAllocationFailed) { - if(kall == 0) { + if (!memoryAllocationFailed) { + if (kall == 0) { Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb); chresidtemp = chresid; chmaxresidtemp = chmaxresid; @@ -1237,32 +1169,33 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete adecomp; - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(bdecomp->memoryAllocationFailed) { + if (bdecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + if (!memoryAllocationFailed) { + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { memoryAllocationFailed = true; } + } } } - if(!memoryAllocationFailed) { - if(kall == 0) { + if (!memoryAllocationFailed) { + if (kall == 0) { Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb); chresid += chresidtemp; chmaxresid += chmaxresidtemp; @@ -1276,36 +1209,38 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete bdecomp; - if(!memoryAllocationFailed) { - if(denoiseLuminance) { + if (!memoryAllocationFailed) { + if (denoiseLuminance) { int edge = 0; - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) { //enhance mode + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { memoryAllocationFailed = true; } + } } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { // copy labdn->L to Lin before it gets modified by reconstruction Lin = new array2D(width, height); #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { (*Lin)[i][j] = labdn->L[i][j]; } + } Ldecomp->reconstruct(labdn->L[0]); } @@ -1316,78 +1251,78 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete Ldecomp; } - if(!memoryAllocationFailed) { - if( (metchoice == 1 || metchoice == 2 || metchoice == 3 || metchoice == 4) && dnparams.median) { + if (!memoryAllocationFailed) { + if ((metchoice == 1 || metchoice == 2 || metchoice == 3 || metchoice == 4) && dnparams.median) { float** tmL; int wid = labdn->W; int hei = labdn->H; tmL = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { tmL[i] = new float[wid]; } - mediantype medianTypeL = MED_3X3SOFT; - mediantype medianTypeAB = MED_3X3SOFT; + Median medianTypeL = Median::TYPE_3X3_SOFT; + Median medianTypeAB = Median::TYPE_3X3_SOFT; - if(dnparams.medmethod == "soft") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_3X3SOFT; + if (dnparams.medmethod == "soft") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_3X3_SOFT; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_3X3SOFT; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_3X3_SOFT; } - } else if(dnparams.medmethod == "33") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_3X3STRONG; + } else if (dnparams.medmethod == "33") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_3X3_STRONG; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_3X3STRONG; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_3X3_STRONG; } - } else if(dnparams.medmethod == "55soft") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_5X5SOFT; + } else if (dnparams.medmethod == "55soft") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_5X5_SOFT; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_5X5SOFT; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_5X5_SOFT; } - } else if(dnparams.medmethod == "55") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_5X5STRONG; + } else if (dnparams.medmethod == "55") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_5X5_STRONG; } else { - medianTypeL = MED_3X3STRONG; - medianTypeAB = MED_5X5STRONG; + medianTypeL = Median::TYPE_3X3_STRONG; + medianTypeAB = Median::TYPE_5X5_STRONG; } - } else if(dnparams.medmethod == "77") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_7X7; + } else if (dnparams.medmethod == "77") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_7X7; } else { - medianTypeL = MED_3X3STRONG; - medianTypeAB = MED_7X7; + medianTypeL = Median::TYPE_3X3_STRONG; + medianTypeAB = Median::TYPE_7X7; } - } else if(dnparams.medmethod == "99") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_9X9; + } else if (dnparams.medmethod == "99") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_9X9; } else { - medianTypeL = MED_5X5SOFT; - medianTypeAB = MED_9X9; + medianTypeL = Median::TYPE_5X5_SOFT; + medianTypeAB = Median::TYPE_9X9; } } if (metchoice == 1 || metchoice == 2 || metchoice == 4) { - Median_Denoise( labdn->L, labdn->L, wid, hei, medianTypeL, dnparams.passes, denoiseNestedLevels, tmL); + Median_Denoise(labdn->L, labdn->L, wid, hei, medianTypeL, dnparams.passes, denoiseNestedLevels, tmL); } - if(metchoice == 2 || metchoice == 3 || metchoice == 4) { - Median_Denoise( labdn->a, labdn->a, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); - Median_Denoise( labdn->b, labdn->b, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + if (metchoice == 2 || metchoice == 3 || metchoice == 4) { + Median_Denoise(labdn->a, labdn->a, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + Median_Denoise(labdn->b, labdn->b, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); } - for (int i = 0; i < hei; i++) { - delete [] tmL[i]; + for (int i = 0; i < hei; ++i) { + delete[] tmL[i]; } - delete [] tmL; + delete[] tmL; } //wavelet denoised L channel @@ -1398,8 +1333,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // blocks are not the same thing as tiles! // calculation for detail recovery blocks - const int numblox_W = ceil(((float)(width)) / (offset)) + 2 * blkrad; - const int numblox_H = ceil(((float)(height)) / (offset)) + 2 * blkrad; + const int numblox_W = ceil((static_cast(width)) / (offset)) + 2 * blkrad; + const int numblox_H = ceil((static_cast(height)) / (offset)) + 2 * blkrad; @@ -1410,23 +1345,24 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // Main detail recovery algorithm: Block loop //DCT block data storage - if(denoiseLuminance /*&& execwavelet*/) { + if (denoiseLuminance /*&& execwavelet*/) { //residual between input and denoised L channel array2D Ldetail(width, height, ARRAY2D_CLEAR_DATA); //pixel weight array2D totwt(width, height, ARRAY2D_CLEAR_DATA); //weight for combining DCT blocks - if(numtiles == 1) - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { - LbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); - fLbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); + if (numtiles == 1) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { + LbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); + fLbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); } + } #ifdef _RT_NESTED_OPENMP int masterThread = omp_get_thread_num(); #endif #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { #ifdef _RT_NESTED_OPENMP @@ -1443,12 +1379,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for #endif - for (int vblk = 0; vblk < numblox_H; vblk++) { + for (int vblk = 0; vblk < numblox_H; ++vblk) { int top = (vblk - blkrad) * offset; float * datarow = pBuf + blkrad * offset; - for (int i = 0; i < TS; i++) { + for (int i = 0; i < TS; ++i) { int row = top + i; int rr = row; @@ -1458,40 +1394,40 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef rr = MAX(0, 2 * height - 2 - row); } - for (int j = 0; j < labdn->W; j++) { + for (int j = 0; j < labdn->W; ++j) { datarow[j] = ((*Lin)[rr][j] - labdn->L[rr][j]); } - for (int j = -blkrad * offset; j < 0; j++) { + for (int j = -blkrad * offset; j < 0; ++j) { datarow[j] = datarow[MIN(-j, width - 1)]; } - for (int j = width; j < width + TS + blkrad * offset; j++) { + for (int j = width; j < width + TS + blkrad * offset; ++j) { datarow[j] = datarow[MAX(0, 2 * width - 2 - j)]; }//now we have a padded data row //now fill this row of the blocks with Lab high pass data - for (int hblk = 0; hblk < numblox_W; hblk++) { + for (int hblk = 0; hblk < numblox_W; ++hblk) { int left = (hblk - blkrad) * offset; int indx = (hblk) * TS; //index of block in malloc - if(top + i >= 0 && top + i < height) { + if (top + i >= 0 && top + i < height) { int j; - for (j = 0; j < min((-left), TS); j++) { + for (j = 0; j < min((-left), TS); ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } - for (; j < min(TS, width - left); j++) { + for (; j < min(TS, width - left); ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data totwt[top + i][left + j] += tilemask_in[i][j] * tilemask_out[i][j]; } - for (; j < TS; j++) { + for (; j < TS; ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } } else { - for (int j = 0; j < TS; j++) { + for (int j = 0; j < TS; ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } } @@ -1502,7 +1438,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //fftwf_print_plan (plan_forward_blox); - if(numblox_W == max_numblox_W) { + if (numblox_W == max_numblox_W) { fftwf_execute_r2r(plan_forward_blox[0], Lblox, fLblox); // DCT an entire row of tiles } else { fftwf_execute_r2r(plan_forward_blox[1], Lblox, fLblox); // DCT an entire row of tiles @@ -1512,14 +1448,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // now process the vblk row of blocks for noise reduction - for (int hblk = 0; hblk < numblox_W; hblk++) { - RGBtile_denoise (fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer ); + for (int hblk = 0; hblk < numblox_W; ++hblk) { + RGBtile_denoise (fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer); }//end of horizontal block loop //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //now perform inverse FT of an entire row of blocks - if(numblox_W == max_numblox_W) { + if (numblox_W == max_numblox_W) { fftwf_execute_r2r(plan_backward_blox[0], fLblox, Lblox); //for DCT } else { fftwf_execute_r2r(plan_backward_blox[1], fLblox, Lblox); //for DCT @@ -1528,7 +1464,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int topproc = (vblk - blkrad) * offset; //add row of blocks to output image tile - RGBoutput_tile_row (Lblox, Ldetail, tilemask_out, height, width, topproc ); + RGBoutput_tile_row (Lblox, Ldetail, tilemask_out, height, width, topproc); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1540,11 +1476,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { //may want to include masking threshold for large hipass data to preserve edges/detail labdn->L[i][j] += Ldetail[i][j] / totwt[i][j]; //note that labdn initially stores the denoised hipass data } @@ -1559,22 +1495,22 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float Hmask[width + 1] ALIGNED16; float newGain; - if(numtiles > 1) { - for (int i = 0; i < height; i++) { + if (numtiles > 1) { + for (int i = 0; i < height; ++i) { Vmask[i] = 1; } newGain = 1.f; - if(isRAW) { + if (isRAW) { newGain = gain; } - for (int j = 0; j < width; j++) { + for (int j = 0; j < width; ++j) { Hmask[j] = 1.f / newGain; } - for (int i = 0; i < overlap; i++) { + for (int i = 0; i < overlap; ++i) { float mask = SQR(xsinf((M_PI * i) / (2 * overlap))); if (tiletop > 0) { @@ -1599,7 +1535,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //convert back to RGB and write to destination array if (isRAW) { - if(!denoiseMethodRgb) {//Lab mode + if (!denoiseMethodRgb) {//Lab mode realred /= 100.f; realblue /= 100.f; @@ -1607,10 +1543,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for schedule(dynamic,16) num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; //modification Jacques feb 2013 //true conversion Lab==>xyz @@ -1619,7 +1555,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float b = labdn->b[i1][j1]; float c_h = SQR(a) + SQR(b); - if(c_h > 9000000.f) { + if (c_h > 9000000.f) { a *= 1.f + qhighFactor * realred; b *= 1.f + qhighFactor * realblue; } @@ -1636,11 +1572,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef b_ = b_ < 32768.f ? igamcurve[b_] : (Color::gammanf(b_ / 32768.f, igam) * 65535.f); //readapt arbitrary gamma (inverse from beginning) - r_ = (*denoisegamtab)[r_]; - g_ = (*denoisegamtab)[g_]; - b_ = (*denoisegamtab)[b_]; + r_ = Color::denoiseGammaTab[r_]; + g_ = Color::denoiseGammaTab[g_]; + b_ = Color::denoiseGammaTab[b_]; - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * r_; dsttmp->g(i, j) = newGain * g_; dsttmp->b(i, j) = newGain * b_; @@ -1657,14 +1593,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float c_h = sqrt(SQR(labdn->a[i1][j1]) + SQR(labdn->b[i1][j1])); - if(c_h > 3000.f) { + if (c_h > 3000.f) { labdn->a[i1][j1] *= 1.f + qhighFactor * realred / 100.f; labdn->b[i1][j1] *= 1.f + qhighFactor * realblue / 100.f; } @@ -1674,11 +1610,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float Z = Y - (labdn->b[i1][j1]); - X = X < 32768.0f ? igamcurve[X] : (Color::gamma((float)X / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - Y = Y < 32768.0f ? igamcurve[Y] : (Color::gamma((float)Y / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - Z = Z < 32768.0f ? igamcurve[Z] : (Color::gamma((float)Z / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + X = X < 32768.f ? igamcurve[X] : (Color::gammaf(X / 32768.f, igam, igamthresh, igamslope) * 65535.f); + Y = Y < 32768.f ? igamcurve[Y] : (Color::gammaf(Y / 32768.f, igam, igamthresh, igamslope) * 65535.f); + Z = Z < 32768.f ? igamcurve[Z] : (Color::gammaf(Z / 32768.f, igam, igamthresh, igamslope) * 65535.f); - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * X; dsttmp->g(i, j) = newGain * Y; dsttmp->b(i, j) = newGain * Z; @@ -1697,10 +1633,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; //modification Jacques feb 2013 float L = labdn->L[i1][j1]; @@ -1708,7 +1644,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float b = labdn->b[i1][j1]; float c_h = sqrt(SQR(a) + SQR(b)); - if(c_h > 3000.f) { + if (c_h > 3000.f) { a *= 1.f + qhighFactor * realred / 100.f; b *= 1.f + qhighFactor * realblue / 100.f; } @@ -1719,11 +1655,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float r_, g_, b_; Color::xyz2rgb(X, Y, Z, r_, g_, b_, wip); //gamma slider is different from Raw - r_ = r_ < 32768.0f ? igamcurve[r_] : (Color::gamman((float)r_ / 32768.0f, igam) * 65535.0f); - g_ = g_ < 32768.0f ? igamcurve[g_] : (Color::gamman((float)g_ / 32768.0f, igam) * 65535.0f); - b_ = b_ < 32768.0f ? igamcurve[b_] : (Color::gamman((float)b_ / 32768.0f, igam) * 65535.0f); + 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); + b_ = b_ < 32768.f ? igamcurve[b_] : (Color::gammanf(b_ / 32768.f, igam) * 65535.f); - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * r_; dsttmp->g(i, j) = newGain * g_; dsttmp->b(i, j) = newGain * b_; @@ -1742,22 +1678,22 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete labdn; - if(denoiseLuminance) { + if (denoiseLuminance) { delete Lin; } }//end of tile row }//end of tile loop - if(numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) { - delete [] noisevarlum; - delete [] noisevarchrom; + if (numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) { + delete[] noisevarlum; + delete[] noisevarchrom; } } - if(denoiseLuminance) { - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { + if (denoiseLuminance) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { fftwf_free(LbloxArray[i]); fftwf_free(fLbloxArray[i]); } @@ -1768,10 +1704,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #endif //copy denoised image to output - if(numtiles > 1) { - if(!memoryAllocationFailed) { + if (numtiles > 1) { + if (!memoryAllocationFailed) { dsttmp->copyData(dst); - } else if(dst != src) { + } else if (dst != src) { src->copyData(dst); } @@ -1783,25 +1719,26 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for #endif - for(int i = 0; i < dst->height; i++) - for(int j = 0; j < dst->width; j++) { + for (int i = 0; i < dst->height; ++i) { + for (int j = 0; j < dst->width; ++j) { dst->r(i, j) = Color::gammatab_srgb[ dst->r(i, j) ]; dst->g(i, j) = Color::gammatab_srgb[ dst->g(i, j) ]; dst->b(i, j) = Color::gammatab_srgb[ dst->b(i, j) ]; } + } } - if(denoiseLuminance) { + if (denoiseLuminance) { // destroy the plans - fftwf_destroy_plan( plan_forward_blox[0] ); - fftwf_destroy_plan( plan_backward_blox[0] ); - fftwf_destroy_plan( plan_forward_blox[1] ); - fftwf_destroy_plan( plan_backward_blox[1] ); + fftwf_destroy_plan(plan_forward_blox[0]); + fftwf_destroy_plan(plan_backward_blox[0]); + fftwf_destroy_plan(plan_forward_blox[1]); + fftwf_destroy_plan(plan_backward_blox[1]); fftwf_cleanup(); } } while(memoryAllocationFailed && numTries < 2 && (options.rgbDenoiseThreadLimit == 0) && !ponder); - if(memoryAllocationFailed) { + if (memoryAllocationFailed) { printf("tiled denoise failed due to isufficient memory. Output is not denoised!\n"); } @@ -1809,13 +1746,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //median 3x3 in complement on RGB - if(dnparams.methodmed == "RGB" && dnparams.median) { + if (dnparams.methodmed == "RGB" && dnparams.median) { //printf("RGB den\n"); int wid = dst->width, hei = dst->height; float** tm; tm = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { tm[i] = new float[wid]; } @@ -1830,135 +1767,125 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int methmed = 0; int border = 1; - if(dnparams.rgbmethod == "soft") { + if (dnparams.rgbmethod == "soft") { methmed = 0; - } else if(dnparams.rgbmethod == "33") { + } else if (dnparams.rgbmethod == "33") { methmed = 1; - } else if(dnparams.rgbmethod == "55") { + } else if (dnparams.rgbmethod == "55") { methmed = 3; border = 2; - } else if(dnparams.rgbmethod == "55soft") { + } else if (dnparams.rgbmethod == "55soft") { methmed = 2; border = 2; } - for(int iteration = 1; iteration <= dnparams.passes; iteration++) { + for (int iteration = 1; iteration <= dnparams.passes; ++iteration) { #pragma omp parallel { - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), tm[i][j]); //3x3 soft + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1)); //3x3 soft } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), tm[i][j]); //3x3 + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1)); //3x3 } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), source->r(i - 2, j), source->r(i + 2, j), source->r(i, j + 2), source->r(i, j - 2), source->r(i - 2, j - 2), source->r(i - 2, j + 2), source->r(i + 2, j - 2), source->r(i + 2, j + 2), - source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2), - tm[i][j]);//5x5 + source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2));//5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->r(i, j); - pp[1] = source->r(i - 1, j); - pp[2] = source->r(i + 1, j); - pp[3] = source->r(i, j + 1); - pp[4] = source->r(i, j - 1); - pp[5] = source->r(i - 1, j - 1); - pp[6] = source->r(i - 1, j + 1); - pp[7] = source->r(i + 1, j - 1); - pp[8] = source->r(i + 1, j + 1); - pp[9] = source->r(i + 2, j); - pp[10] = source->r(i - 2, j); - pp[11] = source->r(i, j + 2); - pp[12] = source->r(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->r(i, j), + source->r(i - 1, j), + source->r(i + 1, j), + source->r(i, j + 1), + source->r(i, j - 1), + source->r(i - 1, j - 1), + source->r(i - 1, j + 1), + source->r(i + 1, j - 1), + source->r(i + 1, j + 1), + source->r(i + 2, j), + source->r(i - 2, j), + source->r(i, j + 2), + source->r(i, j - 2) + ); // 5x5 soft } + } } } #ifdef _OPENMP #pragma omp for nowait #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->r(i, j) = tm[i][j]; } } - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), tm[i][j]); + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1)); } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), tm[i][j]); + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1)); } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), source->b(i - 2, j), source->b(i + 2, j), source->b(i, j + 2), source->b(i, j - 2), source->b(i - 2, j - 2), source->b(i - 2, j + 2), source->b(i + 2, j - 2), source->b(i + 2, j + 2), - source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2), - tm[i][j]);//5x5 + source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2)); // 5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->b(i, j); - pp[1] = source->b(i - 1, j); - pp[2] = source->b(i + 1, j); - pp[3] = source->b(i, j + 1); - pp[4] = source->b(i, j - 1); - pp[5] = source->b(i - 1, j - 1); - pp[6] = source->b(i - 1, j + 1); - pp[7] = source->b(i + 1, j - 1); - pp[8] = source->b(i + 1, j + 1); - pp[9] = source->b(i + 2, j); - pp[10] = source->b(i - 2, j); - pp[11] = source->b(i, j + 2); - pp[12] = source->b(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->b(i, j), + source->b(i - 1, j), + source->b(i + 1, j), + source->b(i, j + 1), + source->b(i, j - 1), + source->b(i - 1, j - 1), + source->b(i - 1, j + 1), + source->b(i + 1, j - 1), + source->b(i + 1, j + 1), + source->b(i + 2, j), + source->b(i - 2, j), + source->b(i, j + 2), + source->b(i, j - 2) + ); // 5x5 soft } + } } } @@ -1966,64 +1893,59 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for nowait #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->b(i, j) = tm[i][j]; } } - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), tm[i][j]); + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1)); } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), tm[i][j]); + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1)); } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), source->g(i - 2, j), source->g(i + 2, j), source->g(i, j + 2), source->g(i, j - 2), source->g(i - 2, j - 2), source->g(i - 2, j + 2), source->g(i + 2, j - 2), source->g(i + 2, j + 2), - source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2), - tm[i][j]);//5x5 + source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2)); // 5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->g(i, j); - pp[1] = source->g(i - 1, j); - pp[2] = source->g(i + 1, j); - pp[3] = source->g(i, j + 1); - pp[4] = source->g(i, j - 1); - pp[5] = source->g(i - 1, j - 1); - pp[6] = source->g(i - 1, j + 1); - pp[7] = source->g(i + 1, j - 1); - pp[8] = source->g(i + 1, j + 1); - pp[9] = source->g(i + 2, j); - pp[10] = source->g(i - 2, j); - pp[11] = source->g(i, j + 2); - pp[12] = source->g(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->g(i, j), + source->g(i - 1, j), + source->g(i + 1, j), + source->g(i, j + 1), + source->g(i, j - 1), + source->g(i - 1, j - 1), + source->g(i - 1, j + 1), + source->g(i + 1, j - 1), + source->g(i + 1, j + 1), + source->g(i + 2, j), + source->g(i - 2, j), + source->g(i, j + 2), + source->g(i, j - 2) + ); // 5x5 soft } + } } } @@ -2031,29 +1953,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->g(i, j) = tm[i][j]; } } } } - for (int i = 0; i < hei; i++) { - delete [] tm[i]; + for (int i = 0; i < hei; ++i) { + delete[] tm[i]; } - delete [] tm; + delete[] tm; } //end median - if(noiseLCurve || useNoiseCCurve) { - delete [] lumcalcBuffer; - delete [] lumcalc; - delete [] ccalcBuffer; - delete [] ccalc; + if (noiseLCurve || useNoiseCCurve) { + delete[] lumcalcBuffer; + delete[] lumcalc; + delete[] ccalcBuffer; + delete[] ccalc; } //#ifdef _DEBUG @@ -2072,7 +1994,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer ) //for DCT +SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer) //for DCT { int blkstart = hblproc * TS * TS; @@ -2080,17 +2002,17 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, #ifdef __SSE2__ __m128 tempv; - __m128 noisevar_Ldetailv = _mm_set1_ps( noisevar_Ldetail ); - __m128 onev = _mm_set1_ps( 1.0f ); + __m128 noisevar_Ldetailv = _mm_set1_ps(noisevar_Ldetail); + __m128 onev = _mm_set1_ps(1.0f); 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 ); + tempv = onev - xexpf(-SQRV(LVF(nbrwt[n])) / noisevar_Ldetailv); + _mm_storeu_ps(&fLblox[blkstart + n], LVFU(fLblox[blkstart + n]) * tempv); }//output neighbor averaged result #else - for (int n = 0; n < TS * TS; n++) { //for DCT + for (int n = 0; n < TS * TS; ++n) { //for DCT fLblox[blkstart + n] *= (1 - xexpf(-SQR(nbrwt[n]) / noisevar_Ldetail)); }//output neighbor averaged result @@ -2105,29 +2027,30 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::RGBoutput_tile_row (float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top ) +void ImProcFunctions::RGBoutput_tile_row (float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top) { - const int numblox_W = ceil(((float)(width)) / (offset)); + const int numblox_W = ceil((static_cast(width)) / (offset)); const float DCTnorm = 1.0f / (4 * TS * TS); //for DCT int imin = MAX(0, -top); - int bottom = MIN( top + TS, height); + int bottom = MIN(top + TS, height); int imax = bottom - top; //add row of tiles to output image - for (int i = imin; i < imax; i++) - for (int hblk = 0; hblk < numblox_W; hblk++) { + for (int i = imin; i < imax; ++i) { + for (int hblk = 0; hblk < numblox_W; ++hblk) { int left = (hblk - blkrad) * offset; int right = MIN(left + TS, width); int jmin = MAX(0, -left); int jmax = right - left; int indx = hblk * TS; - for (int j = jmin; j < jmax; j++) { // this loop gets auto vectorized by gcc + for (int j = jmin; j < jmax; ++j) { // this loop gets auto vectorized by gcc Ldetail[top + i][left + j] += tilemask_out[i][j] * bloxrow_L[(indx + i) * TS + j] * DCTnorm; //for DCT } } + } } /* #undef TS @@ -2148,12 +2071,12 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) int * histo = new int[65536]; //memset(histo, 0, 65536*sizeof(histo)); - for (int i = 0; i < 65536; i++) { + for (int i = 0; i < 65536; ++i) { histo[i] = 0; } //calculate histogram of absolute values of HH wavelet coeffs - for (int i = 0; i < datalen; i++) { + for (int i = 0; i < datalen; ++i) { histo[MAX(0, MIN(65535, abs((int)DataList[i])))]++; } @@ -2162,7 +2085,7 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } //find max of histogram @@ -2177,20 +2100,23 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) delete[] histo; // interpolate - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } -float ImProcFunctions::Mad( float * DataList, const int datalen) +float ImProcFunctions::Mad(float * DataList, const int datalen) { + if(datalen <= 1) { // Avoid possible buffer underrun + return 0; + } //computes Median Absolute Deviation //DataList values should mostly have abs val < 256 because we are in Lab mode int histo[256] ALIGNED64 = {0}; //calculate histogram of absolute values of wavelet coeffs - for (int i = 0; i < datalen; i++) { - histo[min(255, abs((int)DataList[i]))]++; + for (int i = 0; i < datalen; ++i) { + histo[min(255, abs(static_cast(DataList[i])))]++; } //find median of histogram @@ -2198,31 +2124,34 @@ float ImProcFunctions::Mad( float * DataList, const int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } int count_ = count - histo[median - 1]; // interpolate - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } -float ImProcFunctions::MadRgb( float * DataList, const int datalen) +float ImProcFunctions::MadRgb(float * DataList, const int datalen) { + if(datalen <= 1) { // Avoid possible buffer underrun + return 0; + } //computes Median Absolute Deviation //DataList values should mostly have abs val < 65536 because we are in RGB mode int * histo = new int[65536]; - for(int i = 0; i < 65536; i++) { + for (int i = 0; i < 65536; ++i) { histo[i] = 0; } //calculate histogram of absolute values of wavelet coeffs int i; - for (i = 0; i < datalen; i++) { - histo[min(65536, abs((int)DataList[i]))]++; + for (i = 0; i < datalen; ++i) { + histo[min(65535, abs(static_cast(DataList[i])))]++; } //find median of histogram @@ -2230,14 +2159,14 @@ float ImProcFunctions::MadRgb( float * DataList, const int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } int count_ = count - histo[median - 1]; // interpolate - delete [] histo; - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + delete[] histo; + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } @@ -2249,7 +2178,7 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float madC; float maxresid = 0.f; - for (int lvl = 0; lvl < maxlvl; lvl++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); @@ -2257,8 +2186,8 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - for (int dir = 1; dir < 4; dir++) { - if(denoiseMethodRgb) { + for (int dir = 1; dir < 4; ++dir) { + if (denoiseMethodRgb) { madC = SQR(MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); } else { madC = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); @@ -2266,7 +2195,7 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, resid += madC; - if(madC > maxresid ) { + if (madC > maxresid) { maxresid = madC; } } @@ -2283,19 +2212,19 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2303,18 +2232,18 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif for (int lvl = maxlvl - 1; lvl >= 0; lvl--) { //for levels less than max, use level diff to make edge mask - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); @@ -2323,7 +2252,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit if (lvl == maxlvl - 1) { float vari[4]; int edge = 0; - ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], NULL, edge ); + ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], nullptr, edge); } else { //simple wavelet shrinkage float * sfave = buffer[0] + 32; @@ -2335,7 +2264,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit float levelFactor = mad_Lr * 5.f / (lvl + 1); #ifdef __SSE2__ __m128 mad_Lv; - __m128 ninev = _mm_set1_ps( 9.0f ); + __m128 ninev = _mm_set1_ps(9.0f); __m128 epsv = _mm_set1_ps(eps); __m128 mag_Lv; __m128 levelFactorv = _mm_set1_ps(levelFactor); @@ -2344,23 +2273,24 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit 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)); + _mm_storeu_ps(&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++) { + for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); } #else - for (int i = 0; i < Hlvl_L; i++) - for (int j = 0; j < Wlvl_L; j++) { + for (int i = 0; i < Hlvl_L; ++i) { + for (int j = 0; j < Wlvl_L; ++j) { int coeffloc_L = i * Wlvl_L + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); } + } #endif boxblur(sfave, sfaved, blurBuffer, lvl + 2, lvl + 2, Wlvl_L, Hlvl_L); //increase smoothness by locally averaging shrinkage @@ -2376,7 +2306,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit } // few remaining pixels - for (; coeffloc_L < Hlvl_L * Wlvl_L; coeffloc_L++) { + for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { float sf_L = sfave[coeffloc_L]; //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][coeffloc_L] *= (SQR(sfaved[coeffloc_L]) + SQR(sf_L)) / (sfaved[coeffloc_L] + sf_L + eps); @@ -2384,13 +2314,14 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit #else - for (int i = 0; i < Hlvl_L; i++) - for (int j = 0; j < Wlvl_L; j++) { + for (int i = 0; i < Hlvl_L; ++i) { + for (int j = 0; j < Wlvl_L; ++j) { int coeffloc_L = i * Wlvl_L + j; float sf_L = sfave[coeffloc_L]; //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][coeffloc_L] *= (SQR(sfaved[coeffloc_L]) + SQR(sf_L)) / (sfaved[coeffloc_L] + sf_L + eps); }//now luminance coeffs are denoised + } #endif } @@ -2398,10 +2329,11 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); @@ -2412,7 +2344,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi { int maxlvl = WaveletCoeffs_L.maxlevel(); - if(autoch && noisevar_ab <= 0.001f) { + if (autoch && noisevar_ab <= 0.001f) { noisevar_ab = 0.02f; } @@ -2420,19 +2352,19 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2440,25 +2372,25 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madab[lvl][dir - 1] = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); } else { madab[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); @@ -2471,7 +2403,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #endif for (int lvl = maxlvl - 1; lvl >= 0; lvl--) { //for levels less than max, use level diff to make edge mask - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); @@ -2508,7 +2440,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi } // few remaining pixels - for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; coeffloc_ab++) { + for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); @@ -2516,8 +2448,8 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #else - for (int i = 0; i < Hlvl_ab; i++) { - for (int j = 0; j < Wlvl_ab; j++) { + for (int i = 0; i < Hlvl_ab; ++i) { + for (int j = 0; j < Wlvl_ab; ++j) { int coeffloc_ab = i * Wlvl_ab + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); @@ -2536,10 +2468,11 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); @@ -2552,25 +2485,25 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); - if(edge == 1) { + if (edge == 1) { maxlvl = 4; //for refine denoise edge wavelet } int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[4]; @@ -2579,26 +2512,27 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; buffer[3] = new (std::nothrow) float[maxWL * maxHL + 128]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL || buffer[3] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr || buffer[3] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], vari, edge); } } } - for(int i = 3; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 3; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); } @@ -2612,19 +2546,19 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L int maxlvl = WaveletCoeffs_L.maxlevel(); int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2632,26 +2566,27 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl]); } } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); } @@ -2661,7 +2596,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, - float *noisevarlum, float * madL, float * vari, int edge ) + float *noisevarlum, float * madL, float * vari, int edge) { //simple wavelet shrinkage @@ -2678,38 +2613,38 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff // printf("OK lev=%d\n",level); float mad_L = madL[dir - 1] ; - if(edge == 1) { + if (edge == 1) { noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer - for (int i = 0; i < W_L * H_L; i++) { + for (int i = 0; i < W_L * H_L; ++i) { noisevarlum[i] = vari[level]; } } - float levelFactor = mad_L * 5.f / (float)(level + 1); + float levelFactor = mad_L * 5.f / static_cast(level + 1); #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 ); + __m128 ninev = _mm_set1_ps(9.0f); + __m128 epsv = _mm_set1_ps(eps); int i; 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)); + _mm_storeu_ps(&sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); } // few remaining pixels - for (; i < W_L * H_L; i++) { + for (; i < W_L * H_L; ++i) { 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++) { + 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); @@ -2725,11 +2660,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff for (i = 0; i < W_L * H_L - 3; i += 4) { 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)); + _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)); } // few remaining pixels - for (; i < W_L * H_L; i++) { + for (; i < W_L * H_L; ++i) { float sf = sfave[i]; //use smoothed shrinkage unless local shrinkage is much less @@ -2738,7 +2673,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff #else - for (int i = 0; i < W_L * H_L; i++) { + for (int i = 0; i < W_L * H_L; ++i) { float sf = sfave[i]; //use smoothed shrinkage unless local shrinkage is much less @@ -2752,13 +2687,13 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, 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 ) + bool denoiseMethodRgb, float * madL, float * madaab, bool madCalculated) { //simple wavelet shrinkage const float eps = 0.01f; - if(autoch && noisevar_ab <= 0.001f) { + if (autoch && noisevar_ab <= 0.001f) { noisevar_ab = 0.02f; } @@ -2775,10 +2710,10 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef float madab; float mad_L = madL[dir - 1]; - if(madCalculated) { + if (madCalculated) { madab = madaab[dir - 1]; } else { - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madab = SQR(Mad(WavCoeffs_ab[dir], W_ab * H_ab)); } else { madab = SQR(MadRgb(WavCoeffs_ab[dir], W_ab * H_ab)); @@ -2806,7 +2741,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef } // few remaining pixels - for (; coeffloc_ab < H_ab * W_ab; coeffloc_ab++) { + for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); @@ -2814,8 +2749,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef #else - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { int coeffloc_ab = i * W_ab + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); @@ -2836,11 +2771,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef 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)); + _mm_storeu_ps(&WavCoeffs_ab[dir][coeffloc_ab], LVFU(WavCoeffs_ab[dir][coeffloc_ab]) * (SQRV(sfaveabv) + SQRV(sfabv)) / (sfaveabv + sfabv + epsv)); } // few remaining pixels - for (; coeffloc_ab < H_ab * W_ab; coeffloc_ab++) { + for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { //modification Jacques feb 2013 float sfab = sfaveab[coeffloc_ab]; @@ -2850,8 +2785,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef #else - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { int coeffloc_ab = i * W_ab + j; float sfab = sfaveab[coeffloc_ab]; @@ -2872,7 +2807,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** { //simple wavelet shrinkage - if(lvl == 1) { //only one time + if (lvl == 1) { //only one time float chro = 0.f; float dev = 0.f; float devL = 0.f; @@ -2884,56 +2819,56 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** float skin_c = 0.f; int nsk = 0; - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { chro += noisevarchrom[i][j]; - nc++; + ++nc; dev += SQR(noisevarchrom[i][j] - (chro / nc)); - if(noisevarhue[i][j] > -0.8f && noisevarhue[i][j] < 2.0f && noisevarchrom[i][j] > 10000.f) {//saturated red yellow + if (noisevarhue[i][j] > -0.8f && noisevarhue[i][j] < 2.0f && noisevarchrom[i][j] > 10000.f) {//saturated red yellow red_yel += noisevarchrom[i][j]; - nry++; + ++nry; } - if(noisevarhue[i][j] > 0.f && noisevarhue[i][j] < 1.6f && noisevarchrom[i][j] < 10000.f) {//skin + if (noisevarhue[i][j] > 0.f && noisevarhue[i][j] < 1.6f && noisevarchrom[i][j] < 10000.f) {//skin skin_c += noisevarchrom[i][j]; - nsk++; + ++nsk; } lume += noisevarlum[i][j]; - nL++; + ++nL; devL += SQR(noisevarlum[i][j] - (lume / nL)); } } - if(nc > 0) { + if (nc > 0) { chromina = chro / nc; sigma = sqrt(dev / nc); - nsknc = (float)nsk / (float)nc; + nsknc = static_cast(nsk) / static_cast(nc); } else { - nsknc = (float)nsk; + nsknc = static_cast(nsk); } - if(nL > 0) { + if (nL > 0) { lumema = lume / nL; sigma_L = sqrt(devL / nL); } - if(nry > 0) { + if (nry > 0) { redyel = red_yel / nry; } - if(nsk > 0) { + if (nsk > 0) { skinc = skin_c / nsk; } } - const float reduc = (schoice == 2) ? (float) settings->nrhigh : 1.f; + const float reduc = (schoice == 2) ? static_cast( settings->nrhigh) : 1.f; - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { float mada, madb; - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { mada = SQR(Mad(WavCoeffs_a[dir], W_ab * H_ab)); } else { mada = SQR(MadRgb(WavCoeffs_a[dir], W_ab * H_ab)); @@ -2941,18 +2876,18 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** chred += mada; - if(mada > maxchred) { + if (mada > maxchred) { maxchred = mada; } - if(mada < minchred) { + if (mada < minchred) { minchred = mada; } maxredaut = sqrt(reduc * maxchred); minredaut = sqrt(reduc * minchred); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madb = SQR(Mad(WavCoeffs_b[dir], W_ab * H_ab)); } else { madb = SQR(MadRgb(WavCoeffs_b[dir], W_ab * H_ab)); @@ -2960,11 +2895,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** chblue += madb; - if(madb > maxchblue) { + if (madb > maxchblue) { maxchblue = madb; } - if(madb < minchblue) { + if (madb < minchblue) { minchblue = madb; } @@ -2972,7 +2907,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** minblueaut = sqrt(reduc * minchblue); chau += (mada + madb); - nb++; + ++nb; //here evaluation of automatic chaut = sqrt(reduc * chau / (nb + nb)); redaut = sqrt(reduc * chred / nb); @@ -2985,12 +2920,12 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, bool autoch, - 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 multiThread ) + 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 multiThread) { int maxlvl = levwav; - for (int lvl = 0; lvl < maxlvl; lvl++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { int Wlvl_ab = WaveletCoeffs_a.level_W(lvl); int Hlvl_ab = WaveletCoeffs_a.level_H(lvl); @@ -3002,35 +2937,31 @@ void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition & ShrinkAll_info(WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_ab, Hlvl_ab, skip_ab, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevar_abr, noisevar_abb, noi, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, - autoch, schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb, multiThread ); + autoch, schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb, multiThread); } } -void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope) +SSEFUNCTION void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope) { gam = dnparams.gamma; gamthresh = 0.001f; - if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG - if(gam < 1.9f) { + if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG + if (gam < 1.9f) { gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7 } else if (gam >= 1.9f && gam <= 3.f) { gam = (1.4f / 1.1f) * gam - 1.41818f; } } - gamslope = exp(log((double)gamthresh) / gam) / gamthresh; bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; - } + if (denoiseMethodRgb) { + gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; + Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f); } else { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamman((double)i / 65535.0, gam)) * 32768.0f; - } + Color::gammanf2lut(gamcurve, gam, 65535.f, 32768.f); } } @@ -3040,7 +2971,7 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l float reducdelta = 1.f; if (params->dirpyrDenoise.smethod == "shalbi") { - reducdelta = (float)settings->nrhigh; + reducdelta = static_cast(settings->nrhigh); } chaut = (chaut * Nb - maxmax) / (Nb - 1); //suppress maximum for chaut calcul @@ -3089,8 +3020,8 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l } } - if(levaut == 0) { //Low denoise - if(chaut > 300.f) { + if (levaut == 0) { //Low denoise + if (chaut > 300.f) { chaut = 0.714286f * chaut + 85.71428f; } } @@ -3099,15 +3030,15 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l delta *= reducdelta; if (lissage == 1 || lissage == 2) { - if (chaut < 200.f && delta < 200.f ) { + if (chaut < 200.f && delta < 200.f) { delta *= 0.95f; - } else if (chaut < 200.f && delta < 400.f ) { + } else if (chaut < 200.f && delta < 400.f) { delta *= 0.5f; - } else if (chaut < 200.f && delta >= 400.f ) { + } else if (chaut < 200.f && delta >= 400.f) { delta = 200.f; - } else if (chaut < 400.f && delta < 400.f ) { + } else if (chaut < 400.f && delta < 400.f) { delta *= 0.4f; - } else if (chaut < 400.f && delta >= 400.f ) { + } else if (chaut < 400.f && delta >= 400.f) { delta = 120.f; } else if (chaut < 550.f) { delta *= 0.15f; @@ -3137,15 +3068,15 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l } if (lissage == 0) { - if (chaut < 200.f && delta < 200.f ) { + if (chaut < 200.f && delta < 200.f) { delta *= 0.95f; - } else if (chaut < 200.f && delta < 400.f ) { + } else if (chaut < 200.f && delta < 400.f) { delta *= 0.7f; - } else if (chaut < 200.f && delta >= 400.f ) { + } else if (chaut < 200.f && delta >= 400.f) { delta = 280.f; - } else if (chaut < 400.f && delta < 400.f ) { + } else if (chaut < 400.f && delta < 400.f) { delta *= 0.6f; - } else if (chaut < 400.f && delta >= 400.f ) { + } else if (chaut < 400.f && delta >= 400.f) { delta = 200.f; } else if (chaut < 550.f) { delta *= 0.3f; @@ -3199,28 +3130,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat lumcalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { lumcalc[i] = new float[wid]; } acalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { acalc[i] = new float[wid]; } bcalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { bcalc[i] = new float[wid]; } #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif - for(int ii = 0; ii < hei; ii++) { - for(int jj = 0; jj < wid; jj++) { + for (int ii = 0; ii < hei; ++ii) { + for (int jj = 0; jj < wid; ++jj) { float LLum, AAum, BBum; float RL = provicalc->r(ii, jj); float GL = provicalc->g(ii, jj); @@ -3246,12 +3177,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat int tilesize; int overlap; - if(settings->leveldnti == 0) { + if (settings->leveldnti == 0) { tilesize = 1024; overlap = 128; } - if(settings->leveldnti == 1) { + if (settings->leveldnti == 1) { tilesize = 768; overlap = 96; } @@ -3281,24 +3212,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat int nb = 0; int comptlevel = 0; - // To avoid branches in loops we access the gammatabs by pointers - LUTf *denoiseigamtab; - - switch(settings->denoiselabgamma) { - case 0: - denoiseigamtab = &(Color::igammatab_26_11); - break; - - case 1: - denoiseigamtab = &(Color::igammatab_4); - break; - - default: - denoiseigamtab = &(Color::igammatab_55); - break; - } - - for (int tiletop = 0; tiletop < imheight; tiletop += tileHskip) { for (int tileleft = 0; tileleft < imwidth; tileleft += tileWskip) { @@ -3309,19 +3222,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat LabImage * labdn = new LabImage(width, height); float** noisevarlum = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarlum[i] = new float[(width + 1) / 2]; } float** noisevarchrom = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarchrom[i] = new float[(width + 1) / 2]; } float** noisevarhue = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarhue[i] = new float[(width + 1) / 2]; } @@ -3329,19 +3242,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float noisevarab_b, noisevarab_r; float realred, realblue; - float interm_med = (float) dnparams.chroma / 10.0; + float interm_med = static_cast( dnparams.chroma) / 10.0; float intermred, intermblue; - if(dnparams.redchro > 0.) { + if (dnparams.redchro > 0.) { intermred = (dnparams.redchro / 10.); } else { - intermred = (float) dnparams.redchro / 7.0; //increase slower than linear for more sensit + intermred = static_cast( dnparams.redchro) / 7.0; //increase slower than linear for more sensit } - if(dnparams.bluechro > 0.) { + if (dnparams.bluechro > 0.) { intermblue = (dnparams.bluechro / 10.); } else { - intermblue = (float) dnparams.bluechro / 7.0; //increase slower than linear for more sensit + intermblue = static_cast( dnparams.bluechro) / 7.0; //increase slower than linear for more sensit } realred = interm_med + intermred; @@ -3361,7 +3274,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat if (isRAW) {//image is raw; use channel differences for chroma channels #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif for (int i = tiletop; i < tilebottom; i += 2) { @@ -3386,7 +3299,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float cN = sqrtf(SQR(aN) + SQR(bN)); noisevarhue[i1 >> 1][j1 >> 1] = xatan2f(bN, aN); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3402,7 +3315,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float cN = sqrtf(SQR(aN) + SQR(bN)); float hN = xatan2f(bN, aN); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3414,7 +3327,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif for (int i = tiletop; i < tilebottom; i += 2) { @@ -3432,26 +3345,26 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat if (!denoiseMethodRgb) { //lab mode, modification Jacques feb 2013 and july 2014 #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float R_ = gain * src->r(i, j); float G_ = gain * src->g(i, j); float B_ = gain * src->b(i, j); - R_ = (*denoiseigamtab)[R_]; - G_ = (*denoiseigamtab)[G_]; - B_ = (*denoiseigamtab)[B_]; + R_ = Color::denoiseIGammaTab[R_]; + G_ = Color::denoiseIGammaTab[G_]; + B_ = Color::denoiseIGammaTab[B_]; //apply gamma noise standard (slider) - R_ = R_ < 65535.0f ? gamcurve[R_] : (Color::gamman((double)R_ / 65535.0, gam) * 32768.0f); - G_ = G_ < 65535.0f ? gamcurve[G_] : (Color::gamman((double)G_ / 65535.0, gam) * 32768.0f); - B_ = B_ < 65535.0f ? gamcurve[B_] : (Color::gamman((double)B_ / 65535.0, gam) * 32768.0f); + R_ = R_ < 65535.f ? gamcurve[R_] : (Color::gammanf(R_ / 65535.f, gam) * 32768.f); + G_ = G_ < 65535.f ? gamcurve[G_] : (Color::gammanf(G_ / 65535.f, gam) * 32768.f); + B_ = B_ < 65535.f ? gamcurve[B_] : (Color::gammanf(B_ / 65535.f, gam) * 32768.f); //true conversion xyz=>Lab float X, Y, Z; Color::rgbxyz(R_, G_, B_, X, Y, Z, wp); @@ -3466,19 +3379,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } } else { //RGB mode - for (int i = tiletop/*, i1=0*/; i < tilebottom; i++/*, i1++*/) { + for (int i = tiletop/*, i1=0*/; i < tilebottom; ++i/*, ++i1*/) { int i1 = i - tiletop; - for (int j = tileleft/*, j1=0*/; j < tileright; j++/*, j1++*/) { + for (int j = tileleft/*, j1=0*/; j < tileright; ++j/*, ++j1*/) { int j1 = j - tileleft; float X = gain * src->r(i, j); float Y = gain * src->g(i, j); float Z = gain * src->b(i, j); - X = X < 65535.0f ? gamcurve[X] : (Color::gamma((double)X / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma((double)Y / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma((double)Z / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + X = X < 65535.f ? gamcurve[X] : (Color::gammaf(X / 65535.f, gam, gamthresh, gamslope) * 32768.f); + Y = Y < 65535.f ? gamcurve[Y] : (Color::gammaf(Y / 65535.f, gam, gamthresh, gamslope) * 32768.f); + Z = Z < 65535.f ? gamcurve[Z] : (Color::gammaf(Z / 65535.f, gam, gamthresh, gamslope) * 32768.f); labdn->a[i1][j1] = (X - Y); labdn->b[i1][j1] = (Y - Z); @@ -3487,10 +3400,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } } else {//image is not raw; use Lab parametrization - for (int i = tiletop/*, i1=0*/; i < tilebottom; i++/*, i1++*/) { + for (int i = tiletop/*, i1=0*/; i < tilebottom; ++i/*, ++i1*/) { int i1 = i - tiletop; - for (int j = tileleft/*, j1=0*/; j < tileright; j++/*, j1++*/) { + for (int j = tileleft/*, j1=0*/; j < tileright; ++j/*, ++j1*/) { int j1 = j - tileleft; float L, a, b; float rLum = src->r(i, j) ; //for luminance denoise curve @@ -3505,9 +3418,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float btmp = Color::igammatab_srgb[ src->b(i, j) ]; //modification Jacques feb 2013 // gamma slider different from raw - rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp / 65535.0, gam) * 32768.0f); - gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp / 65535.0, gam) * 32768.0f); - btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp / 65535.0, gam) * 32768.0f); + rtmp = rtmp < 65535.f ? gamcurve[rtmp] : (Color::gammanf(rtmp / 65535.f, gam) * 32768.f); + gtmp = gtmp < 65535.f ? gamcurve[gtmp] : (Color::gammanf(gtmp / 65535.f, gam) * 32768.f); + btmp = btmp < 65535.f ? gamcurve[btmp] : (Color::gammanf(btmp / 65535.f, gam) * 32768.f); float X, Y, Z; Color::rgbxyz(rtmp, gtmp, btmp, X, Y, Z, wp); @@ -3515,18 +3428,18 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat //convert Lab Color::XYZ2Lab(X, Y, Z, L, a, b); - if(((i1 | j1) & 1) == 0) { + if (((i1 | j1) & 1) == 0) { float Llum, alum, blum; float XL, YL, ZL; Color::rgbxyz(rLum, gLum, bLum, XL, YL, ZL, wp); Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); float kN = Llum; - if(kN < 2.f) { + if (kN < 2.f) { kN = 2.f; } - if(kN > 32768.f) { + if (kN > 32768.f) { kN = 32768.f; } @@ -3536,7 +3449,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float hN = xatan2f(bN, aN); float cN = sqrt(SQR(aN) + SQR(bN)); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3571,26 +3484,65 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat const int levwav = 5; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel sections if(multiThread) + #pragma omp parallel sections if (multiThread) #endif { #ifdef _RT_NESTED_OPENMP #pragma omp section #endif { - adecomp = new wavelet_decomposition (labdn->data + datalen, labdn->W, labdn->H, levwav, 1 ); + adecomp = new wavelet_decomposition (labdn->data + datalen, labdn->W, labdn->H, levwav, 1); } #ifdef _RT_NESTED_OPENMP #pragma omp section #endif { - bdecomp = new wavelet_decomposition (labdn->data + 2 * datalen, labdn->W, labdn->H, levwav, 1 ); + bdecomp = new wavelet_decomposition (labdn->data + 2 * datalen, labdn->W, labdn->H, levwav, 1); } } bool autoch = dnparams.autochroma; - if(comptlevel == 0) { - WaveletDenoiseAll_info(levwav, *adecomp, *bdecomp, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevarab_r, noisevarab_b, labdn, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, schoice, autoch, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau , chred, chblue, denoiseMethodRgb, multiThread); //enhance mode + if (comptlevel == 0) { + WaveletDenoiseAll_info( + levwav, + *adecomp, + *bdecomp, + noisevarlum, + noisevarchrom, + noisevarhue, + width, + height, + noisevarab_r, + noisevarab_b, + labdn, + chaut, + Nb, + redaut, + blueaut, + maxredaut, + maxblueaut, + minredaut, + minblueaut, + schoice, + autoch, + chromina, + sigma, + lumema, + sigma_L, + redyel, + skinc, + nsknc, + maxchred, + maxchblue, + minchred, + minchblue, + nb, + chau, + chred, + chblue, + denoiseMethodRgb, + multiThread + ); // Enhance mode } comptlevel += 1; @@ -3601,50 +3553,50 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat delete bdecomp; delete labdn; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarlum[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarlum[i]; } - delete [] noisevarlum; + delete[] noisevarlum; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarchrom[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarchrom[i]; } - delete [] noisevarchrom; + delete[] noisevarchrom; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarhue[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarhue[i]; } - delete [] noisevarhue; + delete[] noisevarhue; }//end of tile row }//end of tile loop - for (int i = 0; i < hei; i++) { - delete [] lumcalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] lumcalc[i]; } - delete [] lumcalc; + delete[] lumcalc; - for (int i = 0; i < hei; i++) { - delete [] acalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] acalc[i]; } - delete [] acalc; + delete[] acalc; - for (int i = 0; i < hei; i++) { - delete [] bcalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] bcalc[i]; } - delete [] bcalc; + delete[] bcalc; #undef TS #undef fTS #undef offset #undef epsilon -}//end of main RGB_denoise +} // End of main RGB_denoise } diff --git a/rtengine/LUT.h b/rtengine/LUT.h index b128d89b8..24f883766 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -59,17 +59,8 @@ #ifndef LUT_H_ #define LUT_H_ -// bit representations of flags -#define LUT_CLIP_BELOW 1 -#define LUT_CLIP_ABOVE 2 - -#define LUTf LUT -#define LUTi LUT -#define LUTu LUT -#define LUTd LUT -#define LUTuc LUT - #include +#include #ifndef NDEBUG #include #include @@ -78,6 +69,21 @@ #include #include "rt_math.h" +// Bit representations of flags +enum { + LUT_CLIP_BELOW = 1 << 0, + LUT_CLIP_ABOVE = 1 << 1 +}; + +template +class LUT; + +using LUTf = LUT; +using LUTi = LUT; +using LUTu = LUT; +using LUTd = LUT; +using LUTuc = LUT; + template class LUT { @@ -155,41 +161,6 @@ public: #endif } - LUT(int s, T * source, int flags = 0xfffffff) - { -#ifndef NDEBUG - - if (s <= 0) { - printf("s<=0!\n"); - } - - assert (s > 0); - - if (!source) { - printf("source is NULL!\n"); - } - - assert (source != nullptr); -#endif - dirty = false; // Assumption - clip = flags; - data = new T[s]; - owner = 1; - size = s; - upperBound = size - 1; - maxs = size - 2; - maxsf = (float)maxs; -#if defined( __SSE2__ ) && defined( __x86_64__ ) - maxsv = F2V( size - 2); - sizeiv = _mm_set1_epi32( (int)(size - 1) ); - sizev = F2V( size - 1 ); -#endif - - for (int i = 0; i < s; i++) { - data[i] = source[i]; - } - } - LUT() { data = nullptr; @@ -215,7 +186,7 @@ public: * For a LUT(500), it will return 500 * @return number of element in the array */ - int getSize() + unsigned int getSize() const { return size; } @@ -224,7 +195,7 @@ public: * For a LUT(500), it will return 499, because 500 elements, starting from 0, goes up to 499 * @return number of element in the array */ - int getUpperBound() + unsigned int getUpperBound() const { return size > 0 ? upperBound : 0; } @@ -258,17 +229,54 @@ public: return *this; } - // handy to sum up per thread histograms + // handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (uint32_t). + template::value>::type> LUT & operator+=(LUT &rhs) { if (rhs.size == this->size) { +#ifdef _RT_NESTED_OPENMP // temporary solution to fix Issue #3324 + #pragma omp simd +#endif + for(unsigned int i = 0; i < this->size; i++) { data[i] += rhs.data[i]; } } + return *this; } + // multiply all elements of LUT with a constant float value + template::value>::type> + LUT & operator*=(float factor) + { +#ifdef _RT_NESTED_OPENMP // temporary solution to fix Issue #3324 + #pragma omp simd +#endif + + for(unsigned int i = 0; i < this->size; i++) { + data[i] *= factor; + } + + return *this; + } + + // divide all elements of LUT by a constant float value + template::value>::type> + LUT & operator/=(float divisor) + { +#ifdef _RT_NESTED_OPENMP // temporary solution to fix Issue #3324 + #pragma omp simd +#endif + + for(unsigned int i = 0; i < this->size; i++) { + data[i] /= divisor; + } + + return *this; + } + + // use with integer indices T& operator[](int index) const { @@ -343,6 +351,7 @@ public: } */ #ifdef __SSE4_1__ + template::value>::type> vfloat operator[](vint idxv ) const { vfloat tempv, p1v; @@ -382,6 +391,7 @@ public: return p1v; } #else + template::value>::type> vfloat operator[](vint idxv ) const { vfloat tempv, p1v; @@ -426,6 +436,7 @@ public: #endif // use with float indices + template::value>::type> T operator[](float index) const { int idx = (int)index; // don't use floor! The difference in negative space is no problems here @@ -451,9 +462,10 @@ public: } // Return the value for "index" that is in the [0-1] range. + template::value>::type> T getVal01 (float index) const { - index *= float(upperBound); + index *= (float)upperBound; int idx = (int)index; // don't use floor! The difference in negative space is no problems here if (index < 0.f) { @@ -521,79 +533,122 @@ public: upperBound = 0; maxs = 0; } -}; - - -// TODO: HOMBRE: HueLUT is actually unused, could we delete this class now that LUT::getVal01 has been created? - - -/** @brief LUT subclass handling hue values specifically. - The array has a fixed size of float values and have to be in the [0.; 1.] range in both axis (no error checking implemented) */ -class HueLUT : public LUTf -{ -public: - HueLUT() : LUTf() {} - explicit HueLUT(bool createArray) : LUTf() + // create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor) + template::value>::type> + void makeIdentity(float divisor = 1.f) { - if (createArray) { - this->operator () (501, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); - } - } - - void create() - { - this->operator () (501, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); - } - - // use with integer indices - float& operator[](int index) const - { - return data[ rtengine::LIM(index, 0, upperBound) ]; - } - - // use with float indices in the [0.;1.] range - float operator[](float index) const - { - int idx = int(index * 500.f); // don't use floor! The difference in negative space is no problems here - - if (index < 0.f) { - return data[0]; - } else if (index > 1.f) { - return data[upperBound]; - } - - float balance = index - float(idx / 500.f); - float h1 = data[idx]; - float h2 = data[idx + 1]; - - if (h1 == h2) { - return h1; - } - - if ((h1 > h2) && (h1 - h2 > 0.5f)) { - h1 -= 1.f; - float value = h1 + balance * (h2 - h1); - - if (value < 0.f) { - value += 1.f; + if(divisor == 1.f) { + for(unsigned int i = 0; i < size; i++) { + data[i] = i; } - - return value; - } else if (h2 - h1 > 0.5f) { - h2 -= 1.f; - float value = h1 + balance * (h2 - h1); - - if (value < 0.f) { - value += 1.f; - } - - return value; } else { - return h1 + balance * (h2 - h1); + for(unsigned int i = 0; i < size; i++) { + data[i] = i / divisor; + } } } -}; + // compress a LUT with size y into a LUT with size x (y>x) + template::value>::type> + void compressTo(LUT &dest, unsigned int numVals = 0) const + { + numVals = numVals == 0 ? size : numVals; + numVals = std::min(numVals, size); + float divisor = numVals - 1; + float mult = (dest.size - 1) / divisor; + + for (unsigned int i = 0; i < numVals; i++) { + int hi = (int)(mult * i); + dest.data[hi] += this->data[i] ; + } + } + + // compress a LUT with size y into a LUT with size x (y>x) by using the passTrough LUT to calculate indexes + template::value>::type> + void compressTo(LUT &dest, unsigned int numVals, const LUT &passThrough) const + { + if(passThrough) { + numVals = std::min(numVals, size); + numVals = std::min(numVals, passThrough.getSize()); + float mult = dest.size - 1; + + for (int i = 0; i < numVals; i++) { + int hi = (int)(mult * passThrough[i]); + dest[hi] += this->data[i] ; + } + } + } + + // compute sum and average of a LUT + template::value>::type> + void getSumAndAverage(float &sum, float &avg) const + { + sum = 0.f; + avg = 0.f; + int i = 0; +#ifdef __SSE2__ + vfloat iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f); + vfloat fourv = F2V(4.f); + vint sumv = (vint)ZEROV; + vfloat avgv = ZEROV; + + for(; i < size - 3; i += 4) { + vint datav = _mm_loadu_si128((__m128i*)&data[i]); + sumv += datav; + avgv += iv * _mm_cvtepi32_ps(datav); + iv += fourv; + + } + + sum = vhadd(_mm_cvtepi32_ps(sumv)); + avg = vhadd(avgv); +#endif + + for (; i < size; i++) { + T val = data[i]; + sum += val; + avg += i * val; + } + + avg /= sum; + } + + + template::value>::type> + void makeConstant(float value, unsigned int numVals = 0) + { + numVals = numVals == 0 ? size : numVals; + numVals = std::min(numVals, size); + + for(unsigned int i = 0; i < numVals; i++) { + data[i] = value; + } + } + + // share the buffer with another LUT, handy for same data but different clip flags + void share(const LUT &source, int flags = 0xfffffff) + { + if (owner && data) { + delete[] data; + } + + dirty = false; // Assumption + clip = flags; + data = source.data; + owner = 0; + size = source.getSize(); + upperBound = size - 1; + maxs = size - 2; + maxsf = (float)maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + maxsv = F2V( size - 2); + sizeiv = _mm_set1_epi32( (int)(size - 1) ); + sizev = F2V( size - 1 ); +#endif + } + + +}; #endif /* LUT_H_ */ diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index fce4a14c0..6864e28ec 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -31,6 +31,7 @@ #include "../rtgui/myflatcurve.h" #include "rt_math.h" #include "opthelper.h" +#include "median.h" #ifdef _OPENMP #include @@ -766,7 +767,6 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d #pragma omp parallel { int ip, in, jp, jn; - float pp[9], temp; #pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one for (int i = 0; i < height; i++) { @@ -795,7 +795,7 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d jn = j + 2; } - med3(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn], tmaa[i][j]); + tmaa[i][j] = median(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn]); } } @@ -827,7 +827,7 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d jn = j + 2; } - med3(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn], tmbb[i][j]); + tmbb[i][j] = median(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn]); } } } @@ -1374,7 +1374,6 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d #pragma omp parallel { int ip, in, jp, jn; - float pp[9], temp; #pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one for (int i = 0; i < height; i++) { @@ -1403,7 +1402,7 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d jn = j + 2; } - med3(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn], tmaa[i][j]); + tmaa[i][j] = median(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn]); } } @@ -1435,7 +1434,7 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d jn = j + 2; } - med3(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn], tmbb[i][j]); + tmbb[i][j] = median(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn]); } } } diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h index a33d4dfe8..ac8471b7e 100644 --- a/rtengine/alignedbuffer.h +++ b/rtengine/alignedbuffer.h @@ -18,9 +18,10 @@ */ #ifndef _ALIGNEDBUFFER_ #define _ALIGNEDBUFFER_ -#include +#include #include #include +#include #include #include "../rtgui/threadutils.h" @@ -58,7 +59,7 @@ public: /** @brief Return true if there's no memory allocated */ - bool isEmpty() + bool isEmpty() const { return allocatedSize == 0; } @@ -120,28 +121,14 @@ public: void swap(AlignedBuffer &other) { - void *tmpReal = other.real; - other.real = real; - real = tmpReal; - - char tmpAlignt = other.alignment; - other.alignment = alignment; - alignment = tmpAlignt; - - size_t tmpAllocSize = other.allocatedSize; - other.allocatedSize = allocatedSize; - allocatedSize = tmpAllocSize; - - T* tmpData = other.data; - other.data = data; - data = tmpData; - - bool tmpInUse = other.inUse; - other.inUse = inUse; - inUse = tmpInUse; + std::swap(real, other.real); + std::swap(alignment, other.alignment); + std::swap(allocatedSize, other.allocatedSize); + std::swap(data, other.data); + std::swap(inUse, other.inUse); } - unsigned int getSize() + unsigned int getSize() const { return unitSize ? allocatedSize / unitSize : 0; } diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 6da291303..c5535493c 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -32,6 +32,7 @@ #include "../rtgui/multilangmgr.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" #include "StopWatch.h" namespace rtengine @@ -552,7 +553,7 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat hwtv = onev + temp2v / ( epsv + Ginthv + LVF( cfa[indx])); vmask hcdmask = vmaskf_gt( nsgnv * hcdv, ZEROV ); vfloat hcdoldv = hcdv; - vfloat tempv = nsgnv * (LVF(cfa[indx]) - ULIMV( Ginthv, LVFU(cfa[indx - 1]), LVFU(cfa[indx + 1]) )); + vfloat tempv = nsgnv * (LVF(cfa[indx]) - median( Ginthv, LVFU(cfa[indx - 1]), LVFU(cfa[indx + 1]) )); hcdv = vself( vmaskf_lt( temp2v, -(LVF(cfa[indx]) + Ginthv)), tempv, vintpf(hwtv, hcdv, tempv)); hcdv = vself( hcdmask, hcdv, hcdoldv ); hcdv = vself( vmaskf_gt( Ginthv, clip_ptv), tempv, hcdv); @@ -563,7 +564,7 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat vwtv = onev + temp2v / ( epsv + Gintvv + LVF( cfa[indx])); vmask vcdmask = vmaskf_gt( nsgnv * vcdv, ZEROV ); vfloat vcdoldv = vcdv; - tempv = nsgnv * (LVF(cfa[indx]) - ULIMV( Gintvv, LVF(cfa[indx - v1]), LVF(cfa[indx + v1]) )); + tempv = nsgnv * (LVF(cfa[indx]) - median( Gintvv, LVF(cfa[indx - v1]), LVF(cfa[indx + v1]) )); vcdv = vself( vmaskf_lt( temp2v, -(LVF(cfa[indx]) + Gintvv)), tempv, vintpf(vwtv, vcdv, tempv)); vcdv = vself( vcdmask, vcdv, vcdoldv ); vcdv = vself( vmaskf_gt( Gintvv, clip_ptv), tempv, vcdv); @@ -601,28 +602,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (hcd[indx] > 0) { if (3.f * hcd[indx] > (Ginth + cfa[indx])) { - hcd[indx] = -ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; + hcd[indx] = -median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; } else { float hwt = 1.f - 3.f * hcd[indx] / (eps + Ginth + cfa[indx]); - hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (-ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]); + hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (-median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]); } } if (vcd[indx] > 0) { if (3.f * vcd[indx] > (Gintv + cfa[indx])) { - vcd[indx] = -ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; + vcd[indx] = -median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; } else { float vwt = 1.f - 3.f * vcd[indx] / (eps + Gintv + cfa[indx]); - vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (-ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]); + vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (-median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]); } } if (Ginth > clip_pt) { - hcd[indx] = -ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; + hcd[indx] = -median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; } if (Gintv > clip_pt) { - vcd[indx] = -ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; + vcd[indx] = -median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; } @@ -633,28 +634,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (hcd[indx] < 0) { if (3.f * hcd[indx] < -(Ginth + cfa[indx])) { - hcd[indx] = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; + hcd[indx] = median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; } else { float hwt = 1.f + 3.f * hcd[indx] / (eps + Ginth + cfa[indx]); - hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]); + hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]); } } if (vcd[indx] < 0) { if (3.f * vcd[indx] < -(Gintv + cfa[indx])) { - vcd[indx] = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; + vcd[indx] = median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; } else { float vwt = 1.f + 3.f * vcd[indx] / (eps + Gintv + cfa[indx]); - vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]); + vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]); } } if (Ginth > clip_pt) { - hcd[indx] = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; + hcd[indx] = median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; } if (Gintv > clip_pt) { - vcd[indx] = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; + vcd[indx] = median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; } cddiffsq[indx] = SQR(vcd[indx] - hcd[indx]); @@ -1071,13 +1072,13 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat rbmv = (wtsev * rbnwv + wtnwv * rbsev) / (wtsev + wtnwv); - temp1v = ULIMV(rbmv , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])); + temp1v = median(rbmv , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])); vfloat wtv = vmul2f(cfav - rbmv) / (epsv + rbmv + cfav); temp2v = vintpf(wtv, rbmv, temp1v); temp2v = vself(vmaskf_lt(rbmv + rbmv, cfav), temp1v, temp2v); temp2v = vself(vmaskf_lt(rbmv, cfav), temp2v, rbmv); - STVFU(rbm[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])), temp2v )); + STVFU(rbm[indx1], vself(vmaskf_gt(temp2v, clip_ptv), median(temp2v , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])), temp2v )); temp1v = LC2VFU(cfa[indx + p1]); @@ -1096,13 +1097,13 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat rbpv = (wtnev * rbswv + wtswv * rbnev) / (wtnev + wtswv); - temp1v = ULIMV(rbpv , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])); + temp1v = median(rbpv , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])); wtv = vmul2f(cfav - rbpv) / (epsv + rbpv + cfav); temp2v = vintpf(wtv, rbpv, temp1v); temp2v = vself(vmaskf_lt(rbpv + rbpv, cfav), temp1v, temp2v); temp2v = vself(vmaskf_lt(rbpv, cfav), temp2v, rbpv); - STVFU(rbp[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])), temp2v )); + STVFU(rbp[indx1], vself(vmaskf_gt(temp2v, clip_ptv), median(temp2v , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])), temp2v )); vfloat rbvarmv = epssqv + (gausseven0v * (LVFU(Dgrbsq1m[(indx - v1) >> 1]) + LVFU(Dgrbsq1m[(indx - 1) >> 1]) + LVFU(Dgrbsq1m[(indx + 1) >> 1]) + LVFU(Dgrbsq1m[(indx + v1) >> 1])) + gausseven1v * (LVFU(Dgrbsq1m[(indx - v2 - 1) >> 1]) + LVFU(Dgrbsq1m[(indx - v2 + 1) >> 1]) + LVFU(Dgrbsq1m[(indx - 2 - v1) >> 1]) + LVFU(Dgrbsq1m[(indx + 2 - v1) >> 1]) + @@ -1171,28 +1172,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (rbp[indx1] < cfa[indx]) { if (xmul2f(rbp[indx1]) < cfa[indx]) { - rbp[indx1] = ULIM(rbp[indx1] , cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = median(rbp[indx1] , cfa[indx - p1], cfa[indx + p1]); } else { float pwt = xmul2f(cfa[indx] - rbp[indx1]) / (eps + rbp[indx1] + cfa[indx]); - rbp[indx1] = pwt * rbp[indx1] + (1.f - pwt) * ULIM(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = pwt * rbp[indx1] + (1.f - pwt) * median(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); } } if (rbm[indx1] < cfa[indx]) { if (xmul2f(rbm[indx1]) < cfa[indx]) { - rbm[indx1] = ULIM(rbm[indx1] , cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = median(rbm[indx1] , cfa[indx - m1], cfa[indx + m1]); } else { float mwt = xmul2f(cfa[indx] - rbm[indx1]) / (eps + rbm[indx1] + cfa[indx]); - rbm[indx1] = mwt * rbm[indx1] + (1.f - mwt) * ULIM(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = mwt * rbm[indx1] + (1.f - mwt) * median(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); } } if (rbp[indx1] > clip_pt) { - rbp[indx1] = ULIM(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = median(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); } if (rbm[indx1] > clip_pt) { - rbm[indx1] = ULIM(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = median(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); } } @@ -1254,12 +1255,12 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, gdv = vself(vmaskf_lt(vabsf(onev - crdv), arthreshv), gdv, gd2v); vfloat Gintvv = (LC2VFU(dirwts0[indx - v1]) * gdv + LC2VFU(dirwts0[indx + v1]) * guv) / (LC2VFU(dirwts0[indx + v1]) + LC2VFU(dirwts0[indx - v1])); - vfloat Gint1v = ULIMV(Gintvv , LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])); + vfloat Gint1v = median(Gintvv , LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])); vfloat vwtv = vmul2f(rbintv - Gintvv) / (epsv + Gintvv + rbintv); vfloat Gint2v = vintpf(vwtv, Gintvv, Gint1v); Gint1v = vself(vmaskf_lt(vmul2f(Gintvv), rbintv), Gint1v, Gint2v); Gintvv = vself(vmaskf_lt(Gintvv, rbintv), Gint1v, Gintvv); - Gintvv = vself(vmaskf_gt(Gintvv, clip_ptv), ULIMV(Gintvv, LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])), Gintvv); + Gintvv = vself(vmaskf_gt(Gintvv, clip_ptv), median(Gintvv, LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])), Gintvv); vfloat crlv = vmul2f(LC2VFU(cfa[indx - 1])) / (epsv + rbintv + LVFU(rbint[(indx1 - 1)])); vfloat glv = rbintv * crlv; @@ -1272,12 +1273,12 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, grv = vself(vmaskf_lt(vabsf(onev - crrv), arthreshv), grv, gr2v); vfloat Ginthv = (LC2VFU(dirwts1[indx - 1]) * grv + LC2VFU(dirwts1[indx + 1]) * glv) / (LC2VFU(dirwts1[indx - 1]) + LC2VFU(dirwts1[indx + 1])); - vfloat Gint1h = ULIMV(Ginthv , LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])); + vfloat Gint1h = median(Ginthv , LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])); vfloat hwtv = vmul2f(rbintv - Ginthv) / (epsv + Ginthv + rbintv); vfloat Gint2h = vintpf(hwtv, Ginthv, Gint1h); Gint1h = vself(vmaskf_lt(vmul2f(Ginthv), rbintv), Gint1h, Gint2h); Ginthv = vself(vmaskf_lt(Ginthv, rbintv), Gint1h, Ginthv); - Ginthv = vself(vmaskf_gt(Ginthv, clip_ptv), ULIMV(Ginthv, LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])), Ginthv); + Ginthv = vself(vmaskf_gt(Ginthv, clip_ptv), median(Ginthv, LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])), Ginthv); vfloat greenv = vself(copymask, vintpf(LVFU(hvwt[indx1]), Gintvv, Ginthv), LC2VFU(rgbgreen[indx])); STC2VFU(rgbgreen[indx], greenv); @@ -1338,28 +1339,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, //bound the interpolation in regions of high saturation if (Gintv < rbint[indx1]) { if (2 * Gintv < rbint[indx1]) { - Gintv = ULIM(Gintv , cfa[indx - v1], cfa[indx + v1]); + Gintv = median(Gintv , cfa[indx - v1], cfa[indx + v1]); } else { float vwt = 2.0 * (rbint[indx1] - Gintv) / (eps + Gintv + rbint[indx1]); - Gintv = vwt * Gintv + (1.f - vwt) * ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]); + Gintv = vwt * Gintv + (1.f - vwt) * median(Gintv, cfa[indx - v1], cfa[indx + v1]); } } if (Ginth < rbint[indx1]) { if (2 * Ginth < rbint[indx1]) { - Ginth = ULIM(Ginth , cfa[indx - 1], cfa[indx + 1]); + Ginth = median(Ginth , cfa[indx - 1], cfa[indx + 1]); } else { float hwt = 2.0 * (rbint[indx1] - Ginth) / (eps + Ginth + rbint[indx1]); - Ginth = hwt * Ginth + (1.f - hwt) * ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]); + Ginth = hwt * Ginth + (1.f - hwt) * median(Ginth, cfa[indx - 1], cfa[indx + 1]); } } if (Ginth > clip_pt) { - Ginth = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]); + Ginth = median(Ginth, cfa[indx - 1], cfa[indx + 1]); } if (Gintv > clip_pt) { - Gintv = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]); + Gintv = median(Gintv, cfa[indx - v1], cfa[indx + v1]); } rgbgreen[indx] = Ginth * (1.f - hvwt[indx1]) + Gintv * hvwt[indx1]; diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index b360c3042..0fa31fc2a 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright © 2010 Emil Martinec + * Copyright (C) 2010 Emil Martinec * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/rtengine/cache.h b/rtengine/cache.h new file mode 100644 index 000000000..ea567542c --- /dev/null +++ b/rtengine/cache.h @@ -0,0 +1,236 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (C) 2016 Flössie + * + * 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 +#include +#include +#include +#include + +#include "../rtgui/threadutils.h" + +namespace rtengine +{ + +namespace cache_helper +{ + + // See http://stackoverflow.com/a/20790050 + template + struct has_hash + : std::false_type + { + }; + + template + struct has_hash()(std::declval()), void())> + : std::true_type + { + }; + +} + +template +class Cache +{ +public: + class Hook + { + public: + virtual ~Hook() + { + } + virtual void onDiscard(const K& key, const V& value) = 0; + virtual void onDisplace(const K& key, const V& value) = 0; + virtual void onRemove(const K& key, const V& value) = 0; + virtual void onDestroy() = 0; + }; + + Cache(unsigned long _size, Hook* _hook = 0) : + store_size(_size), + hook(_hook) + { + } + + ~Cache() + { + if (hook) { + resize(0); + hook->onDestroy(); + } + } + + bool get(const K& key, V& value) const + { + mutex.lock(); + const StoreConstIterator store_it = store.find(key); + const bool present = store_it != store.end(); + if (present) { + lru_list.splice( + lru_list.begin(), + lru_list, + store_it->second.lru_list_it + ); + value = store_it->second.value; + } + mutex.unlock(); + + return present; + } + + bool set(const K& key, const V& value) + { + return set(key, value, Mode::UNCOND); + } + + bool replace(const K& key, const V& value) + { + return set(key, value, Mode::KNOWN); + } + + bool insert(const K& key, const V& value) + { + return set(key, value, Mode::UNKNOWN); + } + + bool remove(const K& key) + { + mutex.lock(); + const StoreIterator store_it = store.find(key); + const bool present = store_it != store.end(); + if (present) { + remove(store_it); + } + mutex.unlock(); + + return present; + } + + void resize(unsigned long size) + { + mutex.lock(); + while (lru_list.size() > size) { + discard(); + } + store_size = size; + mutex.unlock(); + } + + void clear() + { + mutex.lock(); + if (hook) { + for (const auto& entry : store) { + hook->onRemove(entry.first, entry.second.value); + } + } + lru_list.clear(); + store.clear(); + mutex.unlock(); + } + +private: + struct Value; + + using Store = typename std::conditional< + cache_helper::has_hash::value, + std::unordered_map, + std::map + >::type; + using StoreIterator = typename Store::iterator; + using StoreConstIterator = typename Store::const_iterator; + + typedef std::list LruList; + using LruListIterator = typename LruList::iterator; + + struct Value { + V value; + LruListIterator lru_list_it; + }; + + enum class Mode { + UNCOND, + KNOWN, + UNKNOWN + }; + + void discard() + { + const StoreIterator store_it = lru_list.back(); + if (hook) { + hook->onDiscard(store_it->first, store_it->second.value); + } + store.erase(store_it); + lru_list.pop_back(); + } + + bool set(const K& key, const V& value, Mode mode) + { + mutex.lock(); + const StoreIterator store_it = store.find(key); + const bool is_new_key = store_it == store.end(); + if (is_new_key) { + if (mode == Mode::UNCOND || mode == Mode::UNKNOWN) { + if (lru_list.size() >= store_size) { + discard(); + } + lru_list.push_front(store.end()); + const Value v = { + value, + lru_list.begin() + }; + lru_list.front() = store.emplace(key, v).first; + } + } else { + if (mode == Mode::UNCOND || mode == Mode::KNOWN) { + if (hook) { + hook->onDisplace(key, store_it->second.value); + } + lru_list.splice( + lru_list.begin(), + lru_list, + store_it->second.lru_list_it + ); + store_it->second.value = value; + } + } + mutex.unlock(); + + return is_new_key; + } + + void remove(const StoreIterator& store_it) + { + if (hook) { + hook->onRemove(store_it->first, store_it->second.value); + } + lru_list.erase(store_it->second.lru_list_it); + store.erase(store_it); + } + + unsigned long store_size; + Hook* const hook; + mutable MyMutex mutex; + Store store; + mutable LruList lru_list; +}; + +} diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index 8290fe085..c7a6412be 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -428,7 +428,7 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float std::map::iterator best_it = mLevels[bw].begin(); if (iso > 0) { - for (it = mLevels[bw].begin(); it != mLevels[bw].end(); it++) { + for (it = mLevels[bw].begin(); it != mLevels[bw].end(); ++it) { if (abs(it->first - iso) <= abs(best_it->first - iso)) { best_it = it; } else { @@ -487,7 +487,7 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float if (it == mApertureScaling.end()) { std::map::reverse_iterator it; - for (it = mApertureScaling.rbegin(); it != mApertureScaling.rend(); it++) { + for (it = mApertureScaling.rbegin(); it != mApertureScaling.rend(); ++it) { if (it->first > fnumber) { scaling = it->second; } else { @@ -550,7 +550,8 @@ CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_) return false; } - size_t bufsize = 4096; + size_t bufsize = 16384; + size_t increment = 2 * bufsize; size_t datasize = 0, ret; char *buf = (char *)malloc(bufsize); @@ -558,8 +559,9 @@ CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_) datasize += ret; if (datasize == bufsize) { - bufsize += 4096; + bufsize += increment; buf = (char *)realloc(buf, bufsize); + increment *= 2; } } @@ -571,7 +573,11 @@ CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_) } fclose(stream); - buf = (char *)realloc(buf, datasize + 1); + + if(datasize == bufsize) { + buf = (char *)realloc(buf, datasize + 1); + } + buf[datasize] = '\0'; // remove comments @@ -637,18 +643,16 @@ CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_) Glib::ustring make_model(ji->valuestring); make_model = make_model.uppercase(); - std::map::iterator existingccIter = mCameraConstants.find(make_model); - if (existingccIter == mCameraConstants.end()) { - // add the new CamConst to the map - mCameraConstants.insert(std::pair(make_model, cc)); + const auto ret = mCameraConstants.emplace(make_model, cc); + if(ret.second) { // entry inserted into map if (settings->verbose) { printf("Add camera constants for \"%s\"\n", make_model.c_str()); } } else { // The CameraConst already exist for this camera make/model -> we merge the values - CameraConst *existingcc = existingccIter->second; + CameraConst *existingcc = ret.first->second; // updating the dcraw matrix existingcc->update_dcrawMatrix(cc->get_dcrawMatrix()); diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 05e21576c..cf3e976ce 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -36,7 +36,7 @@ missing. That's why this file is needed. It's read once during startup, so if the file is updated you need to restart RawTherapee in order to take effect. The file is not intended for modification by the casual user, but advanced users can add missing camera information to this file. -If you do so please report at http://code.google.com/p/rawtherapee/issues so we can +If you do so please report at https://github.com/Beep6581/RawTherapee/issues so we can extend the distributed version of this file so your provided camera information becomes available to all. @@ -58,9 +58,20 @@ Examples: // make and model separated with single space, must match make // and model as provided by dcraw (case-insensitive). "make_model": "ManufacturerA ModelB", + Some Panasonics and some Canon Dslrs (of the low category like Canon 550D) exist + under alternate naming in various marketplaces (EOS 550D, EOS Rebel T2i, EOS Kiss X4). + For new models that are still not supported by the Dcraw version used in current RT, + we have to fill all the alternate names or else RT will not recognize the alternate model names + For models supported by Dcraw, filling the alternate names is simply desired (for better user info). + The format of multiple naming is to write all names in brackets i.e + instead of .. "make_model": "Canon EOS 550D", + type .. "make_model": [ "Canon EOS 550D", "Canon EOS Rebel T2i", "Canon EOS Kiss X4" ], // ColorMatrix with D65 Calibration Illuminant, in dcraw format "dcraw_matrix": [ 7530, -1942, -255, -4318, 11390, 3362, -926, 1694, 7649 ], // black level (or black offset if a base black is already extracted from exif by Dcraw, see Panasonic, resent Nikon ) + // For some rare cases where Dcraw detects wrong Black Level we need to correct it with absolute black i.e one that is not added up + // the detected. For this job we have to define "black" as 65535+desired_black. For example to correct a wrongly detected black level + of 9 instead of the correct 600 we define "black": 66135 i.e. 65535+600. // and white level same for all colors at all ISOs "ranges": { "black": 10, "white": 1000 }, // crop away masked sensor borders, 10 pixels left, 20 pixels top, resulting image width/height 4000x3000 @@ -68,14 +79,18 @@ Examples: that should be removed but keep in mind that sometimes after converting to DNG the borders are already cropped so the "negative number" way is not totally safe. "raw_crop": [ 10, 20, 4000, 3000 ], - // Almost same as MaskedAreas DNG tag, used for black level measuring here two areas defined - "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], - The difference here is the meaning of the numbers which here are expressing the absolute distance (in pixels) + // Almost same as MaskedAreas DNG tag, used for black level measuring. Here up to two areas can be defined + by tetrads of numbers + "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], // two tetrads define two areas + The difference vs "raw_crop" is the meaning of the numbers which here are expressing the absolute distance (in pixels) of each side of each rectangular "masked area" from the top and left side of the sensor - the first number is the distance of the top edge from the sensor's top - the second is the distance of the left side from the sensor's left - the third is the distance of the bottom side from the sensor's top - the fourth is the distance of the right side from the sensor's left + It is useful after detecting the masked areas, to not fully use these areas but leave a border of + 2-4 pixels instead, to take care of possible light leaks from the light sensing area to the optically + black (masked) area or sensor imperfections at the outer borders. }, { @@ -179,14 +194,14 @@ we want conservative values. By conservative values we mean that if you see a white level of most often 15760 and occassionally 15759 (ie very small variation of white level which -is a common case), you set the white level around 40-80 14bit units below or -10-20 12bit units. Say at 15700 in this example, or 4080 instead of 4095 for -12bit raws. This way we get a little margin from noise and camera variation. -Since sensor raw values are linear you lose in this example log2(1-50/15760) = --0.005 stop of detail, ie irrelevant. Thus it's better to provide RawTherapee -with knowledge where the image clips rather than keeping that last 0.005 stop -of highlight information and risking that clipping will not be detected -properly. +is a common case), you set the white level around 50-100 14-bit units below or +10-20 12-bit units. Say at 15700 in this example, or 4080 instead of 4095 for +12-bit raws. This way we get a little margin from noise and camera variation. +Since sensor raw values are linear, you lose, for example, +log2(1-50/15760) = -0.005 stops of detail, i.e. irrelevant. Thus it is better +to provide RawTherapee with knowledge where the image clips rather than keeping +that last 0.005 stop of highlight information and risking that clipping will +not be detected properly. It is very usual for white level to be a bell distribution instead of a candle when the camera applies long exposure noise reduction by subtracting a black frame @@ -201,7 +216,13 @@ whole fuzzy noise peak. If a little of the starting edge of the noise will be included it's not harmful, but 99% of it should be above. This would mean that it's better to measure white level on long exposure/ high temp raws but since this if difficult and time consuming we choose to measure on normal -raws and cover the abnormalities whith the conservative WL values. +raws and cover the abnormalities with the conservative WL values. + A more detailed approach when we only have non LENR measures is to subtract +a value according to per ISO read noise. +We can find data regarding read noise (stdev of gaussian distribution) at +http://www.photonstophotos.net/Charts/RN_ADU.htm . We find the per ISO tead_noise and +subtract from the measured value 6*read_noise. This gives confidence that 99.5% of +the bell is clipped out. If you have used Adobe's DNG Converter and analyzed it's output you may have noticed that it's very conservative regarding white levels, ie it cuts away @@ -326,7 +347,7 @@ About black levels: Unlike for white levels it's much more common that black levels can be derived from the format. Either it's simply 0 (typical for old Nikon cameras, -newer Nikons (year2013-14) have a BL at around 150 12bit or 600/768 14bit ), +newer Nikons (year2013-14) have a BL at around 150 12-bit or 600/768 14-bit ), or it can be derived from masked pixels (typical for Canon cameras) or otherwise be extracted from some tag. Some formats have built-in subtraction information and are pre-processed by DCRaw @@ -412,6 +433,46 @@ Quality X: unknown, ie we knowing to little about the camera properties to know ] } }, + { // quality C, INTERMEDIATE ISO SAMPLES MISSING + "make_model": "Canon EOS-1D X Mark II", + "dcraw_matrix": [ 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 ], + // "raw_crop": [ 192, 96, 8696, 5800 ], // Full sensor 5568x3708 top38, left72, official crop left84, top50, right5555, bottom3697, 5472X3648 + // "masked_areas": [ 50, 4, 3697, 68 ], // left out 4 first columns from calculations because possibly the BL is still imbalanced there + "ranges": { + // black levels are read from raw masked pixels + // white levels are same for all colors all ISOs, but safety margin vary on ISO + "white": [ + { "iso": 50, "levels": 16350 }, // typical for all ISOs: 16383, stdev 2.25 + { "iso": 100, "levels": 16350 }, // stdev 2.25 + { "iso": [ 125, 160, 200, 250 ], "levels": 16340 }, // stdev 2.5 + { "iso": [ 320, 400, 500 ], "levels": 16330 }, // stdev 2.95 + { "iso": [ 640, 800, 1000 ], "levels": 16320 },// stdev x, 4.0 , x + { "iso": [ 1250, 1600, 2000 ], "levels": 16300 },// stdev x, 6.0 , x + { "iso": [ 2500, 3200, 4000 ], "levels": 16250 }, // STDEV x, 9.8 , x + { "iso": [ 5000, 6400, 8000 ], "levels": 16150 }, // stdev x, 17, x + { "iso": [ 10000, 12800, 16000 ], "levels": 16100 },// stdev x, 34 , x + { "iso": [ 20000, 25600, 32000 ], "levels": 16000 },// stdev x, 68 , x + { "iso": [ 40000, 51200, 64000 ], "levels": 15700 },// stdev x, 125, x + { "iso": [ 80000, 102400 ], "levels": 15100 },// stdev x, 245 + { "iso": [ 204800 ], "levels": 14000 }, + { "iso": [ 409600 ], "levels": 13000 } + ], + "white_max": 16383, + "aperture_scaling": [ + /* no need for aperture scaling because typical WL is 16383 at all ISOs .. */ + { "aperture": 1.2, "scale_factor": 1.130 }, // guessed by relative 6D data + { "aperture": 1.4, "scale_factor": 1.090 }, + { "aperture": 1.6, "scale_factor": 1.060 }, + { "aperture": 1.8, "scale_factor": 1.040 }, + { "aperture": 2.0, "scale_factor": 1.030 }, + { "aperture": 2.2, "scale_factor": 1.020 }, + { "aperture": 2.5, "scale_factor": 1.015 }, + { "aperture": 2.8, "scale_factor": 1.010 }, + { "aperture": 3.2, "scale_factor": 1.005 }, + { "aperture": 3.5, "scale_factor": 1.003 } + ] + } + }, { // quality A, "make_model": "Canon EOS 5D Mark III", "dcraw_matrix": [ 6722,-635,-963,-4287,12460,2028,-908,2162,5668 ], @@ -439,6 +500,38 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // Quality B, some intermediate ISO samples missing, LENR samples missing + // so White Levels not properly indicated, some aperture scaling missing + "make_model": "Canon EOS 5D Mark IV", + "dcraw_matrix": [ 6446,-366,-864,-4436,12204,2513,-952,2496,6348 ], // DNG_V9.7 D65 + "raw_crop": [ 136, 42, 6740, 4500 ], // full size 6880x4544, official crop 148,54,6867,4533 + "masked_areas": [ 54, 4, 4534, 132 ], + "ranges": { + "white": [ + { "iso": [ 100, 125, 200, 250 ], "levels": 16100 }, // nominal 16383, LENR? + { "iso": [ 160 ], "levels": 13000 }, // nominal f8-13105 + { "iso": [ 320, 640, 1250, 2500 ], "levels": 13300 }, // G1,G2 F4.0-13422-F2.8-13562-13616 + { "iso": [ 5000, 10000, 20000 ], "levels": 13200 }, // G1,G2 F4.0-13422-F2.8-13562-13616 + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16100 }, // nominal 16383, + { "iso": [ 6400, 8000, 12800, 16000, 25600, 32000 ], "levels": 16000 }, // R,G1,G2 16383, LENR? + { "iso": [ 40000, 51200, 102400 ], "levels": 15800 } // 16383, LENR? + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: need for more data to properly fill all scale factors */ + { "aperture": 1.4, "scale_factor": 1.130 }, // + { "aperture": 1.6, "scale_factor": 1.100 }, // + { "aperture": 1.8, "scale_factor": 1.070 }, // + { "aperture": 2.0, "scale_factor": 1.050 }, // 14171/13422=1.055 + { "aperture": 2.2, "scale_factor": 1.035 }, // 13954/13422=1.039 + { "aperture": 2.5, "scale_factor": 1.025 }, // 11400/11000=1.028 + { "aperture": 2.8, "scale_factor": 1.015 }, // 13562/13422 - 13731,13688,13562 + { "aperture": 3.2, "scale_factor": 1.010 }, // + { "aperture": 3.5, "scale_factor": 1.005 } // 13508/13422 + ] + } + }, + { // Quality C, intermediate ISO samples missing but safely guessed, aperture scaling measures missing "make_model": [ "Canon EOS 5DS R", "Canon EOS 5DS" ], // "dcraw_matrix": [ 6848,-1661,-221,-3904,10931,3434,-470,1251,6039 ], // DNG_V9.0 A @@ -468,14 +561,18 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, - { // Quality A, some missing scaling factors are safelly guessed - most samples by sfink16 at RT forums + { // Quality A, some missing scaling factors are safely guessed - samples by sfink16 & RawConvert at RT forums "make_model": "Canon EOS 6D", "dcraw_matrix": [ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 ], "ranges": { "white": [ - { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 12800, 16000, 25600 ], "levels": 15180 }, // typical 15283 - { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000, 20000 ], "levels": 13100 }, // typical 13225 - { "iso": [ 51200, 102400 ], "levels": 16280 } // typical 16383 + { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200 ], "levels": 15180 }, // typical 15283 + { "iso": [ 4000, 6400, 8000, 12800 ], "levels": 15100 }, // typical 15283 + { "iso": [ 16000, 25600 ], "levels": 14900 }, // typical 15283 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 13100 }, // typical 13225 + { "iso": [ 5000, 10000 ], "levels": 13000 }, // typical 13225 + { "iso": [ 20000 ], "levels": 12800 }, // typical 13225 + { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 ], "white_max": 16383, "aperture_scaling": [ @@ -484,7 +581,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { "aperture": 1.2, "scale_factor": 1.130 }, // from histogramm 1 gap in every 7 levels { "aperture": 1.4, "scale_factor": 1.090 }, // histogram 3 gaps in every 32 levels { "aperture": 1.6, "scale_factor": 1.060 }, // 16213/15283 - { "aperture": 1.8, "scale_factor": 1.040 }, // guessed + { "aperture": 1.8, "scale_factor": 1.040 }, // 16004/15283 { "aperture": 2.0, "scale_factor": 1.030 }, // 15800/15283 { "aperture": 2.2, "scale_factor": 1.020 }, // guessed { "aperture": 2.5, "scale_factor": 1.015 }, // 15541/15283 @@ -521,31 +618,6 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, - { // Quality b, ISO and aperture WL data by ..... at RawTherapee forums, missing samples safely guessed - "make_model": "Canon EOS 550D", - "dcraw_matrix": [ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 ], // dcraw 550d - "ranges": { - "white": [ - { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13584 - { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 - { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 - ], - "white_max": 16383, - "aperture_scaling": [ - /* note: no scale factors known for f/1.2 and f/1.0 (no lenses to test with), but the - typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ - { "aperture": 1.4, "scale_factor": 1.250 }, // guessed - { "aperture": 1.6, "scale_factor": 1.150 }, // guessed - { "aperture": 1.8, "scale_factor": 1.110 }, // 15196/13584 - { "aperture": 2.0, "scale_factor": 1.080 }, // 14734/13584 - { "aperture": 2.2, "scale_factor": 1.050 }, // 14386/13584 - { "aperture": 2.5, "scale_factor": 1.040 }, // 14272/13584 - { "aperture": 2.8, "scale_factor": 1.030 }, // 14042/13584 - { "aperture": 3.2, "scale_factor": 1.015 }, // guessed - { "aperture": 3.5, "scale_factor": 1.000 } // guessed negligible - ] - } - }, { // Quality A, f/1.6 aperture scale factor missing but safely guessed, ISO and aperture data by charlyw at RT forums "make_model": "Canon EOS 7D Mark II", "dcraw_matrix": [ 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 ], // dng_v8.7 d65 @@ -702,8 +774,66 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // Quality C, White Levels not properly indicated, aperture scaling..missing scaling factors are guessed + "make_model": "Canon EOS 80D", + "dcraw_matrix": [ 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 ], // DNG_V9.5 D65 + "raw_crop": [ 264, 34, 6024, 4022 ], // full size 6288x4056, official crop 276,46,6275,4045 + "masked_areas": [ 40, 96, 4000, 260 ], + "ranges": { + "white": [ + { "iso": [ 100, 125, 200, 250 ], "levels": 16200 }, // nominal 16383, LENR blue 16243 + { "iso": [ 160 ], "levels": 13000 }, // nominal 13097, + { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 13200 }, // G1,G2 13415 + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16150 }, // nominal 16383, LENR ISO3200 16150 + { "iso": [ 6400, 8000, 12800, 16000, 25600 ], "levels": 16000 } // R,G1,G2 16383, B 16243, LENR B 16000 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: need for more data to properly fill all scale factors */ + { "aperture": 1.4, "scale_factor": 1.200 }, // guessed + { "aperture": 1.6, "scale_factor": 1.080 }, // guessed + { "aperture": 1.8, "scale_factor": 1.055 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // guessed + { "aperture": 2.2, "scale_factor": 1.025 }, // guessed + { "aperture": 2.5, "scale_factor": 1.020 }, // guessed + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + +// Canon Mid category DSLRs (Rebels) + + { // Quality b, ISO and aperture WL data by ..... at RawTherapee forums, missing samples safely guessed + "make_model": [ "Canon EOS 550D", "Canon EOS Rebel T2i", "Canon EOS Kiss X4" ], + "dcraw_matrix": [ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 ], // dcraw 550d + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13584 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.250 }, // guessed + { "aperture": 1.6, "scale_factor": 1.150 }, // guessed + { "aperture": 1.8, "scale_factor": 1.110 }, // 15196/13584 + { "aperture": 2.0, "scale_factor": 1.080 }, // 14734/13584 + { "aperture": 2.2, "scale_factor": 1.050 }, // 14386/13584 + { "aperture": 2.5, "scale_factor": 1.040 }, // 14272/13584 + { "aperture": 2.8, "scale_factor": 1.030 }, // 14042/13584 + { "aperture": 3.2, "scale_factor": 1.015 }, // guessed + { "aperture": 3.5, "scale_factor": 1.000 } // guessed negligible + ] + } + }, + { // Quality b, scaling factors missing but guessed safely - "make_model": [ "Canon EOS 1200D", "Canon EOS Rebel T5", "Canon EOS 600D", "Canon EOS Rebel T3i" ], + "make_model": [ "Canon EOS 600D", "Canon EOS Rebel T3i", "Canon EOS Kiss X5", "Canon EOS 1200D", "Canon EOS Rebel T5", "Canon EOS Kiss X70" ], + // "dcraw_matrix": [ 13254,-6296,-1798,184,2753,90,1438,-566,1129 ], // Infrared guessed "dcraw_matrix": [ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 ], // dcp D65 colormatrix2 "ranges": { "white": [ @@ -722,14 +852,13 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { "aperture": 2.2, "scale_factor": 1.060 }, // 11971/11222 = 1.066 { "aperture": 2.5, "scale_factor": 1.050 }, // guessed { "aperture": 2.8, "scale_factor": 1.030 }, // iso100: 14042/13584=1.0336 - iso200 15820/15303 = 1.0348 - { "aperture": 3.2, "scale_factor": 1.000 }, // - { "aperture": 3.5, "scale_factor": 1.000 } // + { "aperture": 3.2, "scale_factor": 1.000 } // ] } }, - { // Quality A, only one scaling factor missing and guessed safely - "make_model": [ "Canon EOS 650D", "Canon EOS Rebel T4i" ], + { // Quality A, only one scaling factor missing and guessed safely, EOS 700D not tested but available samples look same as 650D + "make_model": [ "Canon EOS 650D", "Canon EOS Rebel T4i", "Canon EOS Kiss X6i", "Canon EOS 700D", "Canon EOS Rebel T5i", "Canon EOS Kiss X7i" ], "dcraw_matrix": [ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 ], "ranges": { "white": [ @@ -749,14 +878,13 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { "aperture": 2.2, "scale_factor": 1.025 }, // 13921/13583 { "aperture": 2.5, "scale_factor": 1.020 }, // { "aperture": 2.8, "scale_factor": 1.000 }, // - { "aperture": 3.2, "scale_factor": 1.000 }, // - { "aperture": 3.5, "scale_factor": 1.000 } // + { "aperture": 3.2, "scale_factor": 1.000 } // ] } }, { // Quality C, aperture scale factors and intermediate ISOs missing but safely guessed - "make_model": [ "Canon EOS 750D", "Canon EOS Rebel T6i", "Canon EOS 760D", "Canon EOS Rebel T6s" ], + "make_model": [ "Canon EOS 750D", "Canon EOS Rebel T6i", "Canon EOS Kiss X8i", "Canon EOS 760D", "Canon EOS Rebel T6s", "Canon EOS 8000D" ], "dcraw_matrix": [ 6362,-823,-847,-4426,12109,2616,-743,1857,5635 ], // dng_v9.0 d65 "raw_crop": [ 72, 34, 6024, 4022 ], // full size 6096x4056, official crop 84,46,6083,4045 "masked_areas": [ 40, 16, 4000, 54 ], @@ -784,6 +912,38 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, +// Canon Low End DSLRs +// Canon EOS 1200D/Rebel T5/Kiss X70" is upper at the same item as 600D/T3i/X5 + + { // Quality B, integer ISOs measured, intermediate ISO samples missing, + // scaling factors safely guessed to be same as 1200D .. + "make_model": [ "Canon EOS 1300D", "Canon EOS Rebel T6", "Canon EOS Kiss X80" ], + "dcraw_matrix": [ 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 ], // Dcraw 9.27 + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13584 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 12800 ], "levels": 15200 } // typical 15303 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.290 }, // guessed from 60D data + { "aperture": 1.6, "scale_factor": 1.190 }, // guessed + { "aperture": 1.8, "scale_factor": 1.140 }, // guessed + { "aperture": 2.0, "scale_factor": 1.090 }, // 12293/11222 = 1.095 + { "aperture": 2.2, "scale_factor": 1.060 }, // 11971/11222 = 1.066 + { "aperture": 2.5, "scale_factor": 1.050 }, // guessed + { "aperture": 2.8, "scale_factor": 1.030 }, // iso100: 14042/13584=1.0336 - iso200 15820/15303 = 1.0348 + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + +// Canon Mirrorless with Interchangable Lens + { // Quality B, missing scaling factors are guessed safely from 650D relative data "make_model": "Canon EOS M", "dcraw_matrix": [ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 ], @@ -811,6 +971,39 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // Quality C, inconsistent WL per ISO, missing scaling factors + "make_model": "Canon EOS M10", + "dcraw_matrix": [ 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 ], // DNGv9.3 D65 + "ranges": { + "white": [ + { "iso": [ 100, 125, 160, 320, 500, 2000, 4000, 6400 ], "levels": 16300 }, // typical 16383 + { "iso": 200, "levels": 12900 }, // typical 12940-15570-15376 + { "iso": 250, "levels": 14100 }, // typical 14200 + { "iso": 800, "levels": 13400 }, // typical 13500-16383x2 + { "iso": 1000, "levels": 14900 }, // typical 15010-16383 + { "iso": 1250, "levels": 12300 }, // typical 12400 + { "iso": 1600, "levels": 15200 }, // typical 15290-16075-16380 + { "iso": 2500, "levels": 12200 }, // typical 12300 + { "iso": 3200, "levels": 15000 }, // typical 15080-16383-16100-13660 + { "iso": 5000, "levels": 12800 }, // typical 12840 + { "iso": [ 12800, 25600 ], "levels": 16200 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: all scale factors are copied from EOS M3 */ + { "aperture": 1.4, "scale_factor": 1.200 }, // guessed + { "aperture": 1.6, "scale_factor": 1.080 }, // guessed + { "aperture": 1.8, "scale_factor": 1.055 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // guessed + { "aperture": 2.2, "scale_factor": 1.025 }, // guessed + { "aperture": 2.5, "scale_factor": 1.020 }, // guessed + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + { // Quality C, White Levels not properly indicated, aperture scaling..missing scaling factors are guessed "make_model": "Canon EOS M3", "dcraw_matrix": [ 6362,-823,-847,-4426,12109,2616,-743,1857,5635 ], // DNG_V8.8 D65 @@ -838,7 +1031,37 @@ Quality X: unknown, ie we knowing to little about the camera properties to know ] } }, - { /* Quality B, needs a way to auto apply 3/2 or 4/3 crops (read exif tags ..) to work better with auto distortion, + +// Canon Powershot + + { // Quality C, CHDK DNGs, raw frame corrections, experimental infrared support commented out + "make_model": "Canon PowerShot A480", + "dcraw_matrix": [ 8275,-2905,-1261,-128,5305,505,52,482,2450 ], // DNG_CHDK_V1.3.0 Daylight + // "dcraw_matrix": [ 15906,-7425,-2014,-2010,5554,264,404,-265,2706 ], // Infrared guessed + "raw_crop": [ 6, 12, 3684, 2760 ], // full size 3720X2772, official Canon crop 3648x2736 + "masked_areas": [ 12, 3694, 2760, 3716 ], // only left side optically black area is considered + "ranges": { "white": 4080 } + }, + + { // Quality B, experimental infrared support commented out + "make_model": "Canon PowerShot G9", + "dcraw_matrix": [ 7368,-2141,-598,-5621,13254,2625,-1419,1696,5743 ], // DNG_V8.7 D65 + // "dcraw_matrix": [ 8796,-3770,311,-4148,11362,3197,-598,983,5880 ], // DNG_V8.7 A + // "dcraw_matrix": [ 15669,-8084,-2453,-2940,5756,101,126,-401,2463 ], // Infrared guessed 111 + // "dcraw_matrix": [ 13254,-6296,-1798,184,2753,90,1438,-566,1129 ], // Infrared guessed + "ranges": { "white": 4080 } + }, + + { // Quality A, changes for raw crop which is optimistic in Dcraw + "make_model": "Canon PowerShot G12", + "dcraw_matrix": [ 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 ], + // "raw_crop": [ 62, 18, 3666, 2748 ],// max usable + "raw_crop": [ 68, 20, 3656, 2744 ],// equal to official Canon frame, 72,24,3719,2759 = 3648x2736 + "masked_areas": [ 24, 40, 2770, 44 ],// as declared in maker data + "ranges": { "white": 4080 } // + }, + + { /* Quality B, needs a way to auto apply 3/2 or 4/3 crops (read exif tags ..) to work better with auto distortion, for the moment just comment-uncomment the desired raw crop */ "make_model": "Canon PowerShot G1 X Mark II", "dcraw_matrix": [ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 ], // D65 matrix from adobe dcp @@ -851,7 +1074,15 @@ Quality X: unknown, ie we knowing to little about the camera properties to know }, { // Quality B, - "make_model": "Canon PowerShot G7 X", + "make_model": "Canon PowerShot G3 X", + "dcraw_matrix": [ 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 ], // DNG_V9.1.1 D65 + "raw_crop": [ 128, 36, 5480, 3656 ], // Default official 3/2 frame 5472X3648, 4pix borders, Left Border 132-4, Top border 40-4 + "masked_areas": [ 40, 4, 3680, 76 ], + "ranges": { "white": 16300 } + }, + + { // Quality B, + "make_model": [ "Canon PowerShot G7 X", "Canon PowerShot G7 X Mark II" ], "dcraw_matrix": [ 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 ], // DNG_V8.7 D65 // "raw_crop": [ 116, 24, 5504, 3680 ], // Sensor size 5632x3710. Largest useful frame 120-5616X28-3702 = 5504x3682, 4pix RTborders, Left Border 120-4, Top border 28-4 "raw_crop": [ 128, 36, 5480, 3656 ], // Default official 3/2 frame 5472X3648, 4pix borders, Left Border 132-4, Top border 40-4 @@ -860,8 +1091,9 @@ Quality X: unknown, ie we knowing to little about the camera properties to know }, { // Quality B, - "make_model": "Canon PowerShot G3 X", - "dcraw_matrix": [ 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 ], // DNG_V9.1.1 D65 + "make_model": [ "Canon PowerShot G5 X", "Canon PowerShot G9 X" ], + "dcraw_matrix": [ 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 ], // DNG_V8.7 D65 + // "raw_crop": [ 116, 24, 5504, 3680 ], // Sensor size 5632x3710. Largest useful frame 120-5616X28-3702 = 5504x3682, 4pix RTborders, Left Border 120-4, Top border 28-4 "raw_crop": [ 128, 36, 5480, 3656 ], // Default official 3/2 frame 5472X3648, 4pix borders, Left Border 132-4, Top border 40-4 "masked_areas": [ 40, 4, 3680, 76 ], "ranges": { "white": 16300 } @@ -875,15 +1107,6 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "white": 4050 } }, - { // Quality A, changes for raw crop which is optimistic in Dcraw - "make_model": "Canon PowerShot G12", - "dcraw_matrix": [ 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 ], - // "raw_crop": [ 62, 18, 3666, 2748 ],// max usable - "raw_crop": [ 68, 20, 3656, 2744 ],// equal to official Canon frame, 72,24,3719,2759 = 3648x2736 - "masked_areas": [ 24, 40, 2770, 44 ],// as declared in maker data - "ranges": { "white": 4080 } // - }, - { // Quality B "make_model": "Canon PowerShot SX60 HS", "dcraw_matrix": [ 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 ], // DNG_V8.7 D65 @@ -902,16 +1125,43 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "dcraw_matrix": [ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 ], // DNG_v8.7 D65 "ranges": { "white": 16100 } }, + { // Quality B, + "make_model": "FUJIFILM X70", + "dcraw_matrix": [ 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 ], // DNG_v9.4 D65 + // "raw_crop": [ 4, 0, 4988, 3296 ], // full raw 4992,3296, fuji official 4936,3296 - experimental crop + "ranges": { "white": 16100 } + }, - { // Quality B + { // Quality B "make_model": "FUJIFILM X-A2", "dcraw_matrix": [ 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 ], // DNG D65 "ranges": { "white": 4050 } }, + { // Quality B "make_model": [ "FUJIFILM X-T1", "FUJIFILM X-T10", "FUJIFILM X-E2" ], "dcraw_matrix": [ 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 ], // DNG D65 // "dcraw_matrix": [ 9289,-3279,-632,-3539,11137,2758,-1049,1950,6544 ], // X-RITE D55 +// "raw_crop": [ 4, 0, 4936, 3296 ], // full raw 4992,3296, fuji official 4936,3296 - experimental crop + "ranges": { "white": 16100 } + }, + + { // Quality B + "make_model": "FUJIFILM X-E2S", + "dcraw_matrix": [ 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 ], // DNG_v9.4 D65 + "ranges": { "white": 16100 } + }, + + { // Quality B + "make_model": "FUJIFILM X-PRO1", + "dcraw_matrix": [ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 ], // DNG_v9.4 D65 + "ranges": { "white": 4080 } + }, + + { // Quality B + "make_model": [ "FUJIFILM X-PRO2", "FUJIFILM X-T2" ], + "dcraw_matrix": [ 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 ], // DNG_v9.4 D65 + // "raw_crop": [ 0, 0, 6032, 4032 ], // full raw 6160,4032, Usable 6032,4032 - experimental crop "ranges": { "white": 16100 } }, @@ -927,18 +1177,16 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "white": 4040 } }, - { // Quality B - "make_model": "FUJIFILM X-PRO2", - "dcraw_matrix": [ 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 ], // DNG_v9.4 D65 - "raw_crop": [ 0, 0, 6032, 4032 ], // full raw 6160,4032, Usable 6032,4032 - experimental crop - "ranges": { "white": 16100 } - }, - { // Quality B, Matrix from Adobe's dcp D65 instead of the internal in Leica's DNG - "make_model": [ "LEICA SL (Typ 601)", "LEICA Q (Typ 116)" ], + "make_model": "LEICA Q (Typ 116)", "dcraw_matrix": [ 10068,-4043,-1068,-5319,14268,1044,-765,1701,6522 ], // DCP D65 "raw_crop": [ 4, 4, -4, -4 ] // full raw 6016x4016, Official 6000x4000 }, + { // Quality B, Matrix from Adobe's dcp D65 instead of the internal in Leica's DNG + "make_model": "LEICA SL (Typ 601)", + "dcraw_matrix": [ 11492,-4930,-1188,-5593,14673,873,-609,1474,6343 ], // DNGv9.3 D65 + "raw_crop": [ 4, 4, -4, -4 ] // full raw 6016x4016, Official 6000x4000 + }, { // Quality B, frame corrections "make_model": "LG mobile LG-H815", @@ -973,6 +1221,9 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "white": 4080 } // BL autodetected from exif }, +// For all Nikon Dslrs which have multiple bitdepth options (14 and 12 bit) we define the 14-bit value and RT adapts it to 12-bit +// when a 12-bit bitdepth is detected (WL12 = WL14*4095/16383) + { // quality B, samples by Johan Thor at RT.Issues, measures at long exposures with LENR are missing // but a safety margin is included - aperture scaling makes no significant difference "make_model": "Nikon D3S", @@ -991,34 +1242,75 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "white_max": 16383 } }, + { // quality B, intermediate ISO samples missing + "make_model": "Nikon D500", + "dcraw_matrix": [ 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 ], // DNG_v9.5 D65 + "ranges": { + "white": [ // measured at integer ISOs. Safety margin per ISO groups according to expected WL spread after LENR + { "iso": [ 100, 200, 400, 800, 1600 ], "levels": [ 16300, 16100, 16300 ] }, // typical G1,G2 16180 R,B 16383 + { "iso": [ 3200, 6400 ], "levels": [ 16250, 16050, 16250 ] }, // typical G1,G2,16200 R,B 16383 + { "iso": [ 12800, 25600 ], "levels": 16000 }, // typical G1,G2, R,B 16383 + { "iso": [ 51200, 102400 ], "levels": 15800 }, // typical G1,G2, R,B 16383 + { "iso": [ 204800, 409600 ], "levels": 15500 }, // typical G1,G2,R,B 16383 + { "iso": [ 819200, 1638400 ], "levels": 15000 } // typical G1,G2, R,B 16383 + ], + "white_max": 16383 + } + }, { // quality B, lacks aperture and ISO scaling, known to exist, but little to gain as the levels are so close to white_max "make_model": "Nikon D7000", "dcraw_matrix": [ 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 ], // matrix provided by Tanveer(tsk1979) "ranges": { // measured at ISO 100. ISO differences not measured, but known to exist - "white": [ 16370, 15760, 16370 ], // typical R 16383, G 15778, B 16383 + "white": [ 16300, 15700, 16300 ], // typical R 16383, G 15778, B 16383 "white_max": 16383 // aperture scaling not measured, but known to exist, at f/1.8 the G channels hits white_max } }, + { // quality B, + "make_model": "NIKON COOLPIX A", + "dcraw_matrix": [ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 ], // dng_d65 + "ranges": { + "white": [ + { "iso": [ 100, 125, 160, 200, 250, 320, 400, 500, 640, 800 ], "levels": [ 16300, 15700, 16300 ] }, // typical G1,G2 15760-15800 R,B 16383 + { "iso": [ 1000, 1250, 1600, 2000, 2500, 3200 ], "levels": 16300 }, // typical G1,G2, R,B 16383 + { "iso": [ 4000, 5000, 6400 ], "levels": 16200 }, // typical G1,G2, R,B 16383 + { "iso": [ 8000, 10000, 12800 ], "levels": 16000 }, // typical G1,G2,R,B 16383 + { "iso": [ 16000, 20000, 25600 ], "levels": 15700 } // typical G1,G2, R,B 16383 + ], + "white_max": 16383 + } + }, - { // Quality B, aperture scaling used to scale WL at safer levels + { // 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 + "ranges": { "black": 0, "white": 16300 } // WL typical 16383 set to 16300 for safety + }, + + { // Quality B + "make_model": "Nikon D3400", + "dcraw_matrix": [ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 ], // adobe dng_v9.7 d65 + "ranges": { "white": 16300 } // WL value is for 14-bit files, RT auto adapts it for 12-bit files. WL typical 16383 set to 16300 for safety + }, + + { // Quality B "make_model": "Nikon D5300", "dcraw_matrix": [ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 ], // adobe dng_v8.8 d65 - "ranges": { "white": 16300 } // attention.. WL value is for 14bit files, has to be 4070 for 12bit files. WL typical 16383 set to 16300 for safety + "ranges": { "white": 16300 } // WL value is for 14-bit files, RT auto adapts it for 12-bit files. WL typical 16383 set to 16300 for safety }, - { // Quality B, aperture scaling used to scale WL at safer levels + { // Quality B "make_model": "Nikon D5500", "dcraw_matrix": [ 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 ], // adobe dng_v9.0 d65 - "ranges": { "white": 16300 } // attention.. WL value is for 14bit files, has to be 4070 for 12bit files. WL typical 16383 set to 16300 for safety + "ranges": { "white": 16300 } // WL value is for 14-bit files, RT auto adapts it for 12-bit files. WL typical 16383 set to 16300 for safety }, - { // Quality B, color matrix from DNG_v9.0 instead of internal Dcraw_v9.25_r1.475, + { // Quality B "make_model": "Nikon D7200", "dcraw_matrix": [ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 ], // adobe dng_v9.0 d65 - "ranges": { "white": 16300 } // attention.. WL values are for 14bit files, has to be WL4070 for 12bit files. WL typical 16383 set to 16300 for safety, + "ranges": { "white": 16300 } // WL value is for 14-bit files, RT auto adapts it for 12-bit files. WL typical 16383 set to 16300 for safety, }, { // quality B, samples by joachip at RT forums, are measures at long exposures with LongExposureNoiseReduction @@ -1030,18 +1322,18 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "white": [ { "iso": [ 50, 100 ], "levels": [ 15800, 15800, 15350 ] }, // typical G1/G2/R 15879, B 15395-15670 lowered to 15800, 15350, 3969 B3917 { "iso": [ 200, 400, 800 ], "levels": [ 16300, 15700, 16300 ] }, // 15878, 16383 - { "iso": 1000, "levels": [ 16300, 16100, 16300 ] }, // 12bit lossless r4095, 3981-10, b4041- 12bit lossy r,g1,g2 3961 - b3917, + { "iso": 1000, "levels": [ 16300, 16100, 16300 ] }, // 12-bit lossless r4095, 3981-10, b4041- 12-bit lossy r,g1,g2 3961 - b3917, { "iso": 1600, "levels": [ 16300, 16100, 16300 ] }, // 16145-165, 16383 { "iso": [ 3200, 6400, 12800, 25600 ], "levels": [ 16300, 16300, 16300 ] } // 16383 ], "white_max": 16383 } - }, - { // quality B, lacks WL measures at intermediate ISOs (160-250-320 ..) and measures at long exposures with LongExposureNoiseReduction + }, + { // quality B, missing WL measures at intermediate ISOs (160-250-320 ..) and at long exposures with LongExposureNoiseReduction set to ON // aperture scaling known to exist, but little to gain as the levels are so close to white_max "make_model": "Nikon D610", "dcraw_matrix": [ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 ], // dcp d65 - "raw_crop": [ 0, 0, 6034, 4028 ], // Dcraw has no raw crop for D610 + "raw_crop": [ 0, 0, 6034, 4028 ], "ranges": { "white": [ { "iso": [ 50, 100 ], "levels": [ 15800, 15700, 15800 ] }, // typical G1/G2 15778, R/B 15879 lowered to 15700, 15800 for possible WL distribution under LENR @@ -1051,22 +1343,24 @@ Quality X: unknown, ie we knowing to little about the camera properties to know ], "white_max": 16383 } - }, + }, - { // quality B; Data from RusselCottrell at RT forums. sensor is not uniform + { // quality B; Data from RusselCottrell at RT forums. sensor is not uniform "make_model": "Nikon D700", "dcraw_matrix": [ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 ], - "ranges": { "white": 15750 } // Non linearities start at 15750 (hi ISOs) 15850 (low ISOs) with long exposures (>2sec) and LENR ON .. nominal 15892 - // white 15750 is correct for 14bit files, 12 bit files need white level at 3900 - }, + // "dcraw_matrix": [ 9336,-3405,14,-7321,14779,2764,-914,1171,8248 ], // illuminant A + "ranges": { "white": [ 15500, 15500, 15500 ] } + // Non linearities start at 15500 (hi ISOs) 15850 (low ISOs) with long exposures (>2sec) and LENR ON .. nominal 15892 + // white 15500 is correct for 14-bit files, for 12-bit files RT auto_calculates it 15500*4095/16383=3874 + }, - { // Quality B, + { // Quality B, "make_model": "Nikon D750", "dcraw_matrix": [ 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 ], // adobe dcp d65 DNGv8.7 - "ranges": { "white": 16300 } // attention.. WL values are for 14bit files, has to be WL4070 for 12bit files. WL typical 16383 set to 16300 for safety - }, + "ranges": { "white": 16300 } // WL values for 14-bit files, RT auto adapts it for 12-bit files. TypicalWL 16383 set to 16300 for safety + }, - { // quality B; Data from RussellCottrell at RT forums. Largest aperture scale factor is 1.013, about 1/50th of a stop + { // quality B; Data from RussellCottrell at RT forums. Largest aperture scale factor is 1.013, about 1/50th of a stop "make_model": "Nikon D800E", "dcraw_matrix": [ 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 ], // D800/D800E from dcraw.c "ranges": { @@ -1076,17 +1370,30 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { "iso": [ 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 16300 } // 16383 ] } - }, - { // quality B, WL set at 16300 from nominal 16380 for possible non linearities with LENR + }, + { // quality B, WL set at 16300 from nominal 16380 for possible non linearities with LENR "make_model": "Nikon D810", "dcraw_matrix": [ 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 ], // dcp_v8.6 d65 "raw_crop": [ 0, 0, 7380, 4928 ], // Official raw crop 7380x4928, - "ranges": { "white": 16300 } // attention WL 16300 is for 14bit raws and has to be 4070 for 12 bit raws. Typical WL at 16383 + "ranges": { "white": 16300 } // WL values for 14-bit files, RT auto adapts it for 12-bit files. Typical WL at 16383 }, + { // Quality b, 16Mp and 64Mp raw frames "make_model": "OLYMPUS E-M5MarkII", "dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65 - "raw_crop": [ 0, 0, -6, -6 ], // largest valid, full 64Mp 9280x6938, official crop 0 0 9216 6912 - safe 5755 + "raw_crop": [ 0, 0, -6, -6 ], // largest valid, full 64Mp 9280x6938, official crop 0 0 9216 6912 + "ranges": { + "white": [ + { "iso": [ 100, 200 ], "levels": 3950 }, // normal 4080-4095, HR Dpreview 4047, IR 3956 + { "iso": [ 400, 800, 1600, 3200 ], "levels": 4070 }, // 4070-4095 + { "iso": [ 6400, 12800, 25600 ], "levels": 4040 } // 4000-4095 + ] + } + }, + { // Quality B, 20Mp and 80Mp raw frames + "make_model": "OLYMPUS PEN-F", + "dcraw_matrix": [ 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 ], // dng_v9.5 D65 + // "raw_crop": [ 0, 0, 10372, -7780 ], // Highres mode largest valid, full 80Mp 10400X7796, official crop 10 10 10368 7776 "ranges": { "white": [ { "iso": [ 100, 200 ], "levels": 3950 }, // normal 4080-4095, HR Dpreview 4047, IR 3956 @@ -1096,8 +1403,14 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // Quality b, missing per ISO samples + "make_model": "OLYMPUS E-M1", + "dcraw_matrix": [ 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 ], // dng d65 + "ranges": { "white": 4080 } // nominal 4095-4094, spread with some settings as long exposure + }, + { // Quality b, crop correction - "make_model": "OLYMPUS E-M10", + "make_model": [ "OLYMPUS E-M10", "OLYMPUS E-M10 Mark II" ], "dcraw_matrix": [ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 ], "raw_crop": [ 0, 0, 4624, 3472 ], // largest valid - full frame is 4640x3472 // "raw_crop": [ 4, 4, 4616, 3464 ], // olympus jpeg crop 8, 8, 4608, 3456 @@ -1109,27 +1422,27 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "white": 4040 } // nominal 4056 }, - { // Quality B, with long exposure noise reduction White Level gets WL-BL = around 256_12bit levels less + { // Quality B, with long exposure noise reduction White Level gets WL-BL = around 256_12-bit levels less "make_model": "OLYMPUS E-PL7", "dcraw_matrix": [ 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 ], // DNG_V8.7 D65 "ranges": { "white": 4080 } // nominal 4093 }, { // Quality B, per ISO WL measures missing - "make_model": "OLYMPUS SH-2", + "make_model": [ "OLYMPUS SH-2", "Olympus SH-3" ], "dcraw_matrix": [ 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 ], // DNG_V9.1 D65 "ranges": { "white": 4050 } // safe for worst case detected, nominal is 4093 }, - /* since Dcraw_v9.21 Panasonic base BL is read from exif (tags 0x001c BlackLevelRed15 is BL offstet. - Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue + /* since Dcraw_v9.21 Panasonic base BL is read from exif (tags 0x001c BlackLevelRed15 is BL offset. + Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue and we define here the needed offset of around 15. The total BL is base+offset */ { // Quality B, CameraPhone, some samples are missing but has the same sensor as FZ1000 .. - "make_model": "Panasonic DMC-CM1", + "make_model": [ "Panasonic DMC-CM1", "Panasonic DMC-CM10" ], "dcraw_matrix": [ 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 ], // dcp_v8.7 d65 "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 80, "levels": 3600 }, // exif:3277 distribution peak at 3700 up to +/- 100 { "iso": [ 100, 125, 200, 400, 800, 1600 ], "levels": 4050 }, // exif 4095 distribution 4050-4095 @@ -1141,20 +1454,33 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { // Quality A , replicated from rawimage.cc "make_model": "Panasonic DMC-FZ150", "dcraw_matrix": [ 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 ], // RT, copy from custom dcp d55 - "ranges": { "black": 15, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "ranges": { "black": 15, "white": 4050 } // 15 is BL offset. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset }, - { // Quality Β, + { // Quality B, "make_model": [ "Panasonic DMC-FZ300", "Panasonic DMC-FZ330" ], "dcraw_matrix": [ 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 ], // DNG-V9.1.1 - "ranges": { "black": 15, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "ranges": { "black": 15, "white": 4050 } // 15 is BL offset. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset }, { // Quality A, samples by helices at Rt forums "make_model": [ "Panasonic DMC-FZ1000", "Leica V-LUX (Typ 114)" ], "dcraw_matrix": [ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 ], // dcp_v8.6 d65 "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 80, "levels": 3600 }, // exif:3277 distribution peak at 3700 up to +/- 100 + { "iso": [ 100, 125, 200, 400, 800, 1600 ], "levels": 4050 }, // exif 4095 distribution 4050-4095 + { "iso": [ 3200, 6400, 12600, 25600 ], "levels": 4080 } // exif 4095 distribution 4080-4095 + ] + } + }, + { // Quality A, samples by helices at Rt forums and Chris Power at github + "make_model": [ "Panasonic DMC-ZS100", "Panasonic DMC-ZS110", "Panasonic DMC-TZ100", "Panasonic DMC-TZ101", "Panasonic DMC-TZ110", "Panasonic DMC-TX1" ], + "dcraw_matrix": [ 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 ], // dcp_v8.6 d65 + "raw_crop": [ 4, 4, -4, -4 ], // full raw frame 5488x3664 exif crop 5472X3648 with 8pixel borders. Set the borders at 4 pixels which added with RT's 4 pixels border gives exactly the official frame. + "ranges": { + "black": 15, // 15 is BL offset. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 80, "levels": 3600 }, // exif:3277 distribution peak at 3700 up to +/- 100 { "iso": [ 100, 125, 200, 400, 800, 1600 ], "levels": 4050 }, // exif 4095 distribution 4050-4095 @@ -1162,17 +1488,16 @@ Quality X: unknown, ie we knowing to little about the camera properties to know ] } }, - { // Quality A "make_model": [ "Panasonic DMC-LF1", "Leica C (Typ 112)" ], "dcraw_matrix": [ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 ], - "ranges": { "black": 15, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "ranges": { "black": 15, "white": 4050 } // 15 is BL offset. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset }, { // Quality A "make_model": [ "Panasonic DMC-TZ60", "Panasonic DMC-TZ61", "Panasonic DMC-ZS40", "Panasonic DMC-ZS41" ], "dcraw_matrix": [ 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 ], // matrix from Adobe dcp v8.4 "raw_crop": [ 8, 8, -8, -8 ], // crop according to exif 4896 X 3672 plus 4 pixels borders. RT's frame gets smaller than Dcraw but works better with auto distortion - "ranges": { "black": 14, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "ranges": { "black": 14, "white": 4050 } // 15 is BL offset. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset }, { // Quality B, "make_model": [ "Panasonic DMC-TZ70", "Panasonic DMC-TZ71", "Panasonic DMC-ZS50", "Panasonic DMC-ZS51" ], @@ -1198,7 +1523,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-G1", "dcraw_matrix": [ 7477,-1615,-651,-5016,12769,2506,-1380,2475,7240 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": [ 100, 200, 400, 800 ], "levels": 3920 }, // exif:4095 distribution peak at 3977 +/- up to 50 { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 @@ -1209,21 +1534,21 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-G3", "dcraw_matrix": [ 6051,-1406,-671,-4015,11505,2868,-1654,2667,6219 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": 4060 } // exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR }, { // Quality A, Replicated from rawimage.cc "make_model": "Panasonic DMC-G5", "dcraw_matrix": [ 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 ], // RT "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": 4060 } // exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR }, { // Quality A, Replicated from rawimage.cc "make_model": "Panasonic DMC-GF1", "dcraw_matrix": [ 7863,-2080,-668,-4623,12331,2578,-1020,2066,7266 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": [ 100, 200, 400, 800 ], "levels": 3920 }, // exif:4095 distribution peak at 3977 +/- up to 50 { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 @@ -1235,21 +1560,21 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-GF2", "dcraw_matrix": [ 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": 4050 } // exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR }, { // Quality A, Replicated from rawimage.cc "make_model": "Panasonic DMC-GF3", "dcraw_matrix": [ 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": 4050 } // exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR }, { // Quality A, Replicated from rawimage.cc "make_model": "Panasonic DMC-GH1", "dcraw_matrix": [ 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 ], // Colin Walker "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": [ 100, 200, 400, 800 ], "levels": 3930 }, // exif:4095 distribution peak at 3982 +/- up to 50 { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 @@ -1261,7 +1586,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know // "dcraw_matrix": [ 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 ], // Colin Walker - disabled due to problems with underwater "dcraw_matrix": [ 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 ], // Dcraw d65 "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": [ 100, 200, 400, 800 ], "levels": 3930 }, // exif:4095 distribution peak at 3982 +/- up to 50 { "iso": [ 1600, 3200, 6400, 12800 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 @@ -1273,7 +1598,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-GH3", "dcraw_matrix": [ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 ], // dcp d65 "ranges": { - "black": 16, // 16 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 16, // 16 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 125, "levels": 3500 }, // gaussian 3600-4095 { "iso": [ 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 @@ -1285,7 +1610,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-GH4", "dcraw_matrix": [ 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 ], // dng_v8.5 d65 "ranges": { - "black": 16, // 16 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "black": 16, // 16 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 100, "levels": 2700 }, // gaussian center at 2870-2920 range +/- 150, exif 2111 { "iso": 125, "levels": 3100 }, // guessed @@ -1298,7 +1623,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-GM1", "dcraw_matrix": [ 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 ], "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 125, "levels": 3100 }, // bell shape 3150-3650 - exif 2616 { "iso": 160, "levels": 3600 }, // guessed from relative GX7 data @@ -1311,7 +1636,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": "Panasonic DMC-GM5", "dcraw_matrix": [ 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 ], // dng_v8.7 d65 "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 100, "levels": 2800 }, // bell shape 2850-3250 - exif 2111 { "iso": [ 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 @@ -1319,10 +1644,10 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, { // Quality A, - "make_model": [ "Panasonic DMC-GX7", "Panasonic DMC-GF7" ], + "make_model": [ "Panasonic DMC-GX7", "Panasonic DMC-GF7", "Panasonic DMC-GF8" ], "dcraw_matrix": [ 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 ], "ranges": { - "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 15 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 125, "levels": 3100 }, { "iso": 160, "levels": 3600 }, @@ -1334,9 +1659,8 @@ Quality X: unknown, ie we knowing to little about the camera properties to know { // Quality A, "make_model": [ "Panasonic DMC-G7", "Panasonic DMC-G70" ], "dcraw_matrix": [ 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 ],// DNG_v9.1 D65 - // "dcraw_matrix": [ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 ], // LX100, DNG_V8.7 d65 "ranges": { - "black": 16, // 16 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "black": 16, // 16 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset "white": [ { "iso": 100, "levels": 2300 }, // gaussian 2300-2700 exif_linearitylimit 2111 { "iso": 125, "levels": 3180 }, // gaussian 3200-3600 exif_linearitylimit 2626 @@ -1345,12 +1669,36 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, { // Quality B, + "make_model": [ "Panasonic DMC-GX80", "Panasonic DMC-GX85", "Panasonic DMC-GX7MK2" ], + "dcraw_matrix": [ 7771,-3020,-629,-4029,11950,2345,-821,1977,6119 ],// DNG_v9.6 D65 + "ranges": { + "black": 16, // 16 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 100, "levels": 2300 }, // gaussian 2300-2700 exif_linearitylimit 2111 + { "iso": 125, "levels": 3180 }, // gaussian 3200-3600 exif_linearitylimit 2626 + { "iso": [ 160, 200, 250, 320, 400,500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + { // Quality B, Same as Panasonic G7 + "make_model": [ "Panasonic DMC-G8", "Panasonic DMC-G80", "Panasonic DMC-G81", "Panasonic DMC-G85" ], + "dcraw_matrix": [ 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 ],// DNG_v9.7 D65 + "ranges": { + "black": 16, // 16 is BL offset. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 100, "levels": 2300 }, // gaussian 2300-2700 exif_linearitylimit 2111 + { "iso": 125, "levels": 3180 }, // gaussian 3200-3600 exif_linearitylimit 2626 + { "iso": [ 160, 200, 250, 320, 400,500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + { // Quality B, "make_model": "Panasonic DMC-GX8", "dcraw_matrix": [ 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 ], // DNG_v9.1.1 D65 "ranges": { - "black": 15, // 16 is BL offstet. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "black": 15, // 16 is BL offset. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset "white": [ - { "iso": 100, "levels": 2300 }, // gaussian 2300-2700 exif_linearitylimit 2111 + { "iso": 100, "levels": 2800 }, // gaussian 2900-3200 exif_linearitylimit 2111 { "iso": 125, "levels": 3180 }, // guessed gaussian 3200-3600 exif_linearitylimit 2626 { "iso": [ 160, 200, 250, 320, 400,500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 ] @@ -1361,7 +1709,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "dcraw_matrix": [ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 ], // DNG_V8.7 d65 // "dcraw_matrix": [ 6538,-1614,-549,-5475,13096,2646,-1780,2799,5612 ], // calculated from DxO D50 "ranges": { - "black": 15, // 15 is BL offset calculated from exif data. + "black": 15, // 15 is BL offset. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset. "white": [ { "iso": 100, "levels": 2300 }, // gaussian 2400-2700 exif_linearitylimit 2111 { "iso": [ 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 @@ -1369,6 +1717,12 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // 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 + "ranges": { "white": 4080 } // nominal at ISO200 4094 + }, + { // Quality B, intermediate ISOs info missing "make_model": [ "RICOH PENTAX K-3", "PENTAX K-3" ], "dcraw_matrix": [ 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 ], // adobe dcp d65 @@ -1386,10 +1740,25 @@ Quality X: unknown, ie we knowing to little about the camera properties to know } }, + { // Quality B, intermediate ISOs info missing + "make_model": [ "RICOH PENTAX 645Z", "PENTAX 645Z" ], + "dcraw_matrix": [ 9519,-3591,-664,-4074,11725,2671,-624,1501,6653 ], // adobe dcp d65 + "raw_crop": [ 48, 0, 8276, 6208 ],// full sensor 8384x6208 - official jpeg 8256x6192 + "ranges": { + "white": [ + { "iso": 100, "levels": 16310 }, // 16317 or 16350 + { "iso": 200, "levels": 16120 }, // 16254 or 16125 + { "iso": 400, "levels": 15860 }, // 16125 or 15868 + { "iso": 800, "levels": 15360 }, // 15868 or 15364-15370 + { "iso": [ 1600, 3200, 6400, 12800, 25600, 51200 ], "levels": 16300 } // 16383 - pentax dng tag is 15868-15350 + ] + } + }, + { // Quality B, intermediate ISOs info missing, spread due to blackframe subtraction guessed to be around 10levels "make_model": "PENTAX K10D", "dcraw_matrix": [ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 ], // adobe DNG d65 - // "raw_crop": [ 0, 0, 3888, 2608 ], + // "raw_crop": [ 0, , 3888, 2608 ], "ranges": { "white": [ { "iso": 100, "levels": 4080 }, // R,G1,B = 4095 G2= 4087 @@ -1408,7 +1777,7 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "white": 4030 } // double clipping point for each channel at a) 4095 and b) bell distribution with peak at 4038 .. used the conservative one }, { // Quality A, Conflict with "Samsung NX30" in Dcraw_v9.21_r1.414, frame corrections and color data - "make_model": "Samsung NX3000", + "make_model": [ "Samsung NX3000", "Samsung NX3300" ], "dcraw_matrix": [ 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 ], // DNG_v8.7.1 D65 "raw_crop": [ 92, 38, 5480, 3656 ] // jpeg 5472x3648 - full raw: 5600 x 3714 - Samsung's official crop: 96, 42, 5568, 3690 }, @@ -1417,10 +1786,10 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "make_model": [ "Samsung NX1", "Samsung NX500" ], "dcraw_matrix": [ 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 ], // DNG_v8.7 D65 // "dcraw_matrix": [ 13298,-6099,-296,-5243,16153,-1235,-508,1220,7758 ], // DNG_v8.7 Standard Light A - // "dcraw_matrix": [ 9598,-3268,-634,-5678,14795,824,-1255,2675,4523 ], // SAMSUNG DNG CONVERTER + // "dcraw_matrix": [ 9598,-3268,-634,-5678,14795,824,-1255,2675,4523 ], // SAMSUNG DNG CONVERTER v1.0 "ranges": { "white": [ - { "iso": 100, "levels": 16000 }, // typical 16084, LE 16120 and 16383, LENR 16280 + { "iso": 100, "levels": 16000 }, // 16000 typical 16084, LE 16120 and 16383, LENR 16280 { "iso": [ 200, 400, 800, 1600, 3200, 6400, 12800 ], "levels": 16300 }, // 16383 { "iso": [ 25600, 51200 ], "levels": 16300 } // 16383 ] @@ -1465,14 +1834,14 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the top "raw_crop": [ 12, 52, -110, -8 ] // for small size all numbers/2 }, - { // Quality C, correction for frame width, color matrix guessed .. + { // Quality C, correction for frame width, color matrix measured on a DP1 sample .. "make_model": [ "Sigma DP1 Merrill", "Sigma DP2 Merrill", "Sigma DP3 Merrill" ], - "dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // copy fron SD1 Merrill icc cloudy8140 d65 + // "dcraw_matrix": [ 2149,1003,-530,-494,6073,344,-3935,10665,3608 ], // experimental, inverted icc DP1_Merrill_dpreview_daylight WP1.2 + "dcraw_matrix": [ 2517,1175,-621,-587,7080,404,-4677,12402,4231 ], // experimental, inverted icc DP1_Merrill_dpreview_daylight WP1.4 "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the bottom "raw_crop": [ 12, 0, -110, -62 ] // for small size all numbers/2 }, - { // Quality A, correction for color matrix from Colin Walker's d50 to dng d65 "make_model": "Sony NEX-C3", // "dcraw_matrix": [ 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 ], // Colin walker's d50 kept for possible consistency issues @@ -1486,13 +1855,20 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "raw_crop": [ 0, 0, 4920, 3276 ], "ranges": { "black": 512, "white": 16300 } }, - { // Quality A, + { // Quality A, "make_model": "Sony ILCA-77M2", "dcraw_matrix": [ 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 ], // adobe dcp d65 "raw_crop": [ 0, 0, 6024, 4024 ], "ranges": { "black": 512, "white": 16300 } }, + { // Quality B, + "make_model": "Sony ILCA-68", + "dcraw_matrix": [ 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 ], // adobe DNGv9.5 d65 + "raw_crop": [ 0, 0, -30, 0 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A, correction for frame width "make_model": [ "Sony ILCE-3000", "Sony ILCE-3500", "Sony ILCE-5000", "Sony ILCE-QX1" ], "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], // adobe dcp d65 @@ -1511,6 +1887,12 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "raw_crop": [ 0, 0, 6024, 4024 ], "ranges": { "black": 512, "white": 16300 } }, + { // Quality A + "make_model": "Sony ILCE-6300", + "dcraw_matrix": [ 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 ], // DNG_v9.5 D65 + "raw_crop": [ 0, 0, 6024, 4024 ], + "ranges": { "black": 512, "white": 16300 } + }, { // Quality A "make_model": "Sony ILCE-7M2", "dcraw_matrix": [ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 ], // DNGv8.7.1 @@ -1523,10 +1905,10 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "black": 512, "white": 16300 } }, - { // Quality B, correction for frame width, crop modes not covered - "make_model": "Sony ILCE-7RM2", + { // Quality B, correction for frame width, crop modes covered + "make_model": [ "Sony ILCE-7RM2", "Sony DSC-RX1RM2" ], "dcraw_matrix": [ 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 ], // DNG_v9.1.1 D65 - "raw_crop": [ 0, 0, 7964, 5320 ], // full raw frame 8000x5320 - 36 rightmost columns are garbage + "raw_crop": [ 0, 0, -36, 0 ], // full raw frame 8000x5320 - 36 rightmost columns are garbage "ranges": { "black": 512, "white": 16300 } }, @@ -1542,8 +1924,8 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "ranges": { "black": 800, "white": 16300 } }, { // Quality B, - "make_model": "Sony DSC-RX10M2", - "dcraw_matrix": [ 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 ], // DNG_v9.1.1 D65 + "make_model": [ "Sony DSC-RX10M2", "Sony DSC-RX10M3" ], + "dcraw_matrix": [ 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 ], // DNG_v9.6 D65 "ranges": { "black": 800, "white": 16300 } }, @@ -1592,7 +1974,6 @@ Quality X: unknown, ie we knowing to little about the camera properties to know "dcraw_matrix": [ 4479,-895,-536,-5818,13569,2742,-1186,2190,7909], "ranges": { "black": 0, "white": 64400 } }, - { // Quality A for tested CFV, the other models have the same sensor (16 megapixel square sensor) "make_model": [ "Hasselblad V96C", "Hasselblad CFV", "Hasselblad CFV-II" ], "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index 83ff98f95..f10ae4b31 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -180,39 +180,36 @@ void Ciecam02::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu & } } -void Ciecam02::curveJfloat (float br, float contr, int db, LUTf & outCurve, LUTu & histogram ) +void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf & outCurve) { - LUTf dcurve(65536, 0); - int skip = 1; // check if brightness curve is needed if (br > 0.00001f || br < -0.00001f) { - std::vector brightcurvePoints; - brightcurvePoints.resize(9); - brightcurvePoints.at(0) = double(DCT_NURBS); + std::vector brightcurvePoints(9); + brightcurvePoints[0] = double(DCT_NURBS); - brightcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range - brightcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range + brightcurvePoints[1] = 0.f; // black point. Value in [0 ; 1] range + brightcurvePoints[2] = 0.f; // black point. Value in [0 ; 1] range if (br > 0) { - brightcurvePoints.at(3) = 0.1f; // toe point - brightcurvePoints.at(4) = 0.1f + br / 150.0f; //value at toe point + brightcurvePoints[3] = 0.1f; // toe point + brightcurvePoints[4] = 0.1f + br / 150.0f; //value at toe point - brightcurvePoints.at(5) = 0.7f; // shoulder point - brightcurvePoints.at(6) = min(1.0f, 0.7f + br / 300.0f); //value at shoulder point + brightcurvePoints[5] = 0.7f; // shoulder point + brightcurvePoints[6] = min(1.0f, 0.7f + br / 300.0f); //value at shoulder point } else { - brightcurvePoints.at(3) = 0.1f - br / 150.0f; // toe point - brightcurvePoints.at(4) = 0.1f; // value at toe point + brightcurvePoints[3] = 0.1f - br / 150.0f; // toe point + brightcurvePoints[4] = 0.1f; // value at toe point - brightcurvePoints.at(5) = min(1.0f, 0.7f - br / 300.0f); // shoulder point - brightcurvePoints.at(6) = 0.7f; // value at shoulder point + brightcurvePoints[5] = min(1.0f, 0.7f - br / 300.0f); // shoulder point + brightcurvePoints[6] = 0.7f; // value at shoulder point } - brightcurvePoints.at(7) = 1.f; // white point - brightcurvePoints.at(8) = 1.f; // value at white point + brightcurvePoints[7] = 1.f; // white point + brightcurvePoints[8] = 1.f; // value at white point - DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve brightcurve(brightcurvePoints, CURVES_MIN_POLY_POINTS); // Applying brightness curve for (int i = 0; i < 32768; i++) { @@ -221,67 +218,56 @@ void Ciecam02::curveJfloat (float br, float contr, int db, LUTf & outCurve, LUTu float val = (float)i / 32767.0f; // apply brightness curve - val = brightcurve->getVal (val); + val = brightcurve.getVal (val); - // store result in a temporary array - dcurve[i] = CLIPD(val); + // store result + outCurve[i] = CLIPD(val); } - delete brightcurve; } else { - // for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow - for (int i = 0; i < (32768 * db); i++) { // L values range up to 32767, higher values are for highlight overflow - - // set the identity curve in the temporary array - dcurve[i] = (float)i / (db * 32768.0f); - } + // set the identity curve + outCurve.makeIdentity(32767.f); } if (contr > 0.00001f || contr < -0.00001f) { // compute mean luminance of the image with the curve applied - int sum = 0; - float avg = 0; + float sum = 0.f; + float avg = 0.f; - //float sqavg = 0; for (int i = 0; i < 32768; i++) { - avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J + avg += outCurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J sum += histogram[i]; } avg /= sum; - //printf("avg=%f\n",avg); - std::vector contrastcurvePoints; - contrastcurvePoints.resize(9); - contrastcurvePoints.at(0) = double(DCT_NURBS); + std::vector contrastcurvePoints(9); - contrastcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range - contrastcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range + contrastcurvePoints[0] = double(DCT_NURBS); - contrastcurvePoints.at(3) = avg - avg * (0.6f - contr / 250.0f); // toe point - contrastcurvePoints.at(4) = avg - avg * (0.6f + contr / 250.0f); // value at toe point + contrastcurvePoints[1] = 0.f; // black point. Value in [0 ; 1] range + contrastcurvePoints[2] = 0.f; // black point. Value in [0 ; 1] range - contrastcurvePoints.at(5) = avg + (1 - avg) * (0.6f - contr / 250.0f); // shoulder point - contrastcurvePoints.at(6) = avg + (1 - avg) * (0.6f + contr / 250.0f); // value at shoulder point + contrastcurvePoints[3] = avg - avg * (0.6f - contr / 250.0f); // toe point + contrastcurvePoints[4] = avg - avg * (0.6f + contr / 250.0f); // value at toe point - contrastcurvePoints.at(7) = 1.f; // white point - contrastcurvePoints.at(8) = 1.f; // value at white point + contrastcurvePoints[5] = avg + (1 - avg) * (0.6f - contr / 250.0f); // shoulder point + contrastcurvePoints[6] = avg + (1 - avg) * (0.6f + contr / 250.0f); // value at shoulder point - DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS / skip); + contrastcurvePoints[7] = 1.f; // white point + contrastcurvePoints[8] = 1.f; // value at white point + + DiagonalCurve contrastcurve(contrastcurvePoints, CURVES_MIN_POLY_POINTS); // apply contrast enhancement - for (int i = 0; i < (32768 * db); i++) { - dcurve[i] = contrastcurve->getVal (dcurve[i]); + for (int i = 0; i < 32768; i++) { + outCurve[i] = contrastcurve.getVal(outCurve[i]); } - delete contrastcurve; } - // for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i]; - for (int i = 0; i < (db * 32768); i++) { - outCurve[i] = db * 32768.0f * dcurve[i]; - } + outCurve *= 32767.f; } /** @@ -857,7 +843,7 @@ void Ciecam02::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, h = myh; } -void Ciecam02::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s, float &aw, float &fl, float &wh, +void Ciecam02::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s, float aw, float fl, float wh, float x, float y, float z, float xw, float yw, float zw, float c, float nc, int gamu, float pow1, float nbb, float ncb, float pfl, float cz, float d) diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h index e5b61d466..a551b2504 100644 --- a/rtengine/ciecam02.h +++ b/rtengine/ciecam02.h @@ -74,7 +74,7 @@ public: static void curvecolor(double satind, double satval, double &sres, double parsat); static void curvecolorfloat(float satind, float satval, float &sres, float parsat); static void curveJ (double br, double contr, int db, LUTf & outCurve , LUTu & histogram ) ; - static void curveJfloat (float br, float contr, int db, LUTf & outCurve , LUTu & histogram ) ; + static void curveJfloat (float br, float contr, const LUTu & histogram, LUTf & outCurve ) ; /** * Inverse transform from CIECAM02 JCh to XYZ. @@ -125,7 +125,7 @@ public: float c, float nc, float n, float nbb, float ncb, float cz, float d ); static void xyz2jchqms_ciecam02float( float &J, float &C, float &h, - float &Q, float &M, float &s, float &aw, float &fl, float &wh, + float &Q, float &M, float &s, float aw, float fl, float wh, float x, float y, float z, float xw, float yw, float zw, float c, float nc, int gamu, float n, float nbb, float ncb, float pfl, float cz, float d ); diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index a0ea5afb4..f3ef27a79 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -1,442 +1,330 @@ +#include + #include "clutstore.h" + +#include "opthelper.h" #include "rt_math.h" +#include "imagefloat.h" #include "stdimagesource.h" #include "../rtgui/options.h" -rtengine::CLUTStore clutStore; - -using namespace rtengine; - -const float MAXVAL8 = 255.; - -CLUTStore::CLUTStore() +namespace { -} -CLUT* CLUTStore::getClut( const Glib::ustring& filename ) +bool loadFile( + const Glib::ustring& filename, + const Glib::ustring& working_color_space, + AlignedBuffer& clut_image, + unsigned int& clut_level +) { - CLUT *result = 0; - m_mutex.lock(); - Cluts::iterator cluts_it = m_cluts.find(filename); + rtengine::StdImageSource img_src; - if (cluts_it == m_cluts.end()) { - if (m_cluts.size() >= options.clutCacheSize) { - // Evict a "random" entry from cache - Cluts::iterator victim_it = m_cluts.begin(); - - if (--victim_it->second.first == -1) { - delete victim_it->second.second; - m_cluts.erase(victim_it); - } - } - - cluts_it = m_cluts.insert(std::make_pair(filename, std::make_pair(0, new HaldCLUT))).first; - cluts_it->second.second->load( filename ); - } - - if (cluts_it->second.second->isValid()) { - result = cluts_it->second.second; - ++cluts_it->second.first; - } else { - delete cluts_it->second.second; - m_cluts.erase(cluts_it); - } - - m_mutex.unlock(); - - return result; -} - -void CLUTStore::releaseClut( const CLUT* clut ) -{ - m_mutex.lock(); - - for (Cluts::iterator cluts_it = m_cluts.begin(); cluts_it != m_cluts.end(); ++cluts_it) { - if (cluts_it->second.second == clut) { - if (--cluts_it->second.first == -1) { - delete cluts_it->second.second; - m_cluts.erase(cluts_it); - } - - break; - } - } - - m_mutex.unlock(); -} - -void CLUTStore::clearCache() -{ - m_mutex.lock(); - - for (Cluts::iterator cluts_it = m_cluts.begin(); cluts_it != m_cluts.end();) { - if (--cluts_it->second.first == -1) { - delete cluts_it->second.second; - Cluts::iterator tmp = cluts_it; - ++cluts_it; - m_cluts.erase(tmp); - } else { - ++cluts_it; - } - } - - m_mutex.unlock(); -} - -void rtengine::splitClutFilename( Glib::ustring filename, Glib::ustring &name, Glib::ustring &extension, Glib::ustring &profileName ) -{ - filename = Glib::path_get_basename( filename ); - name = filename; - //remove dirs - size_t lastSlashPos = filename.find_last_of( "/" ); - - if ( lastSlashPos == Glib::ustring::npos ) { - lastSlashPos = filename.find_last_of( "\\" ); - } - - size_t lastDotPos = filename.find_last_of( '.' ); - - if ( lastDotPos != Glib::ustring::npos ) { - name = filename.substr( 0, lastDotPos ); - extension = filename.substr( lastDotPos + 1, Glib::ustring::npos ); - } - - profileName = "sRGB"; // sRGB by default - static std::vector workingProfiles = rtengine::getWorkingProfiles(); - - for ( std::vector::iterator it = workingProfiles.begin(); it != workingProfiles.end(); ++it ) { - Glib::ustring ¤tProfile = *it; - - if ( std::search( name.rbegin(), name.rend(), currentProfile.rbegin(), currentProfile.rend() ) == name.rbegin() ) { - profileName = currentProfile; - name = name.substr( 0, name.size() - currentProfile.size() ); - break; - } - } -} - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -HaldCLUT::HaldCLUT() - : m_clutImage( 0 ), - m_level (0), - m_profile( "sRGB" ) -{ -} - -HaldCLUT::~HaldCLUT() -{ - if ( m_clutImage ) { - m_clutImage->free(); - m_clutImage = 0; - } -} - -void HaldCLUT::load( Glib::ustring filename ) -{ - m_clutImage = loadFile( filename, "", m_level ); - Glib::ustring name, ext; - splitClutFilename( filename, name, ext, m_profile ); - - if ( m_clutImage ) { - m_filename = filename; - } -} - -Glib::ustring HaldCLUT::profile() const -{ - return m_profile; -} - -Imagefloat* HaldCLUT::loadFile( Glib::ustring filename, Glib::ustring workingColorSpace, int &outLevel ) -{ - Imagefloat *result = 0; - StdImageSource imgSrc; - - if ( !Glib::file_test( filename, Glib::FILE_TEST_EXISTS ) || imgSrc.load(filename) ) { - return result; + if (!Glib::file_test(filename, Glib::FILE_TEST_EXISTS) || img_src.load(filename)) { + return false; } int fw, fh; - imgSrc.getFullSize (fw, fh, TR_NONE); + img_src.getFullSize(fw, fh, TR_NONE); - bool valid = false; + bool res = false; - //test on Hald format, copypasted from http://www.quelsolaar.com/technology/clut.html - if ( fw == fh ) { - outLevel = 1; + if (fw == fh) { + unsigned int level = 1; - for(; outLevel * outLevel * outLevel < fw; outLevel++); + while (level * level * level < fw) { + ++level; + } - if( !( outLevel * outLevel * outLevel > fw ) ) { - valid = true; + if (level * level * level == fw && level > 1) { + clut_level = level; + res = true; } } - if ( valid ) { - ColorTemp currWB = imgSrc.getWB(); - Imagefloat* baseImg = new Imagefloat (fw, fh); - PreviewProps pp (0, 0, fw, fh, 1); + if (res) { + rtengine::ColorTemp curr_wb = img_src.getWB(); + std::unique_ptr img_float = std::unique_ptr(new rtengine::Imagefloat(fw, fh)); + const PreviewProps pp(0, 0, fw, fh, 1); - procparams::ColorManagementParams icm; - icm.working = workingColorSpace; + rtengine::procparams::ColorManagementParams icm; + icm.working = working_color_space; - imgSrc.getImage (currWB, TR_NONE, baseImg, pp, procparams::ToneCurveParams(), icm, procparams::RAWParams()); + img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), icm, rtengine::procparams::RAWParams()); - if ( !workingColorSpace.empty() ) { - imgSrc.convertColorSpace(baseImg, icm, currWB); + if (!working_color_space.empty()) { + img_src.convertColorSpace(img_float.get(), icm, curr_wb); } - result = baseImg; + AlignedBuffer image(fw * fh * 4 + 4); // getClutValues() loads one pixel in advance + + std::size_t index = 0; + + for (int y = 0; y < fh; ++y) { + for (int x = 0; x < fw; ++x) { + image.data[index] = img_float->r(y, x); + ++index; + image.data[index] = img_float->g(y, x); + ++index; + image.data[index] = img_float->b(y, x); + index += 2; + } + } + + clut_image.swap(image); + } + + return res; +} + +#ifdef __SSE2__ +vfloat2 getClutValues(const AlignedBuffer& clut_image, size_t index) +{ + const vint v_values = _mm_loadu_si128(reinterpret_cast(clut_image.data + index)); +#ifdef __SSE4_1__ + return { + _mm_cvtepi32_ps(_mm_cvtepu16_epi32(v_values)), + _mm_cvtepi32_ps(_mm_cvtepu16_epi32(_mm_srli_si128(v_values, 8))) + }; +#else + const vint v_mask = _mm_set1_epi32(0x0000FFFF); + + vint v_low = _mm_shuffle_epi32(v_values, _MM_SHUFFLE(1, 0, 1, 0)); + vint v_high = _mm_shuffle_epi32(v_values, _MM_SHUFFLE(3, 2, 3, 2)); + v_low = _mm_shufflelo_epi16(v_low, _MM_SHUFFLE(1, 1, 0, 0)); + v_high = _mm_shufflelo_epi16(v_high, _MM_SHUFFLE(1, 1, 0, 0)); + v_low = _mm_shufflehi_epi16(v_low, _MM_SHUFFLE(3, 3, 2, 2)); + v_high = _mm_shufflehi_epi16(v_high, _MM_SHUFFLE(3, 3, 2, 2)); + v_low = vandm(v_low, v_mask); + v_high = vandm(v_high, v_mask); + + return { + _mm_cvtepi32_ps(v_low), + _mm_cvtepi32_ps(v_high) + }; +#endif +} +#endif + +} + +rtengine::HaldCLUT::HaldCLUT() : + clut_level(0), + flevel_minus_one(0.0f), + flevel_minus_two(0.0f), + clut_profile("sRGB") +{ +} + +rtengine::HaldCLUT::~HaldCLUT() +{ +} + +bool rtengine::HaldCLUT::load(const Glib::ustring& filename) +{ + if (loadFile(filename, "", clut_image, clut_level)) { + Glib::ustring name, ext; + splitClutFilename(filename, name, ext, clut_profile); + + clut_filename = filename; + clut_level *= clut_level; + flevel_minus_one = static_cast(clut_level - 1) / 65535.0f; + flevel_minus_two = static_cast(clut_level - 2); + return true; + } + + return false; +} + +rtengine::HaldCLUT::operator bool() const +{ + return !clut_image.isEmpty(); +} + +Glib::ustring rtengine::HaldCLUT::getFilename() const +{ + return clut_filename; +} + +Glib::ustring rtengine::HaldCLUT::getProfile() const +{ + return clut_profile; +} + +void rtengine::HaldCLUT::getRGB( + float strength, + std::size_t line_size, + const float* r, + const float* g, + const float* b, + float* out_rgbx +) const +{ + const unsigned int level = clut_level; // This is important + + const unsigned int level_square = level * level; + +#ifdef __SSE2__ + const vfloat v_strength = F2V(strength); +#endif + + for (std::size_t column = 0; column < line_size; ++column, ++r, ++g, ++b, out_rgbx += 4) { + const unsigned int red = std::min(flevel_minus_two, *r * flevel_minus_one); + const unsigned int green = std::min(flevel_minus_two, *g * flevel_minus_one); + const unsigned int blue = std::min(flevel_minus_two, *b * flevel_minus_one); + + const unsigned int color = red + green * level + blue * level_square; + +#ifndef __SSE2__ + const float re = *r * flevel_minus_one - red; + const float gr = *g * flevel_minus_one - green; + const float bl = *b * flevel_minus_one - blue; + + size_t index = color * 4; + + float tmp1[4] ALIGNED16; + tmp1[0] = intp(re, clut_image.data[index + 4], clut_image.data[index]); + tmp1[1] = intp(re, clut_image.data[index + 5], clut_image.data[index + 1]); + tmp1[2] = intp(re, clut_image.data[index + 6], clut_image.data[index + 2]); + + index = (color + level) * 4; + + float tmp2[4] ALIGNED16; + tmp2[0] = intp(re, clut_image.data[index + 4], clut_image.data[index]); + tmp2[1] = intp(re, clut_image.data[index + 5], clut_image.data[index + 1]); + tmp2[2] = intp(re, clut_image.data[index + 6], clut_image.data[index + 2]); + + out_rgbx[0] = intp(gr, tmp2[0], tmp1[0]); + out_rgbx[1] = intp(gr, tmp2[1], tmp1[1]); + out_rgbx[2] = intp(gr, tmp2[2], tmp1[2]); + + index = (color + level_square) * 4; + + tmp1[0] = intp(re, clut_image.data[index + 4], clut_image.data[index]); + tmp1[1] = intp(re, clut_image.data[index + 5], clut_image.data[index + 1]); + tmp1[2] = intp(re, clut_image.data[index + 6], clut_image.data[index + 2]); + + index = (color + level + level_square) * 4; + + tmp2[0] = intp(re, clut_image.data[index + 4], clut_image.data[index]); + tmp2[1] = intp(re, clut_image.data[index + 5], clut_image.data[index + 1]); + tmp2[2] = intp(re, clut_image.data[index + 6], clut_image.data[index + 2]); + + tmp1[0] = intp(gr, tmp2[0], tmp1[0]); + tmp1[1] = intp(gr, tmp2[1], tmp1[1]); + tmp1[2] = intp(gr, tmp2[2], tmp1[2]); + + out_rgbx[0] = intp(bl, tmp1[0], out_rgbx[0]); + out_rgbx[1] = intp(bl, tmp1[1], out_rgbx[1]); + out_rgbx[2] = intp(bl, tmp1[2], out_rgbx[2]); + + out_rgbx[0] = intp(strength, out_rgbx[0], *r); + out_rgbx[1] = intp(strength, out_rgbx[1], *g); + out_rgbx[2] = intp(strength, out_rgbx[2], *b); +#else + const vfloat v_in = _mm_set_ps(0.0f, *b, *g, *r); + const vfloat v_tmp = v_in * F2V(flevel_minus_one); + const vfloat v_rgb = v_tmp - _mm_cvtepi32_ps(_mm_cvttps_epi32(_mm_min_ps(F2V(flevel_minus_two), v_tmp))); + + size_t index = color * 4; + + const vfloat v_r = PERMUTEPS(v_rgb, _MM_SHUFFLE(0, 0, 0, 0)); + + vfloat2 v_clut_values = getClutValues(clut_image, index); + vfloat v_tmp1 = vintpf(v_r, v_clut_values.y, v_clut_values.x); + + index = (color + level) * 4; + + v_clut_values = getClutValues(clut_image, index); + vfloat v_tmp2 = vintpf(v_r, v_clut_values.y, v_clut_values.x); + + const vfloat v_g = PERMUTEPS(v_rgb, _MM_SHUFFLE(1, 1, 1, 1)); + + vfloat v_out = vintpf(v_g, v_tmp2, v_tmp1); + + index = (color + level_square) * 4; + + v_clut_values = getClutValues(clut_image, index); + v_tmp1 = vintpf(v_r, v_clut_values.y, v_clut_values.x); + + index = (color + level + level_square) * 4; + + v_clut_values = getClutValues(clut_image, index); + v_tmp2 = vintpf(v_r, v_clut_values.y, v_clut_values.x); + + v_tmp1 = vintpf(v_g, v_tmp2, v_tmp1); + + const vfloat v_b = PERMUTEPS(v_rgb, _MM_SHUFFLE(2, 2, 2, 2)); + + v_out = vintpf(v_b, v_tmp1, v_out); + + STVF(*out_rgbx, vintpf(v_strength, v_out, v_in)); +#endif + } +} + +void rtengine::HaldCLUT::splitClutFilename( + const Glib::ustring& filename, + Glib::ustring& name, + Glib::ustring& extension, + Glib::ustring& profile_name +) +{ + Glib::ustring basename = Glib::path_get_basename(filename); + + const Glib::ustring::size_type last_dot_pos = basename.rfind('.'); + + if (last_dot_pos != Glib::ustring::npos) { + name.assign(basename, 0, last_dot_pos); + extension.assign(basename, last_dot_pos + 1, Glib::ustring::npos); + } else { + name = basename; + } + + profile_name = "sRGB"; + + if (!name.empty()) { + for (const auto& working_profile : rtengine::getWorkingProfiles()) { + if ( + !working_profile.empty() // This isn't strictly needed, but an empty wp name should be skipped anyway + && std::search(name.rbegin(), name.rend(), working_profile.rbegin(), working_profile.rend()) == name.rbegin() + ) { + profile_name = working_profile; + name.erase(name.size() - working_profile.size()); + break; + } + } + } +} + +rtengine::CLUTStore& rtengine::CLUTStore::getInstance() +{ + static CLUTStore instance; + return instance; +} + +std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring& filename) +{ + std::shared_ptr result; + + if (!cache.get(filename, result)) { + std::unique_ptr clut(new rtengine::HaldCLUT); + + if (clut->load(filename)) { + result = std::move(clut); + cache.insert(filename, result); + } } return result; } -void HaldCLUT::loadClut( Imagefloat *img, RawClut &outClut ) +void rtengine::CLUTStore::clearCache() { - img->normalizeFloatTo1(); - int y_size = img->getH(); - int x_size = img->getW(); - outClut.resize( x_size * y_size * 3 ); - int clutIdx = 0; - - //int level = m_level * m_level; (unused) - for(int y = 0; y < y_size; y++) { - for(int x = 0; x < x_size; x++) { - outClut[ clutIdx * 3 ] = img->r( y, x ) * MAXVAL8; - outClut[ clutIdx * 3 + 1 ] = img->g( y, x ) * MAXVAL8; - outClut[ clutIdx * 3 + 2 ] = img->b( y, x ) * MAXVAL8; - - ++clutIdx; - } - } + cache.clear(); } -Imagefloat* HaldCLUT::generateIdentImage( int level ) +rtengine::CLUTStore::CLUTStore() : + cache(options.clutCacheSize) { - int imageWidth = level * level * level; - Imagefloat *resultImg = new Imagefloat( imageWidth, imageWidth ); - - int cubeSideSize = level * level; - float step = MAXVALF / (cubeSideSize - 1); - int pos = 0; - - for( int b = 0; b < cubeSideSize; ++b ) { - for ( int g = 0; g < cubeSideSize; ++g ) { - for ( int r = 0; r < cubeSideSize; ++r ) { - int x = pos / imageWidth; - int y = pos % imageWidth; - resultImg->r( x, y ) = step * r; - resultImg->g( x, y ) = step * g; - resultImg->b( x, y ) = step * b; - ++pos; - } - } - } - - return resultImg; -} - - -bool HaldCLUT::isValid() const -{ - return m_clutImage != 0; -} - -void HaldCLUT::getRGB( float rr, float gg, float bb, float &outR, float &outG, float &outB ) const -{ - rr /= MAXVALF; - gg /= MAXVALF; - bb /= MAXVALF; - correct( *m_clutImage, m_level, rr, gg, bb, outR, outG, outB ); -} - -inline float valF( unsigned char val ) -{ - return float( val ) / MAXVAL8; -} - -// copypasted from http://www.quelsolaar.com/technology/clut.html -void HaldCLUT::correct( const HaldCLUT::RawClut& clut, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ) -{ - int color, red, green, blue, i, j; - float tmp[6], r, g, b; - level = level * level; - - red = rr * (float)(level - 1); - - if(red > level - 2) { - red = (float)level - 2; - } - - if(red < 0) { - red = 0; - } - - green = gg * (float)(level - 1); - - if(green > level - 2) { - green = (float)level - 2; - } - - if(green < 0) { - green = 0; - } - - blue = bb * (float)(level - 1); - - if(blue > level - 2) { - blue = (float)level - 2; - } - - if(blue < 0) { - blue = 0; - } - - r = rr * (float)(level - 1) - red; - g = gg * (float)(level - 1) - green; - b = bb * (float)(level - 1) - blue; - - color = red + green * level + blue * level * level; - - i = color * 3; - j = (color + 1) * 3; - - tmp[0] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[1] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[2] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; - - i = (color + level) * 3; - j = (color + level + 1) * 3; - - tmp[3] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[4] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[5] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; - - outR = tmp[0] * (1 - g) + tmp[3] * g; - outG = tmp[1] * (1 - g) + tmp[4] * g; - outB = tmp[2] * (1 - g) + tmp[5] * g; - - i = (color + level * level) * 3; - j = (color + level * level + 1) * 3; - - tmp[0] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[1] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[2] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; - - i = (color + level + level * level) * 3; - j = (color + level + level * level + 1) * 3; - - tmp[3] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[4] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; - tmp[5] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; - - tmp[0] = tmp[0] * (1 - g) + tmp[3] * g; - tmp[1] = tmp[1] * (1 - g) + tmp[4] * g; - tmp[2] = tmp[2] * (1 - g) + tmp[5] * g; - - outR = outR * (1 - b) + tmp[0] * b; - outG = outG * (1 - b) + tmp[1] * b; - outB = outB * (1 - b) + tmp[2] * b; -} - -inline void pos2xy( int pos, int imageSideSize, int &outX, int &outY ) -{ - outX = pos / imageSideSize; - outY = pos % imageSideSize; -} - -void HaldCLUT::correct( Imagefloat &clutImage, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ) -{ - int color, red, green, blue, i, j; - float tmp[6], r, g, b; - level = level * level; - int imageSideSize = clutImage.getW(); - - red = rr * (float)(level - 1); - - if(red > level - 2) { - red = (float)level - 2; - } - - if(red < 0) { - red = 0; - } - - green = gg * (float)(level - 1); - - if(green > level - 2) { - green = (float)level - 2; - } - - if(green < 0) { - green = 0; - } - - blue = bb * (float)(level - 1); - - if(blue > level - 2) { - blue = (float)level - 2; - } - - if(blue < 0) { - blue = 0; - } - - r = rr * (float)(level - 1) - red; - g = gg * (float)(level - 1) - green; - b = bb * (float)(level - 1) - blue; - - color = red + green * level + blue * level * level; - - - i = color; - j = color + 1; - int xi, yi, xj, yj; - pos2xy( i, imageSideSize, xi, yi ); - pos2xy( j, imageSideSize, xj, yj ); - - tmp[0] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; - tmp[1] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; - tmp[2] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; - - i = color + level; - j = color + level + 1; - pos2xy( i, imageSideSize, xi, yi ); - pos2xy( j, imageSideSize, xj, yj ); - - tmp[3] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; - tmp[4] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; - tmp[5] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; - - outR = tmp[0] * (1 - g) + tmp[3] * g; - outG = tmp[1] * (1 - g) + tmp[4] * g; - outB = tmp[2] * (1 - g) + tmp[5] * g; - - i = color + level * level; - j = color + level * level + 1; - pos2xy( i, imageSideSize, xi, yi ); - pos2xy( j, imageSideSize, xj, yj ); - - tmp[0] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; - tmp[1] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; - tmp[2] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; - - i = color + level + level * level; - j = color + level + level * level + 1; - pos2xy( i, imageSideSize, xi, yi ); - pos2xy( j, imageSideSize, xj, yj ); - - tmp[3] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; - tmp[4] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; - tmp[5] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; - - tmp[0] = tmp[0] * (1 - g) + tmp[3] * g; - tmp[1] = tmp[1] * (1 - g) + tmp[4] * g; - tmp[2] = tmp[2] * (1 - g) + tmp[5] * g; - - outR = outR * (1 - b) + tmp[0] * b; - outG = outG * (1 - b) + tmp[1] * b; - outB = outB * (1 - b) + tmp[2] * b; } diff --git a/rtengine/clutstore.h b/rtengine/clutstore.h index de080b737..7383b597f 100644 --- a/rtengine/clutstore.h +++ b/rtengine/clutstore.h @@ -1,107 +1,72 @@ -#ifndef CLUT_STORE_INCLUDED -#define CLUT_STORE_INCLUDED +#pragma once + +#include +#include #include -#include "../rtgui/threadutils.h" -#include "imagefloat.h" -#include -#include + +#include "cache.h" +#include "alignedbuffer.h" namespace rtengine { -// simple CLUT interface -class CLUT -{ -public: - virtual void getRGB( float r, float g, float b, float &outR, float &outG, float &outB ) const = 0; - virtual Glib::ustring profile() const = 0; -protected: - virtual ~CLUT() {}; -}; - -class HaldCLUT : public CLUT +class HaldCLUT { public: HaldCLUT(); + HaldCLUT(const HaldCLUT& other) = delete; + HaldCLUT& operator =(const HaldCLUT& other) = delete; ~HaldCLUT(); - void load( Glib::ustring filename ); - bool isValid() const; - void getRGB( float r, float g, float b, float &outR, float &outG, float &outB ) const; - Glib::ustring profile() const; + bool load(const Glib::ustring& filename); - typedef std::vector RawClut; // using 8 bit for reduce memory usage - static void correct( const RawClut&, int level, float r, float g, float b, float &outR, float &outG, float &outB ); - static void correct( Imagefloat &clutImage, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ); - static Imagefloat* generateIdentImage( int level ); - static Imagefloat* loadFile( Glib::ustring filename, Glib::ustring workingColorSpace, int &outLevel ); + explicit operator bool() const; + + Glib::ustring getFilename() const; + Glib::ustring getProfile() const; + + void getRGB( + float strength, + std::size_t line_size, + const float* r, + const float* g, + const float* b, + float* out_rgbx + ) const; + + static void splitClutFilename( + const Glib::ustring& filename, + Glib::ustring& name, + Glib::ustring& extension, + Glib::ustring& profile_name + ); private: - - void loadClut( Imagefloat *img, RawClut &outClut ); - - Imagefloat *m_clutImage; - int m_level; - Glib::ustring m_filename; - Glib::ustring m_profile; + AlignedBuffer clut_image; + unsigned int clut_level; + float flevel_minus_one; + float flevel_minus_two; + Glib::ustring clut_filename; + Glib::ustring clut_profile; }; -// CLUT cache class CLUTStore { public: - CLUTStore(); + static CLUTStore& getInstance(); - CLUT* getClut( const Glib::ustring& filename ); - void releaseClut( const CLUT* clut ); + CLUTStore(const CLUTStore& other) = delete; + CLUTStore& operator =(const CLUTStore& other) = delete; + + std::shared_ptr getClut(const Glib::ustring& filename); void clearCache(); private: - typedef std::map > Cluts; + CLUTStore(); - Cluts m_cluts; - MyMutex m_mutex; + Cache> cache; }; -void splitClutFilename( Glib::ustring filename, Glib::ustring &name, Glib::ustring &extension, Glib::ustring &profileName ); - -}; //namespace rtengine - -extern rtengine::CLUTStore clutStore; - -namespace rtengine -{ - -//support class for automate call of clutStore.releaseClut() -class ClutPtr -{ -public: - ClutPtr() : m_point( 0 ) {} - explicit ClutPtr(CLUT *p) : m_point( p ) {} - ~ClutPtr() - { - clutStore.releaseClut( m_point ); - } - const CLUT* operator-> () const - { - return m_point; - } - operator bool() const - { - return m_point != 0; - } - void set( CLUT *p ) - { - m_point = p; - } - -private: - ClutPtr& operator=(ClutPtr const& cp ); - CLUT *m_point; -}; - -}; //namespace rtengine - -#endif +} diff --git a/rtengine/color.cc b/rtengine/color.cc index f5a8c86a3..58dc60320 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -24,6 +24,8 @@ #include "sleef.c" #include "opthelper.h" +#define pow_F(a,b) (xexpf(b*xlogf(a))) + using namespace std; namespace rtengine @@ -38,16 +40,13 @@ LUTf Color::gamma2curve; LUTf Color::gammatab; LUTuc Color::gammatabThumb; LUTf Color::igammatab_srgb; +LUTf Color::igammatab_srgb1; LUTf Color::gammatab_srgb; -// LUTf Color::igammatab_709; -// LUTf Color::gammatab_709; -LUTf Color::igammatab_55; -LUTf Color::gammatab_55; -LUTf Color::igammatab_4; -LUTf Color::gammatab_4; +LUTf Color::gammatab_srgb1; + +LUTf Color::denoiseGammaTab; +LUTf Color::denoiseIGammaTab; -LUTf Color::igammatab_26_11; -LUTf Color::gammatab_26_11; LUTf Color::igammatab_24_17; LUTf Color::gammatab_24_17a; LUTf Color::gammatab_13_2; @@ -139,19 +138,17 @@ void Color::init () constexpr auto maxindex = 65536; cachef(maxindex, LUT_CLIP_BELOW); - gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); gammatab(maxindex, 0); gammatabThumb(maxindex, 0); igammatab_srgb(maxindex, 0); + igammatab_srgb1(maxindex, 0); gammatab_srgb(maxindex, 0); - igammatab_55(maxindex, 0); - gammatab_55(maxindex, 0); - igammatab_4(maxindex, 0); - gammatab_4(maxindex, 0); + gammatab_srgb1(maxindex, 0); + + denoiseGammaTab(maxindex, 0); + denoiseIGammaTab(maxindex, 0); - igammatab_26_11(maxindex, 0); - gammatab_26_11(maxindex, 0); igammatab_24_17(maxindex, 0); gammatab_24_17a(maxindex, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); gammatab_13_2(maxindex, 0); @@ -185,61 +182,100 @@ void Color::init () #ifdef _OPENMP #pragma omp section #endif + { + for (int i = 0; i < maxindex; i++) + { + gammatab_srgb[i] = gammatab_srgb1[i] = gamma2(i / 65535.0); + } - for (int i = 0; i < maxindex; i++) { - gammatab_srgb[i] = gamma2curve[i] = 65535.0 * gamma2(i / 65535.0); // two lookup tables with same content but one clips and one does not clip + gammatab_srgb *= 65535.f; + gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags } - #ifdef _OPENMP #pragma omp section #endif + { + for (int i = 0; i < maxindex; i++) + { + igammatab_srgb[i] = igammatab_srgb1[i] = igamma2 (i / 65535.0); + } - for (int i = 0; i < maxindex; i++) { - igammatab_srgb[i] = 65535.0 * igamma2 (i / 65535.0); + igammatab_srgb *= 65535.f; } - #ifdef _OPENMP #pragma omp section #endif { double rsRGBGamma = 1.0 / sRGBGamma; - for (int i = 0; i < maxindex; i++) { + for (int i = 0; i < maxindex; i++) + { double val = pow (i / 65535.0, rsRGBGamma); gammatab[i] = 65535.0 * val; gammatabThumb[i] = (unsigned char)(255.0 * val); } } + #ifdef _OPENMP #pragma omp section #endif + // modify arbitrary data for Lab..I have test : nothing, gamma 2.6 11 - gamma 4 5 - gamma 5.5 10 + // we can put other as gamma g=2.6 slope=11, etc. + // but noting to do with real gamma !!!: it's only for data Lab # data RGB + // finally I opted for gamma55 and with options we can change - for (int i = 0; i < maxindex; i++) { - gammatab_55[i] = 65535.0 * gamma55 (i / 65535.0); + switch(settings->denoiselabgamma) { + case 0: + for (int i = 0; i < maxindex; i++) { + denoiseGammaTab[i] = 65535.0 * gamma26_11 (i / 65535.0); + } + + break; + + case 1: + for (int i = 0; i < maxindex; i++) { + denoiseGammaTab[i] = 65535.0 * gamma4 (i / 65535.0); + } + + break; + + default: + for (int i = 0; i < maxindex; i++) { + denoiseGammaTab[i] = 65535.0 * gamma55 (i / 65535.0); + } + + break; } #ifdef _OPENMP #pragma omp section #endif + // modify arbitrary data for Lab..I have test : nothing, gamma 2.6 11 - gamma 4 5 - gamma 5.5 10 + // we can put other as gamma g=2.6 slope=11, etc. + // but noting to do with real gamma !!!: it's only for data Lab # data RGB + // finally I opted for gamma55 and with options we can change - for (int i = 0; i < maxindex; i++) { - igammatab_55[i] = 65535.0 * igamma55 (i / 65535.0); - } + switch(settings->denoiselabgamma) { + case 0: + for (int i = 0; i < maxindex; i++) { + denoiseIGammaTab[i] = 65535.0 * igamma26_11 (i / 65535.0); + } -#ifdef _OPENMP - #pragma omp section -#endif + break; - for (int i = 0; i < maxindex; i++) { - gammatab_4[i] = 65535.0 * gamma4 (i / 65535.0); - } + case 1: + for (int i = 0; i < maxindex; i++) { + denoiseIGammaTab[i] = 65535.0 * igamma4 (i / 65535.0); + } -#ifdef _OPENMP - #pragma omp section -#endif + break; - for (int i = 0; i < maxindex; i++) { - igammatab_4[i] = 65535.0 * igamma4 (i / 65535.0); + default: + for (int i = 0; i < maxindex; i++) { + denoiseIGammaTab[i] = 65535.0 * igamma55 (i / 65535.0); + } + + break; } #ifdef _OPENMP @@ -290,22 +326,6 @@ void Color::init () igammatab_145_3[i] = 65535.0 * igamma145_3 (i / 65535.0); } -#ifdef _OPENMP - #pragma omp section -#endif - - for (int i = 0; i < maxindex; i++) { - gammatab_26_11[i] = 65535.0 * gamma26_11 (i / 65535.0); - } - -#ifdef _OPENMP - #pragma omp section -#endif - - for (int i = 0; i < maxindex; i++) { - igammatab_26_11[i] = 65535.0 * igamma26_11 (i / 65535.0); - } - #ifdef _OPENMP #pragma omp section #endif @@ -819,6 +839,15 @@ void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, con z = ((xyz_rgb[2][0] * r + xyz_rgb[2][1] * g + xyz_rgb[2][2] * b)) ; } +#ifdef __SSE2__ +void Color::rgbxyz (vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]) +{ + x = ((xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b)) ; + y = ((xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b)) ; + z = ((xyz_rgb[2][0] * r + xyz_rgb[2][1] * g + xyz_rgb[2][2] * b)) ; +} +#endif + void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]) { //Transform to output color. Standard sRGB is D65, but internal representation is D50 @@ -841,6 +870,14 @@ void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, co b = ((rgb_xyz[2][0] * x + rgb_xyz[2][1] * y + rgb_xyz[2][2] * z)) ; } +void Color::xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]) // for black & white we need only r channel +{ + //Transform to output color. Standard sRGB is D65, but internal representation is D50 + //Note that it is only at this point that we should have need of clipping color data + + r = ((rgb_xyz[0][0] * x + rgb_xyz[0][1] * y + rgb_xyz[0][2] * z)) ; +} + // same for float void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]) { @@ -858,19 +895,65 @@ void Color::xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat } #endif // __SSE2__ +#ifdef __SSE2__ void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) { - // correct gamma for black and white image : pseudo TRC curve of ICC profil - b /= 65535.0f; - b = pow (max(b, 0.0f), gammabwb); + // correct gamma for black and white image : pseudo TRC curve of ICC profile + vfloat rgbv = _mm_set_ps(0.f, r, r, r); // input channel is always r + vfloat gammabwv = _mm_set_ps(0.f, gammabwb, gammabwg, gammabwr); + vfloat c65535v = F2V(65535.f); + rgbv /= c65535v; + rgbv = vmaxf(rgbv, ZEROV); + rgbv = pow_F(rgbv, gammabwv); + rgbv *= c65535v; + float temp[4] ALIGNED16; + STVF(temp[0], rgbv); + r = temp[0]; + g = temp[1]; + b = temp[2]; +} +void Color::trcGammaBWRow (float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb) +{ + // correct gamma for black and white image : pseudo TRC curve of ICC profile + vfloat c65535v = F2V(65535.f); + vfloat gammabwrv = F2V(gammabwr); + vfloat gammabwgv = F2V(gammabwg); + vfloat gammabwbv = F2V(gammabwb); + int i = 0; + for(; i < width - 3; i += 4 ) { + vfloat inv = _mm_loadu_ps(&r[i]); // input channel is always r + inv /= c65535v; + inv = vmaxf(inv, ZEROV); + vfloat rv = pow_F(inv, gammabwrv); + vfloat gv = pow_F(inv, gammabwgv); + vfloat bv = pow_F(inv, gammabwbv); + rv *= c65535v; + gv *= c65535v; + bv *= c65535v; + _mm_storeu_ps(&r[i], rv); + _mm_storeu_ps(&g[i], gv); + _mm_storeu_ps(&b[i], bv); + } + for(; i < width; i++) { + trcGammaBW(r[i], g[i], b[i], gammabwr, gammabwg, gammabwb); + } +} + +#else +void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) +{ + // correct gamma for black and white image : pseudo TRC curve of ICC profile + float in = r; // input channel is always r + in /= 65535.0f; + in = max(in, 0.f); + b = pow_F (in, gammabwb); b *= 65535.0f; - r /= 65535.0f; - r = pow (max(r, 0.0f), gammabwr); + r = pow_F (in, gammabwr); r *= 65535.0f; - g /= 65535.0f; - g = pow (max(g, 0.0f), gammabwg); + g = pow_F (in, gammabwg); g *= 65535.0f; } +#endif /** @brief Compute the B&W constants for the B&W processing and its tool's GUI * @@ -1345,12 +1428,10 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg float bal, balH, cal, calH, calm; bal = balH = balance; cal = calH = calm = 1.f - chromat; - float med = (iphigh + iplow) / 2.f; - float medH = (iphigh + iplow) / 2.f; + float med = 1.f; + float medH = 0.f; float medL = (iphigh + iplow) / 2.f; - med = 1.f; - medH = 0.f; //new algo for 2 colors float calan; calan = chromat; @@ -1464,6 +1545,80 @@ void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0 return; } } +void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) +{ +#ifdef __SSE2__ + // SSE2 version is more than 6 times faster than scalar version + vfloat iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f); + vfloat fourv = F2V(4.f); + vfloat gammav = F2V(1.f / gamma); + vfloat slopev = F2V((slope / divisor) * factor); + vfloat divisorv = F2V(xlogf(divisor)); + vfloat factorv = F2V(factor); + vfloat comparev = F2V(start * divisor); + int border = start * divisor; + int border1 = border - (border & 3); + int border2 = border1 + 4; + int i = 0; + + for(; i < border1; i += 4) { + vfloat resultv = iv * slopev; + STVFU(gammacurve[i], resultv); + iv += fourv; + } + + for(; i < border2; i += 4) { + vfloat result0v = iv * slopev; + vfloat result1v = xexpf((xlogf(iv) - divisorv) * gammav) * factorv; + STVFU(gammacurve[i], vself(vmaskf_le(iv, comparev), result0v, result1v)); + iv += fourv; + } + + for(; i < 65536; i += 4) { + vfloat resultv = xexpfNoCheck((xlogfNoCheck(iv) - divisorv) * gammav) * factorv; + STVFU(gammacurve[i], resultv); + iv += fourv; + } + +#else + + for (int i = 0; i < 65536; ++i) { + gammacurve[i] = gammaf(static_cast(i) / divisor, gamma, start, slope) * factor; + } + +#endif +} + +void Color::gammanf2lut (LUTf &gammacurve, float gamma, float divisor, float factor) //standard gamma without slope... +{ +#ifdef __SSE2__ + // SSE2 version is more than 6 times faster than scalar version + vfloat iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f); + vfloat fourv = F2V(4.f); + vfloat gammav = F2V(1.f / gamma); + vfloat divisorv = F2V(xlogf(divisor)); + vfloat factorv = F2V(factor); + + // first input value is zero => we have to use the xlogf function which checks this + vfloat resultv = xexpf((xlogf(iv) - divisorv) * gammav) * factorv; + STVFU(gammacurve[0], resultv); + iv += fourv; + + // inside the loop we can use xlogfNoCheck and xexpfNoCheck because we know about the input values + for(int i = 4; i < 65536; i += 4) { + resultv = xexpfNoCheck((xlogfNoCheck(iv) - divisorv) * gammav) * factorv; + STVFU(gammacurve[i], resultv); + iv += fourv; + } + +#else + + for (int i = 0; i < 65536; ++i) { + gammacurve[i] = Color::gammanf(static_cast(i) / divisor, gamma) * factor; + } + +#endif +} void Color::Lab2XYZ(float L, float a, float b, float &x, float &y, float &z) { @@ -1478,6 +1633,17 @@ void Color::Lab2XYZ(float L, float a, float b, float &x, float &y, float &z) y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa; } +void Color::L2XYZ(float L, float &x, float &y, float &z) // for black & white +{ + float LL = L / 327.68f; + float fy = (0.00862069f * LL) + 0.137932f; // (L+16)/116 + float fxz = 65535.f * f2xyz(fy); + x = fxz * D50x; + z = fxz * D50z; + y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa; +} + + #ifdef __SSE2__ void Color::Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z) { @@ -1710,7 +1876,7 @@ void Color::skinred ( double J, double h, double sres, double Sp, float dred, fl if (J < 16.0) { dred = 40.0f; } else if(J < 22.0) { - dred = (4.1666f) * (float)J - 26.6f; + dred = 2.5f * (float)J; } else if(J < 60.0) { dred = 55.0f; } else if(J < 70.0) { @@ -1769,16 +1935,16 @@ void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, f float chromapro = sres / Sp; if(sk == 1) { //in C mode to adapt dred to J - if (J < 16.0) { - dred = 40.0f; - } else if(J < 22.0) { - dred = (4.1666f) * (float)J - 26.6f; - } else if(J < 60.0) { - dred = 55.0f; - } else if(J < 70.0) { - dred = -1.5f * (float)J + 145.0f; + if (J < 16.f) { + dred = 40.f; + } else if(J < 22.f) { + dred = 2.5f * J; + } else if(J < 60.f) { + dred = 55.f; + } else if(J < 70.f) { + dred = 145.f - 1.5f * J; } else { - dred = 40.0f; + dred = 40.f; } } @@ -1835,21 +2001,13 @@ void Color::transitred (const float HH, float const Chprov1, const float dred, c if(HH >= 0.15f && HH < 1.3f) { if (Chprov1 < dred) { factor = factorskin; - } else if(Chprov1 < (dred + protect_red)) - // factor = (factorsat-factorskin)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskin)/protect_red; - // optimized formula - { + } else if(Chprov1 < (dred + protect_red)) { factor = ((factorsat - factorskin) * Chprov1 + factorsat * protect_red - (dred + protect_red) * (factorsat - factorskin)) / protect_red; } - } - // then test if chroma is in the extanded range - else if ( HH > (0.15f - deltaHH) || HH < (1.3f + deltaHH) ) { + } else if ( HH > (0.15f - deltaHH) && HH < (1.3f + deltaHH) ) { // test if chroma is in the extended range if (Chprov1 < dred) { factor = factorskinext; // C=dred=55 => real max of skin tones - } else if (Chprov1 < (dred + protect_red)) // transition - // factor = (factorsat-factorskinext)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskinext)/protect_red; - // optimized formula - { + } else if (Chprov1 < (dred + protect_red)) {// transition factor = ((factorsat - factorskinext) * Chprov1 + factorsat * protect_red - (dred + protect_red) * (factorsat - factorskinext)) / protect_red; } } @@ -2131,16 +2289,16 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) #endif { - const float ClipLevel = 65535.0f; + constexpr float ClipLevel = 65535.0f; bool inGamut; #ifdef _DEBUG neg = false, more_rgb = false; #endif + float ChprovSave = Chprov1; do { inGamut = true; - //Lprov1=LL; float aprov1 = Chprov1 * sincosval.y; float bprov1 = Chprov1 * sincosval.x; @@ -2150,9 +2308,8 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr float fz = fy - (0.005f * bprov1); float x_ = 65535.0f * f2xyz(fx) * D50x; - // float y_ = 65535.0f * f2xyz(fy); float z_ = 65535.0f * f2xyz(fz) * D50z; - float y_ = (Lprov1 > epskap) ? 65535.0 * fy * fy * fy : 65535.0 * Lprov1 / kappa; + float y_ = (Lprov1 > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * Lprov1 / kappa; xyz2rgb(x_, y_, z_, R, G, B, wip); @@ -2162,6 +2319,12 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr neg = true; #endif + if (isnan(HH)) { + float atemp = ChprovSave * sincosval.y * 327.68; + float btemp = ChprovSave * sincosval.x * 327.68; + HH = xatan2f(btemp, atemp); + } + if (Lprov1 < 0.1f) { Lprov1 = 0.1f; } diff --git a/rtengine/color.h b/rtengine/color.h index 3f78692d8..350cd3b2a 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -129,14 +129,13 @@ public: // look-up tables for the standard srgb gamma and its inverse (filled by init()) static LUTf igammatab_srgb; + static LUTf igammatab_srgb1; static LUTf gammatab_srgb; - static LUTf igammatab_55; - static LUTf gammatab_55; - static LUTf igammatab_4; - static LUTf gammatab_4; + static LUTf gammatab_srgb1; + + static LUTf denoiseGammaTab; + static LUTf denoiseIGammaTab; - static LUTf igammatab_26_11; - static LUTf gammatab_26_11; static LUTf igammatab_24_17; static LUTf gammatab_24_17a; static LUTf gammatab_13_2; @@ -229,6 +228,55 @@ public: */ static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); + static inline float rgb2s(float r, float g, float b) // fast version if only saturation is needed + { + float var_Min = min(r, g, b); + float var_Max = max(r, g, b); + float del_Max = var_Max - var_Min; + + if (del_Max < 0.00001f) { + return 0.f; + } else { + return del_Max / var_Max; + } + } + + static inline bool rgb2hsvdcp(float r, float g, float b, float &h, float &s, float &v) + { + + float var_Min = min(r, g, b); + + if(var_Min < 0.f) { + return false; + } else { + float var_Max = max(r, g, b); + float del_Max = var_Max - var_Min; + v = var_Max / 65535.f; + + if (fabsf(del_Max) < 0.00001f) { + h = 0.f; + s = 0.f; + } else { + s = del_Max / var_Max; + + if ( r == var_Max ) { + h = (g - b) / del_Max; + } else if ( g == var_Max ) { + h = 2.f + (b - r) / del_Max; + } else { /*if ( b == var_Max ) */ + h = 4.f + (r - g) / del_Max; + } + + if ( h < 0.f ) { + h += 6.f; + } else if ( h > 6.f ) { + h -= 6.f; + } + } + + return true; + } + } /** * @brief Convert hue saturation value in red green blue @@ -240,6 +288,57 @@ public: * @param b blue channel [0 ; 65535] (return value) */ static void hsv2rgb (float h, float s, float v, float &r, float &g, float &b); + + static inline void hsv2rgbdcp (float h, float s, float v, float &r, float &g, float &b) + { + // special version for dcp which saves 1 division (in caller) and six multiplications (inside this function) + int sector = h; // sector 0 to 5, floor() is very slow, and h is always >0 + float f = h - sector; // fractional part of h + + v *= 65535.f; + float vs = v * s; + float p = v - vs; + float q = v - f * vs; + float t = p + v - q; + + switch (sector) { + case 1: + r = q; + g = v; + b = p; + break; + + case 2: + r = p; + g = v; + b = t; + break; + + case 3: + r = p; + g = q; + b = v; + break; + + case 4: + r = t; + g = p; + b = v; + break; + + case 5: + r = v; + g = p; + b = q; + break; + + default: + r = v; + g = t; + b = p; + } + } + static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); @@ -306,6 +405,7 @@ public: * @param rgb_xyz[3][3] transformation matrix to use for the conversion */ static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]); + static void xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]); static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]); #ifdef __SSE2__ static void xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]); @@ -325,7 +425,9 @@ public: */ static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]); static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]); - +#ifdef __SSE2__ + static void rgbxyz (vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]); +#endif /** * @brief Convert Lab in xyz @@ -337,6 +439,7 @@ public: * @param z Z coordinate [0 ; 65535] ; can be negative! (return value) */ static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); + static void L2XYZ(float L, float &x, float &y, float &z); #ifdef __SSE2__ static void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z); @@ -788,6 +891,9 @@ public: * @param gammabwb gamma value for red channel [>0] */ static void trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb); +#ifdef __SSE2__ + static void trcGammaBWRow (float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb); +#endif /** @brief Compute the B&W constants for the Black and White processing and its GUI @@ -1000,6 +1106,15 @@ public: { return (x <= start ? x*slope : exp(log(x) / gamma) * mul - add); } + + static inline float gammaf (float x, float gamma, float start, float slope) + { + return x <= start ? x * slope : xexpf(xlogf(x) / gamma); + } + + //fills a LUT of size 65536 using gamma with slope... + static void gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor); + static inline double igamma (double x, double gamma, double start, double slope, double mul, double add) { return (x <= start * slope ? x / slope : exp(log((x + add) / mul) * gamma) ); @@ -1014,7 +1129,7 @@ public: */ static inline double gamman (double x, double gamma) //standard gamma without slope... { - return (x = exp(log(x) / gamma)); + return exp(log(x) / gamma); } /** @@ -1025,9 +1140,10 @@ public: */ static inline float gammanf (float x, float gamma) //standard gamma without slope... { - return (x = xexpf(xlogf(x) / gamma)); + return xexpf(xlogf(x) / gamma); } - + //fills a LUT of size 65536 using gamma without slope... + static void gammanf2lut (LUTf &gammacurve, float gamma, float divisor, float factor); /** * @brief Very simply inverse gamma @@ -1037,7 +1153,7 @@ public: */ static inline double igamman (double x, double gamma) //standard inverse gamma without slope... { - return (x = exp(log(x) * gamma) ); + return exp(log(x) * gamma); } @@ -1077,6 +1193,10 @@ public: { return gammatab_srgb[x]; } + static inline float gamma_srgbclipped (float x) + { + return gamma2curve[x]; + } static inline float gamma (float x) { return gammatab[x]; diff --git a/rtengine/colorclip.h b/rtengine/colorclip.h deleted file mode 100644 index 6a3144166..000000000 --- a/rtengine/colorclip.h +++ /dev/null @@ -1,169 +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 . - */ -inline double tightestroot (double L, double a, double b, double r1, double r2, double r3); - -#ifndef __COLORCLIP__ -#define __COLORCLIP__ - -#include -#include "median.h" - -// gives back the tightest >0 amplification by which color clipping occures - -inline double tightestroot (double L, double a, double b, double r1, double r2, double r3) -{ - - double an = a / 500.0, bn = b / 200.0, p = (L + 16.0) / 116.0; - - double coeff3 = r1 * an * an * an - r3 * bn * bn * bn; - double coeff2 = 3.0 * p * (r1 * an * an + r3 * bn * bn); - double coeff1 = 3.0 * p * p * (r1 * an - r3 * bn); - double coeff0 = p * p * p * (r1 + r2 + r3) - 1.0; - - double a1 = coeff2 / coeff3; - double a2 = coeff1 / coeff3; - double a3 = coeff0 / coeff3; - - double Q = (a1 * a1 - 3.0 * a2) / 9.0; - double R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0; - double Qcubed = Q * Q * Q; - double d = Qcubed - R * R; - -// printf ("input L=%g, a=%g, b=%g\n", L, a, b); -// printf ("c1=%g, c2=%g, c3=%g, c4=%g\n", coeff3, coeff2, coeff1, coeff0); - - - /* Three real roots */ - if (d >= 0) { - double theta = acos(R / sqrt(Qcubed)); - double sqrtQ = sqrt(Q); - double x0 = -2.0 * sqrtQ * cos( theta / 3.0) - a1 / 3.0; - double x1 = -2.0 * sqrtQ * cos((theta + 2.0 * M_PI) / 3.0) - a1 / 3.0; - double x2 = -2.0 * sqrtQ * cos((theta + 4.0 * M_PI) / 3.0) - a1 / 3.0; - -// printf ("3 roots: %g, %g, %g\n", x0, x1, x2); - - SORT3 (x0, x1, x2, a1, a2, a3); - - if (a1 > 0) { - return a1; - } - - if (a2 > 0) { - return a2; - } - - if (a3 > 0) { - return a3; - } - - return -1; - } - - /* One real root */ - else { -// double e = pow(sqrt(-d) + fabs(R), 1.0 / 3.0); - double e = exp (1.0 / 3.0 * log (sqrt(-d) + fabs(R))); - - if (R > 0) { - e = -e; - } - - double x0 = (e + Q / e) - a1 / 3.0; - -// printf ("1 root: %g\n", x0); - - if (x0 < 0) { - return -1; - } else { - return x0; - } - } -} - - -/******************************************************************************* - * FindCubicRoots - * -------------- - * - * Copyright (C) 1997-2001 Ken Turkowski. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * ------------------------------------------------------------------------ - * - * Solve: - * coeff[3] * x^3 + coeff[2] * x^2 + coeff[1] * x + coeff[0] = 0 - * - * returns: - * 3 - 3 real roots - * 1 - 1 real root (2 complex conjugate) - * - *******************************************************************************/ - -/*long -FindCubicRoots(const FLOAT coeff[4], FLOAT x[3]) -{ - FLOAT a1 = coeff[2] / coeff[3]; - FLOAT a2 = coeff[1] / coeff[3]; - FLOAT a3 = coeff[0] / coeff[3]; - - double_t Q = (a1 * a1 - 3 * a2) / 9; - double_t R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54; - double_t Qcubed = Q * Q * Q; - double_t d = Qcubed - R * R; - - // Three real roots - if (d >= 0) { - double_t theta = acos(R / sqrt(Qcubed)); - double_t sqrtQ = sqrt(Q); - x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3; - x[1] = -2 * sqrtQ * cos((theta + 2 * pi) / 3) - a1 / 3; - x[2] = -2 * sqrtQ * cos((theta + 4 * pi) / 3) - a1 / 3; - return (3); - } - - // One real root - else { - double_t e = pow(sqrt(-d) + fabs(R), 1. / 3.); - if (R > 0) - e = -e; - x[0] = (e + Q / e) - a1 / 3.; - return (1); - } -} -*/ -#endif diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 2ccbcba8d..1514357d8 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -34,7 +34,7 @@ namespace rtengine extern const Settings* settings; -static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis observer 2� +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}, {0.001368, 0.000039, 0.006450001}, {0.002236, 0.000064, 0.01054999}, {0.004243, 0.000120, 0.02005001}, @@ -70,7 +70,7 @@ static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desm {0.000001251141, 0.00000045181, 0.000000} }; -ColorTemp::ColorTemp (double t, double g, double e, Glib::ustring m) : temp(t), green(g), equal(e), method(m) +ColorTemp::ColorTemp (double t, double g, double e, const Glib::ustring &m) : temp(t), green(g), equal(e), method(m) { clip (temp, green, equal); @@ -114,13 +114,12 @@ void ColorTemp::clip (double &temp, double &green, double &equal) } } -ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) +ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e), method("Custom") { - method = "Custom"; mul2temp (mulr, mulg, mulb, equal, temp, green); } -void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) +void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const { double maxtemp = double(MAXTEMP), mintemp = double(MINTEMP); @@ -296,7 +295,7 @@ const double ColorTemp::Solux4100_spect[97] = { 62.40, 61.373, 59.75, 58.1810, 56.25, 54.395, 51.90, 49.496, 47.05, 44.620 }; -//spectral data for Solux lamp : near Daylight (for example "mus�e d'Orsay..") - 4700K +//spectral data for Solux lamp : near Daylight (for example "Musée d'Orsay") - 4700K const double ColorTemp::Solux4700_spect[97] = { 0.4590, 0.83, 1.2011, 1.53, 1.8647, 2.15, 2.5338, 3.06, 3.5809, 3.99, 4.4137, 4.82, 5.2228, 5.63, 6.0387, 6.53, 6.9944, 7.55, 8.0266, 8.475, 8.9276, 8.90, 9.7840, 10.20, 10.6390, 11.00, 11.3600, 11.75, 12.1340, 12.36, 12.5880, 12.74, 12.8790, 13.07, 13.2560, 13.38, 13.5220, 13.41, 13.3070, 13.35, 13.3990, 13.37, 13.3420, 13.39, 13.4220, 13.65, 13.2710, 13.25, 13.2330, 13.12, 13.0110, 12.93, 12.8470, 12.805, 12.7630, 12.66, 12.5760, 12.563, 12.5490, @@ -849,7 +848,7 @@ const double ColorTemp::ColabSky42_0_m24_spect[97] = { /* LERP(a,b,c) = linear interpolation macro, is 'a' when c == 0.0 and 'b' when c == 1.0 */ #define LERP(a,b,c) (((b) - (a)) * (c) + (a)) -int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp) +int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp) const { typedef struct UVT { @@ -1128,7 +1127,7 @@ void ColorTemp::temp2mulxyz (double tem, double gree, std::string method , doubl //printf("Xxyz=%f Zxyz=%f\n",Xxyz,Zxyz); } -void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) +void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const { clip (temp, green, equal); @@ -1798,7 +1797,7 @@ The next 3 methods are inspired from: this values are often called xBar yBar zBar and are characteristics of a color / illuminant -values cie_colour_match[][3] = Observer 2� x2, y2, z2 +values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increase precision used by J.Walker and pass to 350nm to 830nm */ @@ -1856,7 +1855,7 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou this values are often called xBar yBar zBar and are characteristics of a color / illuminant - values cie_colour_match[][3] = Observer 2� x2, y2, z2 + values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increased the precision used by J.Walker and pass from 350nm to 830nm */ diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index c79ebb4bf..a1a805092 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -47,12 +47,14 @@ private: std::string method; static void clip (double &temp, double &green); static void clip (double &temp, double &green, double &equal); + int XYZtoCorColorTemp(double x0, double y0 , double z0, double &temp) const; + void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const; public: ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {} ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} - ColorTemp (double t, double g, double e, Glib::ustring m); + ColorTemp (double t, double g, double e, const Glib::ustring &m); ColorTemp (double mulr, double mulg, double mulb, double e); void update (const double rmul, const double gmul, const double bmul, const double equal) @@ -67,42 +69,40 @@ public: this->equal = equal; } - inline std::string getMethod() + inline std::string getMethod() const { return method; } - inline double getTemp () + inline double getTemp () const { return temp; } - inline double getGreen () + inline double getGreen () const { return green; } - inline double getEqual () + inline double getEqual () const { return equal; } - void getMultipliers (double &mulr, double &mulg, double &mulb) + void getMultipliers (double &mulr, double &mulg, double &mulb) const { temp2mul (temp, green, equal, mulr, mulg, mulb); } - void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green); - void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul); + void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const; static void temp2mulxyz (double tem, double gree, std::string method, double &Xxyz, double &Zxyz); - int XYZtoCorColorTemp(double x0, double y0 , double z0, double &temp); static void cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, double &CAM02BB01, double &CAM02BB02, double &CAM02BB10, double &CAM02BB11, double &CAM02BB12, double &CAM02BB20, double &CAM02BB21, double &CAM02BB22, double adap ); //static void CAT02 (Imagefloat* baseImg, const ProcParams* params); //static void ciecam_02 (LabImage* lab, const ProcParams* params); - bool operator== (const ColorTemp& other) + bool operator== (const ColorTemp& other) const { return fabs(temp - other.temp) < 1e-10 && fabs(green - other.green) < 1e-10; } - bool operator!= (const ColorTemp& other) + bool operator!= (const ColorTemp& other) const { return !(*this == other); } diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 6792df50d..9b68cc9ee 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -16,12 +16,13 @@ * 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 -#include -#include -#include -#include #ifdef _OPENMP #include #endif @@ -43,7 +44,7 @@ using namespace std; namespace rtengine { -Curve::Curve () : N(0), x(NULL), y(NULL), ypp(NULL), hashSize(1000 /* has to be initialized to the maximum value */ ) {} +Curve::Curve () : N(0), x(nullptr), y(nullptr), ypp(nullptr), hashSize(1000 /* has to be initialized to the maximum value */) {} void Curve::AddPolygons () { @@ -69,6 +70,18 @@ void Curve::AddPolygons () poly_y.push_back(y3); } +void Curve::fillDyByDx () +{ + dyByDx.resize(poly_x.size() - 1); + + for(unsigned int i = 0; i < poly_x.size() - 1; i++) { + double dx = poly_x[i + 1] - poly_x[i]; + double dy = poly_y[i + 1] - poly_y[i]; + dyByDx[i] = dy / dx; + + } +} + void Curve::fillHash() { hash.resize(hashSize + 2); @@ -155,11 +168,9 @@ void Curve::getControlPoint(int cpNum, double &x, double &y) const const double CurveFactory::sRGBGamma = 2.2; const double CurveFactory::sRGBGammaCurve = 2.4; -SSEFUNCTION void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) +void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) { - if (needed) { - LUTf lutCurve (65536); for (int i = 0; i <= 0xffff; i += i < 0xffff - skip ? skip : 1 ) { // change to [0,1] range @@ -167,353 +178,157 @@ SSEFUNCTION void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int sk // apply custom/parametric/NURBS curve, if any val = diagCurve->getVal (val); // store result in a temporary array - lutCurve[i] = (val); + outCurve[i] = val; } // if skip>1, let apply linear interpolation in the skipped points of the curve if (skip > 1) { - int prev = 0; + float skipmul = 1.f / (float) skip; - for (int i = 1; i <= 0xffff - skip; i++) { - if (i % skip == 0) { - prev += skip; - continue; + for (int i = 0; i <= 0x10000 - skip; i += skip) { + for(int j = 1; j < skip; j++) { + outCurve[i + j] = ( outCurve[i] * (skip - j) + outCurve[i + skip] * j ) * skipmul; } - - lutCurve[i] = ( lutCurve[prev] * (skip - i % skip) + lutCurve[prev + skip] * (i % skip) ) / skip; } } - for (int i = 0; i <= 0xffff; i++) { - outCurve[i] = (65535.f * lutCurve[i]); - } + outCurve *= 65535.f; } else { -#ifdef __SSE2__ - __m128 fourv = _mm_set1_ps(4.f); - __m128 iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f); - - for (int i = 0; i <= 0xfffc; i += 4) { - _mm_storeu_ps(&outCurve[i], iv); - iv += fourv; - } - -#else - - for (int i = 0; i <= 0xffff; i++) { - outCurve[i] = (float)i; - } - -#endif - } - -} - -void CurveFactory::updatechroma ( - const std::vector& cccurvePoints, - LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma - int skip) -{ - LUTf dCcurve(65536, 0); - float val; - - for (int i = 0; i < 48000; i++) { //32768*1.414 + ... - val = (double)i / 47999.0; - dCcurve[i] = CLIPD(val); - } - - outBeforeCCurveHistogramC.clear(); - bool histNeededC = false; - - - if (!cccurvePoints.empty() && cccurvePoints[0] != 0) { - if (outBeforeCCurveHistogramC /*&& histogramCropped*/) { - histNeededC = true; - } - } - - for (int i = 0; i < 48000; i++) { //32768*1.414 + ... - float val; - - if (histNeededC) { - float hval = dCcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); // - outBeforeCCurveHistogramC[hi] += histogramC[i] ; - } + outCurve.makeIdentity(); } } - -void CurveFactory::curveLightBrightColor ( - procparams::ColorAppearanceParams::eTCModeId curveMode1, const std::vector& curvePoints1, - procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector& curvePoints2, - procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector& curvePoints3, - LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram,//for Luminance - LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma - ColorAppearance & customColCurve1, - ColorAppearance & customColCurve2, - ColorAppearance & customColCurve3, - int skip) +void CurveFactory::curveLightBrightColor (const std::vector& curvePoints1, const std::vector& curvePoints2, const std::vector& curvePoints3, + const LUTu & histogram, LUTu & outBeforeCCurveHistogram,//for Luminance + const LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma + ColorAppearance & customColCurve1, ColorAppearance & customColCurve2, ColorAppearance & customColCurve3, int skip) { outBeforeCCurveHistogram.clear(); outBeforeCCurveHistogramC.clear(); - bool histNeededC = false; - bool histNeeded = false; - DiagonalCurve* tcurve = NULL; customColCurve3.Reset(); if (!curvePoints3.empty() && curvePoints3[0] > DCT_Linear && curvePoints3[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePoints3, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve tcurve(curvePoints3, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogramC /*&& histogramCropped*/) { - histNeededC = true; + if (outBeforeCCurveHistogramC) { + histogramC.compressTo(outBeforeCCurveHistogramC, 48000); } - } - - if (tcurve) { - if (tcurve->isIdentity()) { - delete tcurve; - tcurve = NULL; - } else { + if (!tcurve.isIdentity()) { customColCurve3.Set(tcurve); } - - delete tcurve; - tcurve = NULL; } + customColCurve2.Reset(); if (!curvePoints2.empty() && curvePoints2[0] > DCT_Linear && curvePoints2[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePoints2, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve tcurve(curvePoints2, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { + if (outBeforeCCurveHistogram) { histNeeded = true; } - } - - if (tcurve) { - if (tcurve->isIdentity()) { - delete tcurve; - tcurve = NULL; - } else { + if (!tcurve.isIdentity()) { customColCurve2.Set(tcurve); } - - delete tcurve; - tcurve = NULL; } + // create first curve if needed customColCurve1.Reset(); if (!curvePoints1.empty() && curvePoints1[0] > DCT_Linear && curvePoints1[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePoints1, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve tcurve(curvePoints1, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { + if (outBeforeCCurveHistogram) { histNeeded = true; } - } - - if (tcurve) { - if (tcurve->isIdentity()) { - delete tcurve; - tcurve = NULL; - } else { + if (!tcurve.isIdentity()) { customColCurve1.Set(tcurve); - delete tcurve; - tcurve = NULL; } } if (histNeeded) { - for (int i = 0; i < 32768; i++) { - double hval = CLIPD((double)i / 32767.0); - int hi = (int)(255.0 * hval); - outBeforeCCurveHistogram[hi] += histogram[i] ; - } - } - - if (histNeededC) { - for (int i = 0; i < 48000; i++) { //32768*1.414 + ... - double hval = CLIPD((double)i / 47999.0); - int hi = (int)(255.0 * hval); // - outBeforeCCurveHistogramC[hi] += histogramC[i] ; - } - } - - if (tcurve) { - delete tcurve; - } - -} -// add curve Denoise : C=f(C) -void CurveFactory::denoiseCC ( bool & ccdenoiseutili, const std::vector& cccurvePoints, LUTf & NoiseCCcurve, int skip) -{ - bool needed; - DiagonalCurve* dCurve = NULL; - LUTf dCcurve(65536, 0); - - float val; - - for (int i = 0; i < 48000; i++) { - dCcurve[i] = (float)i / 47999.0; - } - - needed = false; - - if (!cccurvePoints.empty() && cccurvePoints[0] != 0) { - dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS / skip); - - if (dCurve && !dCurve->isIdentity()) { - needed = true; - ccdenoiseutili = true; - } - } - - fillCurveArray(dCurve, NoiseCCcurve, skip, needed); - //NoiseCCcurve.dump("Noise"); - - if (dCurve) { - delete dCurve; - dCurve = NULL; + histogram.compressTo(outBeforeCCurveHistogram, 32768); } } - -void CurveFactory::curveBW ( - const std::vector& curvePointsbw, const std::vector& curvePointsbw2, - LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance - ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) +void CurveFactory::curveBW ( const std::vector& curvePointsbw, const std::vector& curvePointsbw2, + const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance + ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) { + const float gamma_ = Color::sRGBGammaCurve; - const float start = expf(gamma_ * logf( -0.055 / ((1.0 / gamma_ - 1.0) * 1.055 ))); - const float slope = 1.055 * powf (start, 1.0 / gamma_ - 1) - 0.055 / start; - const float mul = 1.055; - const float add = 0.055; outBeforeCCurveHistogrambw.clear(); bool histNeeded = false; - DiagonalCurve* tcurve = NULL; customToneCurvebw2.Reset(); if (!curvePointsbw2.empty() && curvePointsbw2[0] > DCT_Linear && curvePointsbw2[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePointsbw2, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve tcurve(curvePointsbw2, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogrambw /*&& histogramCropped*/) { + if (outBeforeCCurveHistogrambw) { histNeeded = true; } - } - - if (tcurve) { - if (!tcurve->isIdentity()) { - customToneCurvebw2.Set(tcurve, gamma_, start, slope, mul, add); + if (!tcurve.isIdentity()) { + customToneCurvebw2.Set(tcurve, gamma_); } - - delete tcurve; - tcurve = NULL; } + customToneCurvebw1.Reset(); if (!curvePointsbw.empty() && curvePointsbw[0] > DCT_Linear && curvePointsbw[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePointsbw, CURVES_MIN_POLY_POINTS / skip); + DiagonalCurve tcurve(curvePointsbw, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogrambw /*&& histogramCropped*/) { + if (outBeforeCCurveHistogrambw ) { histNeeded = true; } - } - - if (tcurve) { - if (!tcurve->isIdentity()) { - customToneCurvebw1.Set(tcurve, gamma_, start, slope, mul, add); + if (!tcurve.isIdentity()) { + customToneCurvebw1.Set(tcurve, gamma_); } - - delete tcurve; - tcurve = NULL; } + // create first curve if needed if (histNeeded) { - LUTf dcurve(65536, 0); - - float val; - - for (int i = 0; i < 32768; i++) { - val = (float)i / 32767.f; - dcurve[i] = CLIPD(val); - } - - for (int i = 0; i < 32768; i++) { - float hval = dcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); - outBeforeCCurveHistogrambw[hi] += histogrambw[i] ; - } + histogrambw.compressTo(outBeforeCCurveHistogrambw, 32768); } - - if (tcurve) { - delete tcurve; - } - } + // add curve Lab : C=f(L) -void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip) +void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, int skip) { - bool needed; - DiagonalCurve* dCurve = NULL; - - if (outBeforeCLurveHistogram) { - outBeforeCLurveHistogram.clear(); - } - - bool histNeededCL = false; - - needed = false; + clcutili = false; + std::unique_ptr dCurve; if (!clcurvePoints.empty() && clcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip); - - if (outBeforeCLurveHistogram) { - histNeededCL = true; - } + dCurve = std::unique_ptr(new DiagonalCurve(clcurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { - needed = true; clcutili = true; } } - if(histNeededCL) - for (int i = 0; i < 50000; i++) { //32768*1.414 + ... - int hi = (int)(255.0 * CLIPD((float)i / 49999.0)); // - outBeforeCLurveHistogram[hi] += histogramcl[i] ; - } - - - fillCurveArray(dCurve, clCurve, skip, needed); - - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + fillCurveArray(dCurve.get(), clCurve, skip, clcutili); } -void CurveFactory::mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram) +void CurveFactory::mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram) { bool needed = false; - DiagonalCurve* dCurve = NULL; + std::unique_ptr dCurve; outBeforeCurveHistogram.clear(); bool histNeeded = false; if (!mapcurvePoints.empty() && mapcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (mapcurvePoints, CURVES_MIN_POLY_POINTS / skip); + dCurve = std::unique_ptr(new DiagonalCurve(mapcurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (outBeforeCurveHistogram) { histNeeded = true; @@ -526,33 +341,21 @@ void CurveFactory::mapcurve ( bool & mapcontlutili, const std::vector& m } if (histNeeded) { - for (int i = 0; i < 32768; i++) { - double hval = CLIPD((double)i / 32767.0); - int hi = (int)(255.0 * hval); - outBeforeCurveHistogram[hi] += histogram[i] ; - } + histogram.compressTo(outBeforeCurveHistogram, 32768); } - fillCurveArray(dCurve, mapcurve, skip, needed); - - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + fillCurveArray(dCurve.get(), mapcurve, skip, needed); } - - - -void CurveFactory::curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram) +void CurveFactory::curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram) { bool needed = false; - DiagonalCurve* dCurve = NULL; + std::unique_ptr dCurve; outBeforeCurveHistogram.clear(); bool histNeeded = false; if (!dehaclcurvePoints.empty() && dehaclcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (dehaclcurvePoints, CURVES_MIN_POLY_POINTS / skip); + dCurve = std::unique_ptr(new DiagonalCurve(dehaclcurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (outBeforeCurveHistogram) { histNeeded = true; @@ -565,37 +368,20 @@ void CurveFactory::curveDehaContL ( bool & dehacontlutili, const std::vector& wavclcurvePoints, LUTf & wavclCurve, /*LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip) { - bool needed; - DiagonalCurve* dCurve = NULL; - - // if (outBeforeWavCLurveHistogram) - // outBeforeWavCLurveHistogram.clear(); - bool histNeededCL = false; - - needed = false; + bool needed = false; + std::unique_ptr dCurve; if (!wavclcurvePoints.empty() && wavclcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (wavclcurvePoints, CURVES_MIN_POLY_POINTS / skip); - // if (outBeforeWavCLurveHistogram) - // histNeededCL = true; + dCurve = std::unique_ptr(new DiagonalCurve(wavclcurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { needed = true; @@ -603,212 +389,89 @@ void CurveFactory::curveWavContL ( bool & wavcontlutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip) +// add curve Colortoning : C=f(L) and CLf(L) +void CurveFactory::curveToning ( const std::vector& curvePoints, LUTf & ToningCurve, int skip) { - bool needed; - DiagonalCurve* dCurve = NULL; + bool needed = false; + std::unique_ptr dCurve; - needed = false; - - if (!clcurvePoints.empty() && clcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip); + if (!curvePoints.empty() && curvePoints[0] != 0) { + dCurve = std::unique_ptr(new DiagonalCurve(curvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { needed = true; - clctoningutili = true; } } - fillCurveArray(dCurve, clToningCurve, skip, needed); - - // clToningCurve.dump("CLToning"); - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + fillCurveArray(dCurve.get(), ToningCurve, skip, needed); } -// add curve Colortoning : CLf(L) -void CurveFactory::curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip) -{ - bool needed; - DiagonalCurve* dCurve = NULL; - - needed = false; - - if (!llcurvePoints.empty() && llcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (llcurvePoints, CURVES_MIN_POLY_POINTS / skip); - - if (dCurve && !dCurve->isIdentity()) { - needed = true; - llctoningutili = true; - } - } - - fillCurveArray(dCurve, llToningCurve, skip, needed); -// llToningCurve.dump("LLToning"); - - if (dCurve) { - delete dCurve; - dCurve = NULL; - } -} //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void CurveFactory::complexsgnCurve (float adjustr, bool & autili, bool & butili, bool & ccutili, bool & cclutili, double saturation, double rstprotection, +void CurveFactory::complexsgnCurve (bool & autili, bool & butili, bool & ccutili, bool & cclutili, const std::vector& acurvePoints, const std::vector& bcurvePoints, const std::vector& cccurvePoints, const std::vector& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, - LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, //for chroma int skip) { - - //----------------------------------------------------- - - bool needed; - DiagonalCurve* dCurve = NULL; - LUTf dCcurve(65536, 0); - int k = 48000; //32768*1.41 - - if(outBeforeCCurveHistogram || outBeforeLCurveHistogram) { - for (int i = 0; i < k * adjustr; i++) { //# 32768*1.414 approximation maxi for chroma - dCcurve[i] = (float)i / (k * adjustr - 1); - } - } - - if (outBeforeCCurveHistogram) { - outBeforeCCurveHistogram.clear(); - } - - bool histNeededC = false; - - if (outBeforeLCurveHistogram) { - outBeforeLCurveHistogram.clear(); - } - - bool histNeededLC = false; - - //----------------------------------------------------- - - needed = false; + autili = butili = ccutili = cclutili = false; + std::unique_ptr dCurve; // create a curve if needed if (!acurvePoints.empty() && acurvePoints[0] != 0) { - dCurve = new DiagonalCurve (acurvePoints, CURVES_MIN_POLY_POINTS / skip); + dCurve = std::unique_ptr(new DiagonalCurve(acurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { - needed = true; autili = true; } } - fillCurveArray(dCurve, aoutCurve, skip, needed); - //if(autili) aoutCurve.dump("acurve"); + fillCurveArray(dCurve.get(), aoutCurve, skip, autili); - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + dCurve = nullptr; //----------------------------------------------------- - needed = false; - if (!bcurvePoints.empty() && bcurvePoints[0] != 0) { - dCurve = new DiagonalCurve (bcurvePoints, CURVES_MIN_POLY_POINTS / skip); + dCurve = std::unique_ptr(new DiagonalCurve(bcurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { - needed = true; butili = true; } } - fillCurveArray(dCurve, boutCurve, skip, needed); + fillCurveArray(dCurve.get(), boutCurve, skip, butili); - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + dCurve = nullptr; //----------------------------------------------- - needed = false; if (!cccurvePoints.empty() && cccurvePoints[0] != 0) { - dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS / skip); - - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { - histNeededC = true; - } + dCurve = std::unique_ptr(new DiagonalCurve(cccurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { - needed = true; ccutili = true; } } - if (histNeededC) { - for (int i = 0; i < k * adjustr; i++) { //32768*1.414 + ... - float hval = dCcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); // - outBeforeCCurveHistogram[hi] += histogramC[i] ; - } - } + fillCurveArray(dCurve.get(), satCurve, skip, ccutili); - fillCurveArray(dCurve, satCurve, skip, needed); - - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + dCurve = nullptr; //---------------------------- - needed = false; if (!lccurvePoints.empty() && lccurvePoints[0] != 0) { - dCurve = new DiagonalCurve (lccurvePoints, CURVES_MIN_POLY_POINTS / skip); - - if (outBeforeLCurveHistogram /*&& histogramCropped*/) { - histNeededLC = true; - } + dCurve = std::unique_ptr(new DiagonalCurve(lccurvePoints, CURVES_MIN_POLY_POINTS / skip)); if (dCurve && !dCurve->isIdentity()) { - needed = true; cclutili = true; } } - if (histNeededLC) { - for (int i = 0; i < k * adjustr; i++) { //32768*1.414 + ... - float hval = dCcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); // - outBeforeLCurveHistogram[hi] += histogramLC[i] ; - } - } - - - fillCurveArray(dCurve, lhskCurve, skip, needed); - - if (dCurve) { - delete dCurve; - dCurve = NULL; - } + fillCurveArray(dCurve.get(), lhskCurve, skip, cclutili); } @@ -820,7 +483,7 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double double shcompr, double br, double contr, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, - LUTu & histogram, LUTu & histogramCropped, + LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & customToneCurve1, @@ -846,36 +509,35 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double // tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - DiagonalCurve* brightcurve = NULL; + std::unique_ptr brightcurve; // check if brightness curve is needed if (br > 0.00001 || br < -0.00001) { - std::vector brightcurvePoints; - brightcurvePoints.resize(9); - brightcurvePoints.at(0) = double(DCT_NURBS); + std::vector brightcurvePoints(9); + brightcurvePoints[0] = DCT_NURBS; - brightcurvePoints.at(1) = 0.; //black point. Value in [0 ; 1] range - brightcurvePoints.at(2) = 0.; //black point. Value in [0 ; 1] range + brightcurvePoints[1] = 0.; //black point. Value in [0 ; 1] range + brightcurvePoints[2] = 0.; //black point. Value in [0 ; 1] range if(br > 0) { - brightcurvePoints.at(3) = 0.1; //toe point - brightcurvePoints.at(4) = 0.1 + br / 150.0; //value at toe point + brightcurvePoints[3] = 0.1; //toe point + brightcurvePoints[4] = 0.1 + br / 150.0; //value at toe point - brightcurvePoints.at(5) = 0.7; //shoulder point - brightcurvePoints.at(6) = min(1.0, 0.7 + br / 300.0); //value at shoulder point + brightcurvePoints[5] = 0.7; //shoulder point + brightcurvePoints[6] = min(1.0, 0.7 + br / 300.0); //value at shoulder point } else { - brightcurvePoints.at(3) = max(0.0, 0.1 - br / 150.0); //toe point - brightcurvePoints.at(4) = 0.1; //value at toe point + brightcurvePoints[3] = max(0.0, 0.1 - br / 150.0); //toe point + brightcurvePoints[4] = 0.1; //value at toe point - brightcurvePoints.at(5) = 0.7 - br / 300.0; //shoulder point - brightcurvePoints.at(6) = 0.7; //value at shoulder point + brightcurvePoints[5] = 0.7 - br / 300.0; //shoulder point + brightcurvePoints[6] = 0.7; //value at shoulder point } - brightcurvePoints.at(7) = 1.; // white point - brightcurvePoints.at(8) = 1.; // value at white point + brightcurvePoints[7] = 1.; // white point + brightcurvePoints[8] = 1.; // value at white point - brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS / skip); + brightcurve = std::unique_ptr(new DiagonalCurve(brightcurvePoints, CURVES_MIN_POLY_POINTS / skip)); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -885,26 +547,52 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double float scale = 65536.0; float comp = (max(0.0, ecomp) + 1.0) * hlcompr / 100.0; float shoulder = ((scale / max(1.0f, exp_scale)) * (hlcomprthresh / 200.0)) + 0.1; - //printf("shoulder = %e\n",shoulder); - //printf ("exp_scale= %f comp= %f def_mul=%f a= %f \n",exp_scale,comp,def_mul,a); - if (comp <= 0.0f) - for (int i = 0; i < 0x10000; i++) { - hlCurve[i] = exp_scale; - } - else { - for (int i = 0; i <= shoulder; i++) { - hlCurve[i] = exp_scale; - } + if (comp <= 0.0f) { + hlCurve.makeConstant(exp_scale); + } else { + hlCurve.makeConstant(exp_scale, shoulder + 1); float scalemshoulder = scale - shoulder; - for (int i = shoulder + 1; i < 0x10000; i++) { +#ifdef __SSE2__ + int i = shoulder + 1; + + if(i & 1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference // change to [0,1] range float val = (float)i - shoulder; float R = val * comp / (scalemshoulder); hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision + i++; } + + vdouble onev = _mm_set1_pd(1.0); + vdouble Rv = _mm_set_pd((i + 1 - shoulder) * (double)comp / scalemshoulder, (i - shoulder) * (double)comp / scalemshoulder); + vdouble incrementv = _mm_set1_pd(2.0 * comp / scalemshoulder); + vdouble exp_scalev = _mm_set1_pd(exp_scale); + + for (; i < 0x10000; i += 2) { + // change to [0,1] range + vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv; + vfloat resultfv = _mm_cvtpd_ps(resultv); + _mm_store_ss(&hlCurve[i], resultfv); + resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1, 1, 1, 1)); + _mm_store_ss(&hlCurve[i + 1], resultfv); + Rv += incrementv; + } + +#else + float R = comp / scalemshoulder; + float increment = R; + + for (int i = shoulder + 1; i < 0x10000; i++) { + // change to [0,1] range + hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision + R += increment; + } + +#endif + } @@ -915,11 +603,11 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double // change to [0,1] range shCurve.setClip(LUT_CLIP_ABOVE); // used LUT_CLIP_ABOVE, because the curve converges to 1.0 at the upper end and we don't want to exceed this value. float val = 1.f / 65535.f; - float val2 = simplebasecurve (val, black, 0.015 * shcompr); + float val2 = simplebasecurve (val, black, 0.015 * shcompr); shCurve[0] = CLIPD(val2) / val; - val = 0.0; // gamma correction - val = gamma (val, gamma_, start, slope, mul, add); + + val = Color::gammatab_srgb[0] / 65535.f; // apply brightness curve if (brightcurve) { @@ -929,30 +617,25 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double // store result in a temporary array dcurve[0] = CLIPD(val); - #pragma omp parallel for - for (int i = 1; i < 0x10000; i++) { - float val; - val = (float)i / 65535.0f; + float val = i / 65535.f; float val2 = simplebasecurve (val, black, 0.015 * shcompr); - shCurve[i] = CLIPD(val2) / val; + shCurve[i] = val2 / val; // gamma correction - val = gamma (val, gamma_, start, slope, mul, add); + val = Color::gammatab_srgb[i] / 65535.f; // apply brightness curve if (brightcurve) { - val = brightcurve->getVal (val); // TODO: getVal(double) is very slow! Optimize with a LUTf + val = CLIPD(brightcurve->getVal (val)); // TODO: getVal(double) is very slow! Optimize with a LUTf } // store result in a temporary array - dcurve[i] = CLIPD(val); + dcurve[i] = val; } - if (brightcurve) { - delete brightcurve; - } + brightcurve = nullptr; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -965,71 +648,57 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double unsigned int sum = 0; float avg = 0; - //double sqavg = 0; for (int i = 0; i <= 0xffff; i++) { - float fi = i; - fi *= hlCurve[i]; + float fi = i * hlCurve[i]; avg += dcurve[(int)(shCurve[fi] * fi)] * histogram[i]; - //sqavg += dcurve[i]*dcurve[i] * histogram[i]; sum += histogram[i]; } avg /= sum; - //sqavg /= sum; - //double stddev = sqrt(sqavg-avg*avg); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - std::vector contrastcurvePoints; - contrastcurvePoints.resize(9); - contrastcurvePoints.at(0) = double(DCT_NURBS); + std::vector contrastcurvePoints(9); + contrastcurvePoints[0] = DCT_NURBS; - contrastcurvePoints.at(1) = 0; //black point. Value in [0 ; 1] range - contrastcurvePoints.at(2) = 0; //black point. Value in [0 ; 1] range + contrastcurvePoints[1] = 0; //black point. Value in [0 ; 1] range + contrastcurvePoints[2] = 0; //black point. Value in [0 ; 1] range - contrastcurvePoints.at(3) = avg - avg * (0.6 - contr / 250.0); //toe point - contrastcurvePoints.at(4) = avg - avg * (0.6 + contr / 250.0); //value at toe point + contrastcurvePoints[3] = avg - avg * (0.6 - contr / 250.0); //toe point + contrastcurvePoints[4] = avg - avg * (0.6 + contr / 250.0); //value at toe point - contrastcurvePoints.at(5) = avg + (1 - avg) * (0.6 - contr / 250.0); //shoulder point - contrastcurvePoints.at(6) = avg + (1 - avg) * (0.6 + contr / 250.0); //value at shoulder point + contrastcurvePoints[5] = avg + (1 - avg) * (0.6 - contr / 250.0); //shoulder point + contrastcurvePoints[6] = avg + (1 - avg) * (0.6 + contr / 250.0); //value at shoulder point - contrastcurvePoints.at(7) = 1.; // white point - contrastcurvePoints.at(8) = 1.; // value at white point + contrastcurvePoints[7] = 1.; // white point + contrastcurvePoints[8] = 1.; // value at white point - DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS / skip); + const DiagonalCurve contrastcurve(contrastcurvePoints, CURVES_MIN_POLY_POINTS / skip); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // apply contrast enhancement for (int i = 0; i <= 0xffff; i++) { - dcurve[i] = contrastcurve->getVal (dcurve[i]); + dcurve[i] = contrastcurve.getVal (dcurve[i]); } - - delete contrastcurve; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // create second curve if needed bool histNeeded = false; - DiagonalCurve* tcurve = NULL; customToneCurve2.Reset(); if (!curvePoints2.empty() && curvePoints2[0] > DCT_Linear && curvePoints2[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePoints2, CURVES_MIN_POLY_POINTS / skip); + const DiagonalCurve tcurve(curvePoints2, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { + if (!tcurve.isIdentity()) { + customToneCurve2.Set(tcurve, gamma_); + } + + if (outBeforeCCurveHistogram ) { histNeeded = true; } } - if (tcurve) { - if (!tcurve->isIdentity()) { - customToneCurve2.Set(tcurve, gamma_, start, slope, mul, add); - } - - delete tcurve; - tcurve = NULL; - } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1038,90 +707,52 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double customToneCurve1.Reset(); if (!curvePoints.empty() && curvePoints[0] > DCT_Linear && curvePoints[0] < DCT_Unchanged) { - tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip); + const DiagonalCurve tcurve(curvePoints, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { + if (!tcurve.isIdentity()) { + customToneCurve1.Set(tcurve, gamma_); + } + + if (outBeforeCCurveHistogram) { histNeeded = true; } } - if (tcurve) { - if (!tcurve->isIdentity()) { - customToneCurve1.Set(tcurve, gamma_, start, slope, mul, add); - } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - delete tcurve; - tcurve = NULL; +#ifdef __SSE2__ + vfloat gamma_v = F2V(gamma_); + vfloat startv = F2V(start); + vfloat slopev = F2V(slope); + vfloat mulv = F2V(mul); + vfloat addv = F2V(add); + vfloat c65535v = F2V(65535.f); + + for (int i = 0; i <= 0xffff; i += 4) { + vfloat valv = LVFU(dcurve[i]); + valv = igamma (valv, gamma_v, startv, slopev, mulv, addv); + STVFU(outCurve[i], c65535v * valv); } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - // create curve bw - // curve 2 - /* DiagonalCurve* tbwcurve = NULL; - customToneCurvebw2.Reset(); - - if (!curvePointsbw2.empty() && curvePointsbw2[0]>DCT_Linear && curvePointsbw2[0]isIdentity()) { - delete tbwcurve; - tbwcurve = NULL; - } - else - customToneCurvebw2.Set(tbwcurve); - delete tbwcurve; - tbwcurve = NULL; - } - - customToneCurvebw1.Reset(); - - if (!curvePointsbw.empty() && curvePointsbw[0]>DCT_Linear && curvePointsbw[0]isIdentity()) { - delete tbwcurve; - tbwcurve = NULL; - } - else if (curveModeb != procparams::BlackWhiteParams::TC_MODE_STD_BW) { - customToneCurvebw1.Set(tbwcurve); - delete tbwcurve; - tbwcurve = NULL; - } - } - */ - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#else for (int i = 0; i <= 0xffff; i++) { float val = dcurve[i]; - - if (histNeeded) { - float fi = i; - float hval = hlCurve[i] * fi; - hval = dcurve[shCurve[hval] * hval]; - //if (needigamma) - // hval = igamma2 (hval); - int hi = (int)(255.0 * (hval)); - outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ; - } - val = igamma (val, gamma_, start, slope, mul, add); outCurve[i] = (65535.f * val); } - if (tcurve) { - delete tcurve; - } +#endif - /*if (outBeforeCCurveHistogram) { - for (int i=0; i<256; i++) printf("i= %d bchist= %d \n",i,outBeforeCCurveHistogram[i]); - }*/ + if (histNeeded) { + for (int i = 0; i <= 0xffff; i++) { + float fi = i; + float hval = hlCurve[i] * fi; + hval = dcurve[shCurve[hval] * hval]; + int hi = (int)(255.f * (hval)); + outBeforeCCurveHistogram[hi] += histogram[i] ; + } + } } @@ -1130,13 +761,11 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePoints, - LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, + const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili) { - // curve without contrast - LUTf dcurve(65536, 0); - + utili = false; // clear array that stores histogram valid before applying the custom curve if (outBeforeCCurveHistogram) { outBeforeCCurveHistogram.clear(); @@ -1174,7 +803,7 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vectorgetVal (val); + val = brightcurve.getVal (val); // store result in a temporary array - dcurve[i] = CLIPD(val); + outCurve[i] = CLIPD(val); } - delete brightcurve; } else { - for (int i = 0; i < 32768; i++) { // L values range up to 32767, higher values are for highlight overflow - // set the identity curve in the temporary array - dcurve[i] = (float)i / 32767.0; - } + outCurve.makeIdentity(32767.f); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1206,27 +831,21 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector 0.00001 || contr < -0.00001) { utili = true; - DiagonalCurve* contrastcurve = NULL; - // compute mean luminance of the image with the curve applied int sum = 0; float avg = 0; - //float sqavg = 0; for (int i = 0; i < 32768; i++) { - avg += dcurve[i] * histogram[i]; - //sqavg += dcurve[i]*dcurve[i] * histogram[i]; + avg += outCurve[i] * histogram[i]; sum += histogram[i]; } + std::vector contrastcurvePoints; + if(sum) { avg /= sum; - //sqavg /= sum; - //float stddev = sqrt(sqavg-avg*avg); - // printf("avg=%f\n",avg); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - std::vector contrastcurvePoints; contrastcurvePoints.resize(9); contrastcurvePoints.at(0) = double(DCT_NURBS); @@ -1242,12 +861,10 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector contrastcurvePoints; contrastcurvePoints.resize(5); contrastcurvePoints.at(0) = double(DCT_NURBS); @@ -1257,35 +874,34 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vectorgetVal (dcurve[i]); + outCurve[i] = contrastcurve.getVal (outCurve[i]); } - delete contrastcurve; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // create a curve if needed - DiagonalCurve* tcurve = NULL; + std::unique_ptr tcurve; bool histNeeded = false; if (!curvePoints.empty() && curvePoints[0] != 0) { - tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip); + tcurve = std::unique_ptr(new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip)); - if (outBeforeCCurveHistogram /*&& histogramCropped*/) { + if (outBeforeCCurveHistogram) { histNeeded = true; } } if (tcurve && tcurve->isIdentity()) { - delete tcurve; - tcurve = NULL; + tcurve = nullptr; } if (tcurve) { @@ -1296,41 +912,32 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vectorgetVal (dcurve[i]); + val = tcurve->getVal (outCurve[i]); - outCurve[i] = (32767.0 * val); + outCurve[i] = (32767.f * val); } } else { + // Skip the slow getval method if no curve is used (or an identity curve) // L values go up to 32767, last stop is for highlight overflow - for (int i = 0; i < 32768; i++) { - if (histNeeded) { - float hval = dcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); - outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ; - } - - outCurve[i] = 32767.0 * dcurve[i]; + if(histNeeded) { + histogram.compressTo(outBeforeCCurveHistogram, 32768, outCurve); } + + outCurve *= 32767.f; + } - for (int i = 32768; i < 65536; i++) { + for (int i = 32768; i < 32770; i++) { // set last two elements of lut to 32768 and 32769 to allow linear interpolation outCurve[i] = (float)i; } - if (tcurve) { - delete tcurve; - } - - /*if (outBeforeCCurveHistogram) { - for (int i=0; i<256; i++) printf("i= %d bchist= %d \n",i,outBeforeCCurveHistogram[i]); - }*/ } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1340,19 +947,15 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePoints, LUTf & outCurve, int skip) { - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // create a curve if needed - DiagonalCurve* tcurve = NULL; + std::unique_ptr tcurve; if (!curvePoints.empty() && curvePoints[0] != 0) { - tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip); + tcurve = std::unique_ptr(new DiagonalCurve(curvePoints, CURVES_MIN_POLY_POINTS / skip)); } if (tcurve && tcurve->isIdentity()) { - delete tcurve; - tcurve = NULL; + tcurve = nullptr; } if (tcurve) { @@ -1362,23 +965,14 @@ void CurveFactory::RGBCurve (const std::vector& curvePoints, LUTf & outC for (int i = 0; i < 65536; i++) { // apply custom/parametric/NURBS curve, if any - // RGB curves are defined with sRGB gamma, but operate on linear data - float val = float(i) / 65535.f; - val = CurveFactory::gamma2 (val); + float val = Color::gamma2curve[i] / 65535.f; val = tcurve->getVal(val); - val = CurveFactory::igamma2 (val); - //float val = tcurve->getVal ((float)i/65536.0f); - outCurve[i] = (65536.0f * val); + outCurve[i] = Color::igammatab_srgb[val * 65535.f]; } - - delete tcurve; - } - // let the LUTf empty for identity curves - else { + } else { // let the LUTf empty for identity curves outCurve.reset(); } - } @@ -1388,12 +982,12 @@ void ColorAppearance::Reset() } // Fill a LUT with X/Y, ranged 0xffff -void ColorAppearance::Set(Curve *pCurve) +void ColorAppearance::Set(const Curve &pCurve) { lutColCurve(65536); for (int i = 0; i < 65536; i++) { - lutColCurve[i] = pCurve->getVal(double(i) / 65535.) * 65535.; + lutColCurve[i] = pCurve.getVal(double(i) / 65535.) * 65535.; } } @@ -1430,26 +1024,73 @@ void RetinextransmissionCurve::Set(const std::vector &curvePoints) } } + +RetinexgaintransmissionCurve::RetinexgaintransmissionCurve() {}; + +void RetinexgaintransmissionCurve::Reset() +{ + lutgaintransmission.reset(); +} + +void RetinexgaintransmissionCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + lutgaintransmission.reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutgaintransmission(501); // raise this value if the quality suffers from this number of samples + + for (int i = 0; i < 501; i++) { + lutgaintransmission[i] = pCurve.getVal(double(i) / 500.); + } +} + +void RetinexgaintransmissionCurve::Set(const std::vector &curvePoints) +{ + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve tcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve.setIdentityValue(0.); + Set(tcurve); + } else { + Reset(); + } +} + void ToneCurve::Reset() { lutToneCurve.reset(); } // Fill a LUT with X/Y, ranged 0xffff -void ToneCurve::Set(Curve *pCurve, float gamma, float start, float slope, float mul, float add) +void ToneCurve::Set(const Curve &pCurve, float gamma) { lutToneCurve(65536); if (gamma <= 0.0 || gamma == 1.) { for (int i = 0; i < 65536; i++) { - lutToneCurve[i] = (float)pCurve->getVal(float(i) / 65535.f) * 65535.f; + lutToneCurve[i] = (float)pCurve.getVal(float(i) / 65535.f) * 65535.f; } + } else if(gamma == (float)Color::sRGBGammaCurve) { + // for sRGB gamma we can use luts, which is much faster + for (int i = 0; i < 65536; i++) { + float val = Color::gammatab_srgb[i] / 65535.f; + val = pCurve.getVal(val); + val = Color::igammatab_srgb[val * 65535.f]; + lutToneCurve[i] = val; + } + } else { + const float start = expf(gamma * logf( -0.055 / ((1.0 / gamma - 1.0) * 1.055 ))); + const float slope = 1.055 * powf (start, 1.0 / gamma - 1) - 0.055 / start; + const float mul = 1.055; + const float add = 0.055; + // apply gamma, that is 'pCurve' is defined with the given gamma and here we convert it to a curve in linear space for (int i = 0; i < 65536; i++) { float val = float(i) / 65535.f; val = CurveFactory::gamma (val, gamma, start, slope, mul, add); - val = pCurve->getVal(val); + val = pCurve.getVal(val); val = CurveFactory::igamma (val, gamma, start, slope, mul, add); lutToneCurve[i] = val * 65535.f; } @@ -1479,18 +1120,17 @@ void OpacityCurve::Set(const Curve *pCurve) void OpacityCurve::Set(const std::vector &curvePoints, bool &opautili) { - FlatCurve* tcurve = NULL; + std::unique_ptr tcurve; if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { - tcurve = new FlatCurve (curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve = std::unique_ptr(new FlatCurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2)); tcurve->setIdentityValue(0.); } if (tcurve) { - Set(tcurve); + Set(tcurve.get()); opautili = true; - delete tcurve; - tcurve = NULL; + tcurve = nullptr; } } @@ -1863,16 +1503,14 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], void ColorGradientCurve::SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin) { - FlatCurve* tcurve = NULL; + std::unique_ptr tcurve; if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { - tcurve = new FlatCurve (curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve = std::unique_ptr(new FlatCurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2)); } if (tcurve) { - SetXYZ(tcurve, xyz_rgb, rgb_xyz, satur, lumin); - delete tcurve; - tcurve = NULL; + SetXYZ(tcurve.get(), xyz_rgb, rgb_xyz, satur, lumin); } } @@ -1964,16 +1602,14 @@ void ColorGradientCurve::SetRGB(const Curve *pCurve, const double xyz_rgb[3][3], void ColorGradientCurve::SetRGB(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3]) { - FlatCurve* tcurve = NULL; + std::unique_ptr tcurve; if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { - tcurve = new FlatCurve (curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve = std::unique_ptr(new FlatCurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2)); } if (tcurve) { - SetRGB(tcurve, xyz_rgb, rgb_xyz); - delete tcurve; - tcurve = NULL; + SetRGB(tcurve.get(), xyz_rgb, rgb_xyz); } } diff --git a/rtengine/curves.h b/rtengine/curves.h index b0e9d691f..348772075 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -159,7 +159,9 @@ protected: static inline double simplebasecurve (double x, double b, double sr) { // a = 1, D = 1, hr = 0 (unused for a = D = 1) - if (b < 0) { + if (b == 0.0) { + return x; + } else if (b < 0) { double m = 0.5;//midpoint double slope = 1.0 + b; //slope of straight line between (0,-b) and (1,1) double y = -b + m * slope; //value at midpoint @@ -175,7 +177,7 @@ protected: double y = (m - b) * slope; if (x <= m) { - return b == 0 ? x * slope : clower (x / m, slope * m / y, sr) * y; + return clower (x / m, slope * m / y, sr) * y; } else { return y + (x - m) * slope; } @@ -238,13 +240,22 @@ public: } static inline float gamma (float x, float gamma, float start, float slope, float mul, float add) { - return (x <= start ? x*slope : expf(logf(x) / gamma) * mul - add); + return (x <= start ? x*slope : xexpf(xlogf(x) / gamma) * mul - add); } static inline float igamma (float x, float gamma, float start, float slope, float mul, float add) { - return (x <= start * slope ? x / slope : expf(logf((x + add) / mul) * gamma) ); + return (x <= start * slope ? x / slope : xexpf(xlogf((x + add) / mul) * gamma) ); } - +#ifdef __SSE2__ + static inline vfloat igamma (vfloat x, vfloat gamma, vfloat start, vfloat slope, vfloat mul, vfloat add) + { +#if !defined(__clang__) + return (x <= start * slope ? x / slope : xexpf(xlogf((x + add) / mul) * gamma) ); +#else + return vself(vmaskf_le(x, start * slope), x / slope, xexpf(xlogf((x + add) / mul) * gamma)); +#endif + } +#endif static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level) { if (comp > 0.0) { @@ -271,42 +282,31 @@ public: public: static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, - - LUTu & histogram, LUTu & histogramCropped, - LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, + 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, LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, + static void curveBW (const std::vector& curvePointsbw, const std::vector& curvePointsbw2, const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip); - static void curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip); + static void curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, int skip); static void curveWavContL ( bool & wavcontlutili, const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip); - static void curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram); - static void mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram); + static void curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram); + static void mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram); - static void curveToningCL ( bool & clctoningutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip); - static void curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip); - static void denoiseCC ( bool & ccdenoiseutili, const std::vector& cccurvePoints, LUTf & NoiseCCcurve, int skip); + static void curveToning ( const std::vector& curvePoints, LUTf & ToningCurve, int skip); - static void complexsgnCurve ( float adjustr, bool & autili, bool & butili, bool & ccutili, bool & clcutili, double saturation, double rstprotection, const std::vector& acurvePoints, + static void complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, bool & clcutili, const std::vector& acurvePoints, const std::vector& bcurvePoints, const std::vector& cccurvePoints, const std::vector& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, - LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, ///for chroma int skip = 1); - static void complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, - LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); - - static void updatechroma ( - const std::vector& cccurvePoints, - LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma - int skip = 1); + static void complexLCurve (double br, double contr, const std::vector& curvePoints, const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); static void curveLightBrightColor ( - procparams::ColorAppearanceParams::eTCModeId curveMode, const std::vector& curvePoints, - procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector& curvePoints2, - procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector& curvePoints3, - LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram, - LUTu & histogramC, LUTu & outBeforeCCurveHistogramC, + const std::vector& curvePoints, + const std::vector& curvePoints2, + const std::vector& curvePoints3, + const LUTu & histogram, LUTu & outBeforeCCurveHistogram, + const LUTu & histogramC, LUTu & outBeforeCCurveHistogramC, ColorAppearance & outColCurve1, ColorAppearance & outColCurve2, ColorAppearance & outColCurve3, @@ -337,6 +337,7 @@ protected: // end of variables used in Parametric curves only std::vector poly_x; // X points of the faceted curve std::vector poly_y; // Y points of the faceted curve + std::vector dyByDx; std::vector hash; unsigned short hashSize; // hash table's size, between [10, 100, 1000] @@ -358,11 +359,11 @@ protected: } static inline double p01 (double x, double prot) { - return x <= 0.5 ? CurveFactory::clower (x * 2, 2.0, prot) / 2.0 : 0.5 + CurveFactory::cupper ((x - 0.5) * 2, 2.0, prot) / 2.0; + return x <= 0.5 ? CurveFactory::clower (x * 2, 2.0, prot) * 0.5 : 0.5 + CurveFactory::cupper ((x - 0.5) * 2, 2.0, prot) * 0.5; } static inline double p10 (double x, double prot) { - return x <= 0.5 ? CurveFactory::cupper (x * 2, 2.0, prot) / 2.0 : 0.5 + CurveFactory::clower ((x - 0.5) * 2, 2.0, prot) / 2.0; + return x <= 0.5 ? CurveFactory::cupper (x * 2, 2.0, prot) * 0.5 : 0.5 + CurveFactory::clower ((x - 0.5) * 2, 2.0, prot) * 0.5; } static inline double pfull (double x, double prot, double sh, double hl) { @@ -370,6 +371,7 @@ protected: } void fillHash(); + void fillDyByDx(); public: Curve (); @@ -407,7 +409,7 @@ public: class FlatCurve : public Curve { -protected: +private: FlatCurveType kind; double* leftTangent; double* rightTangent; @@ -454,6 +456,30 @@ public: } }; +class RetinexgaintransmissionCurve +{ +private: + LUTf lutgaintransmission; // 0xffff range + void Set(const Curve &pCurve); + +public: + virtual ~RetinexgaintransmissionCurve() {}; + RetinexgaintransmissionCurve(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const + { + return lutgaintransmission[index]; + } + + operator bool (void) const + { + return lutgaintransmission; + } +}; + class ToneCurve @@ -464,7 +490,7 @@ public: virtual ~ToneCurve() {}; void Reset(); - void Set(Curve *pCurve, float gamma = 0, float start = 0, float slope = 0, float mul = 0, float add = 0); + void Set(const Curve &pCurve, float gamma = 0); operator bool (void) const { return lutToneCurve; @@ -688,7 +714,7 @@ public: virtual ~ColorAppearance() {}; void Reset(); - void Set(Curve *pCurve); + void Set(const Curve &pCurve); operator bool (void) const { return lutColCurve; diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index c05230738..a597fa8db 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + +#include #include #include "dcp.h" @@ -25,389 +27,100 @@ #include "improcfun.h" #include "rt_math.h" -using namespace std; using namespace rtengine; using namespace rtexif; -static const float adobe_camera_raw_default_curve[] = { - 0.00000f, 0.00078f, 0.00160f, 0.00242f, - 0.00314f, 0.00385f, 0.00460f, 0.00539f, - 0.00623f, 0.00712f, 0.00806f, 0.00906f, - 0.01012f, 0.01122f, 0.01238f, 0.01359f, - 0.01485f, 0.01616f, 0.01751f, 0.01890f, - 0.02033f, 0.02180f, 0.02331f, 0.02485f, - 0.02643f, 0.02804f, 0.02967f, 0.03134f, - 0.03303f, 0.03475f, 0.03648f, 0.03824f, - 0.04002f, 0.04181f, 0.04362f, 0.04545f, - 0.04730f, 0.04916f, 0.05103f, 0.05292f, - 0.05483f, 0.05675f, 0.05868f, 0.06063f, - 0.06259f, 0.06457f, 0.06655f, 0.06856f, - 0.07057f, 0.07259f, 0.07463f, 0.07668f, - 0.07874f, 0.08081f, 0.08290f, 0.08499f, - 0.08710f, 0.08921f, 0.09134f, 0.09348f, - 0.09563f, 0.09779f, 0.09996f, 0.10214f, - 0.10433f, 0.10652f, 0.10873f, 0.11095f, - 0.11318f, 0.11541f, 0.11766f, 0.11991f, - 0.12218f, 0.12445f, 0.12673f, 0.12902f, - 0.13132f, 0.13363f, 0.13595f, 0.13827f, - 0.14061f, 0.14295f, 0.14530f, 0.14765f, - 0.15002f, 0.15239f, 0.15477f, 0.15716f, - 0.15956f, 0.16197f, 0.16438f, 0.16680f, - 0.16923f, 0.17166f, 0.17410f, 0.17655f, - 0.17901f, 0.18148f, 0.18395f, 0.18643f, - 0.18891f, 0.19141f, 0.19391f, 0.19641f, - 0.19893f, 0.20145f, 0.20398f, 0.20651f, - 0.20905f, 0.21160f, 0.21416f, 0.21672f, - 0.21929f, 0.22185f, 0.22440f, 0.22696f, - 0.22950f, 0.23204f, 0.23458f, 0.23711f, - 0.23963f, 0.24215f, 0.24466f, 0.24717f, - 0.24967f, 0.25216f, 0.25465f, 0.25713f, - 0.25961f, 0.26208f, 0.26454f, 0.26700f, - 0.26945f, 0.27189f, 0.27433f, 0.27676f, - 0.27918f, 0.28160f, 0.28401f, 0.28641f, - 0.28881f, 0.29120f, 0.29358f, 0.29596f, - 0.29833f, 0.30069f, 0.30305f, 0.30540f, - 0.30774f, 0.31008f, 0.31241f, 0.31473f, - 0.31704f, 0.31935f, 0.32165f, 0.32395f, - 0.32623f, 0.32851f, 0.33079f, 0.33305f, - 0.33531f, 0.33756f, 0.33981f, 0.34205f, - 0.34428f, 0.34650f, 0.34872f, 0.35093f, - 0.35313f, 0.35532f, 0.35751f, 0.35969f, - 0.36187f, 0.36404f, 0.36620f, 0.36835f, - 0.37050f, 0.37264f, 0.37477f, 0.37689f, - 0.37901f, 0.38112f, 0.38323f, 0.38533f, - 0.38742f, 0.38950f, 0.39158f, 0.39365f, - 0.39571f, 0.39777f, 0.39982f, 0.40186f, - 0.40389f, 0.40592f, 0.40794f, 0.40996f, - 0.41197f, 0.41397f, 0.41596f, 0.41795f, - 0.41993f, 0.42191f, 0.42388f, 0.42584f, - 0.42779f, 0.42974f, 0.43168f, 0.43362f, - 0.43554f, 0.43747f, 0.43938f, 0.44129f, - 0.44319f, 0.44509f, 0.44698f, 0.44886f, - 0.45073f, 0.45260f, 0.45447f, 0.45632f, - 0.45817f, 0.46002f, 0.46186f, 0.46369f, - 0.46551f, 0.46733f, 0.46914f, 0.47095f, - 0.47275f, 0.47454f, 0.47633f, 0.47811f, - 0.47989f, 0.48166f, 0.48342f, 0.48518f, - 0.48693f, 0.48867f, 0.49041f, 0.49214f, - 0.49387f, 0.49559f, 0.49730f, 0.49901f, - 0.50072f, 0.50241f, 0.50410f, 0.50579f, - 0.50747f, 0.50914f, 0.51081f, 0.51247f, - 0.51413f, 0.51578f, 0.51742f, 0.51906f, - 0.52069f, 0.52232f, 0.52394f, 0.52556f, - 0.52717f, 0.52878f, 0.53038f, 0.53197f, - 0.53356f, 0.53514f, 0.53672f, 0.53829f, - 0.53986f, 0.54142f, 0.54297f, 0.54452f, - 0.54607f, 0.54761f, 0.54914f, 0.55067f, - 0.55220f, 0.55371f, 0.55523f, 0.55673f, - 0.55824f, 0.55973f, 0.56123f, 0.56271f, - 0.56420f, 0.56567f, 0.56715f, 0.56861f, - 0.57007f, 0.57153f, 0.57298f, 0.57443f, - 0.57587f, 0.57731f, 0.57874f, 0.58017f, - 0.58159f, 0.58301f, 0.58443f, 0.58583f, - 0.58724f, 0.58864f, 0.59003f, 0.59142f, - 0.59281f, 0.59419f, 0.59556f, 0.59694f, - 0.59830f, 0.59966f, 0.60102f, 0.60238f, - 0.60373f, 0.60507f, 0.60641f, 0.60775f, - 0.60908f, 0.61040f, 0.61173f, 0.61305f, - 0.61436f, 0.61567f, 0.61698f, 0.61828f, - 0.61957f, 0.62087f, 0.62216f, 0.62344f, - 0.62472f, 0.62600f, 0.62727f, 0.62854f, - 0.62980f, 0.63106f, 0.63232f, 0.63357f, - 0.63482f, 0.63606f, 0.63730f, 0.63854f, - 0.63977f, 0.64100f, 0.64222f, 0.64344f, - 0.64466f, 0.64587f, 0.64708f, 0.64829f, - 0.64949f, 0.65069f, 0.65188f, 0.65307f, - 0.65426f, 0.65544f, 0.65662f, 0.65779f, - 0.65897f, 0.66013f, 0.66130f, 0.66246f, - 0.66362f, 0.66477f, 0.66592f, 0.66707f, - 0.66821f, 0.66935f, 0.67048f, 0.67162f, - 0.67275f, 0.67387f, 0.67499f, 0.67611f, - 0.67723f, 0.67834f, 0.67945f, 0.68055f, - 0.68165f, 0.68275f, 0.68385f, 0.68494f, - 0.68603f, 0.68711f, 0.68819f, 0.68927f, - 0.69035f, 0.69142f, 0.69249f, 0.69355f, - 0.69461f, 0.69567f, 0.69673f, 0.69778f, - 0.69883f, 0.69988f, 0.70092f, 0.70196f, - 0.70300f, 0.70403f, 0.70506f, 0.70609f, - 0.70711f, 0.70813f, 0.70915f, 0.71017f, - 0.71118f, 0.71219f, 0.71319f, 0.71420f, - 0.71520f, 0.71620f, 0.71719f, 0.71818f, - 0.71917f, 0.72016f, 0.72114f, 0.72212f, - 0.72309f, 0.72407f, 0.72504f, 0.72601f, - 0.72697f, 0.72794f, 0.72890f, 0.72985f, - 0.73081f, 0.73176f, 0.73271f, 0.73365f, - 0.73460f, 0.73554f, 0.73647f, 0.73741f, - 0.73834f, 0.73927f, 0.74020f, 0.74112f, - 0.74204f, 0.74296f, 0.74388f, 0.74479f, - 0.74570f, 0.74661f, 0.74751f, 0.74842f, - 0.74932f, 0.75021f, 0.75111f, 0.75200f, - 0.75289f, 0.75378f, 0.75466f, 0.75555f, - 0.75643f, 0.75730f, 0.75818f, 0.75905f, - 0.75992f, 0.76079f, 0.76165f, 0.76251f, - 0.76337f, 0.76423f, 0.76508f, 0.76594f, - 0.76679f, 0.76763f, 0.76848f, 0.76932f, - 0.77016f, 0.77100f, 0.77183f, 0.77267f, - 0.77350f, 0.77432f, 0.77515f, 0.77597f, - 0.77680f, 0.77761f, 0.77843f, 0.77924f, - 0.78006f, 0.78087f, 0.78167f, 0.78248f, - 0.78328f, 0.78408f, 0.78488f, 0.78568f, - 0.78647f, 0.78726f, 0.78805f, 0.78884f, - 0.78962f, 0.79040f, 0.79118f, 0.79196f, - 0.79274f, 0.79351f, 0.79428f, 0.79505f, - 0.79582f, 0.79658f, 0.79735f, 0.79811f, - 0.79887f, 0.79962f, 0.80038f, 0.80113f, - 0.80188f, 0.80263f, 0.80337f, 0.80412f, - 0.80486f, 0.80560f, 0.80634f, 0.80707f, - 0.80780f, 0.80854f, 0.80926f, 0.80999f, - 0.81072f, 0.81144f, 0.81216f, 0.81288f, - 0.81360f, 0.81431f, 0.81503f, 0.81574f, - 0.81645f, 0.81715f, 0.81786f, 0.81856f, - 0.81926f, 0.81996f, 0.82066f, 0.82135f, - 0.82205f, 0.82274f, 0.82343f, 0.82412f, - 0.82480f, 0.82549f, 0.82617f, 0.82685f, - 0.82753f, 0.82820f, 0.82888f, 0.82955f, - 0.83022f, 0.83089f, 0.83155f, 0.83222f, - 0.83288f, 0.83354f, 0.83420f, 0.83486f, - 0.83552f, 0.83617f, 0.83682f, 0.83747f, - 0.83812f, 0.83877f, 0.83941f, 0.84005f, - 0.84069f, 0.84133f, 0.84197f, 0.84261f, - 0.84324f, 0.84387f, 0.84450f, 0.84513f, - 0.84576f, 0.84639f, 0.84701f, 0.84763f, - 0.84825f, 0.84887f, 0.84949f, 0.85010f, - 0.85071f, 0.85132f, 0.85193f, 0.85254f, - 0.85315f, 0.85375f, 0.85436f, 0.85496f, - 0.85556f, 0.85615f, 0.85675f, 0.85735f, - 0.85794f, 0.85853f, 0.85912f, 0.85971f, - 0.86029f, 0.86088f, 0.86146f, 0.86204f, - 0.86262f, 0.86320f, 0.86378f, 0.86435f, - 0.86493f, 0.86550f, 0.86607f, 0.86664f, - 0.86720f, 0.86777f, 0.86833f, 0.86889f, - 0.86945f, 0.87001f, 0.87057f, 0.87113f, - 0.87168f, 0.87223f, 0.87278f, 0.87333f, - 0.87388f, 0.87443f, 0.87497f, 0.87552f, - 0.87606f, 0.87660f, 0.87714f, 0.87768f, - 0.87821f, 0.87875f, 0.87928f, 0.87981f, - 0.88034f, 0.88087f, 0.88140f, 0.88192f, - 0.88244f, 0.88297f, 0.88349f, 0.88401f, - 0.88453f, 0.88504f, 0.88556f, 0.88607f, - 0.88658f, 0.88709f, 0.88760f, 0.88811f, - 0.88862f, 0.88912f, 0.88963f, 0.89013f, - 0.89063f, 0.89113f, 0.89163f, 0.89212f, - 0.89262f, 0.89311f, 0.89360f, 0.89409f, - 0.89458f, 0.89507f, 0.89556f, 0.89604f, - 0.89653f, 0.89701f, 0.89749f, 0.89797f, - 0.89845f, 0.89892f, 0.89940f, 0.89987f, - 0.90035f, 0.90082f, 0.90129f, 0.90176f, - 0.90222f, 0.90269f, 0.90316f, 0.90362f, - 0.90408f, 0.90454f, 0.90500f, 0.90546f, - 0.90592f, 0.90637f, 0.90683f, 0.90728f, - 0.90773f, 0.90818f, 0.90863f, 0.90908f, - 0.90952f, 0.90997f, 0.91041f, 0.91085f, - 0.91130f, 0.91173f, 0.91217f, 0.91261f, - 0.91305f, 0.91348f, 0.91392f, 0.91435f, - 0.91478f, 0.91521f, 0.91564f, 0.91606f, - 0.91649f, 0.91691f, 0.91734f, 0.91776f, - 0.91818f, 0.91860f, 0.91902f, 0.91944f, - 0.91985f, 0.92027f, 0.92068f, 0.92109f, - 0.92150f, 0.92191f, 0.92232f, 0.92273f, - 0.92314f, 0.92354f, 0.92395f, 0.92435f, - 0.92475f, 0.92515f, 0.92555f, 0.92595f, - 0.92634f, 0.92674f, 0.92713f, 0.92753f, - 0.92792f, 0.92831f, 0.92870f, 0.92909f, - 0.92947f, 0.92986f, 0.93025f, 0.93063f, - 0.93101f, 0.93139f, 0.93177f, 0.93215f, - 0.93253f, 0.93291f, 0.93328f, 0.93366f, - 0.93403f, 0.93440f, 0.93478f, 0.93515f, - 0.93551f, 0.93588f, 0.93625f, 0.93661f, - 0.93698f, 0.93734f, 0.93770f, 0.93807f, - 0.93843f, 0.93878f, 0.93914f, 0.93950f, - 0.93986f, 0.94021f, 0.94056f, 0.94092f, - 0.94127f, 0.94162f, 0.94197f, 0.94231f, - 0.94266f, 0.94301f, 0.94335f, 0.94369f, - 0.94404f, 0.94438f, 0.94472f, 0.94506f, - 0.94540f, 0.94573f, 0.94607f, 0.94641f, - 0.94674f, 0.94707f, 0.94740f, 0.94774f, - 0.94807f, 0.94839f, 0.94872f, 0.94905f, - 0.94937f, 0.94970f, 0.95002f, 0.95035f, - 0.95067f, 0.95099f, 0.95131f, 0.95163f, - 0.95194f, 0.95226f, 0.95257f, 0.95289f, - 0.95320f, 0.95351f, 0.95383f, 0.95414f, - 0.95445f, 0.95475f, 0.95506f, 0.95537f, - 0.95567f, 0.95598f, 0.95628f, 0.95658f, - 0.95688f, 0.95718f, 0.95748f, 0.95778f, - 0.95808f, 0.95838f, 0.95867f, 0.95897f, - 0.95926f, 0.95955f, 0.95984f, 0.96013f, - 0.96042f, 0.96071f, 0.96100f, 0.96129f, - 0.96157f, 0.96186f, 0.96214f, 0.96242f, - 0.96271f, 0.96299f, 0.96327f, 0.96355f, - 0.96382f, 0.96410f, 0.96438f, 0.96465f, - 0.96493f, 0.96520f, 0.96547f, 0.96574f, - 0.96602f, 0.96629f, 0.96655f, 0.96682f, - 0.96709f, 0.96735f, 0.96762f, 0.96788f, - 0.96815f, 0.96841f, 0.96867f, 0.96893f, - 0.96919f, 0.96945f, 0.96971f, 0.96996f, - 0.97022f, 0.97047f, 0.97073f, 0.97098f, - 0.97123f, 0.97149f, 0.97174f, 0.97199f, - 0.97223f, 0.97248f, 0.97273f, 0.97297f, - 0.97322f, 0.97346f, 0.97371f, 0.97395f, - 0.97419f, 0.97443f, 0.97467f, 0.97491f, - 0.97515f, 0.97539f, 0.97562f, 0.97586f, - 0.97609f, 0.97633f, 0.97656f, 0.97679f, - 0.97702f, 0.97725f, 0.97748f, 0.97771f, - 0.97794f, 0.97817f, 0.97839f, 0.97862f, - 0.97884f, 0.97907f, 0.97929f, 0.97951f, - 0.97973f, 0.97995f, 0.98017f, 0.98039f, - 0.98061f, 0.98082f, 0.98104f, 0.98125f, - 0.98147f, 0.98168f, 0.98189f, 0.98211f, - 0.98232f, 0.98253f, 0.98274f, 0.98295f, - 0.98315f, 0.98336f, 0.98357f, 0.98377f, - 0.98398f, 0.98418f, 0.98438f, 0.98458f, - 0.98478f, 0.98498f, 0.98518f, 0.98538f, - 0.98558f, 0.98578f, 0.98597f, 0.98617f, - 0.98636f, 0.98656f, 0.98675f, 0.98694f, - 0.98714f, 0.98733f, 0.98752f, 0.98771f, - 0.98789f, 0.98808f, 0.98827f, 0.98845f, - 0.98864f, 0.98882f, 0.98901f, 0.98919f, - 0.98937f, 0.98955f, 0.98973f, 0.98991f, - 0.99009f, 0.99027f, 0.99045f, 0.99063f, - 0.99080f, 0.99098f, 0.99115f, 0.99133f, - 0.99150f, 0.99167f, 0.99184f, 0.99201f, - 0.99218f, 0.99235f, 0.99252f, 0.99269f, - 0.99285f, 0.99302f, 0.99319f, 0.99335f, - 0.99351f, 0.99368f, 0.99384f, 0.99400f, - 0.99416f, 0.99432f, 0.99448f, 0.99464f, - 0.99480f, 0.99495f, 0.99511f, 0.99527f, - 0.99542f, 0.99558f, 0.99573f, 0.99588f, - 0.99603f, 0.99619f, 0.99634f, 0.99649f, - 0.99664f, 0.99678f, 0.99693f, 0.99708f, - 0.99722f, 0.99737f, 0.99751f, 0.99766f, - 0.99780f, 0.99794f, 0.99809f, 0.99823f, - 0.99837f, 0.99851f, 0.99865f, 0.99879f, - 0.99892f, 0.99906f, 0.99920f, 0.99933f, - 0.99947f, 0.99960f, 0.99974f, 0.99987f, - 1.00000f -}; +namespace +{ // This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here -static float sRGBGammaForward (const float x) + +DCPProfile::Matrix invert3x3(const DCPProfile::Matrix& a) { - if (x <= 0.0031308) { - return x * 12.92; - } else if (x > 1.0) { - return 1.0 + (x - 1.0) * (1.055 * (1.0 / 2.4)); // linear extension - } else { - return 1.055 * pow (x, 1.0 / 2.4) - 0.055; - } -} -static float sRGBGammaInverse (const float y) -{ - if (y <= 0.0031308 * 12.92) { - return y * (1.0 / 12.92); - } else if (y > 1.0) { - return 1.0 + (y - 1.0) / (1.055 * (1.0 / 2.4)); - } else { - return pow ((y + 0.055) * (1.0 / 1.055), 2.4); + const double res00 = a[1][1] * a[2][2] - a[2][1] * a[1][2]; + const double res10 = a[2][0] * a[1][2] - a[1][0] * a[2][2]; + const double res20 = a[1][0] * a[2][1] - a[2][0] * a[1][1]; + + const double det = a[0][0] * res00 + a[0][1] * res10 + a[0][2] * res20; + + if (std::fabs(det) < 1.0e-10) { + std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl; + return a; } + + DCPProfile::Matrix res; + + res[0][0] = res00 / det; + res[0][1] = (a[2][1] * a[0][2] - a[0][1] * a[2][2]) / det; + res[0][2] = (a[0][1] * a[1][2] - a[1][1] * a[0][2]) / det; + res[1][0] = res10 / det; + res[1][1] = (a[0][0] * a[2][2] - a[2][0] * a[0][2]) / det; + res[1][2] = (a[1][0] * a[0][2] - a[0][0] * a[1][2]) / det; + res[2][0] = res20 / det; + res[2][1] = (a[2][0] * a[0][1] - a[0][0] * a[2][1]) / det; + res[2][2] = (a[0][0] * a[1][1] - a[1][0] * a[0][1]) / det; + + return res; } -static void Invert3x3(const double (*A)[3], double (*B)[3]) +DCPProfile::Matrix multiply3x3(const DCPProfile::Matrix& a, const DCPProfile::Matrix& b) { + DCPProfile::Matrix res; - double a00 = A[0][0]; - double a01 = A[0][1]; - double a02 = A[0][2]; - double a10 = A[1][0]; - double a11 = A[1][1]; - double a12 = A[1][2]; - double a20 = A[2][0]; - double a21 = A[2][1]; - double a22 = A[2][2]; - double temp [3][3]; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + res[i][j] = 0; - temp[0][0] = a11 * a22 - a21 * a12; - temp[0][1] = a21 * a02 - a01 * a22; - temp[0][2] = a01 * a12 - a11 * a02; - temp[1][0] = a20 * a12 - a10 * a22; - temp[1][1] = a00 * a22 - a20 * a02; - temp[1][2] = a10 * a02 - a00 * a12; - temp[2][0] = a10 * a21 - a20 * a11; - temp[2][1] = a20 * a01 - a00 * a21; - temp[2][2] = a00 * a11 - a10 * a01; - - double det = a00 * temp[0][0] + a01 * temp[1][0] + a02 * temp[2][0]; - - if (fabs(det) < 1.0E-10) { - abort(); // can't be inverted, we shouldn't be dealing with such matrices - } - - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 3; k++) { - B[j][k] = temp[j][k] / det; - } - } -} - -static void Multiply3x3(const double (*A)[3], const double (*B)[3], double (*C)[3]) -{ - - // use temp to support having output same as input - double M[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - M[i][j] = 0; - - for (int k = 0; k < 3; k++) { - M[i][j] += A[i][k] * B[k][j]; + for (int k = 0; k < 3; ++k) { + res[i][j] += a[i][k] * b[k][j]; } } } - memcpy(C, M, 3 * 3 * sizeof(double)); + return res; } -static void Multiply3x3_v3(const double (*A)[3], const double B[3], double C[3]) +DCPProfile::Triple multiply3x3_v3(const DCPProfile::Matrix& a, const DCPProfile::Triple& b) { + DCPProfile::Triple res = {}; - // use temp to support having output same as input - double M[3] = { 0, 0, 0 }; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - M[i] += A[i][j] * B[j]; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + res[i] += a[i][j] * b[j]; } } - memcpy(C, M, 3 * sizeof(double)); + return res; } -static void Mix3x3(const double (*A)[3], double mulA, const double (*B)[3], double mulB, double (*C)[3]) +DCPProfile::Matrix mix3x3(const DCPProfile::Matrix& a, double mul_a, const DCPProfile::Matrix& b, double mul_b) { + DCPProfile::Matrix res; - double M[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - M[i][j] = A[i][j] * mulA + B[i][j] * mulB; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + res[i][j] = a[i][j] * mul_a + b[i][j] * mul_b; } } - memcpy(C, M, 3 * 3 * sizeof(double)); + return res; } -static void MapWhiteMatrix(const double white1[3], const double white2[3], double (*B)[3]) +DCPProfile::Matrix mapWhiteMatrix(const DCPProfile::Triple& white1, const DCPProfile::Triple& white2) { + // Code adapted from dng_color_spec::MapWhiteMatrix - // code adapted from dng_color_spec::MapWhiteMatrix + // Use the linearized Bradford adaptation matrix + const DCPProfile::Matrix mb = { + { + { 0.8951, 0.2664, -0.1614 }, + { -0.7502, 1.7135, 0.0367 }, + { 0.0389, -0.0685, 1.0296 } + } + }; - // Use the linearized Bradford adaptation matrix. - double Mb[3][3] = { { 0.8951, 0.2664, -0.1614 }, { -0.7502, 1.7135, 0.0367 }, { 0.0389, -0.0685, 1.0296 }}; - - double w1[3]; - Multiply3x3_v3(Mb, white1, w1); - double w2[3]; - Multiply3x3_v3(Mb, white2, w2); + DCPProfile::Triple w1 = multiply3x3_v3(mb, white1); + DCPProfile::Triple w2 = multiply3x3_v3(mb, white2); // Negative white coordinates are kind of meaningless. w1[0] = std::max(w1[0], 0.0); @@ -418,163 +131,1201 @@ static void MapWhiteMatrix(const double white1[3], const double white2[3], doubl w2[2] = std::max(w2[2], 0.0); // Limit scaling to something reasonable. - double A[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - A[0][0] = std::max(0.1, std::min(w1[0] > 0.0 ? w2[0] / w1[0] : 10.0, 10.0)); - A[1][1] = std::max(0.1, std::min(w1[1] > 0.0 ? w2[1] / w1[1] : 10.0, 10.0)); - A[2][2] = std::max(0.1, std::min(w1[2] > 0.0 ? w2[2] / w1[2] : 10.0, 10.0)); + DCPProfile::Matrix a = {}; + a[0][0] = std::max(0.1, std::min(w1[0] > 0.0 ? w2[0] / w1[0] : 10.0, 10.0)); + a[1][1] = std::max(0.1, std::min(w1[1] > 0.0 ? w2[1] / w1[1] : 10.0, 10.0)); + a[2][2] = std::max(0.1, std::min(w1[2] > 0.0 ? w2[2] / w1[2] : 10.0, 10.0)); - double temp[3][3]; - Invert3x3(Mb, temp); - Multiply3x3(temp, A, temp); - Multiply3x3(temp, Mb, B); + return multiply3x3(multiply3x3(invert3x3(mb), a), mb); } -static void XYZtoXY(const double XYZ[3], double XY[2]) +std::array xyzToXy(const DCPProfile::Triple& xyz) { - double X = XYZ[0]; - double Y = XYZ[1]; - double Z = XYZ[2]; - double total = X + Y + Z; + const double total = xyz[0] + xyz[1] + xyz[2]; - if (total > 0.0) { - XY[0] = X / total; - XY[1] = Y / total; - } else { - XY[0] = 0.3457; - XY[1] = 0.3585; - } + return + total > 0.0 + ? std::array{ + xyz[0] / total, + xyz[1] / total + } + : std::array{ + 0.3457, + 0.3585 + }; } -static void XYtoXYZ(const double XY[2], double XYZ[3]) +DCPProfile::Triple xyToXyz(std::array xy) { - double temp[2] = { XY[0], XY[1] }; // Restrict xy coord to someplace inside the range of real xy coordinates. // This prevents math from doing strange things when users specify // extreme temperature/tint coordinates. - temp[0] = std::max(0.000001, std::min(temp[0], 0.999999)); - temp[1] = std::max(0.000001, std::min(temp[1], 0.999999)); + xy[0] = std::max(0.000001, std::min(xy[0], 0.999999)); + xy[1] = std::max(0.000001, std::min(xy[1], 0.999999)); - if (temp[0] + temp[1] > 0.999999) { - double scale = 0.999999 / (temp[0] + temp[1]); - temp[0] *= scale; - temp[1] *= scale; + const double sum = xy[0] + xy[1]; + + if (sum > 0.999999) { + const double scale = 0.999999 / sum; + xy[0] *= scale; + xy[1] *= scale; } - XYZ[0] = temp[0] / temp[1]; - XYZ[1] = 1.0; - XYZ[2] = (1.0 - temp[0] - temp[1]) / temp[1]; + return { + xy[0] / xy[1], + 1.0, + (1.0 - xy[0] - xy[1]) / xy[1] + }; } -enum dngCalibrationIlluminant { - lsUnknown = 0, - lsDaylight = 1, - lsFluorescent = 2, - lsTungsten = 3, - lsFlash = 4, - lsFineWeather = 9, - lsCloudyWeather = 10, - lsShade = 11, - lsDaylightFluorescent = 12, // D 5700 - 7100K - lsDayWhiteFluorescent = 13, // N 4600 - 5500K - lsCoolWhiteFluorescent = 14, // W 3800 - 4500K - lsWhiteFluorescent = 15, // WW 3250 - 3800K - lsWarmWhiteFluorescent = 16, // L 2600 - 3250K - lsStandardLightA = 17, - lsStandardLightB = 18, - lsStandardLightC = 19, - lsD55 = 20, - lsD65 = 21, - lsD75 = 22, - lsD50 = 23, - lsISOStudioTungsten = 24, - lsOther = 255 +double calibrationIlluminantToTemperature(int light) +{ + enum class LightSource { + UNKNOWN = 0, + DAYLIGHT = 1, + FLUORESCENT = 2, + TUNGSTEN = 3, + FLASH = 4, + FINE_WEATHER = 9, + CLOUDY_WEATHER = 10, + SHADE = 11, + DAYLIGHT_FLUORESCENT = 12, // D 5700 - 7100K + DAYWHITE_FLUORESCENT = 13, // N 4600 - 5500K + COOL_WHITE_FLUORESCENT = 14, // W 3800 - 4500K + WHITE_FLUORESCENT = 15, // WW 3250 - 3800K + WARM_WHITE_FLUORESCENT = 16, // L 2600 - 3250K + STANDARD_LIGHT_A = 17, + STANDARD_LIGHT_B = 18, + STANDARD_LIGHT_C = 19, + D55 = 20, + D65 = 21, + D75 = 22, + D50 = 23, + ISO_STUDIO_TUNGSTEN = 24, + OTHER = 255 + }; + + // These temperatures are those found in DNG SDK reference code + switch (LightSource(light)) { + case LightSource::STANDARD_LIGHT_A: + case LightSource::TUNGSTEN: { + return 2850.0; + } + + case LightSource::ISO_STUDIO_TUNGSTEN: { + return 3200.0; + } + + case LightSource::D50: { + return 5000.0; + } + + case LightSource::D55: + case LightSource::DAYLIGHT: + case LightSource::FINE_WEATHER: + case LightSource::FLASH: + case LightSource::STANDARD_LIGHT_B: { + return 5500.0; + } + + case LightSource::D65: + case LightSource::STANDARD_LIGHT_C: + case LightSource::CLOUDY_WEATHER: { + return 6500.0; + } + + case LightSource::D75: + case LightSource::SHADE: { + return 7500.0; + } + + case LightSource::DAYLIGHT_FLUORESCENT: { + return (5700.0 + 7100.0) * 0.5; + } + + case LightSource::DAYWHITE_FLUORESCENT: { + return (4600.0 + 5500.0) * 0.5; + } + + case LightSource::COOL_WHITE_FLUORESCENT: + case LightSource::FLUORESCENT: { + return (3800.0 + 4500.0) * 0.5; + } + + case LightSource::WHITE_FLUORESCENT: { + return (3250.0 + 3800.0) * 0.5; + } + + case LightSource::WARM_WHITE_FLUORESCENT: { + return (2600.0 + 3250.0) * 0.5; + } + + default: { + return 0.0; + } + } +} + +double xyCoordToTemperature(const std::array& white_xy) +{ + struct Ruvt { + double r; + double u; + double v; + double t; + }; + + static const Ruvt temp_table[] = { + { 0, 0.18006, 0.26352, -0.24341 }, + { 10, 0.18066, 0.26589, -0.25479 }, + { 20, 0.18133, 0.26846, -0.26876 }, + { 30, 0.18208, 0.27119, -0.28539 }, + { 40, 0.18293, 0.27407, -0.30470 }, + { 50, 0.18388, 0.27709, -0.32675 }, + { 60, 0.18494, 0.28021, -0.35156 }, + { 70, 0.18611, 0.28342, -0.37915 }, + { 80, 0.18740, 0.28668, -0.40955 }, + { 90, 0.18880, 0.28997, -0.44278 }, + { 100, 0.19032, 0.29326, -0.47888 }, + { 125, 0.19462, 0.30141, -0.58204 }, + { 150, 0.19962, 0.30921, -0.70471 }, + { 175, 0.20525, 0.31647, -0.84901 }, + { 200, 0.21142, 0.32312, -1.0182 }, + { 225, 0.21807, 0.32909, -1.2168 }, + { 250, 0.22511, 0.33439, -1.4512 }, + { 275, 0.23247, 0.33904, -1.7298 }, + { 300, 0.24010, 0.34308, -2.0637 }, + { 325, 0.24702, 0.34655, -2.4681 }, + { 350, 0.25591, 0.34951, -2.9641 }, + { 375, 0.26400, 0.35200, -3.5814 }, + { 400, 0.27218, 0.35407, -4.3633 }, + { 425, 0.28039, 0.35577, -5.3762 }, + { 450, 0.28863, 0.35714, -6.7262 }, + { 475, 0.29685, 0.35823, -8.5955 }, + { 500, 0.30505, 0.35907, -11.324 }, + { 525, 0.31320, 0.35968, -15.628 }, + { 550, 0.32129, 0.36011, -23.325 }, + { 575, 0.32931, 0.36038, -40.770 }, + { 600, 0.33724, 0.36051, -116.45 } + }; + + constexpr double tint_scale = -3000.0; + + double res = 0; + + // Convert to uv space. + double u = 2.0 * white_xy[0] / (1.5 - white_xy[0] + 6.0 * white_xy[1]); + double v = 3.0 * white_xy[1] / (1.5 - white_xy[0] + 6.0 * white_xy[1]); + + // Search for line pair coordinate is between. + double last_dt = 0.0; + double last_dv = 0.0; + double last_du = 0.0; + + for (uint32_t index = 1; index <= 30; ++index) { + // Convert slope to delta-u and delta-v, with length 1. + double du = 1.0; + double dv = temp_table[index].t; + double len = sqrt(1.0 + dv * dv); + du /= len; + dv /= len; + + // Find delta from black body point to test coordinate. + double uu = u - temp_table[index].u; + double vv = v - temp_table[index].v; + + // Find distance above or below line. + double dt = -uu * dv + vv * du; + + // If below line, we have found line pair. + if (dt <= 0.0 || index == 30) { + // Find fractional weight of two lines. + if (dt > 0.0) { + dt = 0.0; + } + + dt = -dt; + + double f; + + if (index == 1) { + f = 0.0; + } else { + f = dt / (last_dt + dt); + } + + // Interpolate the temperature. + res = 1.0e6 / (temp_table[index - 1].r * f + temp_table[index].r * (1.0 - f)); + + // Find delta from black body point to test coordinate. + uu = u - (temp_table [index - 1].u * f + temp_table [index].u * (1.0 - f)); + vv = v - (temp_table [index - 1].v * f + temp_table [index].v * (1.0 - f)); + // Interpolate vectors along slope. + du = du * (1.0 - f) + last_du * f; + dv = dv * (1.0 - f) + last_dv * f; + len = sqrt (du * du + dv * dv); + du /= len; + dv /= len; + break; + } + + // Try next line pair. + last_dt = dt; + last_du = du; + last_dv = dv; + } + + return res; +} + +} + +struct DCPProfile::ApplyState::Data { + float pro_photo[3][3]; + float work[3][3]; + bool already_pro_photo; + bool use_tone_curve; + bool apply_look_table; + float bl_scale; }; -// should probably be moved to colortemp.cc -static double calibrationIlluminantToTemperature(int light) +DCPProfile::ApplyState::ApplyState() : + data(new Data{}) { +} - // these temperatures are those found in DNG SDK reference code. - switch (light) { - case lsStandardLightA: - case lsTungsten: - return 2850.0; +DCPProfile::ApplyState::~ApplyState() +{ +} - case lsISOStudioTungsten: - return 3200.0; +DCPProfile::DCPProfile(const Glib::ustring& filename) : + has_color_matrix_1(false), + has_color_matrix_2(false), + has_forward_matrix_1(false), + has_forward_matrix_2(false), + has_tone_curve(false), + has_baseline_exposure_offset(false), + will_interpolate(false), + baseline_exposure_offset(0.0) +{ + constexpr int tiff_float_size = 4; - case lsD50: - return 5000.0; + enum class TagKey : int { + COLOR_MATRIX_1 = 50721, + COLOR_MATRIX_2 = 50722, + PROFILE_HUE_SAT_MAP_DIMS = 50937, + PROFILE_HUE_SAT_MAP_DATA_1 = 50938, + PROFILE_HUE_SAT_MAP_DATA_2 = 50939, + PROFILE_TONE_CURVE = 50940, + PROFILE_TONE_COPYRIGHT = 50942, + CALIBRATION_ILLUMINANT_1 = 50778, + CALIBRATION_ILLUMINANT_2 = 50779, + FORWARD_MATRIX_1 = 50964, + FORWARD_MATRIX_2 = 50965, + PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant + PROFILE_LOOK_TABLE_DATA = 50982, + PROFILE_HUE_SAT_MAP_ENCODING = 51107, + PROFILE_LOOK_TABLE_ENCODING = 51108, + BASELINE_EXPOSURE_OFFSET = 51109 + }; - case lsD55: - case lsDaylight: - case lsFineWeather: - case lsFlash: - case lsStandardLightB: - return 5500.0; + static const float adobe_camera_raw_default_curve[] = { + 0.00000f, 0.00078f, 0.00160f, 0.00242f, + 0.00314f, 0.00385f, 0.00460f, 0.00539f, + 0.00623f, 0.00712f, 0.00806f, 0.00906f, + 0.01012f, 0.01122f, 0.01238f, 0.01359f, + 0.01485f, 0.01616f, 0.01751f, 0.01890f, + 0.02033f, 0.02180f, 0.02331f, 0.02485f, + 0.02643f, 0.02804f, 0.02967f, 0.03134f, + 0.03303f, 0.03475f, 0.03648f, 0.03824f, + 0.04002f, 0.04181f, 0.04362f, 0.04545f, + 0.04730f, 0.04916f, 0.05103f, 0.05292f, + 0.05483f, 0.05675f, 0.05868f, 0.06063f, + 0.06259f, 0.06457f, 0.06655f, 0.06856f, + 0.07057f, 0.07259f, 0.07463f, 0.07668f, + 0.07874f, 0.08081f, 0.08290f, 0.08499f, + 0.08710f, 0.08921f, 0.09134f, 0.09348f, + 0.09563f, 0.09779f, 0.09996f, 0.10214f, + 0.10433f, 0.10652f, 0.10873f, 0.11095f, + 0.11318f, 0.11541f, 0.11766f, 0.11991f, + 0.12218f, 0.12445f, 0.12673f, 0.12902f, + 0.13132f, 0.13363f, 0.13595f, 0.13827f, + 0.14061f, 0.14295f, 0.14530f, 0.14765f, + 0.15002f, 0.15239f, 0.15477f, 0.15716f, + 0.15956f, 0.16197f, 0.16438f, 0.16680f, + 0.16923f, 0.17166f, 0.17410f, 0.17655f, + 0.17901f, 0.18148f, 0.18395f, 0.18643f, + 0.18891f, 0.19141f, 0.19391f, 0.19641f, + 0.19893f, 0.20145f, 0.20398f, 0.20651f, + 0.20905f, 0.21160f, 0.21416f, 0.21672f, + 0.21929f, 0.22185f, 0.22440f, 0.22696f, + 0.22950f, 0.23204f, 0.23458f, 0.23711f, + 0.23963f, 0.24215f, 0.24466f, 0.24717f, + 0.24967f, 0.25216f, 0.25465f, 0.25713f, + 0.25961f, 0.26208f, 0.26454f, 0.26700f, + 0.26945f, 0.27189f, 0.27433f, 0.27676f, + 0.27918f, 0.28160f, 0.28401f, 0.28641f, + 0.28881f, 0.29120f, 0.29358f, 0.29596f, + 0.29833f, 0.30069f, 0.30305f, 0.30540f, + 0.30774f, 0.31008f, 0.31241f, 0.31473f, + 0.31704f, 0.31935f, 0.32165f, 0.32395f, + 0.32623f, 0.32851f, 0.33079f, 0.33305f, + 0.33531f, 0.33756f, 0.33981f, 0.34205f, + 0.34428f, 0.34650f, 0.34872f, 0.35093f, + 0.35313f, 0.35532f, 0.35751f, 0.35969f, + 0.36187f, 0.36404f, 0.36620f, 0.36835f, + 0.37050f, 0.37264f, 0.37477f, 0.37689f, + 0.37901f, 0.38112f, 0.38323f, 0.38533f, + 0.38742f, 0.38950f, 0.39158f, 0.39365f, + 0.39571f, 0.39777f, 0.39982f, 0.40186f, + 0.40389f, 0.40592f, 0.40794f, 0.40996f, + 0.41197f, 0.41397f, 0.41596f, 0.41795f, + 0.41993f, 0.42191f, 0.42388f, 0.42584f, + 0.42779f, 0.42974f, 0.43168f, 0.43362f, + 0.43554f, 0.43747f, 0.43938f, 0.44129f, + 0.44319f, 0.44509f, 0.44698f, 0.44886f, + 0.45073f, 0.45260f, 0.45447f, 0.45632f, + 0.45817f, 0.46002f, 0.46186f, 0.46369f, + 0.46551f, 0.46733f, 0.46914f, 0.47095f, + 0.47275f, 0.47454f, 0.47633f, 0.47811f, + 0.47989f, 0.48166f, 0.48342f, 0.48518f, + 0.48693f, 0.48867f, 0.49041f, 0.49214f, + 0.49387f, 0.49559f, 0.49730f, 0.49901f, + 0.50072f, 0.50241f, 0.50410f, 0.50579f, + 0.50747f, 0.50914f, 0.51081f, 0.51247f, + 0.51413f, 0.51578f, 0.51742f, 0.51906f, + 0.52069f, 0.52232f, 0.52394f, 0.52556f, + 0.52717f, 0.52878f, 0.53038f, 0.53197f, + 0.53356f, 0.53514f, 0.53672f, 0.53829f, + 0.53986f, 0.54142f, 0.54297f, 0.54452f, + 0.54607f, 0.54761f, 0.54914f, 0.55067f, + 0.55220f, 0.55371f, 0.55523f, 0.55673f, + 0.55824f, 0.55973f, 0.56123f, 0.56271f, + 0.56420f, 0.56567f, 0.56715f, 0.56861f, + 0.57007f, 0.57153f, 0.57298f, 0.57443f, + 0.57587f, 0.57731f, 0.57874f, 0.58017f, + 0.58159f, 0.58301f, 0.58443f, 0.58583f, + 0.58724f, 0.58864f, 0.59003f, 0.59142f, + 0.59281f, 0.59419f, 0.59556f, 0.59694f, + 0.59830f, 0.59966f, 0.60102f, 0.60238f, + 0.60373f, 0.60507f, 0.60641f, 0.60775f, + 0.60908f, 0.61040f, 0.61173f, 0.61305f, + 0.61436f, 0.61567f, 0.61698f, 0.61828f, + 0.61957f, 0.62087f, 0.62216f, 0.62344f, + 0.62472f, 0.62600f, 0.62727f, 0.62854f, + 0.62980f, 0.63106f, 0.63232f, 0.63357f, + 0.63482f, 0.63606f, 0.63730f, 0.63854f, + 0.63977f, 0.64100f, 0.64222f, 0.64344f, + 0.64466f, 0.64587f, 0.64708f, 0.64829f, + 0.64949f, 0.65069f, 0.65188f, 0.65307f, + 0.65426f, 0.65544f, 0.65662f, 0.65779f, + 0.65897f, 0.66013f, 0.66130f, 0.66246f, + 0.66362f, 0.66477f, 0.66592f, 0.66707f, + 0.66821f, 0.66935f, 0.67048f, 0.67162f, + 0.67275f, 0.67387f, 0.67499f, 0.67611f, + 0.67723f, 0.67834f, 0.67945f, 0.68055f, + 0.68165f, 0.68275f, 0.68385f, 0.68494f, + 0.68603f, 0.68711f, 0.68819f, 0.68927f, + 0.69035f, 0.69142f, 0.69249f, 0.69355f, + 0.69461f, 0.69567f, 0.69673f, 0.69778f, + 0.69883f, 0.69988f, 0.70092f, 0.70196f, + 0.70300f, 0.70403f, 0.70506f, 0.70609f, + 0.70711f, 0.70813f, 0.70915f, 0.71017f, + 0.71118f, 0.71219f, 0.71319f, 0.71420f, + 0.71520f, 0.71620f, 0.71719f, 0.71818f, + 0.71917f, 0.72016f, 0.72114f, 0.72212f, + 0.72309f, 0.72407f, 0.72504f, 0.72601f, + 0.72697f, 0.72794f, 0.72890f, 0.72985f, + 0.73081f, 0.73176f, 0.73271f, 0.73365f, + 0.73460f, 0.73554f, 0.73647f, 0.73741f, + 0.73834f, 0.73927f, 0.74020f, 0.74112f, + 0.74204f, 0.74296f, 0.74388f, 0.74479f, + 0.74570f, 0.74661f, 0.74751f, 0.74842f, + 0.74932f, 0.75021f, 0.75111f, 0.75200f, + 0.75289f, 0.75378f, 0.75466f, 0.75555f, + 0.75643f, 0.75730f, 0.75818f, 0.75905f, + 0.75992f, 0.76079f, 0.76165f, 0.76251f, + 0.76337f, 0.76423f, 0.76508f, 0.76594f, + 0.76679f, 0.76763f, 0.76848f, 0.76932f, + 0.77016f, 0.77100f, 0.77183f, 0.77267f, + 0.77350f, 0.77432f, 0.77515f, 0.77597f, + 0.77680f, 0.77761f, 0.77843f, 0.77924f, + 0.78006f, 0.78087f, 0.78167f, 0.78248f, + 0.78328f, 0.78408f, 0.78488f, 0.78568f, + 0.78647f, 0.78726f, 0.78805f, 0.78884f, + 0.78962f, 0.79040f, 0.79118f, 0.79196f, + 0.79274f, 0.79351f, 0.79428f, 0.79505f, + 0.79582f, 0.79658f, 0.79735f, 0.79811f, + 0.79887f, 0.79962f, 0.80038f, 0.80113f, + 0.80188f, 0.80263f, 0.80337f, 0.80412f, + 0.80486f, 0.80560f, 0.80634f, 0.80707f, + 0.80780f, 0.80854f, 0.80926f, 0.80999f, + 0.81072f, 0.81144f, 0.81216f, 0.81288f, + 0.81360f, 0.81431f, 0.81503f, 0.81574f, + 0.81645f, 0.81715f, 0.81786f, 0.81856f, + 0.81926f, 0.81996f, 0.82066f, 0.82135f, + 0.82205f, 0.82274f, 0.82343f, 0.82412f, + 0.82480f, 0.82549f, 0.82617f, 0.82685f, + 0.82753f, 0.82820f, 0.82888f, 0.82955f, + 0.83022f, 0.83089f, 0.83155f, 0.83222f, + 0.83288f, 0.83354f, 0.83420f, 0.83486f, + 0.83552f, 0.83617f, 0.83682f, 0.83747f, + 0.83812f, 0.83877f, 0.83941f, 0.84005f, + 0.84069f, 0.84133f, 0.84197f, 0.84261f, + 0.84324f, 0.84387f, 0.84450f, 0.84513f, + 0.84576f, 0.84639f, 0.84701f, 0.84763f, + 0.84825f, 0.84887f, 0.84949f, 0.85010f, + 0.85071f, 0.85132f, 0.85193f, 0.85254f, + 0.85315f, 0.85375f, 0.85436f, 0.85496f, + 0.85556f, 0.85615f, 0.85675f, 0.85735f, + 0.85794f, 0.85853f, 0.85912f, 0.85971f, + 0.86029f, 0.86088f, 0.86146f, 0.86204f, + 0.86262f, 0.86320f, 0.86378f, 0.86435f, + 0.86493f, 0.86550f, 0.86607f, 0.86664f, + 0.86720f, 0.86777f, 0.86833f, 0.86889f, + 0.86945f, 0.87001f, 0.87057f, 0.87113f, + 0.87168f, 0.87223f, 0.87278f, 0.87333f, + 0.87388f, 0.87443f, 0.87497f, 0.87552f, + 0.87606f, 0.87660f, 0.87714f, 0.87768f, + 0.87821f, 0.87875f, 0.87928f, 0.87981f, + 0.88034f, 0.88087f, 0.88140f, 0.88192f, + 0.88244f, 0.88297f, 0.88349f, 0.88401f, + 0.88453f, 0.88504f, 0.88556f, 0.88607f, + 0.88658f, 0.88709f, 0.88760f, 0.88811f, + 0.88862f, 0.88912f, 0.88963f, 0.89013f, + 0.89063f, 0.89113f, 0.89163f, 0.89212f, + 0.89262f, 0.89311f, 0.89360f, 0.89409f, + 0.89458f, 0.89507f, 0.89556f, 0.89604f, + 0.89653f, 0.89701f, 0.89749f, 0.89797f, + 0.89845f, 0.89892f, 0.89940f, 0.89987f, + 0.90035f, 0.90082f, 0.90129f, 0.90176f, + 0.90222f, 0.90269f, 0.90316f, 0.90362f, + 0.90408f, 0.90454f, 0.90500f, 0.90546f, + 0.90592f, 0.90637f, 0.90683f, 0.90728f, + 0.90773f, 0.90818f, 0.90863f, 0.90908f, + 0.90952f, 0.90997f, 0.91041f, 0.91085f, + 0.91130f, 0.91173f, 0.91217f, 0.91261f, + 0.91305f, 0.91348f, 0.91392f, 0.91435f, + 0.91478f, 0.91521f, 0.91564f, 0.91606f, + 0.91649f, 0.91691f, 0.91734f, 0.91776f, + 0.91818f, 0.91860f, 0.91902f, 0.91944f, + 0.91985f, 0.92027f, 0.92068f, 0.92109f, + 0.92150f, 0.92191f, 0.92232f, 0.92273f, + 0.92314f, 0.92354f, 0.92395f, 0.92435f, + 0.92475f, 0.92515f, 0.92555f, 0.92595f, + 0.92634f, 0.92674f, 0.92713f, 0.92753f, + 0.92792f, 0.92831f, 0.92870f, 0.92909f, + 0.92947f, 0.92986f, 0.93025f, 0.93063f, + 0.93101f, 0.93139f, 0.93177f, 0.93215f, + 0.93253f, 0.93291f, 0.93328f, 0.93366f, + 0.93403f, 0.93440f, 0.93478f, 0.93515f, + 0.93551f, 0.93588f, 0.93625f, 0.93661f, + 0.93698f, 0.93734f, 0.93770f, 0.93807f, + 0.93843f, 0.93878f, 0.93914f, 0.93950f, + 0.93986f, 0.94021f, 0.94056f, 0.94092f, + 0.94127f, 0.94162f, 0.94197f, 0.94231f, + 0.94266f, 0.94301f, 0.94335f, 0.94369f, + 0.94404f, 0.94438f, 0.94472f, 0.94506f, + 0.94540f, 0.94573f, 0.94607f, 0.94641f, + 0.94674f, 0.94707f, 0.94740f, 0.94774f, + 0.94807f, 0.94839f, 0.94872f, 0.94905f, + 0.94937f, 0.94970f, 0.95002f, 0.95035f, + 0.95067f, 0.95099f, 0.95131f, 0.95163f, + 0.95194f, 0.95226f, 0.95257f, 0.95289f, + 0.95320f, 0.95351f, 0.95383f, 0.95414f, + 0.95445f, 0.95475f, 0.95506f, 0.95537f, + 0.95567f, 0.95598f, 0.95628f, 0.95658f, + 0.95688f, 0.95718f, 0.95748f, 0.95778f, + 0.95808f, 0.95838f, 0.95867f, 0.95897f, + 0.95926f, 0.95955f, 0.95984f, 0.96013f, + 0.96042f, 0.96071f, 0.96100f, 0.96129f, + 0.96157f, 0.96186f, 0.96214f, 0.96242f, + 0.96271f, 0.96299f, 0.96327f, 0.96355f, + 0.96382f, 0.96410f, 0.96438f, 0.96465f, + 0.96493f, 0.96520f, 0.96547f, 0.96574f, + 0.96602f, 0.96629f, 0.96655f, 0.96682f, + 0.96709f, 0.96735f, 0.96762f, 0.96788f, + 0.96815f, 0.96841f, 0.96867f, 0.96893f, + 0.96919f, 0.96945f, 0.96971f, 0.96996f, + 0.97022f, 0.97047f, 0.97073f, 0.97098f, + 0.97123f, 0.97149f, 0.97174f, 0.97199f, + 0.97223f, 0.97248f, 0.97273f, 0.97297f, + 0.97322f, 0.97346f, 0.97371f, 0.97395f, + 0.97419f, 0.97443f, 0.97467f, 0.97491f, + 0.97515f, 0.97539f, 0.97562f, 0.97586f, + 0.97609f, 0.97633f, 0.97656f, 0.97679f, + 0.97702f, 0.97725f, 0.97748f, 0.97771f, + 0.97794f, 0.97817f, 0.97839f, 0.97862f, + 0.97884f, 0.97907f, 0.97929f, 0.97951f, + 0.97973f, 0.97995f, 0.98017f, 0.98039f, + 0.98061f, 0.98082f, 0.98104f, 0.98125f, + 0.98147f, 0.98168f, 0.98189f, 0.98211f, + 0.98232f, 0.98253f, 0.98274f, 0.98295f, + 0.98315f, 0.98336f, 0.98357f, 0.98377f, + 0.98398f, 0.98418f, 0.98438f, 0.98458f, + 0.98478f, 0.98498f, 0.98518f, 0.98538f, + 0.98558f, 0.98578f, 0.98597f, 0.98617f, + 0.98636f, 0.98656f, 0.98675f, 0.98694f, + 0.98714f, 0.98733f, 0.98752f, 0.98771f, + 0.98789f, 0.98808f, 0.98827f, 0.98845f, + 0.98864f, 0.98882f, 0.98901f, 0.98919f, + 0.98937f, 0.98955f, 0.98973f, 0.98991f, + 0.99009f, 0.99027f, 0.99045f, 0.99063f, + 0.99080f, 0.99098f, 0.99115f, 0.99133f, + 0.99150f, 0.99167f, 0.99184f, 0.99201f, + 0.99218f, 0.99235f, 0.99252f, 0.99269f, + 0.99285f, 0.99302f, 0.99319f, 0.99335f, + 0.99351f, 0.99368f, 0.99384f, 0.99400f, + 0.99416f, 0.99432f, 0.99448f, 0.99464f, + 0.99480f, 0.99495f, 0.99511f, 0.99527f, + 0.99542f, 0.99558f, 0.99573f, 0.99588f, + 0.99603f, 0.99619f, 0.99634f, 0.99649f, + 0.99664f, 0.99678f, 0.99693f, 0.99708f, + 0.99722f, 0.99737f, 0.99751f, 0.99766f, + 0.99780f, 0.99794f, 0.99809f, 0.99823f, + 0.99837f, 0.99851f, 0.99865f, 0.99879f, + 0.99892f, 0.99906f, 0.99920f, 0.99933f, + 0.99947f, 0.99960f, 0.99974f, 0.99987f, + 1.00000f + }; - case lsD65: - case lsStandardLightC: - case lsCloudyWeather: - return 6500.0; + FILE* const file = g_fopen(filename.c_str(), "rb"); - case lsD75: - case lsShade: - return 7500.0; + std::unique_ptr tagDir(ExifManager::parseTIFF(file, false)); - case lsDaylightFluorescent: - return (5700.0 + 7100.0) * 0.5; + Tag* tag = tagDir->getTag(toUnderlying(TagKey::CALIBRATION_ILLUMINANT_1)); + light_source_1 = + tag + ? tag->toInt(0, rtexif::SHORT) + : -1; + tag = tagDir->getTag(toUnderlying(TagKey::CALIBRATION_ILLUMINANT_2)); + light_source_2 = + tag + ? tag->toInt(0, rtexif::SHORT) + : -1; + temperature_1 = calibrationIlluminantToTemperature(light_source_1); + temperature_2 = calibrationIlluminantToTemperature(light_source_2); - case lsDayWhiteFluorescent: - return (4600.0 + 5500.0) * 0.5; + const bool has_second_hue_sat = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_2)); // Some profiles have two matrices, but just one huesat - case lsCoolWhiteFluorescent: - case lsFluorescent: - return (3800.0 + 4500.0) * 0.5; + // Fetch Forward Matrices, if any + tag = tagDir->getTag(toUnderlying(TagKey::FORWARD_MATRIX_1)); - case lsWhiteFluorescent: - return (3250.0 + 3800.0) * 0.5; + if (tag) { + has_forward_matrix_1 = true; - case lsWarmWhiteFluorescent: - return (2600.0 + 3250.0) * 0.5; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + forward_matrix_1[row][col] = tag->toDouble((col + row * 3) * 8); + } + } + } - default: - return 0.0; + tag = tagDir->getTag(toUnderlying(TagKey::FORWARD_MATRIX_2)); + + if (tag) { + has_forward_matrix_2 = true; + + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + forward_matrix_2[row][col] = tag->toDouble((col + row * 3) * 8); + } + } + } + + // Color Matrix (one is always there) + tag = tagDir->getTag(toUnderlying(TagKey::COLOR_MATRIX_1)); + + if (!tag) { + std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; + return; + } + + has_color_matrix_1 = true; + + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + color_matrix_1[row][col] = tag->toDouble((col + row * 3) * 8); + } + } + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_DIMS)); + + if (tag) { + look_info.hue_divisions = tag->toInt(0); + look_info.sat_divisions = tag->toInt(4); + look_info.val_divisions = tag->toInt(8); + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_ENCODING)); + look_info.srgb_gamma = tag && tag->toInt(0); + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_DATA)); + look_info.array_count = tag->getCount() / 3; + + look_table.resize(look_info.array_count); + + for (unsigned int i = 0; i < look_info.array_count; i++) { + look_table[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); + look_table[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); + look_table[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + } + + // Precalculated constants for table application + look_info.pc.h_scale = + look_info.hue_divisions < 2 + ? 0.0f + : static_cast(look_info.hue_divisions) / 6.0f; + look_info.pc.s_scale = look_info.sat_divisions - 1; + look_info.pc.v_scale = look_info.val_divisions - 1; + look_info.pc.max_hue_index0 = look_info.hue_divisions - 1; + look_info.pc.max_sat_index0 = look_info.sat_divisions - 2; + look_info.pc.max_val_index0 = look_info.val_divisions - 2; + look_info.pc.hue_step = look_info.sat_divisions; + look_info.pc.val_step = look_info.hue_divisions * look_info.pc.hue_step; + } + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DIMS)); + + if (tag) { + delta_info.hue_divisions = tag->toInt(0); + delta_info.sat_divisions = tag->toInt(4); + delta_info.val_divisions = tag->toInt(8); + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_ENCODING)); + delta_info.srgb_gamma = tag && tag->toInt(0); + + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_1)); + delta_info.array_count = tag->getCount() / 3; + + deltas_1.resize(delta_info.array_count); + + for (unsigned int i = 0; i < delta_info.array_count; ++i) { + deltas_1[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); + deltas_1[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); + deltas_1[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + } + + delta_info.pc.h_scale = + delta_info.hue_divisions < 2 + ? 0.0f + : static_cast(delta_info.hue_divisions) / 6.0f; + delta_info.pc.s_scale = delta_info.sat_divisions - 1; + delta_info.pc.v_scale = delta_info.val_divisions - 1; + delta_info.pc.max_hue_index0 = delta_info.hue_divisions - 1; + delta_info.pc.max_sat_index0 = delta_info.sat_divisions - 2; + delta_info.pc.max_val_index0 = delta_info.val_divisions - 2; + delta_info.pc.hue_step = delta_info.sat_divisions; + delta_info.pc.val_step = delta_info.hue_divisions * delta_info.pc.hue_step; + } + + if (light_source_2 != -1) { + // Second matrix + has_color_matrix_2 = true; + + tag = tagDir->getTag(toUnderlying(TagKey::COLOR_MATRIX_2)); + + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + color_matrix_2[row][col] = + tag + ? tag->toDouble((col + row * 3) * 8) + : color_matrix_1[row][col]; + } + } + + // Second huesatmap + if (has_second_hue_sat) { + deltas_2.resize(delta_info.array_count); + + // Saturation maps. Need to be unwinded. + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_2)); + + for (int i = 0; i < delta_info.array_count; ++i) { + deltas_2[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); + deltas_2[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); + deltas_2[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + } + } + } + + tag = tagDir->getTag(toUnderlying(TagKey::BASELINE_EXPOSURE_OFFSET)); + + if (tag) { + has_baseline_exposure_offset = true; + baseline_exposure_offset = tag->toDouble(); + } + + // Read tone curve points, if any, but disable to RTs own profiles + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_TONE_CURVE)); + + if (tag) { + std::vector curve_points = { + static_cast(DCT_Spline) // The first value is the curve type + }; + + // Push back each X/Y coordinates in a loop + bool curve_is_linear = true; + + for (int i = 0; i < tag->getCount(); i += 2) { + const double x = tag->toDouble((i + 0) * tiff_float_size); + const double y = tag->toDouble((i + 1) * tiff_float_size); + + if (x != y) { + curve_is_linear = false; + } + + curve_points.push_back(x); + curve_points.push_back(y); + } + + if (!curve_is_linear) { + // Create the curve + has_tone_curve = true; + tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); + } + } else { + tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_TONE_COPYRIGHT)); + + if (tag && tag->valueToString().find("Adobe Systems") != std::string::npos) { + // An Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that + std::vector curve_points = { + static_cast(DCT_Spline) + }; + + constexpr size_t tc_len = sizeof(adobe_camera_raw_default_curve) / sizeof(adobe_camera_raw_default_curve[0]); + + for (size_t i = 0; i < tc_len; ++i) { + const double x = static_cast(i) / (tc_len - 1); + const double y = adobe_camera_raw_default_curve[i]; + curve_points.push_back(x); + curve_points.push_back(y); + } + + has_tone_curve = true; + tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); + } + } + + will_interpolate = false; + + if (has_forward_matrix_1) { + if (has_forward_matrix_2) { + if (forward_matrix_1 != forward_matrix_2) { + // Common that forward matrices are the same! + will_interpolate = true; + } + + if (!deltas_1.empty() && !deltas_2.empty()) { + // We assume tables are different + will_interpolate = true; + } + } + } + + if (has_color_matrix_1 && has_color_matrix_2) { + if (color_matrix_1 != color_matrix_2) { + will_interpolate = true; + } + + if (!deltas_1.empty() && !deltas_2.empty()) { + will_interpolate = true; + } + } + + if (file) { + fclose(file); } } -void DCPProfile::MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], int preferredIlluminant, double (*mXYZCAM)[3]) const -{ - // code adapted from dng_color_spec::FindXYZtoCamera - // note that we do not support monochrome or colorplanes > 3 (no reductionMatrix support) - // we do not support cameracalibration either - double neutral[3]; // same as the DNG "AsShotNeutral" tag if white balance is Camera's own +DCPProfile::~DCPProfile() +{ +} + +DCPProfile::operator bool() const +{ + return has_color_matrix_1; +} + +bool DCPProfile::getHasToneCurve() const +{ + return has_tone_curve; +} + +bool DCPProfile::getHasLookTable() const +{ + return !look_table.empty(); +} + +bool DCPProfile::getHasHueSatMap() const +{ + return !deltas_1.empty(); +} + +bool DCPProfile::getHasBaselineExposureOffset() const +{ + return has_baseline_exposure_offset; +} + +DCPProfile::Illuminants DCPProfile::getIlluminants() const +{ + return { + light_source_1, + light_source_2, + temperature_1, + temperature_2, + will_interpolate + }; +} + +void DCPProfile::apply( + Imagefloat* img, + int preferred_illuminant, + const Glib::ustring& working_space, + const ColorTemp& white_balance, + const Triple& pre_mul, + const Matrix& cam_wb_matrix, + bool apply_hue_sat_map +) const +{ + + const TMatrix work_matrix = iccStore->workingSpaceInverseMatrix(working_space); + + const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant); // Camera RGB to XYZ D50 matrix + + const std::vector delta_base = makeHueSatMap(white_balance, preferred_illuminant); + + if (delta_base.empty()) { + apply_hue_sat_map = false; + } + + if (!apply_hue_sat_map) { + // The fast path: No LUT --> Calculate matrix for direct conversion raw -> working space + float mat[3][3] = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + for (int k = 0; k < 3; ++k) { + mat[i][j] += work_matrix[i][k] * xyz_cam[k][j]; + } + } + } + + // Apply the matrix part +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int y = 0; y < img->height; ++y) { + for (int x = 0; x < img->width; x++) { + const float& newr = mat[0][0] * img->r(y, x) + mat[0][1] * img->g(y, x) + mat[0][2] * img->b(y, x); + const float& newg = mat[1][0] * img->r(y, x) + mat[1][1] * img->g(y, x) + mat[1][2] * img->b(y, x); + const float& newb = mat[2][0] * img->r(y, x) + mat[2][1] * img->g(y, x) + mat[2][2] * img->b(y, x); + + img->r(y, x) = newr; + img->g(y, x) = newg; + img->b(y, x) = newb; + } + } + } else { + // LUT available --> Calculate matrix for conversion raw>ProPhoto + float pro_photo[3][3] = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + for (int k = 0; k < 3; ++k) { + pro_photo[i][j] += prophoto_xyz[i][k] * xyz_cam[k][j]; + } + } + } + + float work[3][3] = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + for (int k = 0; k < 3; ++k) { + work[i][j] += work_matrix[i][k] * xyz_prophoto[k][j]; + } + } + } + + // Convert to ProPhoto and apply LUT +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < img->height; ++y) { + for (int x = 0; x < img->width; x++) { + float newr = pro_photo[0][0] * img->r(y, x) + pro_photo[0][1] * img->g(y, x) + pro_photo[0][2] * img->b(y, x); + float newg = pro_photo[1][0] * img->r(y, x) + pro_photo[1][1] * img->g(y, x) + pro_photo[1][2] * img->b(y, x); + float newb = pro_photo[2][0] * img->r(y, x) + pro_photo[2][1] * img->g(y, x) + pro_photo[2][2] * img->b(y, x); + + // If point is in negative area, just the matrix, but not the LUT. This is checked inside Color::rgb2hsvdcp + float h; + float s; + float v; + + if(Color::rgb2hsvdcp(newr, newg, newb, h , s, v)) { + + hsdApply(delta_info, delta_base, h, s, v); + + // RT range correction + if (h < 0.0f) { + h += 6.0f; + } else if (h >= 6.0f) { + h -= 6.0f; + } + + Color::hsv2rgbdcp(h, s, v, newr, newg, newb); + } + + img->r(y, x) = work[0][0] * newr + work[0][1] * newg + work[0][2] * newb; + img->g(y, x) = work[1][0] * newr + work[1][1] * newg + work[1][2] * newb; + img->b(y, x) = work[2][0] * newr + work[2][1] * newg + work[2][2] * newb; + } + } + } +} + +void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out) +{ + as_out.data->use_tone_curve = use_tone_curve; + as_out.data->apply_look_table = apply_look_table; + as_out.data->bl_scale = 1.0; + + if (look_table.empty()) { + as_out.data->apply_look_table = false; + } + + if (!has_tone_curve) { + as_out.data->use_tone_curve = false; + } + + if (has_baseline_exposure_offset && apply_baseline_exposure) { + as_out.data->bl_scale = powf(2, baseline_exposure_offset); + } + + if (working_space == "ProPhoto") { + as_out.data->already_pro_photo = true; + } else { + as_out.data->already_pro_photo = false; + TMatrix mWork; + + mWork = iccStore->workingSpaceMatrix (working_space); + memset(as_out.data->pro_photo, 0, sizeof(as_out.data->pro_photo)); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { + as_out.data->pro_photo[i][j] += prophoto_xyz[i][k] * mWork[k][j]; + } + + mWork = iccStore->workingSpaceInverseMatrix (working_space); + memset(as_out.data->work, 0, sizeof(as_out.data->work)); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { + as_out.data->work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; + } + } +} + +void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const ApplyState& as_in) const +{ + +#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) +#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) + + float exp_scale = as_in.data->bl_scale; + + if (!as_in.data->use_tone_curve && !as_in.data->apply_look_table) { + if (exp_scale == 1.f) { + return; + } + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + rc[y * tile_width + x] *= exp_scale; + gc[y * tile_width + x] *= exp_scale; + bc[y * tile_width + x] *= exp_scale; + } + } + } else { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + float r = rc[y * tile_width + x]; + float g = gc[y * tile_width + x]; + float b = bc[y * tile_width + x]; + + r *= exp_scale; + g *= exp_scale; + b *= exp_scale; + + float newr, newg, newb; + + if (as_in.data->already_pro_photo) { + newr = r; + newg = g; + newb = b; + } else { + newr = as_in.data->pro_photo[0][0] * r + as_in.data->pro_photo[0][1] * g + as_in.data->pro_photo[0][2] * b; + newg = as_in.data->pro_photo[1][0] * r + as_in.data->pro_photo[1][1] * g + as_in.data->pro_photo[1][2] * b; + newb = as_in.data->pro_photo[2][0] * r + as_in.data->pro_photo[2][1] * g + as_in.data->pro_photo[2][2] * b; + } + + // with looktable and tonecurve we need to clip + newr = FCLIP(newr); + newg = FCLIP(newg); + newb = FCLIP(newb); + + if (as_in.data->apply_look_table) { + float h, s, v; + Color::rgb2hsvdcp(newr, newg, newb, h, s, v); + + hsdApply(look_info, look_table, h, s, v); + s = CLIP01(s); + v = CLIP01(v); + + // RT range correction + if (h < 0.0f) { + h += 6.0f; + } else if (h >= 6.0f) { + h -= 6.0f; + } + + Color::hsv2rgbdcp( h, s, v, newr, newg, newb); + } + + if (as_in.data->use_tone_curve) { + tone_curve.Apply(newr, newg, newb); + } + + if (as_in.data->already_pro_photo) { + rc[y * tile_width + x] = newr; + gc[y * tile_width + x] = newg; + bc[y * tile_width + x] = newb; + } else { + rc[y * tile_width + x] = as_in.data->work[0][0] * newr + as_in.data->work[0][1] * newg + as_in.data->work[0][2] * newb; + gc[y * tile_width + x] = as_in.data->work[1][0] * newr + as_in.data->work[1][1] * newg + as_in.data->work[1][2] * newb; + bc[y * tile_width + x] = as_in.data->work[2][0] * newr + as_in.data->work[2][1] * newg + as_in.data->work[2][2] * newb; + } + } + } + } +} + +DCPProfile::Matrix DCPProfile::findXyztoCamera(const std::array& white_xy, int preferred_illuminant) const +{ + bool has_col_1 = has_color_matrix_1; + bool has_col_2 = has_color_matrix_2; + + if (preferred_illuminant == 1) { + if (has_col_1) { + has_col_2 = false; + } + } else if (preferred_illuminant == 2) { + if (has_col_2) { + has_col_1 = false; + } + } + + // Mix if we have two matrices + if (has_col_1 && has_col_2) { + /* + Note: We're using DNG SDK reference code for XY to temperature translation to get the exact same mix as + the reference code does. + */ + const double wbtemp = xyCoordToTemperature(white_xy); + + double mix; + if (wbtemp <= temperature_1) { + mix = 1.0; + } else if (wbtemp >= temperature_2) { + mix = 0.0; + } else { + const double invT = 1.0 / wbtemp; + mix = (invT - (1.0 / temperature_2)) / ((1.0 / temperature_1) - (1.0 / temperature_2)); + } + + // Interpolate + if (mix >= 1.0) { + return color_matrix_1; + } else if (mix <= 0.0) { + return color_matrix_2; + } else { + return mix3x3(color_matrix_1, mix, color_matrix_2, 1.0 - mix); + } + } else if (has_col_1) { + return color_matrix_1; + } else { + return color_matrix_2; + } +} + +std::array DCPProfile::neutralToXy(const Triple& neutral, int preferred_illuminant) const +{ + enum { + MAX_PASSES = 30 + }; + + std::array last_xy = {0.3457, 0.3585}; // D50 + + for (unsigned int pass = 0; pass < MAX_PASSES; ++pass) { + const Matrix& xyz_to_camera = findXyztoCamera(last_xy, preferred_illuminant); + const Matrix& inv_m = invert3x3(xyz_to_camera); + const Triple& next_xyz = multiply3x3_v3(inv_m, neutral); + + std::array next_xy = xyzToXy(next_xyz); + + if (std::fabs(next_xy[0] - last_xy[0]) + std::fabs(next_xy[1] - last_xy[1]) < 0.0000001) { + return next_xy; + } + + // If we reach the limit without converging, we are most likely + // in a two value oscillation. So take the average of the last + // two estimates and give up. + if (pass == MAX_PASSES - 1) { + next_xy[0] = (last_xy[0] + next_xy[0]) * 0.5; + next_xy[1] = (last_xy[1] + next_xy[1]) * 0.5; + } + + last_xy = next_xy; + } + + return last_xy; +} + +DCPProfile::Matrix DCPProfile::makeXyzCam(const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, int preferred_illuminant) const +{ + // Code adapted from dng_color_spec::FindXYZtoCamera. + // Note that we do not support monochrome or colorplanes > 3 (no reductionMatrix support), + // we do not support cameracalibration either. + + Triple neutral; // Same as the DNG "AsShotNeutral" tag if white balance is Camera's own { /* A bit messy matrixing and conversions to get the neutral[] array from RT's own white balance which is stored in sRGB space, while the DCP code needs multipliers in CameraRGB space */ double r, g, b; - wb.getMultipliers(r, g, b); + white_balance.getMultipliers(r, g, b); - // camWbMatrix == imatrices.xyz_cam - double cam_xyz[3][3]; - Invert3x3(camWbMatrix, cam_xyz); - double cam_rgb[3][3]; - Multiply3x3(cam_xyz, xyz_sRGB, cam_rgb); + constexpr Matrix xyz_srgb = { + { + {xyz_sRGB[0][0], xyz_sRGB[0][1], xyz_sRGB[0][2]}, + {xyz_sRGB[1][0], xyz_sRGB[1][1], xyz_sRGB[1][2]}, + {xyz_sRGB[2][0], xyz_sRGB[2][1], xyz_sRGB[2][2]} + } + }; + const Matrix cam_rgb = multiply3x3(invert3x3(cam_wb_matrix), xyz_srgb); double camwb_red = cam_rgb[0][0] * r + cam_rgb[0][1] * g + cam_rgb[0][2] * b; double camwb_green = cam_rgb[1][0] * r + cam_rgb[1][1] * g + cam_rgb[1][2] * b; double camwb_blue = cam_rgb[2][0] * r + cam_rgb[2][1] * g + cam_rgb[2][2] * b; neutral[0] = camwb_red / pre_mul[0]; neutral[1] = camwb_green / pre_mul[1]; neutral[2] = camwb_blue / pre_mul[2]; - double maxentry = 0; - for (int i = 0; i < 3; i++) { - if (neutral[i] > maxentry) { - maxentry = neutral[i]; - } - } + const double maxentry = std::max({neutral[0], neutral[1], neutral[2]}); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; ++i) { neutral[i] /= maxentry; } } @@ -583,68 +1334,66 @@ void DCPProfile::MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix DCP ColorMatrix or ColorMatrices if dual-illuminant. This is the DNG reference code way to do it, which is a bit different from RT's own white balance model at the time of writing. When RT's white balance can make use of the DCP color matrices we could use that instead. */ - double white_xy[2]; - dngref_NeutralToXY(neutral, preferredIlluminant, white_xy); + const std::array white_xy = neutralToXy(neutral, preferred_illuminant); - bool hasFwd1 = hasForwardMatrix1; - bool hasFwd2 = hasForwardMatrix2; - bool hasCol1 = hasColorMatrix1; - bool hasCol2 = hasColorMatrix2; + bool has_fwd_1 = has_forward_matrix_1; + bool has_fwd_2 = has_forward_matrix_2; + bool has_col_1 = has_color_matrix_1; + bool has_col_2 = has_color_matrix_2; - if (preferredIlluminant == 1) { - if (hasFwd1) { - hasFwd2 = false; + if (preferred_illuminant == 1) { + if (has_fwd_1) { + has_fwd_2 = false; } - if (hasCol1) { - hasCol2 = false; + if (has_col_1) { + has_col_2 = false; } - } else if (preferredIlluminant == 2) { - if (hasFwd2) { - hasFwd1 = false; + } else if (preferred_illuminant == 2) { + if (has_fwd_2) { + has_fwd_1 = false; } - if (hasCol2) { - hasCol1 = false; + if (has_col_2) { + has_col_1 = false; } } - // mix if we have two matrices + // Mix if we have two matrices double mix = 1.0; - if ((hasCol1 && hasCol2) || (hasFwd1 && hasFwd2)) { - double wbtemp; + if ((has_col_1 && has_col_2) || (has_fwd_1 && has_fwd_2)) { /* DNG ref way to convert XY to temperature, which affect matrix mixing. A different model here typically does not affect the result too much, ie it's probably not strictly necessary to use the DNG reference code here, but we do it for now. */ - dngref_XYCoord2Temperature(white_xy, &wbtemp, NULL); + const double wbtemp = xyCoordToTemperature(white_xy); - if (wbtemp <= temperature1) { + if (wbtemp <= temperature_1) { mix = 1.0; - } else if (wbtemp >= temperature2) { + } else if (wbtemp >= temperature_2) { mix = 0.0; } else { - double invT = 1.0 / wbtemp; - mix = (invT - (1.0 / temperature2)) / ((1.0 / temperature1) - (1.0 / temperature2)); + const double& invT = 1.0 / wbtemp; + mix = (invT - (1.0 / temperature_2)) / ((1.0 / temperature_1) - (1.0 / temperature_2)); } } // Colormatrix - double mCol[3][3]; + Matrix color_matrix; - if (hasCol1 && hasCol2) { + if (has_col_1 && has_col_2) { // interpolate if (mix >= 1.0) { - memcpy(mCol, mColorMatrix1, sizeof(mCol)); + color_matrix = color_matrix_1; } else if (mix <= 0.0) { - memcpy(mCol, mColorMatrix2, sizeof(mCol)); + color_matrix = color_matrix_2; } else { - Mix3x3(mColorMatrix1, mix, mColorMatrix2, 1.0 - mix, mCol); + color_matrix = mix3x3(color_matrix_1, mix, color_matrix_2, 1.0 - mix); } - } else if (hasCol1) { - memcpy(mCol, mColorMatrix1, sizeof(mCol)); + } else if (has_col_1) { + color_matrix = color_matrix_1; } else { - memcpy(mCol, mColorMatrix2, sizeof(mCol)); + color_matrix = color_matrix_2; } /* @@ -655,1135 +1404,391 @@ void DCPProfile::MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix will show incorrect color. */ - double white_xyz[3]; - XYtoXYZ(white_xy, white_xyz); + const Triple white_xyz = xyToXyz(white_xy); - double cam_xyz[3][3]; + Matrix cam_xyz; - if (hasFwd1 || hasFwd2) { - // always prefer ForwardMatrix ahead of ColorMatrix - double mFwd[3][3]; + if (has_fwd_1 || has_fwd_2) { + // Always prefer ForwardMatrix to ColorMatrix + Matrix fwd; - if (hasFwd1 && hasFwd2) { - // interpolate + if (has_fwd_1 && has_fwd_2) { + // Interpolate if (mix >= 1.0) { - memcpy(mFwd, mForwardMatrix1, sizeof(mFwd)); + fwd = forward_matrix_1; } else if (mix <= 0.0) { - memcpy(mFwd, mForwardMatrix2, sizeof(mFwd)); + fwd = forward_matrix_2; } else { - Mix3x3(mForwardMatrix1, mix, mForwardMatrix2, 1.0 - mix, mFwd); + fwd = mix3x3(forward_matrix_1, mix, forward_matrix_2, 1.0 - mix); } - } else if (hasFwd1) { - memcpy(mFwd, mForwardMatrix1, sizeof(mFwd)); + } else if (has_fwd_1) { + fwd = forward_matrix_1; } else { - memcpy(mFwd, mForwardMatrix2, sizeof(mFwd)); + fwd = forward_matrix_2; } // adapted from dng_color_spec::SetWhiteXY - double CameraWhite[3]; - Multiply3x3_v3(mCol, white_xyz, CameraWhite); + const Triple camera_white = multiply3x3_v3(color_matrix, white_xyz); + const Matrix white_diag = { + { + {camera_white[0], 0, 0}, + {0, camera_white[1], 0}, + {0, 0, camera_white[2]} + } + }; - double whiteDiag[3][3] = {{CameraWhite[0], 0, 0}, {0, CameraWhite[1], 0}, {0, 0, CameraWhite[2]}}; - double whiteDiagInv[3][3]; - Invert3x3(whiteDiag, whiteDiagInv); - - double xyz_cam[3][3]; - Multiply3x3(mFwd, whiteDiagInv, xyz_cam); - Invert3x3(xyz_cam, cam_xyz); + cam_xyz = invert3x3(multiply3x3(fwd, invert3x3(white_diag))); } else { - double whiteMatrix[3][3]; - const double white_d50[3] = { 0.3457, 0.3585, 0.2958 }; // D50 - MapWhiteMatrix(white_d50, white_xyz, whiteMatrix); - Multiply3x3(mCol, whiteMatrix, cam_xyz); + constexpr Triple white_d50 = {0.3457, 0.3585, 0.2958}; // D50 + + cam_xyz = multiply3x3(color_matrix, mapWhiteMatrix(white_d50, white_xyz)); } - // convert cam_xyz (XYZ D50 to CameraRGB, "PCS to Camera" in DNG terminology) to mXYZCAM + // Convert cam_xyz (XYZ D50 to CameraRGB, "PCS to Camera" in DNG terminology) to mXYZCAM - { - // This block can probably be simplified, seems unnecessary to pass through the sRGB matrix - // (probably dcraw legacy), it does no harm though as we don't clip anything. - int i, j, k; + // This block can probably be simplified, seems unnecessary to pass through the sRGB matrix + // (probably dcraw legacy), it does no harm though as we don't clip anything. + int i, j, k; - // Multiply out XYZ colorspace - double cam_rgb[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + // Multiply out XYZ colorspace + double cam_rgb[3][3] = {}; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - for (k = 0; k < 3; k++) { - cam_rgb[i][j] += cam_xyz[i][k] * xyz_sRGB[k][j]; - } - - // Normalize cam_rgb so that: cam_rgb * (1,1,1) is (1,1,1,1) - double num; - - for (i = 0; i < 3; i++) { - for (num = j = 0; j < 3; j++) { - num += cam_rgb[i][j]; - } - - for (j = 0; j < 3; j++) { - cam_rgb[i][j] /= num; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + cam_rgb[i][j] += cam_xyz[i][k] * xyz_sRGB[k][j]; } } - - double rgb_cam[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - RawImageSource::inverse33 (cam_rgb, rgb_cam); - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) { - mXYZCAM[i][j] = 0; - } - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - for (k = 0; k < 3; k++) { - mXYZCAM[i][j] += xyz_sRGB[i][k] * rgb_cam[k][j]; - } } + + // Normalize cam_rgb so that cam_rgb * (1,1,1) is (1,1,1,1) + double num; + + for (i = 0; i < 3; ++i) { + for (num = j = 0; j < 3; ++j) { + num += cam_rgb[i][j]; + } + + for (j = 0; j < 3; ++j) { + cam_rgb[i][j] /= num; + } + } + + double rgb_cam[3][3] = {}; + RawImageSource::inverse33(cam_rgb, rgb_cam); + + Matrix res = {}; + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + res[i][j] += xyz_sRGB[i][k] * rgb_cam[k][j]; + } + } + } + + return res; } -const DCPProfile::HSBModify* DCPProfile::MakeHueSatMap(ColorTemp &wb, int preferredIlluminant, HSBModify **deleteHandle) const +std::vector DCPProfile::makeHueSatMap(const ColorTemp& white_balance, int preferred_illuminant) const { - - *deleteHandle = NULL; - - if (!aDeltas1) { - return NULL; + if (deltas_1.empty()) { + return std::vector(); } - if (!aDeltas2) { - return aDeltas1; + if (deltas_2.empty()) { + return deltas_1; } - if (preferredIlluminant == 1) { - return aDeltas1; - } else if (preferredIlluminant == 2) { - return aDeltas2; + if (preferred_illuminant == 1) { + return deltas_1; + } else if (preferred_illuminant == 2) { + return deltas_2; } - // Interpolate based on color temperature. - if (temperature1 <= 0.0 || temperature2 <= 0.0 || temperature1 == temperature2) { - return aDeltas1; + // Interpolate based on color temperature + if ( + temperature_1 <= 0.0 + || temperature_2 <= 0.0 + || temperature_1 == temperature_2 + ) { + return deltas_1; } - bool reverseOrder = temperature1 > temperature2; - double t1, t2; - - if (reverseOrder) { - t1 = temperature2; - t2 = temperature1; - } else { - t1 = temperature1; - t2 = temperature2; - } + const bool reverse = temperature_1 > temperature_2; + const double t1 = + reverse + ? temperature_2 + : temperature_1; + const double t2 = + reverse + ? temperature_1 + : temperature_2; double mix; - if (wb.getTemp() <= t1) { + if (white_balance.getTemp() <= t1) { mix = 1.0; - } else if (wb.getTemp() >= t2) { + } else if (white_balance.getTemp() >= t2) { mix = 0.0; } else { - double invT = 1.0 / wb.getTemp(); + const double invT = 1.0 / white_balance.getTemp(); mix = (invT - (1.0 / t2)) / ((1.0 / t1) - (1.0 / t2)); } - if (reverseOrder) { + if (reverse) { mix = 1.0 - mix; } if (mix >= 1.0) { - return aDeltas1; + return deltas_1; } else if (mix <= 0.0) { - return aDeltas2; + return deltas_2; } // Interpolate between the tables. - HSBModify *aDeltas = new HSBModify[DeltaInfo.iArrayCount]; - *deleteHandle = aDeltas; - float w1 = (float)mix; - float w2 = 1.0f - (float)mix; + std::vector res(delta_info.array_count); - for (int i = 0; i < DeltaInfo.iArrayCount; i++) { - aDeltas[i].fHueShift = w1 * aDeltas1[i].fHueShift + w2 * aDeltas2[i].fHueShift; - aDeltas[i].fSatScale = w1 * aDeltas1[i].fSatScale + w2 * aDeltas2[i].fSatScale; - aDeltas[i].fValScale = w1 * aDeltas1[i].fValScale + w2 * aDeltas2[i].fValScale; + const float w1 = mix; + const float w2 = 1.0f - w1; + + for (unsigned int i = 0; i < delta_info.array_count; ++i) { + res[i].hue_shift = w1 * deltas_1[i].hue_shift + w2 * deltas_2[i].hue_shift; + res[i].sat_scale = w1 * deltas_1[i].sat_scale + w2 * deltas_2[i].sat_scale; + res[i].val_scale = w1 * deltas_1[i].val_scale + w2 * deltas_2[i].val_scale; } - return aDeltas; + return res; } -DCPProfile::DCPProfile(Glib::ustring fname) +void DCPProfile::hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const { - const int TIFFFloatSize = 4; - const int TagColorMatrix1 = 50721, TagColorMatrix2 = 50722, TagProfileHueSatMapDims = 50937; - const int TagForwardMatrix1 = 50964, TagForwardMatrix2 = 50965; - const int TagProfileHueSatMapData1 = 50938, TagProfileHueSatMapData2 = 50939; - const int TagCalibrationIlluminant1 = 50778, TagCalibrationIlluminant2 = 50779; - const int TagProfileLookTableData = 50982, TagProfileLookTableDims = 50981; // ProfileLookup is the low quality variant - const int TagProfileHueSatMapEncoding = 51107, TagProfileLookTableEncoding = 51108; - const int TagProfileToneCurve = 50940, TagBaselineExposureOffset = 51109; - const int TagProfileCopyright = 50942; + // Apply the HueSatMap. Ported from Adobes reference implementation. + float hue_shift; + float sat_scale; + float val_scale; + float v_encoded = v; - aDeltas1 = aDeltas2 = aLookTable = NULL; + if (table_info.val_divisions < 2) { + // Optimize most common case of "2.5D" table + const float h_scaled = h * table_info.pc.h_scale; + const float s_scaled = s * table_info.pc.s_scale; - FILE *pFile = g_fopen(fname.c_str (), "rb"); + int h_index0 = max(h_scaled, 0); + const int s_index0 = std::max(std::min(s_scaled, table_info.pc.max_sat_index0), 0); - TagDirectory *tagDir = ExifManager::parseTIFF(pFile, false); + int h_index1 = h_index0 + 1; - Tag* tag = tagDir->getTag(TagCalibrationIlluminant1); - iLightSource1 = (tag != NULL ? tag->toInt(0, rtexif::SHORT) : -1); - tag = tagDir->getTag(TagCalibrationIlluminant2); - iLightSource2 = (tag != NULL ? tag->toInt(0, rtexif::SHORT) : -1); - temperature1 = calibrationIlluminantToTemperature(iLightSource1); - temperature2 = calibrationIlluminantToTemperature(iLightSource2); - - bool hasSecondHueSat = tagDir->getTag(TagProfileHueSatMapData2) != NULL; // some profiles have two matrices, but just one huesat - - // Fetch Forward Matrices, if any - hasForwardMatrix1 = false; - hasForwardMatrix2 = false; - hasColorMatrix1 = false; - hasColorMatrix2 = false; - hasToneCurve = false; - hasBaselineExposureOffset = false; - baselineExposureOffset = 0; - tag = tagDir->getTag(TagForwardMatrix1); - - if (tag) { - hasForwardMatrix1 = true; - - for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) { - mForwardMatrix1[row][col] = (float)tag->toDouble((col + row * 3) * 8); - } - } - } - - tag = tagDir->getTag(TagForwardMatrix2); - - if (tag) { - hasForwardMatrix2 = true; - - for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) { - mForwardMatrix2[row][col] = (float)tag->toDouble((col + row * 3) * 8); - } - } - } - - // Color Matrix (1 is always there) - tag = tagDir->getTag(TagColorMatrix1); - - if (!tag) { - // FIXME: better error handling - fprintf(stderr, "Bad DCP, no ColorMatrix1\n"); - abort(); - } - - hasColorMatrix1 = true; - - for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) { - mColorMatrix1[row][col] = (float)tag->toDouble((col + row * 3) * 8); - } - } - - tag = tagDir->getTag(TagProfileLookTableDims); - - if (tag != NULL) { - LookInfo.iHueDivisions = tag->toInt(0); - LookInfo.iSatDivisions = tag->toInt(4); - LookInfo.iValDivisions = tag->toInt(8); - - tag = tagDir->getTag(TagProfileLookTableEncoding); - LookInfo.sRGBGamma = tag != NULL && tag->toInt(0); - - tag = tagDir->getTag(TagProfileLookTableData); - LookInfo.iArrayCount = tag->getCount() / 3; - - aLookTable = new HSBModify[LookInfo.iArrayCount]; - - for (int i = 0; i < LookInfo.iArrayCount; i++) { - aLookTable[i].fHueShift = tag->toDouble((i * 3) * TIFFFloatSize); - aLookTable[i].fSatScale = tag->toDouble((i * 3 + 1) * TIFFFloatSize); - aLookTable[i].fValScale = tag->toDouble((i * 3 + 2) * TIFFFloatSize); + if (h_index0 >= table_info.pc.max_hue_index0) { + h_index0 = table_info.pc.max_hue_index0; + h_index1 = 0; } - // precalculated constants for table application - LookInfo.pc.hScale = (LookInfo.iHueDivisions < 2) ? 0.0f : (LookInfo.iHueDivisions * (1.0f / 6.0f)); - LookInfo.pc.sScale = (float) (LookInfo.iSatDivisions - 1); - LookInfo.pc.vScale = (float) (LookInfo.iValDivisions - 1); - LookInfo.pc.maxHueIndex0 = LookInfo.iHueDivisions - 1; - LookInfo.pc.maxSatIndex0 = LookInfo.iSatDivisions - 2; - LookInfo.pc.maxValIndex0 = LookInfo.iValDivisions - 2; - LookInfo.pc.hueStep = LookInfo.iSatDivisions; - LookInfo.pc.valStep = LookInfo.iHueDivisions * LookInfo.pc.hueStep; - } + const float h_fract1 = h_scaled - static_cast(h_index0); + const float s_fract1 = s_scaled - static_cast(s_index0); - tag = tagDir->getTag(TagProfileHueSatMapDims); + const float h_fract0 = 1.0f - h_fract1; + const float s_fract0 = 1.0f - s_fract1; - if (tag != NULL) { - DeltaInfo.iHueDivisions = tag->toInt(0); - DeltaInfo.iSatDivisions = tag->toInt(4); - DeltaInfo.iValDivisions = tag->toInt(8); + std::vector::size_type e00_index = h_index0 * table_info.pc.hue_step + s_index0; + std::vector::size_type e01_index = e00_index + (h_index1 - h_index0) * table_info.pc.hue_step; - tag = tagDir->getTag(TagProfileHueSatMapEncoding); - DeltaInfo.sRGBGamma = tag != NULL && tag->toInt(0); + const float hue_shift0 = h_fract0 * table_base[e00_index].hue_shift + h_fract1 * table_base[e01_index].hue_shift; + const float sat_scale0 = h_fract0 * table_base[e00_index].sat_scale + h_fract1 * table_base[e01_index].sat_scale; + const float val_scale0 = h_fract0 * table_base[e00_index].val_scale + h_fract1 * table_base[e01_index].val_scale; - tag = tagDir->getTag(TagProfileHueSatMapData1); - DeltaInfo.iArrayCount = tag->getCount() / 3; + ++e00_index; + ++e01_index; - aDeltas1 = new HSBModify[DeltaInfo.iArrayCount]; - - for (int i = 0; i < DeltaInfo.iArrayCount; i++) { - aDeltas1[i].fHueShift = tag->toDouble((i * 3) * TIFFFloatSize); - aDeltas1[i].fSatScale = tag->toDouble((i * 3 + 1) * TIFFFloatSize); - aDeltas1[i].fValScale = tag->toDouble((i * 3 + 2) * TIFFFloatSize); - } - - DeltaInfo.pc.hScale = (DeltaInfo.iHueDivisions < 2) ? 0.0f : (DeltaInfo.iHueDivisions * (1.0f / 6.0f)); - DeltaInfo.pc.sScale = (float) (DeltaInfo.iSatDivisions - 1); - DeltaInfo.pc.vScale = (float) (DeltaInfo.iValDivisions - 1); - DeltaInfo.pc.maxHueIndex0 = DeltaInfo.iHueDivisions - 1; - DeltaInfo.pc.maxSatIndex0 = DeltaInfo.iSatDivisions - 2; - DeltaInfo.pc.maxValIndex0 = DeltaInfo.iValDivisions - 2; - DeltaInfo.pc.hueStep = DeltaInfo.iSatDivisions; - DeltaInfo.pc.valStep = DeltaInfo.iHueDivisions * DeltaInfo.pc.hueStep; - } - - if (iLightSource2 != -1) { - // Second matrix - tag = tagDir->getTag(TagColorMatrix2); - hasColorMatrix2 = true; - - for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) { - mColorMatrix2[row][col] = (tag != NULL ? (float)tag->toDouble((col + row * 3) * 8) : mColorMatrix1[row][col]); - } - } - - // Second huesatmap - if (hasSecondHueSat) { - aDeltas2 = new HSBModify[DeltaInfo.iArrayCount]; - - // Saturation maps. Need to be unwinded. - tag = tagDir->getTag(TagProfileHueSatMapData2); - - for (int i = 0; i < DeltaInfo.iArrayCount; i++) { - aDeltas2[i].fHueShift = tag->toDouble((i * 3) * TIFFFloatSize); - aDeltas2[i].fSatScale = tag->toDouble((i * 3 + 1) * TIFFFloatSize); - aDeltas2[i].fValScale = tag->toDouble((i * 3 + 2) * TIFFFloatSize); - } - } - } - - tag = tagDir->getTag(TagBaselineExposureOffset); - - if (tag) { - hasBaselineExposureOffset = true; - baselineExposureOffset = tag->toDouble(); - } - - // Read tone curve points, if any, but disable to RTs own profiles - tag = tagDir->getTag(TagProfileToneCurve); - - if (tag != NULL) { - std::vector cPoints; - cPoints.push_back(double(DCT_Spline)); // The first value is the curve type - - // push back each X/Y coordinates in a loop - bool curve_is_linear = true; - - for (int i = 0; i < tag->getCount(); i += 2) { - double x = tag->toDouble((i + 0) * TIFFFloatSize); - double y = tag->toDouble((i + 1) * TIFFFloatSize); - - if (x != y) { - curve_is_linear = false; - } - - cPoints.push_back( x ); - cPoints.push_back( y ); - } - - if (!curve_is_linear) { - // Create the curve - DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); - - toneCurve.Set((Curve*)&rawCurve); - hasToneCurve = true; - } - } else if (tag == NULL) { - tag = tagDir->getTag(TagProfileCopyright); - - if (tag != NULL && tag->valueToString().find("Adobe Systems") != std::string::npos) { - // an Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that - std::vector cPoints; - cPoints.push_back(double(DCT_Spline)); - const size_t tc_len = sizeof(adobe_camera_raw_default_curve) / sizeof(adobe_camera_raw_default_curve[0]); - - for (size_t i = 0; i < tc_len; i++) { - double x = (double)i / (tc_len - 1); - double y = (double)adobe_camera_raw_default_curve[i]; - cPoints.push_back( x ); - cPoints.push_back( y ); - } - - DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); - toneCurve.Set((Curve*)&rawCurve); - hasToneCurve = true; - } - } - - willInterpolate = false; - - if (hasForwardMatrix1) { - if (hasForwardMatrix2) { - if (memcmp(mForwardMatrix1, mForwardMatrix2, sizeof(mForwardMatrix1)) != 0) { - // common that forward matrices are the same! - willInterpolate = true; - } - - if (aDeltas1 && aDeltas2) { - // we assume tables are different - willInterpolate = true; - } - } - } - - if (hasColorMatrix1 && hasColorMatrix2) { - if (memcmp(mColorMatrix1, mColorMatrix2, sizeof(mColorMatrix1)) != 0) { - willInterpolate = true; - } - - if (aDeltas1 && aDeltas2) { - willInterpolate = true; - } - } - - if (pFile != NULL) { - fclose(pFile); - } - - delete tagDir; -} - -DCPProfile::~DCPProfile() -{ - delete[] aDeltas1; - delete[] aDeltas2; - delete[] aLookTable; -} - -void DCPProfile::HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, float &h, float &s, float &v) const -{ - - // Apply the HueSatMap. Ported from Adobes reference implementation - float hueShift, satScale, valScale; - float vEncoded = v; - - if (ti.iValDivisions < 2) { // Optimize most common case of "2.5D" table. - float hScaled = h * ti.pc.hScale; - float sScaled = s * ti.pc.sScale; - - int hIndex0 = max((int)hScaled, 0); - int sIndex0 = max(min((int)sScaled, ti.pc.maxSatIndex0), 0); - - int hIndex1 = hIndex0 + 1; - - if (hIndex0 >= ti.pc.maxHueIndex0) { - hIndex0 = ti.pc.maxHueIndex0; - hIndex1 = 0; - } - - float hFract1 = hScaled - (float) hIndex0; - float sFract1 = sScaled - (float) sIndex0; - - float hFract0 = 1.0f - hFract1; - float sFract0 = 1.0f - sFract1; - - const HSBModify *entry00 = tableBase + hIndex0 * ti.pc.hueStep + sIndex0; - const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * ti.pc.hueStep; - - float hueShift0 = hFract0 * entry00->fHueShift + hFract1 * entry01->fHueShift; - float satScale0 = hFract0 * entry00->fSatScale + hFract1 * entry01->fSatScale; - float valScale0 = hFract0 * entry00->fValScale + hFract1 * entry01->fValScale; - - entry00++; - entry01++; - - float hueShift1 = hFract0 * entry00->fHueShift + - hFract1 * entry01->fHueShift; - - float satScale1 = hFract0 * entry00->fSatScale + - hFract1 * entry01->fSatScale; - - float valScale1 = hFract0 * entry00->fValScale + - hFract1 * entry01->fValScale; - - hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; - satScale = sFract0 * satScale0 + sFract1 * satScale1; - valScale = sFract0 * valScale0 + sFract1 * valScale1; + const float hueShift1 = h_fract0 * table_base[e00_index].hue_shift + h_fract1 * table_base[e01_index].hue_shift; + const float satScale1 = h_fract0 * table_base[e00_index].sat_scale + h_fract1 * table_base[e01_index].sat_scale; + const float valScale1 = h_fract0 * table_base[e00_index].val_scale + h_fract1 * table_base[e01_index].val_scale; + hue_shift = s_fract0 * hue_shift0 + s_fract1 * hueShift1; + sat_scale = s_fract0 * sat_scale0 + s_fract1 * satScale1; + val_scale = s_fract0 * val_scale0 + s_fract1 * valScale1; } else { + const float h_scaled = h * table_info.pc.h_scale; + const float s_scaled = s * table_info.pc.s_scale; - float hScaled = h * ti.pc.hScale; - float sScaled = s * ti.pc.sScale; - - if (ti.sRGBGamma) { - vEncoded = sRGBGammaForward(v); + if (table_info.srgb_gamma) { + v_encoded = Color::gammatab_srgb1[v * 65535.f]; } - float vScaled = vEncoded * ti.pc.vScale; + const float v_scaled = v_encoded * table_info.pc.v_scale; - int hIndex0 = (int) hScaled; - int sIndex0 = max(min((int)sScaled, ti.pc.maxSatIndex0), 0); - int vIndex0 = max(min((int)vScaled, ti.pc.maxValIndex0), 0); + int h_index0 = h_scaled; + const int s_index0 = std::max(std::min(s_scaled, table_info.pc.max_sat_index0), 0); + const int v_index0 = std::max(std::min(v_scaled, table_info.pc.max_val_index0), 0); - int hIndex1 = hIndex0 + 1; + int h_index1 = h_index0 + 1; - if (hIndex0 >= ti.pc.maxHueIndex0) { - hIndex0 = ti.pc.maxHueIndex0; - hIndex1 = 0; + if (h_index0 >= table_info.pc.max_hue_index0) { + h_index0 = table_info.pc.max_hue_index0; + h_index1 = 0; } - float hFract1 = hScaled - (float) hIndex0; - float sFract1 = sScaled - (float) sIndex0; - float vFract1 = vScaled - (float) vIndex0; + const float h_fract1 = h_scaled - static_cast(h_index0); + const float s_fract1 = s_scaled - static_cast(s_index0); + const float v_fract1 = v_scaled - static_cast(v_index0); - float hFract0 = 1.0f - hFract1; - float sFract0 = 1.0f - sFract1; - float vFract0 = 1.0f - vFract1; + const float h_fract0 = 1.0f - h_fract1; + const float s_fract0 = 1.0f - s_fract1; + const float v_fract0 = 1.0f - v_fract1; - const HSBModify *entry00 = tableBase + vIndex0 * ti.pc.valStep + hIndex0 * ti.pc.hueStep + sIndex0; + std::vector::size_type e00_index = v_index0 * table_info.pc.val_step + h_index0 * table_info.pc.hue_step + s_index0; + std::vector::size_type e01_index = e00_index + (h_index1 - h_index0) * table_info.pc.hue_step; + std::vector::size_type e10_index = e00_index + table_info.pc.val_step; + std::vector::size_type e11_index = e01_index + table_info.pc.val_step; - const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * ti.pc.hueStep; + const float hueShift0 = + v_fract0 * (h_fract0 * table_base[e00_index].hue_shift + h_fract1 * table_base[e01_index].hue_shift) + + v_fract1 * (h_fract0 * table_base[e10_index].hue_shift + h_fract1 * table_base[e11_index].hue_shift); + const float satScale0 = + v_fract0 * (h_fract0 * table_base[e00_index].sat_scale + h_fract1 * table_base[e01_index].sat_scale) + + v_fract1 * (h_fract0 * table_base[e10_index].sat_scale + h_fract1 * table_base[e11_index].sat_scale); + const float valScale0 = + v_fract0 * (h_fract0 * table_base[e00_index].val_scale + h_fract1 * table_base[e01_index].val_scale) + + v_fract1 * (h_fract0 * table_base[e10_index].val_scale + h_fract1 * table_base[e11_index].val_scale); - const HSBModify *entry10 = entry00 + ti.pc.valStep; - const HSBModify *entry11 = entry01 + ti.pc.valStep; + ++e00_index; + ++e01_index; + ++e10_index; + ++e11_index; - float hueShift0 = vFract0 * (hFract0 * entry00->fHueShift + - hFract1 * entry01->fHueShift) + - vFract1 * (hFract0 * entry10->fHueShift + - hFract1 * entry11->fHueShift); + const float hueShift1 = + v_fract0 * (h_fract0 * table_base[e00_index].hue_shift + h_fract1 * table_base[e01_index].hue_shift) + + v_fract1 * (h_fract0 * table_base[e10_index].hue_shift + h_fract1 * table_base[e11_index].hue_shift); + const float satScale1 = + v_fract0 * (h_fract0 * table_base[e00_index].sat_scale + h_fract1 * table_base[e01_index].sat_scale) + + v_fract1 * (h_fract0 * table_base[e10_index].sat_scale + h_fract1 * table_base[e11_index].sat_scale); + const float valScale1 = + v_fract0 * (h_fract0 * table_base[e00_index].val_scale + h_fract1 * table_base[e01_index].val_scale) + + v_fract1 * (h_fract0 * table_base[e10_index].val_scale + h_fract1 * table_base[e11_index].val_scale); - float satScale0 = vFract0 * (hFract0 * entry00->fSatScale + - hFract1 * entry01->fSatScale) + - vFract1 * (hFract0 * entry10->fSatScale + - hFract1 * entry11->fSatScale); - - float valScale0 = vFract0 * (hFract0 * entry00->fValScale + - hFract1 * entry01->fValScale) + - vFract1 * (hFract0 * entry10->fValScale + - hFract1 * entry11->fValScale); - - entry00++; - entry01++; - entry10++; - entry11++; - - float hueShift1 = vFract0 * (hFract0 * entry00->fHueShift + - hFract1 * entry01->fHueShift) + - vFract1 * (hFract0 * entry10->fHueShift + - hFract1 * entry11->fHueShift); - - float satScale1 = vFract0 * (hFract0 * entry00->fSatScale + - hFract1 * entry01->fSatScale) + - vFract1 * (hFract0 * entry10->fSatScale + - hFract1 * entry11->fSatScale); - - float valScale1 = vFract0 * (hFract0 * entry00->fValScale + - hFract1 * entry01->fValScale) + - vFract1 * (hFract0 * entry10->fValScale + - hFract1 * entry11->fValScale); - - hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; - satScale = sFract0 * satScale0 + sFract1 * satScale1; - valScale = sFract0 * valScale0 + sFract1 * valScale1; + hue_shift = s_fract0 * hueShift0 + s_fract1 * hueShift1; + sat_scale = s_fract0 * satScale0 + s_fract1 * satScale1; + val_scale = s_fract0 * valScale0 + s_fract1 * valScale1; } - hueShift *= (6.0f / 360.0f); // Convert to internal hue range. + hue_shift *= 6.0f / 360.0f; // Convert to internal hue range. - h += hueShift; - s *= satScale; // no clipping here, we are RT float :-) + h += hue_shift; + s *= sat_scale; // No clipping here, we are RT float :-) - if (ti.sRGBGamma) { - v = sRGBGammaInverse(vEncoded * valScale); + if (table_info.srgb_gamma) { + v = Color::igammatab_srgb1[v_encoded * val_scale * 65535.f]; } else { - v *= valScale; + v *= val_scale; } } -struct ruvt { - double r; - double u; - double v; - double t; -}; - -static const double kTintScale = -3000.0; -static const ruvt kTempTable [] = { - { 0, 0.18006, 0.26352, -0.24341 }, - { 10, 0.18066, 0.26589, -0.25479 }, - { 20, 0.18133, 0.26846, -0.26876 }, - { 30, 0.18208, 0.27119, -0.28539 }, - { 40, 0.18293, 0.27407, -0.30470 }, - { 50, 0.18388, 0.27709, -0.32675 }, - { 60, 0.18494, 0.28021, -0.35156 }, - { 70, 0.18611, 0.28342, -0.37915 }, - { 80, 0.18740, 0.28668, -0.40955 }, - { 90, 0.18880, 0.28997, -0.44278 }, - { 100, 0.19032, 0.29326, -0.47888 }, - { 125, 0.19462, 0.30141, -0.58204 }, - { 150, 0.19962, 0.30921, -0.70471 }, - { 175, 0.20525, 0.31647, -0.84901 }, - { 200, 0.21142, 0.32312, -1.0182 }, - { 225, 0.21807, 0.32909, -1.2168 }, - { 250, 0.22511, 0.33439, -1.4512 }, - { 275, 0.23247, 0.33904, -1.7298 }, - { 300, 0.24010, 0.34308, -2.0637 }, - { 325, 0.24702, 0.34655, -2.4681 }, - { 350, 0.25591, 0.34951, -2.9641 }, - { 375, 0.26400, 0.35200, -3.5814 }, - { 400, 0.27218, 0.35407, -4.3633 }, - { 425, 0.28039, 0.35577, -5.3762 }, - { 450, 0.28863, 0.35714, -6.7262 }, - { 475, 0.29685, 0.35823, -8.5955 }, - { 500, 0.30505, 0.35907, -11.324 }, - { 525, 0.31320, 0.35968, -15.628 }, - { 550, 0.32129, 0.36011, -23.325 }, - { 575, 0.32931, 0.36038, -40.770 }, - { 600, 0.33724, 0.36051, -116.45 } -}; - -void DCPProfile::dngref_XYCoord2Temperature(const double whiteXY[2], double *temp, double *tint) const -{ - double fTemperature = 0; - double fTint = 0; - - // Convert to uv space. - double u = 2.0 * whiteXY[0] / (1.5 - whiteXY[0] + 6.0 * whiteXY[1]); - double v = 3.0 * whiteXY[1] / (1.5 - whiteXY[0] + 6.0 * whiteXY[1]); - - // Search for line pair coordinate is between. - double last_dt = 0.0; - double last_dv = 0.0; - double last_du = 0.0; - - for (uint32_t index = 1; index <= 30; index++) { - // Convert slope to delta-u and delta-v, with length 1. - double du = 1.0; - double dv = kTempTable [index] . t; - double len = sqrt (1.0 + dv * dv); - du /= len; - dv /= len; - - // Find delta from black body point to test coordinate. - double uu = u - kTempTable [index] . u; - double vv = v - kTempTable [index] . v; - - // Find distance above or below line. - double dt = - uu * dv + vv * du; - - // If below line, we have found line pair. - if (dt <= 0.0 || index == 30) { - // Find fractional weight of two lines. - if (dt > 0.0) { - dt = 0.0; - } - - dt = -dt; - double f; - - if (index == 1) { - f = 0.0; - } else { - f = dt / (last_dt + dt); - } - - // Interpolate the temperature. - fTemperature = 1.0E6 / (kTempTable [index - 1] . r * f + - kTempTable [index ] . r * (1.0 - f)); - - // Find delta from black body point to test coordinate. - uu = u - (kTempTable [index - 1] . u * f + - kTempTable [index ] . u * (1.0 - f)); - vv = v - (kTempTable [index - 1] . v * f + - kTempTable [index ] . v * (1.0 - f)); - // Interpolate vectors along slope. - du = du * (1.0 - f) + last_du * f; - dv = dv * (1.0 - f) + last_dv * f; - len = sqrt (du * du + dv * dv); - du /= len; - dv /= len; - - // Find distance along slope. - fTint = (uu * du + vv * dv) * kTintScale; - break; - } - - // Try next line pair. - last_dt = dt; - last_du = du; - last_dv = dv; - } - - if (temp != NULL) { - *temp = fTemperature; - } - - if (tint != NULL) { - *tint = fTint; - } -} - -void DCPProfile::dngref_FindXYZtoCamera(const double whiteXY[2], int preferredIlluminant, double (*xyzToCamera)[3]) const -{ - - bool hasCol1 = hasColorMatrix1; - bool hasCol2 = hasColorMatrix2; - - if (preferredIlluminant == 1) { - if (hasCol1) { - hasCol2 = false; - } - } else if (preferredIlluminant == 2) { - if (hasCol2) { - hasCol1 = false; - } - } - - // mix if we have two matrices - double mix; - - if (hasCol1 && hasCol2) { - double wbtemp; - /* - Note: we're using DNG SDK reference code for XY to temperature translation to get the exact same mix as - the reference code does. - */ - dngref_XYCoord2Temperature(whiteXY, &wbtemp, NULL); - - if (wbtemp <= temperature1) { - mix = 1.0; - } else if (wbtemp >= temperature2) { - mix = 0.0; - } else { - double invT = 1.0 / wbtemp; - mix = (invT - (1.0 / temperature2)) / ((1.0 / temperature1) - (1.0 / temperature2)); - } - } - - // Interpolate the color matrix. - double mCol[3][3]; - - if (hasCol1 && hasCol2) { - // interpolate - if (mix >= 1.0) { - memcpy(mCol, mColorMatrix1, sizeof(mCol)); - } else if (mix <= 0.0) { - memcpy(mCol, mColorMatrix2, sizeof(mCol)); - } else { - Mix3x3(mColorMatrix1, mix, mColorMatrix2, 1.0 - mix, mCol); - } - } else if (hasCol1) { - memcpy(mCol, mColorMatrix1, sizeof(mCol)); - } else { - memcpy(mCol, mColorMatrix2, sizeof(mCol)); - } - - memcpy(xyzToCamera, mCol, sizeof(mCol)); -} - -void DCPProfile::dngref_NeutralToXY(double neutral[3], int preferredIlluminant, double XY[2]) const -{ - const int kMaxPasses = 30; - double lastXY[2] = { 0.3457, 0.3585 }; // D50 - - for (int pass = 0; pass < kMaxPasses; pass++) { - double xyzToCamera[3][3]; - dngref_FindXYZtoCamera(lastXY, preferredIlluminant, xyzToCamera); - - double invM[3][3], nextXYZ[3], nextXY[2]; - Invert3x3(xyzToCamera, invM); - Multiply3x3_v3(invM, neutral, nextXYZ); - XYZtoXY(nextXYZ, nextXY); - - if (fabs(nextXY[0] - lastXY[0]) + - fabs(nextXY[1] - lastXY[1]) < 0.0000001) { - XY[0] = nextXY[0]; - XY[1] = nextXY[1]; - return; - } - - // If we reach the limit without converging, we are most likely - // in a two value oscillation. So take the average of the last - // two estimates and give up. - if (pass == kMaxPasses - 1) { - nextXY[0] = (lastXY[0] + nextXY[0]) * 0.5; - nextXY[1] = (lastXY[1] + nextXY[1]) * 0.5; - } - - lastXY[0] = nextXY[0]; - lastXY[1] = nextXY[1]; - } - - XY[0] = lastXY[0]; - XY[1] = lastXY[1]; -} - -void DCPProfile::Apply(Imagefloat *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], bool useToneCurve, bool applyHueSatMap, bool applyLookTable) const -{ - - TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); - - double mXYZCAM[3][3]; // Camera RGB to XYZ D50 matrix - MakeXYZCAM(wb, pre_mul, camWbMatrix, preferredIlluminant, mXYZCAM); - HSBModify *deleteTableHandle; - const HSBModify *deltaBase = MakeHueSatMap(wb, preferredIlluminant, &deleteTableHandle); - - if (!deltaBase) { - applyHueSatMap = false; - } - - if (!aLookTable) { - applyLookTable = false; - } - - useToneCurve &= toneCurve; - - if (!applyHueSatMap && !applyLookTable && !useToneCurve) { - //===== The fast path: no LUT and not tone curve- Calculate matrix for direct conversion raw>working space - double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (int k = 0; k < 3; k++) { - mat[i][j] += mWork[i][k] * mXYZCAM[k][j]; - } - - // Apply the matrix part - #pragma omp parallel for - - for (int y = 0; y < pImg->height; y++) { - float newr, newg, newb; - - for (int x = 0; x < pImg->width; x++) { - newr = mat[0][0] * pImg->r(y, x) + mat[0][1] * pImg->g(y, x) + mat[0][2] * pImg->b(y, x); - newg = mat[1][0] * pImg->r(y, x) + mat[1][1] * pImg->g(y, x) + mat[1][2] * pImg->b(y, x); - newb = mat[2][0] * pImg->r(y, x) + mat[2][1] * pImg->g(y, x) + mat[2][2] * pImg->b(y, x); - - pImg->r(y, x) = newr; - pImg->g(y, x) = newg; - pImg->b(y, x) = newb; - } - } - } else { - //===== LUT available- Calculate matrix for conversion raw>ProPhoto - double m2ProPhoto[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (int k = 0; k < 3; k++) { - m2ProPhoto[i][j] += prophoto_xyz[i][k] * mXYZCAM[k][j]; - } - - double m2Work[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (int k = 0; k < 3; k++) { - m2Work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; - } - - // Convert to prophoto and apply LUT - #pragma omp parallel for - - for (int y = 0; y < pImg->height; y++) { - float newr, newg, newb, h, s, v, hs, ss, vs; - - for (int x = 0; x < pImg->width; x++) { - newr = m2ProPhoto[0][0] * pImg->r(y, x) + m2ProPhoto[0][1] * pImg->g(y, x) + m2ProPhoto[0][2] * pImg->b(y, x); - newg = m2ProPhoto[1][0] * pImg->r(y, x) + m2ProPhoto[1][1] * pImg->g(y, x) + m2ProPhoto[1][2] * pImg->b(y, x); - newb = m2ProPhoto[2][0] * pImg->r(y, x) + m2ProPhoto[2][1] * pImg->g(y, x) + m2ProPhoto[2][2] * pImg->b(y, x); - - // if point is in negative area, just the matrix, but not the LUT - if ((applyHueSatMap || applyLookTable) && newr >= 0 && newg >= 0 && newb >= 0) { - Color::rgb2hsv(newr, newg, newb, h , s, v); - h *= 6.f; // RT calculates in [0,1] - - if (applyHueSatMap) { - HSDApply(DeltaInfo, deltaBase, h, s, v); - } - - if (applyLookTable) { - HSDApply(LookInfo, aLookTable, h, s, v); - } - - // RT range correction - if (h < 0.0f) { - h += 6.0f; - } - - if (h >= 6.0f) { - h -= 6.0f; - } - - h /= 6.f; - Color::hsv2rgb( h, s, v, newr, newg, newb); - } - - // tone curve - if (useToneCurve) { - toneCurve.Apply(newr, newg, newb); - } - - pImg->r(y, x) = m2Work[0][0] * newr + m2Work[0][1] * newg + m2Work[0][2] * newb; - pImg->g(y, x) = m2Work[1][0] * newr + m2Work[1][1] * newg + m2Work[1][2] * newb; - pImg->b(y, x) = m2Work[2][0] * newr + m2Work[2][1] * newg + m2Work[2][2] * newb; - } - } - } - - if (deleteTableHandle) { - delete[] deleteTableHandle; - } -} - -void DCPProfile::setStep2ApplyState(Glib::ustring workingSpace, bool useToneCurve, bool applyLookTable, bool applyBaselineExposure) -{ - - applyState.useToneCurve = useToneCurve; - applyState.applyLookTable = applyLookTable; - applyState.blScale = 1.0; - - if (!aLookTable) { - applyState.applyLookTable = false; - } - - if (!hasToneCurve) { - applyState.useToneCurve = false; - } - - if (hasBaselineExposureOffset && applyBaselineExposure) { - applyState.blScale = powf(2, baselineExposureOffset); - } - - if (workingSpace == "ProPhoto") { - applyState.alreadyProPhoto = true; - } else { - applyState.alreadyProPhoto = false; - TMatrix mWork; - - mWork = iccStore->workingSpaceMatrix (workingSpace); - memset(applyState.m2ProPhoto, 0, sizeof(applyState.m2ProPhoto)); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (int k = 0; k < 3; k++) { - applyState.m2ProPhoto[i][j] += prophoto_xyz[i][k] * mWork[k][j]; - } - - mWork = iccStore->workingSpaceInverseMatrix (workingSpace); - memset(applyState.m2Work, 0, sizeof(applyState.m2Work)); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (int k = 0; k < 3; k++) { - applyState.m2Work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; - } - } -} - -void DCPProfile::step2ApplyTile(float *rc, float *gc, float *bc, int width, int height, int tileWidth) const -{ - -#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) -#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) - - float exp_scale = 1.0; - exp_scale *= applyState.blScale; - - if (!applyState.useToneCurve && !applyState.applyLookTable) { - if (exp_scale == 1.0) { - return; - } - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - rc[y * tileWidth + x] *= exp_scale; - gc[y * tileWidth + x] *= exp_scale; - bc[y * tileWidth + x] *= exp_scale; - } - } - } else { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - float r = rc[y * tileWidth + x]; - float g = gc[y * tileWidth + x]; - float b = bc[y * tileWidth + x]; - - if (exp_scale != 1.0) { - r *= exp_scale; - g *= exp_scale; - b *= exp_scale; - } - - float newr, newg, newb; - - if (applyState.alreadyProPhoto) { - newr = r; - newg = g; - newb = b; - } else { - newr = applyState.m2ProPhoto[0][0] * r + applyState.m2ProPhoto[0][1] * g + applyState.m2ProPhoto[0][2] * b; - newg = applyState.m2ProPhoto[1][0] * r + applyState.m2ProPhoto[1][1] * g + applyState.m2ProPhoto[1][2] * b; - newb = applyState.m2ProPhoto[2][0] * r + applyState.m2ProPhoto[2][1] * g + applyState.m2ProPhoto[2][2] * b; - } - - // with looktable and tonecurve we need to clip - newr = FCLIP(newr); - newg = FCLIP(newg); - newb = FCLIP(newb); - - if (applyState.applyLookTable) { - float h, s, v; - Color::rgb2hsv(newr, newg, newb, h, s, v); - h *= 6.f; // RT calculates in [0,1] - - HSDApply(LookInfo, aLookTable, h, s, v); - s = CLIP01(s); - v = CLIP01(v); - - // RT range correction - if (h < 0.0f) { - h += 6.0f; - } - - if (h >= 6.0f) { - h -= 6.0f; - } - - h /= 6.f; - Color::hsv2rgb( h, s, v, newr, newg, newb); - } - - if (applyState.useToneCurve) { - toneCurve.Apply(newr, newg, newb); - } - - if (applyState.alreadyProPhoto) { - rc[y * tileWidth + x] = newr; - gc[y * tileWidth + x] = newg; - bc[y * tileWidth + x] = newb; - } else { - rc[y * tileWidth + x] = applyState.m2Work[0][0] * newr + applyState.m2Work[0][1] * newg + applyState.m2Work[0][2] * newb; - gc[y * tileWidth + x] = applyState.m2Work[1][0] * newr + applyState.m2Work[1][1] * newg + applyState.m2Work[1][2] * newb; - bc[y * tileWidth + x] = applyState.m2Work[2][0] * newr + applyState.m2Work[2][1] * newg + applyState.m2Work[2][2] * newb; - } - } - } - } -} - -// Generates as singleton DCPStore* DCPStore::getInstance() { - static DCPStore instance_; - return &instance_; + static DCPStore instance; + return &instance; } -// Reads all profiles from the given profiles dir -void DCPStore::init (Glib::ustring rtProfileDir) +void DCPStore::init(const Glib::ustring& rt_profile_dir) { - MyMutex::MyLock lock(mtx); + MyMutex::MyLock lock(mutex); - fileStdProfiles.clear(); + file_std_profiles.clear(); - Glib::ustring rootDirName = rtProfileDir; + if (!rt_profile_dir.empty()) { + std::deque dirs = { + rt_profile_dir + }; - if (rootDirName != "") { - std::deque qDirs; + while (!dirs.empty()) { + // Process directory + Glib::ustring dirname = dirs.back(); + dirs.pop_back(); - qDirs.push_front(rootDirName); - - while (!qDirs.empty()) { - // process directory - Glib::ustring dirname = qDirs.back(); - qDirs.pop_back(); - - Glib::Dir* dir = NULL; + std::unique_ptr dir; try { - if (!Glib::file_test (dirname, Glib::FILE_TEST_IS_DIR)) { + if (!Glib::file_test(dirname, Glib::FILE_TEST_IS_DIR)) { return; } - dir = new Glib::Dir (dirname); - } catch (Glib::Exception& fe) { + dir.reset(new Glib::Dir(dirname)); + } catch (Glib::Exception& exception) { return; } - dirname = dirname + "/"; + dirname += '/'; - for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - Glib::ustring fname = dirname + *i; - Glib::ustring sname = *i; + for (const Glib::ustring& sname : *dir) { + const Glib::ustring fname = dirname + sname; - // ignore directories - if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { - size_t lastdot = sname.find_last_of ('.'); + if (!Glib::file_test(fname, Glib::FILE_TEST_IS_DIR)) { + // File + const auto lastdot = sname.rfind('.'); - if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".dcp"))) { - Glib::ustring camShortName = sname.substr(0, lastdot).uppercase(); - fileStdProfiles[camShortName] = fname; // they will be loaded and cached on demand + if ( + lastdot != Glib::ustring::npos + && lastdot <= sname.size() - 4 + && !sname.casefold().compare(lastdot, 4, ".dcp") + ) { + const Glib::ustring cam_short_name = sname.substr(0, lastdot).uppercase(); + file_std_profiles[cam_short_name] = fname; // They will be loaded and cached on demand } } else { - qDirs.push_front(fname); // for later scanning + // Directory + dirs.push_front(fname); } } - - delete dir; } } } -DCPProfile* DCPStore::getProfile (Glib::ustring filename) +bool DCPStore::isValidDCPFileName(const Glib::ustring& filename) const { - MyMutex::MyLock lock(mtx); - - std::map::iterator r = profileCache.find (filename); - - if (r != profileCache.end()) { - return r->second; - } - - // Add profile - profileCache[filename] = new DCPProfile(filename); - - return profileCache[filename]; -} - -DCPProfile* DCPStore::getStdProfile(Glib::ustring camShortName) -{ - Glib::ustring name2 = camShortName.uppercase(); - - // Warning: do NOT use map.find(), since it does not seem to work reliably here - for (std::map::iterator i = fileStdProfiles.begin(); i != fileStdProfiles.end(); i++) - if (name2 == (*i).first) { - return getProfile((*i).second); - } - - return NULL; -} - -bool DCPStore::isValidDCPFileName(Glib::ustring filename) const -{ - if (!Glib::file_test (filename, Glib::FILE_TEST_EXISTS) || Glib::file_test (filename, Glib::FILE_TEST_IS_DIR)) { + if (!Glib::file_test(filename, Glib::FILE_TEST_EXISTS) || Glib::file_test(filename, Glib::FILE_TEST_IS_DIR)) { return false; } - size_t pos = filename.find_last_of ('.'); - return pos > 0 && (!filename.casefold().compare (pos, 4, ".dcp") || !filename.casefold().compare (pos, 4, ".dng")); + const auto pos = filename.rfind('.'); + return + pos > 0 + && ( + !filename.casefold().compare(pos, 4, ".dcp") + || !filename.casefold().compare(pos, 4, ".dng") + ); +} + +DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const +{ + MyMutex::MyLock lock(mutex); + + const std::map::iterator r = profile_cache.find(filename); + + if (r != profile_cache.end()) { + return r->second; + } + + DCPProfile* const res = new DCPProfile(filename); + + if (*res) { + // Add profile + profile_cache[filename] = res; + return res; + } + + delete res; + return nullptr; +} + +DCPProfile* DCPStore::getStdProfile(const Glib::ustring& cam_short_name) const +{ + const Glib::ustring name = cam_short_name.uppercase(); + + // Warning: do NOT use map.find(), since it does not seem to work reliably here + for (const auto& file_std_profile : file_std_profiles) + if (file_std_profile.first == name) { + return getProfile(file_std_profile.second); + } + + return nullptr; } diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 7a960edc9..11e368b80 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -17,117 +17,159 @@ * along with RawTherapee. If not, see . */ -#ifndef _DCP_ -#define _DCP_ +#pragma once + +#include +#include +#include +#include + +#include #include "imagefloat.h" #include "curves.h" #include "colortemp.h" + #include "../rtgui/threadutils.h" -#include -#include -#include namespace rtengine { -class DCPProfile +class DCPProfile final { - struct HSBModify { - float fHueShift; - float fSatScale; - float fValScale; +public: + class ApplyState final + { + public: + ApplyState(); + ~ApplyState(); + + private: + struct Data; + + std::unique_ptr data; + + friend class DCPProfile; }; - struct HSDTableInfo { - int iHueDivisions, iSatDivisions, iValDivisions; - int iHueStep, iValStep, iArrayCount; - bool sRGBGamma; + + struct Illuminants { + short light_source_1; + short light_source_2; + double temperature_1; + double temperature_2; + bool will_interpolate; + }; + + using Triple = std::array; + using Matrix = std::array; + + DCPProfile(const Glib::ustring& filename); + ~DCPProfile(); + + explicit operator bool() const; + + bool getHasToneCurve() const; + bool getHasLookTable() const; + bool getHasHueSatMap() const; + bool getHasBaselineExposureOffset() const; + + Illuminants getIlluminants() const; + + void apply( + Imagefloat* img, + int preferred_illuminant, + const Glib::ustring& working_space, + const ColorTemp& white_balance, + const Triple& pre_mul, + 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; + +private: + struct HsbModify { + float hue_shift; + float sat_scale; + float val_scale; + }; + + struct HsdTableInfo { + int hue_divisions; + int sat_divisions; + int val_divisions; + int hue_step; + int val_step; + unsigned int array_count; + bool srgb_gamma; struct { - float hScale, sScale, vScale; - int maxHueIndex0, maxSatIndex0, maxValIndex0; - int hueStep, valStep; + float h_scale; + float s_scale; + float v_scale; + int max_hue_index0; + int max_sat_index0; + int max_val_index0; + int hue_step; + int val_step; } pc; }; - double mColorMatrix1[3][3], mColorMatrix2[3][3]; - bool hasColorMatrix1, hasColorMatrix2, hasForwardMatrix1, hasForwardMatrix2, hasToneCurve, hasBaselineExposureOffset, willInterpolate; - double mForwardMatrix1[3][3], mForwardMatrix2[3][3]; - double temperature1, temperature2; - double baselineExposureOffset; - HSBModify *aDeltas1, *aDeltas2, *aLookTable; - HSDTableInfo DeltaInfo, LookInfo; - short iLightSource1, iLightSource2; + Matrix findXyztoCamera(const std::array& white_xy, int preferred_illuminant) const; + std::array neutralToXy(const Triple& neutral, int preferred_illuminant) const; + Matrix makeXyzCam(const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, int preferred_illuminant) const; + std::vector makeHueSatMap(const ColorTemp& white_balance, int preferred_illuminant) const; + void hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const; - AdobeToneCurve toneCurve; - struct { - double m2ProPhoto[3][3]; - double m2Work[3][3]; - bool alreadyProPhoto; - bool useToneCurve; - bool applyLookTable; - float blScale; - } applyState; + Matrix color_matrix_1; + Matrix color_matrix_2; + bool has_color_matrix_1; + bool has_color_matrix_2; + bool has_forward_matrix_1; + bool has_forward_matrix_2; + bool has_tone_curve; + bool has_baseline_exposure_offset; + bool will_interpolate; + Matrix forward_matrix_1; + Matrix forward_matrix_2; + double temperature_1; + double temperature_2; + double baseline_exposure_offset; + std::vector deltas_1; + std::vector deltas_2; + std::vector look_table; + HsdTableInfo delta_info; + HsdTableInfo look_info; + short light_source_1; + short light_source_2; - void dngref_XYCoord2Temperature(const double whiteXY[2], double *temp, double *tint) const; - void dngref_FindXYZtoCamera(const double whiteXY[2], int preferredIlluminant, double (*xyzToCamera)[3]) const; - void dngref_NeutralToXY(double neutral[3], int preferredIlluminant, double XY[2]) const; - void MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], int preferredIlluminant, double (*mXYZCAM)[3]) const; - const HSBModify* MakeHueSatMap(ColorTemp &wb, int preferredIlluminant, HSBModify **deleteHandle) const; - void HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, float &h, float &s, float &v) const; - -public: - DCPProfile(Glib::ustring fname); - ~DCPProfile(); - - bool getHasToneCurve() - { - return hasToneCurve; - } - bool getHasLookTable() - { - return !!aLookTable; - } - bool getHasHueSatMap() - { - return !!aDeltas1; - } - bool getHasBaselineExposureOffset() - { - return hasBaselineExposureOffset; - } - void getIlluminants(int &i1, double &temp1, int &i2, double &temp2, bool &willInterpolate_) - { - i1 = iLightSource1; - i2 = iLightSource2; - temp1 = temperature1, temp2 = temperature2; - willInterpolate_ = willInterpolate; - }; - void Apply(Imagefloat *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, double pre_mul[3], double camMatrix[3][3], bool useToneCurve = false, bool applyHueSatMap = true, bool applyLookTable = false) const; - void setStep2ApplyState(Glib::ustring workingSpace, bool useToneCurve, bool applyLookTable, bool applyBaselineExposure); - void step2ApplyTile(float *r, float *g, float *b, int width, int height, int tileWidth) const; + AdobeToneCurve tone_curve; }; -class DCPStore +class DCPStore final { - MyMutex mtx; +public: + static DCPStore* getInstance(); + + DCPStore(const DCPStore& other) = delete; + DCPStore& operator =(const DCPStore& other) = delete; + + void init(const Glib::ustring& rt_profile_dir); + + bool isValidDCPFileName(const Glib::ustring& filename) const; + + DCPProfile* getProfile(const Glib::ustring& filename) const; + DCPProfile* getStdProfile(const Glib::ustring& camShortName) const; + +private: + DCPStore() = default; + + mutable MyMutex mutex; // these contain standard profiles from RT. keys are all in uppercase, file path is value - std::map fileStdProfiles; + std::map file_std_profiles; // Maps file name to profile as cache - std::map profileCache; - -public: - void init(Glib::ustring rtProfileDir); - - bool isValidDCPFileName(Glib::ustring filename) const; - - DCPProfile* getProfile(Glib::ustring filename); - DCPProfile* getStdProfile(Glib::ustring camShortName); - - static DCPStore* getInstance(); + mutable std::map profile_cache; }; -#define dcpStore DCPStore::getInstance() } -#endif diff --git a/rtengine/dcraw.c b/rtengine/dcraw.c index cf1afe4ac..441f967da 100644 --- a/rtengine/dcraw.c +++ b/rtengine/dcraw.c @@ -1,6 +1,6 @@ /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net This is a command-line ANSI C program to convert raw photos from any digital camera on any computer running any operating system. @@ -19,11 +19,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.475 $ - $Date: 2015/04/11 00:08:36 $ + $Revision: 1.477 $ + $Date: 2016/05/10 21:30:43 $ */ -#define DCRAW_VERSION "9.25" +#define DCRAW_VERSION "9.27" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -89,15 +89,6 @@ typedef unsigned long long UINT64; #define _(String) (String) #endif -#ifdef LJPEG_DECODE -#error Please compile dcraw.c by itself. -#error Do not link it with ljpeg_decode. -#endif - -#ifndef LONG_BIT -#define LONG_BIT (8 * sizeof (long)) -#endif - #if !defined(uchar) #define uchar unsigned char #endif @@ -158,6 +149,7 @@ struct decode { struct tiff_ifd { int width, height, bps, comp, phint, offset, flip, samples, bytes; int tile_width, tile_length; + float shutter; } tiff_ifd[10]; struct ph1 { @@ -179,7 +171,7 @@ struct ph1 { #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define LIM(x,min,max) MAX(min,MIN(x,max)) #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) -#define CLIP(x) LIM(x,0,65535) +#define CLIP(x) LIM((int)(x),0,65535) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } /* @@ -813,27 +805,22 @@ void CLASS canon_load_raw() FORC(2) free (huff[c]); } -/* - Not a full implementation of Lossless JPEG, just - enough to decode Canon, Kodak and Adobe DNG images. - */ struct jhead { - int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; - ushort *huff[6], *free[4], *row; + int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort quant[64], idct[64], *huff[20], *free[20], *row; }; int CLASS ljpeg_start (struct jhead *jh, int info_only) { - int c, tag, len; + ushort c, tag, len; uchar data[0x10000]; const uchar *dp; memset (jh, 0, sizeof *jh); jh->restart = INT_MAX; - fread (data, 2, 1, ifp); - if (data[1] != 0xd8) return 0; + if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0; do { - fread (data, 2, 2, ifp); + if (!fread (data, 2, 2, ifp)) return 0; tag = data[0] << 8 | data[1]; len = (data[2] << 8 | data[3]) - 2; if (tag <= 0xff00) return 0; @@ -841,7 +828,9 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) switch (tag) { case 0xffc3: jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc1: case 0xffc0: + jh->algo = tag & 0xff; jh->bits = data[0]; jh->high = data[1] << 8 | data[2]; jh->wide = data[3] << 8 | data[4]; @@ -850,20 +839,25 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) break; case 0xffc4: if (info_only) break; - for (dp = data; dp < data+len && (c = *dp++) < 4; ) + for (dp = data; dp < data+len && !((c = *dp++) & -20); ) jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); break; case 0xffda: jh->psv = data[1+data[0]*2]; jh->bits -= data[3+data[0]*2] & 15; break; + case 0xffdb: + FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2]; + break; case 0xffdd: jh->restart = data[0] << 8 | data[1]; } } while (tag != 0xffda); + if (jh->bits > 16 || jh->clrs > 6 || + !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; if (info_only) return 1; - if (jh->clrs > 6 || !jh->huff[0]) return 0; - FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (!jh->huff[0]) return 0; + FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; if (jh->sraw) { FORC(4) jh->huff[2+c] = jh->huff[1]; FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; @@ -1042,23 +1036,59 @@ void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) { int c; - if (is_raw == 2 && shot_select) (*rp)++; + if (tiff_samples == 2 && shot_select) (*rp)++; if (raw_image) { if (row < raw_height && col < raw_width) RAW(row,col) = curve[**rp]; - *rp += is_raw; + *rp += tiff_samples; } else { if (row < height && col < width) FORC(tiff_samples) image[row*width+col][c] = curve[(*rp)[c]]; *rp += tiff_samples; } - if (is_raw == 2 && shot_select) (*rp)--; + if (tiff_samples == 2 && shot_select) (*rp)--; +} + +void CLASS ljpeg_idct (struct jhead *jh) +{ + int c, i, j, len, skip, coef; + float work[3][8][8]; + static float cs[106] = { 0 }; + static const uchar zigzag[80] = + { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33, + 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54, + 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 }; + + if (!cs[0]) + FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2; + memset (work, 0, sizeof work); + work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0]; + for (i=1; i < 64; i++ ) { + len = gethuff (jh->huff[16]); + i += skip = len >> 4; + if (!(len &= 15) && skip < 15) break; + coef = getbits(len); + if ((coef & (1 << (len-1))) == 0) + coef -= (1 << len) - 1; + ((float *)work)[zigzag[i]] = coef * jh->quant[i]; + } + FORC(8) work[0][0][c] *= M_SQRT1_2; + FORC(8) work[0][c][0] *= M_SQRT1_2; + for (i=0; i < 8; i++) + for (j=0; j < 8; j++) + FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c]; + for (i=0; i < 8; i++) + for (j=0; j < 8; j++) + FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c]; + + FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5); } void CLASS lossless_dng_load_raw() { - unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j; struct jhead jh; ushort *rp; @@ -1069,14 +1099,32 @@ void CLASS lossless_dng_load_raw() if (!ljpeg_start (&jh, 0)) break; jwide = jh.wide; if (filters) jwide *= jh.clrs; - jwide /= is_raw; - for (row=col=jrow=0; jrow < jh.high; jrow++) { - rp = ljpeg_row (jrow, &jh); - for (jcol=0; jcol < jwide; jcol++) { - adobe_copy_pixel (trow+row, tcol+col, &rp); - if (++col >= tile_width || col >= raw_width) - row += 1 + (col = 0); - } + jwide /= MIN (is_raw, tiff_samples); + switch (jh.algo) { + case 0xc1: + jh.vpred[0] = 16384; + getbits(-1); + for (jrow=0; jrow+7 < jh.high; jrow += 8) { + for (jcol=0; jcol+7 < jh.wide; jcol += 8) { + ljpeg_idct (&jh); + rp = jh.idct; + row = trow + jcol/tile_width + jrow*2; + col = tcol + jcol%tile_width; + for (i=0; i < 16; i+=2) + for (j=0; j < 8; j++) + adobe_copy_pixel (row+i, col+j, &rp); + } + } + break; + case 0xc3: + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } } fseek (ifp, save+4, SEEK_SET); if ((tcol += tile_width) >= raw_width) @@ -1721,7 +1769,7 @@ void CLASS phase_one_load_raw_c() pixel[col] = curve[pixel[col]]; } for (col=0; col < raw_width; col++) { - i = (pixel[col] << 2) - ph1.black + i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black + cblack[row][col >= ph1.split_col] + rblack[col][row >= ph1.split_row]; if (i > 0) RAW(row,col) = i; @@ -2813,6 +2861,8 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes) fseek (ifp, seg[0][1]+1, SEEK_SET); getbits(-1); + if (seg[1][0] > raw_width*raw_height) + seg[1][0] = raw_width*raw_height; for (pix=seg[0][0]; pix < seg[1][0]; pix++) { for (s=0; s < 3; s++) { data = data << nbits | getbits(nbits); @@ -5261,7 +5311,7 @@ nf: order = 0x4949; FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); } if (tag == 0x3d && type == 3 && len == 4) - FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps); if (tag == 0x81 && type == 4) { data_offset = get4(); fseek (ifp, data_offset + 41, SEEK_SET); @@ -5291,7 +5341,8 @@ nf: order = 0x4949; break; case 102: fseek (ifp, 6, SEEK_CUR); - goto get2_rggb; + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + break; case 103: fseek (ifp, 16, SEEK_CUR); FORC4 cam_mul[c] = get2(); @@ -5325,7 +5376,7 @@ nf: order = 0x4949; if (tag == 0x200 && len == 4) FORC4 cblack[c ^ c >> 1] = get2(); if (tag == 0x201 && len == 4) - goto get2_rggb; + FORC4 cam_mul[c ^ (c >> 1)] = get2(); if (tag == 0x220 && type == 7) meta_offset = ftell(ifp); if (tag == 0x401 && type == 4 && len == 4) @@ -5371,7 +5422,7 @@ get2_256: } if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) fseek (ifp, get4()+base, SEEK_SET); - if (tag == 0x2020) + if (tag == 0x2020 && !strncmp(buf,"OLYMP",5)) parse_thumb_note (base, 257, 258); if (tag == 0x2040) parse_makernote (base, 0x2040); @@ -5382,11 +5433,12 @@ get2_256: if (tag == 0x4001 && len > 500) { i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; fseek (ifp, i, SEEK_CUR); -get2_rggb: FORC4 cam_mul[c ^ (c >> 1)] = get2(); - i = len >> 3 == 164 || len == 1506 ? 112:22; - fseek (ifp, i, SEEK_CUR); - FORC4 sraw_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; + } } if (tag == 0x4021 && get4() && get4()) FORC4 cam_mul[c] = 1024; @@ -5439,12 +5491,14 @@ void CLASS parse_exif (int base) while (entries--) { tiff_get (base, &tag, &type, &len, &save); switch (tag) { - case 33434: shutter = getreal(type); break; + case 33434: tiff_ifd[tiff_nifds-1].shutter = + shutter = getreal(type); break; case 33437: aperture = getreal(type); break; case 34855: iso_speed = get2(); break; case 36867: case 36868: get_timestamp(0); break; case 37377: if ((expo = -getreal(type)) < 128) + tiff_ifd[tiff_nifds-1].shutter = shutter = pow (2, expo); break; case 37378: aperture = pow (2, getreal(type)/2); break; case 37386: focal_len = getreal(type); break; @@ -5682,6 +5736,8 @@ int CLASS parse_tiff_ifd (int base) case 61443: tiff_ifd[ifd].samples = len & 7; tiff_ifd[ifd].bps = getint(type); + if (tiff_bps < tiff_ifd[ifd].bps) + tiff_bps = tiff_ifd[ifd].bps; break; case 61446: raw_height = 0; @@ -5843,7 +5899,7 @@ int CLASS parse_tiff_ifd (int base) parse_kodak_ifd (base); break; case 33434: /* ExposureTime */ - shutter = getreal(type); + tiff_ifd[ifd].shutter = shutter = getreal(type); break; case 33437: /* FNumber */ aperture = getreal(type); @@ -5971,6 +6027,14 @@ int CLASS parse_tiff_ifd (int base) if (!make[0]) strcpy (make, "DNG"); is_raw = 1; break; + case 50708: /* UniqueCameraModel */ + if (model[0]) break; + fgets (make, 64, ifp); + if ((cp = strchr(make,' '))) { + strcpy(model,cp+1); + *cp = 0; + } + break; case 50710: /* CFAPlaneColor */ if (filters == 9) break; if (len > 4) len = 4; @@ -5984,10 +6048,7 @@ guess_cfa_pc: filters -= !filters; break; case 50711: /* CFALayout */ - if (get2() == 2) { - fuji_width = 1; - filters = 0x49494949; - } + if (get2() == 2) fuji_width = 1; break; case 291: case 50712: /* LinearizationTable */ @@ -6010,7 +6071,7 @@ guess_cfa_pc: break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ - for (num=i=0; i < len; i++) + for (num=i=0; i < (len & 0xffff); i++) num += getreal(type); black += num/len + 0.5; break; @@ -6128,7 +6189,7 @@ int CLASS parse_tiff (int base) void CLASS apply_tiff() { - int max_samp=0, raw=-1, thm=-1, i; + int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i; struct jhead jh; thumb_misc = 16; @@ -6140,13 +6201,25 @@ void CLASS apply_tiff() thumb_height = jh.high; } } + for (i=tiff_nifds; i--; ) { + if (tiff_ifd[i].shutter) + shutter = tiff_ifd[i].shutter; + tiff_ifd[i].shutter = shutter; + } for (i=0; i < tiff_nifds; i++) { if (max_samp < tiff_ifd[i].samples) max_samp = tiff_ifd[i].samples; if (max_samp > 3) max_samp = 3; + os = raw_width*raw_height; + ns = tiff_ifd[i].width*tiff_ifd[i].height; + if (tiff_bps) { + os *= tiff_bps; + ns *= tiff_ifd[i].bps; + } if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && - tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + ns && ((ns > os && (ties = 1)) || + (ns == os && shot_select == ties++))) { raw_width = tiff_ifd[i].width; raw_height = tiff_ifd[i].height; tiff_bps = tiff_ifd[i].bps; @@ -6156,9 +6229,11 @@ void CLASS apply_tiff() tiff_samples = tiff_ifd[i].samples; tile_width = tiff_ifd[i].tile_width; tile_length = tiff_ifd[i].tile_length; + shutter = tiff_ifd[i].shutter; raw = i; } } + if (is_raw == 1 && ties) is_raw = ties; if (!tile_width ) tile_width = INT_MAX; if (!tile_length) tile_length = INT_MAX; for (i=tiff_nifds; i--; ) @@ -6235,8 +6310,8 @@ void CLASS apply_tiff() if (!dng_version) if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 && (tiff_compress & -16) != 32768) - || (tiff_bps == 8 && !strcasestr(make,"Kodak") && - !strstr(model2,"DEBUG RAW"))) + || (tiff_bps == 8 && strncmp(make,"Phase",5) && + !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW"))) is_raw = 0; for (i=0; i < tiff_nifds; i++) if (i != raw && tiff_ifd[i].samples == max_samp && @@ -6377,9 +6452,7 @@ void CLASS ciff_block_1030() bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); vbits += 16; } - white[row][col] = - bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); - vbits -= bpp; + white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp); } } @@ -6658,7 +6731,7 @@ void CLASS parse_fuji (int offset) } else if (tag == 0xc000) { c = order; order = 0x4949; - if ((tag = get4()) > 10000) tag = get4(); + while ((tag = get4()) > raw_width); width = tag; height = get4(); order = c; @@ -6680,7 +6753,7 @@ int CLASS parse_jpeg (int offset) order = 0x4d4d; len = get2() - 2; save = ftell(ifp); - if (mark == 0xc0 || mark == 0xc3) { + if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) { fgetc(ifp); raw_height = get2(); raw_width = get2(); @@ -6974,8 +7047,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, { "Canon EOS D60", 0, 0xfa0, { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, - { "Canon EOS 5DS", 0, 0x3c96, /* DJC */ - { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, + { "Canon EOS 5DS", 0, 0x3c96, + { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, { "Canon EOS 5D Mark III", 0, 0x3c80, { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { "Canon EOS 5D Mark II", 0, 0x3cf0, @@ -7004,6 +7077,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, { "Canon EOS 70D", 0, 0x3bc7, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 80D", 0, 0, + { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -7024,12 +7099,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 700D", 0, 0x3c00, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 750D", 0, 0x368e, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS 760D", 0, 0x350f, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { "Canon EOS 1000D", 0, 0xe43, { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, { "Canon EOS 1100D", 0, 0x3510, { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, { "Canon EOS 1200D", 0, 0x37c2, { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS 1300D", 0, 0x3510, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { "Canon EOS M3", 0, 0, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS M10", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, { "Canon EOS M", 0, 0, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS-1Ds Mark III", 0, 0x3bb0, @@ -7048,6 +7133,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, { "Canon EOS-1D C", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D X Mark II", 0, 0, + { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, { "Canon EOS-1D X", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { "Canon EOS-1D", 0, 0xe20, @@ -7076,14 +7163,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, { "Canon PowerShot G2", 0, 0, { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3 X", 0, 0, + { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, { "Canon PowerShot G3", 0, 0, { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G5", 0, 0, { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, { "Canon PowerShot G6", 0, 0, { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, { "Canon PowerShot G7 X", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { "Canon PowerShot G9 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G9", 0, 0, { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, { "Canon PowerShot Pro1", 0, 0, @@ -7142,6 +7235,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, { "Canon PowerShot SX220", 0, 0, /* DJC */ { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, + { "Canon IXUS 160", 0, 0, /* DJC */ + { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, { "Casio EX-S20", 0, 0, /* DJC */ { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, { "Casio EX-Z750", 0, 0, /* DJC */ @@ -7156,6 +7251,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, { "Contax N Digital", 0, 0xf1e, { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "DXO ONE", 0, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Epson R-D1", 0, 0, { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, { "Fujifilm E550", 0, 0, @@ -7236,25 +7333,31 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, { "Fujifilm X30", 0, 0, { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { "Fujifilm X70", 0, 0, + { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-Pro2", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { "Fujifilm X-A1", 0, 0, { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, { "Fujifilm X-A2", 0, 0, { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E2S", 0, 0, + { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, { "Fujifilm X-E2", 0, 0, { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm X-M1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm X-T1", 0, 0, + { "Fujifilm X-T1", 0, 0, /* also X-T10 */ { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 + { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */ { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, @@ -7396,8 +7499,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D5500", 0, 0, { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { "Nikon D500", 0, 0, + { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D5", 0, 0, + { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } }, { "Nikon D600", 0, 0x3e07, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D610", 0, 0, @@ -7408,8 +7515,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D7100", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, - { "Nikon D7200", 0, 0, /* DJC */ - { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D7200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { "Nikon D750", 0, 0, { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { "Nikon D700", 0, 0, @@ -7474,8 +7581,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, { "Nikon 1 J4", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, - { "Nikon 1 J5", 0, 0, /* DJC */ - { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, + { "Nikon 1 J5", 0, 0, + { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } }, { "Nikon 1 S2", 200, 0, { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, { "Nikon 1 V2", 0, 0, @@ -7486,6 +7593,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */ { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, + { "Olympus AIR A01", 0, 0, + { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } }, { "Olympus C5050", 0, 0, { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, { "Olympus C5060", 0, 0, @@ -7556,7 +7665,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, - { "Olympus E-M10", 0, 0, + { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */ { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, @@ -7564,6 +7673,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus PEN-F", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, + { "Olympus SH-2", 0, 0, + { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } }, { "Olympus SP350", 0, 0, { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, { "Olympus SP3", 0, 0, @@ -7580,6 +7693,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, { "Olympus STYLUS1", 0, 0, { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, + { "Olympus TG-4", 0, 0, + { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "Olympus XZ-1", 0, 0, @@ -7614,6 +7729,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, { "Pentax K-r", 0, 0, { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, + { "Pentax K-1", 0, 0, + { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } }, + { "Pentax K-30", 0, 0, + { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } }, + { "Pentax K-3 II", 0, 0, + { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } }, { "Pentax K-3", 0, 0, { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, { "Pentax K-5 II", 0, 0, @@ -7624,6 +7745,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, { "Pentax K-S1", 0, 0, { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, + { "Pentax K-S2", 0, 0, + { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } }, + { "Pentax Q-S1", 0, 0, + { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } }, { "Pentax 645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, { "Panasonic DMC-CM1", 15, 0, @@ -7634,6 +7759,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, { "Panasonic DMC-FZ28", 15, 0xf96, { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ330", 15, 0, + { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, + { "Panasonic DMC-FZ300", 15, 0, + { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, { "Panasonic DMC-FZ30", 0, 0xf94, { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, { "Panasonic DMC-FZ3", 15, 0, @@ -7714,6 +7843,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, { "Panasonic DMC-G6", 15, 0xfff, { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, + { "Panasonic DMC-G7", 15, 0xfff, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GF1", 15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { "Panasonic DMC-GF2", 15, 0xfff, @@ -7726,6 +7857,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, { "Panasonic DMC-GF7", 15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GF8", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GH1", 15, 0xf92, { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, { "Panasonic DMC-GH2", 15, 0xf95, @@ -7742,6 +7875,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-GX7", 15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GX8", 15, 0, + { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, + { "Panasonic DMC-TZ1", 15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + { "Panasonic DMC-ZS1", 15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { "Panasonic DMC-TZ6", 15, 0, { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, { "Panasonic DMC-ZS4", 15, 0, @@ -7750,6 +7889,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, { "Panasonic DMC-ZS5", 15, 0, { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-TZ8", 15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { "Panasonic DMC-ZS6", 15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { "Leica S (Typ 007)", 0, 0, + { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } }, + { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */ + { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } }, + { "Leica Q (Typ 116)", 0, 0, + { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, + { "Leica M (Typ 262)", 0, 0, + { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } }, + { "Leica SL (Typ 601)", 0, 0, + { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -7764,8 +7917,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { "Phase One P65", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Photron BC2-HD", 0, 0, /* DJC */ + { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } }, { "Red One", 704, 0xffff, /* DJC */ { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, + { "Ricoh GR II", 0, 0, + { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } }, + { "Ricoh GR", 0, 0, + { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } }, { "Samsung EX1", 0, 0x3e00, { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { "Samsung EX2F", 0, 0x7ff, @@ -7774,6 +7933,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + { "Samsung NX3300", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { "Samsung NX3000", 0, 0, { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ @@ -7790,8 +7951,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { "Samsung NX10", 0, 0, /* also NX100 */ { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, - { "Samsung NX500", 0, 0, /* DJC */ - { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX500", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { "Samsung NX5", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { "Samsung NX1", 0, 0, @@ -7808,17 +7969,19 @@ void CLASS adobe_coeff (const char *make, const char *model) { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, { "Sony DSC-F828", 0, 0, { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, - { "Sony DSC-R1", 512, 0, + { "Sony DSC-R1", 0, 0, { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, - { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ + { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */ { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, - { "Sony DSC-RX100", 200, 0, + { "Sony DSC-RX100", 0, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, - { "Sony DSC-RX10", 200, 0, + { "Sony DSC-RX10", 0, 0, /* also RX10M2 */ { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, - { "Sony DSC-RX1", 128, 0, + { "Sony DSC-RX1RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony DSC-RX1", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { "Sony DSLR-A100", 0, 0xfeb, { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, @@ -7836,71 +7999,77 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, { "Sony DSLR-A390", 0, 0, { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, - { "Sony DSLR-A450", 128, 0xfeb, + { "Sony DSLR-A450", 0, 0xfeb, { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, - { "Sony DSLR-A580", 128, 0xfeb, + { "Sony DSLR-A580", 0, 0xfeb, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, - { "Sony DSLR-A500", 128, 0xfeb, + { "Sony DSLR-A500", 0, 0xfeb, { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, - { "Sony DSLR-A5", 128, 0xfeb, + { "Sony DSLR-A5", 0, 0xfeb, { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, - { "Sony DSLR-A700", 128, 0, + { "Sony DSLR-A700", 0, 0, { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, - { "Sony DSLR-A850", 128, 0, + { "Sony DSLR-A850", 0, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, - { "Sony DSLR-A900", 128, 0, + { "Sony DSLR-A900", 0, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, - { "Sony ILCA-77M2", 128, 0, + { "Sony ILCA-68", 0, 0, + { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } }, + { "Sony ILCA-77M2", 0, 0, { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, - { "Sony ILCE-7M2", 128, 0, + { "Sony ILCE-6300", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { "Sony ILCE-7M2", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE-7S", 128, 0, + { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */ { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, - { "Sony ILCE-7R", 128, 0, + { "Sony ILCE-7RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony ILCE-7R", 0, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, - { "Sony ILCE-7", 128, 0, + { "Sony ILCE-7", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ + { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony NEX-5N", 128, 0, + { "Sony NEX-5N", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony NEX-5R", 128, 0, + { "Sony NEX-5R", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-5T", 128, 0, + { "Sony NEX-5T", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-3N", 128, 0, + { "Sony NEX-3N", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3", 138, 0, /* DJC */ { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, { "Sony NEX-5", 116, 0, /* DJC */ { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, - { "Sony NEX-3", 128, 0, /* Adobe */ + { "Sony NEX-3", 0, 0, /* Adobe */ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, - { "Sony NEX-5", 128, 0, /* Adobe */ + { "Sony NEX-5", 0, 0, /* Adobe */ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, - { "Sony NEX-6", 128, 0, + { "Sony NEX-6", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-7", 128, 0, + { "Sony NEX-7", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony NEX", 128, 0, /* NEX-C3, NEX-F3 */ + { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A33", 128, 0, + { "Sony SLT-A33", 0, 0, { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, - { "Sony SLT-A35", 128, 0, + { "Sony SLT-A35", 0, 0, { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, - { "Sony SLT-A37", 128, 0, + { "Sony SLT-A37", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A55", 128, 0, + { "Sony SLT-A55", 0, 0, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, - { "Sony SLT-A57", 128, 0, + { "Sony SLT-A57", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A58", 128, 0, + { "Sony SLT-A58", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A65", 128, 0, + { "Sony SLT-A65", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony SLT-A77", 128, 0, + { "Sony SLT-A77", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony SLT-A99", 128, 0, + { "Sony SLT-A99", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, }; double cam_xyz[4][3]; @@ -8057,6 +8226,8 @@ void CLASS identify() { 5712, 3774, 62, 20, 10, 2 }, { 5792, 3804, 158, 51, 0, 0 }, { 5920, 3950, 122, 80, 2, 0 }, + { 6096, 4056, 72, 34, 0, 0 }, + { 6288, 4056, 264, 34, 0, 0 }, { 8896, 5920, 160, 64, 0, 0 }, }; static const struct { @@ -8070,6 +8241,7 @@ void CLASS identify() { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, { 0x325, "EOS 70D" }, + { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" }, { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, @@ -8079,9 +8251,12 @@ void CLASS identify() { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" }, { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" }, { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" }, + { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" }, + { 0x347, "EOS 760D" }, { 0x254, "EOS 1000D" }, { 0x288, "EOS 1100D" }, - { 0x327, "EOS 1200D" }, + { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" }, + { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" }, { 0x346, "EOS 100D" }, }, sonique[] = { { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, @@ -8109,7 +8284,10 @@ void CLASS identify() { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, - { 0x15a, "ILCE-QX1" }, + { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" }, + { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" }, + { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" }, + { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" }, }; static const struct { unsigned fsize; @@ -8146,6 +8324,7 @@ void CLASS identify() { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, + { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" }, { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" }, { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" }, @@ -8204,6 +8383,8 @@ void CLASS identify() { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" }, { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" }, { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" }, + { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" }, + { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 }, { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" }, { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" }, { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" }, @@ -8220,7 +8401,7 @@ void CLASS identify() static const char *corp[] = { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm", "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", - "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", + "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One", "Samsung", "Sigma", "Sinar", "Sony" }; char head[32], *cp; int hlen, flen, fsize, zero_fsize=1, i, c; @@ -8387,7 +8568,7 @@ void CLASS identify() parse_foveon(); else if (!memcmp (head,"CI",2)) parse_cine(); - else + if (make[0] == 0) for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) if (fsize == table[i].fsize) { strcpy (make, table[i].make ); @@ -8482,9 +8663,10 @@ void CLASS identify() width = 4014; if (dng_version) { if (filters == UINT_MAX) filters = 0; - if (filters) is_raw = tiff_samples; - else colors = tiff_samples; + if (filters) is_raw *= tiff_samples; + else colors = tiff_samples; switch (tiff_compress) { + case 0: case 1: load_raw = &CLASS packed_dng_load_raw; break; case 7: load_raw = &CLASS lossless_dng_load_raw; break; case 34892: load_raw = &CLASS lossy_dng_load_raw; break; @@ -8536,6 +8718,8 @@ void CLASS identify() top_margin = filters = 0; strcpy (model,"C603"); } + if (!strcmp(make,"Sony") && raw_width > 3888) + black = 128 << (tiff_bps - 12); if (is_foveon) { if (height*2 < width) pixel_aspect = 0.5; if (height > width) pixel_aspect = 2; @@ -8550,6 +8734,10 @@ void CLASS identify() SWAP(height,width); SWAP(raw_height,raw_width); } + if (width == 7200 && height == 3888) { + raw_width = width = 6480; + raw_height = height = 4320; + } filters = 0; tiff_samples = colors = 3; load_raw = &CLASS canon_sraw_load_raw; @@ -8725,7 +8913,7 @@ canon_a5: top_margin = (raw_height - height) >> 2 << 1; left_margin = (raw_width - width ) >> 2 << 1; if (width == 2848 || width == 3664) filters = 0x16161616; - if (width == 4032 || width == 4952) left_margin = 0; + if (width == 4032 || width == 4952 || width == 6032) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; if (width == 4936) left_margin = 4; if (!strcmp(model,"HS50EXR") || @@ -8968,6 +9156,8 @@ konica_400z: thumb_length = flen - (thumb_offset = 0xa39800); thumb_height = 480; thumb_width = 640; + } else if (!strcmp(model,"TG-4")) { + width -= 16; } } else if (!strcmp(model,"N Digital")) { height = 2047; @@ -8995,16 +9185,29 @@ konica_400z: order = 0x4d4d; } else if (!strcmp(make,"Sony") && raw_width == 4288) { width -= 32; + } else if (!strcmp(make,"Sony") && raw_width == 4600) { + if (!strcmp(model,"DSLR-A350")) + height -= 4; + black = 0; } else if (!strcmp(make,"Sony") && raw_width == 4928) { if (height < 3280) width -= 8; } else if (!strcmp(make,"Sony") && raw_width == 5504) { width -= height > 3664 ? 8 : 32; + if (!strncmp(model,"DSC",3)) + black = 200 << (tiff_bps - 12); } else if (!strcmp(make,"Sony") && raw_width == 6048) { width -= 24; if (strstr(model,"RX1") || strstr(model,"A99")) width -= 6; } else if (!strcmp(make,"Sony") && raw_width == 7392) { width -= 30; + } else if (!strcmp(make,"Sony") && raw_width == 8000) { + width -= 32; + if (!strncmp(model,"DSC",3)) { + tiff_bps = 14; + load_raw = &CLASS unpacked_load_raw; + black = 512; + } } else if (!strcmp(model,"DSLR-A100")) { if (width == 3880) { height--; @@ -9016,8 +9219,6 @@ konica_400z: load_flags = 2; } filters = 0x61616161; - } else if (!strcmp(model,"DSLR-A350")) { - height -= 4; } else if (!strcmp(model,"PIXL")) { height -= top_margin = 4; width -= left_margin = 32; @@ -9082,6 +9283,7 @@ bw: colors = 1; width = 768; data_offset = 1152; load_raw = &CLASS kodak_radc_load_raw; + tiff_bps = 12; } else if (strstr(model,"DC50")) { strcpy (model, "DC50"); height = 512; @@ -9160,7 +9362,7 @@ dng_skip: if (raw_color) adobe_coeff ("Apple","Quicktake"); if (fuji_width) { fuji_width = width >> !fuji_layout; - if (~fuji_width & 1) filters = 0x49494949; + filters = fuji_width & 1 ? 0x94949494 : 0x49494949; width = (height >> fuji_layout) + fuji_width; height = width - 1; pixel_aspect = 1; @@ -9274,10 +9476,14 @@ void CLASS convert_to_rgb() { { 0.529317, 0.330092, 0.140588 }, { 0.098368, 0.873465, 0.028169 }, { 0.016879, 0.117663, 0.865457 } }; + static const double aces_rgb[3][3] = + { { 0.432996, 0.375380, 0.189317 }, + { 0.089427, 0.816523, 0.102989 }, + { 0.019165, 0.118150, 0.941914 } }; static const double (*out_rgb[])[3] = - { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; + { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb }; static const char *name[] = - { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; + { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" }; static const unsigned phead[] = { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; @@ -9298,7 +9504,7 @@ void CLASS convert_to_rgb() gamma_curve (gamm[0], gamm[1], 0, 0); memcpy (out_cam, rgb_cam, sizeof out_cam); raw_color |= colors == 1 || document_mode || - output_color < 1 || output_color > 5; + output_color < 1 || output_color > 6; if (!raw_color) { oprof = (unsigned *) calloc (phead[0], 1); merror (oprof, "convert_to_rgb()"); @@ -9461,21 +9667,25 @@ struct tiff_hdr { char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; -void CLASS tiff_set (ushort *ntag, +void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag, ushort tag, ushort type, int count, int val) { struct tiff_tag *tt; int c; tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; - tt->tag = tag; - tt->type = type; - tt->count = count; - if (type < 3 && count <= 4) + tt->val.i = val; + if (type == 1 && count <= 4) FORC(4) tt->val.c[c] = val >> (c << 3); - else if (type == 3 && count <= 2) + else if (type == 2) { + count = strnlen((char *)th + val, count-1) + 1; + if (count <= 4) + FORC(4) tt->val.c[c] = ((char *)th)[val+c]; + } else if (type == 3 && count <= 2) FORC(2) tt->val.s[c] = val >> (c << 4); - else tt->val.i = val; + tt->count = count; + tt->type = type; + tt->tag = tag; } #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) @@ -9489,55 +9699,6 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) th->order = htonl(0x4d4d4949) >> 16; th->magic = 42; th->ifd = 10; - if (full) { - tiff_set (&th->ntag, 254, 4, 1, 0); - tiff_set (&th->ntag, 256, 4, 1, width); - tiff_set (&th->ntag, 257, 4, 1, height); - tiff_set (&th->ntag, 258, 3, colors, output_bps); - if (colors > 2) - th->tag[th->ntag-1].val.i = TOFF(th->bps); - FORC4 th->bps[c] = output_bps; - tiff_set (&th->ntag, 259, 3, 1, 1); - tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); - } - tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); - tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); - tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); - if (full) { - if (oprof) psize = ntohl(oprof[0]); - tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); - tiff_set (&th->ntag, 277, 3, 1, colors); - tiff_set (&th->ntag, 278, 4, 1, height); - tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); - } else - tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); - tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); - tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); - tiff_set (&th->ntag, 284, 3, 1, 1); - tiff_set (&th->ntag, 296, 3, 1, 2); - tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); - tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); - tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); - tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); - if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); - tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); - tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); - tiff_set (&th->nexif, 34855, 3, 1, iso_speed); - tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); - if (gpsdata[1]) { - tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); - tiff_set (&th->ngps, 0, 1, 4, 0x202); - tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); - tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); - tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); - tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); - tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); - tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); - tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); - tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); - tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); - memcpy (th->gps, gpsdata, sizeof th->gps); - } th->rat[0] = th->rat[2] = 300; th->rat[1] = th->rat[3] = 1; FORC(6) th->rat[4+c] = 1000000; @@ -9552,6 +9713,55 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); strncpy (th->artist, artist, 64); + if (full) { + tiff_set (th, &th->ntag, 254, 4, 1, 0); + tiff_set (th, &th->ntag, 256, 4, 1, width); + tiff_set (th, &th->ntag, 257, 4, 1, height); + tiff_set (th, &th->ntag, 258, 3, colors, output_bps); + if (colors > 2) + th->tag[th->ntag-1].val.i = TOFF(th->bps); + FORC4 th->bps[c] = output_bps; + tiff_set (th, &th->ntag, 259, 3, 1, 1); + tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1)); + } + tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc)); + tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make)); + tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model)); + if (full) { + if (oprof) psize = ntohl(oprof[0]); + tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize); + tiff_set (th, &th->ntag, 277, 3, 1, colors); + tiff_set (th, &th->ntag, 278, 4, 1, height); + tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8); + } else + tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0'); + tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0])); + tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2])); + tiff_set (th, &th->ntag, 284, 3, 1, 1); + tiff_set (th, &th->ntag, 296, 3, 1, 2); + tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft)); + tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist)); + tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif)); + if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th); + tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4])); + tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6])); + tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed); + tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8])); + if (gpsdata[1]) { + tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps)); + tiff_set (th, &th->ngps, 0, 1, 4, 0x202); + tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]); + tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0])); + tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]); + tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6])); + tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]); + tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18])); + tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12])); + tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20])); + tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23])); + memcpy (th->gps, gpsdata, sizeof th->gps); + } } void CLASS jpeg_thumb() @@ -9672,7 +9882,7 @@ int CLASS main (int argc, const char **argv) puts(_("-n Set threshold for wavelet denoising")); puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); - puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); + puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)")); #ifndef NO_LCMS puts(_("-o Apply output ICC profile from file")); puts(_("-p Apply camera ICC profile from file or \"embed\"")); diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index c0dbd816d..3593f2777 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -10,9 +10,10 @@ /*RT*/#define LOCALTIME /*RT*/#define DJGPP +#include "opthelper.h" /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net This is a command-line ANSI C program to convert raw photos from any digital camera on any computer running any operating system. @@ -31,11 +32,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.475 $ - $Date: 2015/04/11 00:08:36 $ + $Revision: 1.477 $ + $Date: 2016/05/10 21:30:43 $ */ -#define DCRAW_VERSION "9.25" +#define DCRAW_VERSION "9.27" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -100,15 +101,6 @@ typedef unsigned long long UINT64; #define _(String) (String) #endif -#ifdef LJPEG_DECODE -#error Please compile dcraw.c by itself. -#error Do not link it with ljpeg_decode. -#endif - -#ifndef LONG_BIT -#define LONG_BIT (8 * sizeof (long)) -#endif - #define ushort UshORt typedef unsigned char uchar; typedef unsigned short ushort; @@ -139,7 +131,7 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 }; #define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) #define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) #define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) -#define ULIM(x,y,z) rtengine::ULIM(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) +#define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) #define CLIP(x) rtengine::CLIP(x) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } @@ -560,13 +552,13 @@ int CLASS canon_s2is() return 0; } -unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) +inline unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) { /*RT static unsigned bitbuf=0; */ /*RT static int vbits=0, reset=0; */ unsigned c; - if (nbits > 25) return 0; + if (UNLIKELY(nbits > 25)) return 0; if (nbits < 0) return bitbuf = vbits = reset = 0; if (nbits == 0 || vbits < 0) return 0; @@ -787,17 +779,15 @@ struct jhead { int CLASS ljpeg_start (struct jhead *jh, int info_only) { - int c, tag; - ushort len; + ushort c, tag, len; uchar data[0x10000]; const uchar *dp; memset (jh, 0, sizeof *jh); jh->restart = INT_MAX; - fread (data, 2, 1, ifp); - if (data[1] != 0xd8) return 0; + if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0; do { - fread (data, 2, 2, ifp); + if (!fread (data, 2, 2, ifp)) return 0; tag = data[0] << 8 | data[1]; len = (data[2] << 8 | data[3]) - 2; if (tag <= 0xff00) return 0; @@ -805,7 +795,9 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) switch (tag) { case 0xffc3: jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc1: case 0xffc0: + jh->algo = tag & 0xff; jh->bits = data[0]; jh->high = data[1] << 8 | data[2]; jh->wide = data[3] << 8 | data[4]; @@ -814,25 +806,30 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) break; case 0xffc4: if (info_only) break; - for (dp = data; dp < data+len && (c = *dp++) < 4; ) + for (dp = data; dp < data+len && !((c = *dp++) & -20); ) jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); break; case 0xffda: jh->psv = data[1+data[0]*2]; jh->bits -= data[3+data[0]*2] & 15; break; + case 0xffdb: + FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2]; + break; case 0xffdd: jh->restart = data[0] << 8 | data[1]; } } while (tag != 0xffda); + if (jh->bits > 16 || jh->clrs > 6 || + !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; if (info_only) return 1; - if (jh->clrs > 6 || !jh->huff[0]) return 0; - FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (!jh->huff[0]) return 0; + FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; if (jh->sraw) { FORC(4) jh->huff[2+c] = jh->huff[1]; FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; } - jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + jh->row = (ushort *) calloc (2 * jh->wide*jh->clrs, 4); merror (jh->row, "ljpeg_start()"); return zero_after_ff = 1; } @@ -844,7 +841,7 @@ void CLASS ljpeg_end (struct jhead *jh) free (jh->row); } -int CLASS ljpeg_diff (ushort *huff) +inline int CLASS ljpeg_diff (ushort *huff) { int len, diff; @@ -871,7 +868,7 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) } getbits(-1); } - FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); + FORC3 row[c] = (jh->row + ((jrow & 1) + 1) * (jh->wide*jh->clrs*((jrow+c) & 1))); for (col=0; col < jh->wide; col++) FORC(jh->clrs) { diff = ljpeg_diff (jh->huff[c]); @@ -879,8 +876,7 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) pred = spred; else if (col) pred = row[0][-jh->clrs]; else pred = (jh->vpred[c] += diff) - diff; - if (jrow && col) switch (jh->psv) { - case 1: break; + if (jh->psv != 1 && jrow && col) switch (jh->psv) { case 2: pred = row[1][0]; break; case 3: pred = row[1][-jh->clrs]; break; case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; @@ -889,7 +885,7 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) case 7: pred = (pred + row[1][0]) >> 1; break; default: pred = 0; } - if ((**row = pred + diff) >> jh->bits) derror(); + if (UNLIKELY((**row = pred + diff) >> jh->bits)) derror(); if (c <= jh->sraw) spred = **row; row[0]++; row[1]++; } @@ -898,22 +894,38 @@ ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) void CLASS lossless_jpeg_load_raw() { - int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; struct jhead jh; - ushort *rp; + int row=0, col=0; if (!ljpeg_start (&jh, 0)) return; - jwide = jh.wide * jh.clrs; + int jwide = jh.wide * jh.clrs; + ushort *rp[2]; + rp[0] = ljpeg_row (0, &jh); - for (jrow=0; jrow < jh.high; jrow++) { - rp = ljpeg_row (jrow, &jh); + for (int jrow=0; jrow < jh.high; jrow++) { +#ifdef _OPENMP +#pragma omp parallel sections +#endif +{ +#ifdef _OPENMP + #pragma omp section +#endif + { + if(jrow < jh.high - 1) + rp[(jrow + 1)&1] = ljpeg_row (jrow + 1, &jh); + } +#ifdef _OPENMP + #pragma omp section +#endif + { if (load_flags & 1) row = jrow & 1 ? height-1-jrow/2 : jrow/2; - for (jcol=0; jcol < jwide; jcol++) { - val = curve[*rp++]; + for (int jcol=0; jcol < jwide; jcol++) { + int val = curve[*rp[jrow&1]++]; if (cr2_slice[0]) { - jidx = jrow*jwide + jcol; - i = jidx / (cr2_slice[1]*raw_height); + int jidx = jrow*jwide + jcol; + int i = jidx / (cr2_slice[1]*raw_height); + int j; if ((j = i >= cr2_slice[0])) i = cr2_slice[0]; jidx -= i * (cr2_slice[1]*raw_height); @@ -926,6 +938,8 @@ void CLASS lossless_jpeg_load_raw() if (++col >= raw_width) col = (row++,0); } + } +} } ljpeg_end (&jh); } @@ -1006,23 +1020,59 @@ void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) { int c; - if (is_raw == 2 && shot_select) (*rp)++; + if (tiff_samples == 2 && shot_select) (*rp)++; if (raw_image) { if (row < raw_height && col < raw_width) RAW(row,col) = curve[**rp]; - *rp += is_raw; + *rp += tiff_samples; } else { if (row < height && col < width) FORC(tiff_samples) image[row*width+col][c] = curve[(*rp)[c]]; *rp += tiff_samples; } - if (is_raw == 2 && shot_select) (*rp)--; + if (tiff_samples == 2 && shot_select) (*rp)--; +} + +void CLASS ljpeg_idct (struct jhead *jh) +{ + int c, i, j, len, skip, coef; + float work[3][8][8]; + static float cs[106] = { 0 }; + static const uchar zigzag[80] = + { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33, + 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54, + 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 }; + + if (!cs[0]) + FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2; + memset (work, 0, sizeof work); + work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0]; + for (i=1; i < 64; i++ ) { + len = gethuff (jh->huff[16]); + i += skip = len >> 4; + if (!(len &= 15) && skip < 15) break; + coef = getbits(len); + if ((coef & (1 << (len-1))) == 0) + coef -= (1 << len) - 1; + ((float *)work)[zigzag[i]] = coef * jh->quant[i]; + } + FORC(8) work[0][0][c] *= M_SQRT1_2; + FORC(8) work[0][c][0] *= M_SQRT1_2; + for (i=0; i < 8; i++) + for (j=0; j < 8; j++) + FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c]; + for (i=0; i < 8; i++) + for (j=0; j < 8; j++) + FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c]; + + FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5); } void CLASS lossless_dng_load_raw() { - unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j; struct jhead jh; ushort *rp; @@ -1033,15 +1083,32 @@ void CLASS lossless_dng_load_raw() if (!ljpeg_start (&jh, 0)) break; jwide = jh.wide; if (filters) jwide *= jh.clrs; - jwide /= is_raw; - for (row=col=jrow=0; jrow < jh.high; jrow++) { - rp = ljpeg_row (jrow, &jh); - for (jcol=0; jcol < jwide; jcol++) { - adobe_copy_pixel (trow+row, tcol+col, &rp); - if (++col >= tile_width || col >= raw_width) - row += 1 + (col = 0); - } - } + jwide /= MIN (is_raw, tiff_samples); + switch (jh.algo) { + case 0xc1: + jh.vpred[0] = 16384; + getbits(-1); + for (jrow=0; jrow+7 < jh.high; jrow += 8) { + for (jcol=0; jcol+7 < jh.wide; jcol += 8) { + ljpeg_idct (&jh); + rp = jh.idct; + row = trow + jcol/tile_width + jrow*2; + col = tcol + jcol%tile_width; + for (i=0; i < 16; i+=2) + for (j=0; j < 8; j++) + adobe_copy_pixel (row+i, col+j, &rp); + } + } + break; + case 0xc3: + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } } fseek (ifp, save+4, SEEK_SET); if ((tcol += tile_width) >= raw_width) trow += tile_length + (tcol = 0); @@ -1685,8 +1752,7 @@ void CLASS phase_one_load_raw_c() pixel[col] = curve[pixel[col]]; } for (col=0; col < raw_width; col++) { - if (ph1.format != 8) pixel[col] <<= 2; - i = pixel[col] - ph1.black + i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black + cblack[row][col >= ph1.split_col] + rblack[col][row >= ph1.split_row]; if (i > 0) RAW(row,col) = i; @@ -3111,6 +3177,8 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes) fseek (ifp, seg[0][1]+1, SEEK_SET); getbits(-1); + if (seg[1][0] > raw_width*raw_height) + seg[1][0] = raw_width*raw_height; for (pix=seg[0][0]; pix < seg[1][0]; pix++) { for (s=0; s < 3; s++) { data = data << nbits | getbits(nbits); @@ -3153,7 +3221,10 @@ void CLASS smal_decode_segment (unsigned seg[2][2], int holes) diff = diff ? -diff : 0x80; if (ftell(ifp) + 12 >= seg[1][1]) diff = 0; - raw_image[pix] = pred[pix & 1] += diff; + if(pix>=raw_width*raw_height) + derror(); + else + raw_image[pix] = pred[pix & 1] += diff; if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; } maximum = 0xff; @@ -5237,7 +5308,7 @@ nf: order = 0x4949; FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); } if (tag == 0x3d && type == 3 && len == 4) - FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps); if (tag == 0x81 && type == 4) { data_offset = get4(); fseek (ifp, data_offset + 41, SEEK_SET); @@ -5267,7 +5338,8 @@ nf: order = 0x4949; break; case 102: fseek (ifp, 6, SEEK_CUR); - goto get2_rggb; + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + break; case 103: fseek (ifp, 16, SEEK_CUR); FORC4 cam_mul[c] = get2(); @@ -5301,7 +5373,7 @@ nf: order = 0x4949; if (tag == 0x200 && len == 4) FORC4 cblack[c ^ c >> 1] = get2(); if (tag == 0x201 && len == 4) - goto get2_rggb; + FORC4 cam_mul[c ^ (c >> 1)] = get2(); if (tag == 0x220 && type == 7) meta_offset = ftell(ifp); if (tag == 0x401 && type == 4 && len == 4) @@ -5347,7 +5419,7 @@ get2_256: } if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) fseek (ifp, get4()+base, SEEK_SET); - if (tag == 0x2020) + if (tag == 0x2020 && !strncmp(buf,"OLYMP",5)) parse_thumb_note (base, 257, 258); if (tag == 0x2040) parse_makernote (base, 0x2040); @@ -5358,11 +5430,12 @@ get2_256: if (tag == 0x4001 && len > 500) { i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; fseek (ifp, i, SEEK_CUR); -get2_rggb: FORC4 cam_mul[c ^ (c >> 1)] = get2(); - i = len >> 3 == 164 || len == 1506 ? 112:22; - fseek (ifp, i, SEEK_CUR); - FORC4 sraw_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; + } } if (tag == 0x4021 && get4() && get4()) FORC4 cam_mul[c] = 1024; @@ -5415,13 +5488,14 @@ void CLASS parse_exif (int base) while (entries--) { tiff_get (base, &tag, &type, &len, &save); switch (tag) { - case 33434: shutter = getreal(type); break; + case 33434: tiff_ifd[tiff_nifds-1].shutter = shutter = getreal(type); break; case 33437: aperture = getreal(type); break; case 34855: iso_speed = get2(); break; case 34866: if((!iso_speed) || iso_speed == 65535) iso_speed = get4();break; case 36867: case 36868: get_timestamp(0); break; case 37377: if ((expo = -getreal(type)) < 128) + tiff_ifd[tiff_nifds-1].shutter = shutter = pow (2, expo); break; case 37378: aperture = pow (2, getreal(type)/2); break; case 37386: focal_len = getreal(type); break; @@ -5664,6 +5738,8 @@ int CLASS parse_tiff_ifd (int base) case 61443: tiff_ifd[ifd].samples = len & 7; tiff_ifd[ifd].bps = getint(type); + if (tiff_bps < tiff_ifd[ifd].bps) + tiff_bps = tiff_ifd[ifd].bps; break; case 61446: raw_height = 0; @@ -5835,7 +5911,7 @@ int CLASS parse_tiff_ifd (int base) parse_kodak_ifd (base); break; case 33434: /* ExposureTime */ - shutter = getreal(type); + tiff_ifd[ifd].shutter = shutter = getreal(type); break; case 33437: /* FNumber */ aperture = getreal(type); @@ -5964,7 +6040,12 @@ int CLASS parse_tiff_ifd (int base) is_raw = 1; break; case 50708: /* UniqueCameraModel */ - fgets (model3, 64, ifp); + if (model[0]) break; + fgets (make, 64, ifp); + if ((cp = strchr(make,' '))) { + strcpy(model,cp+1); + *cp = 0; + } break; case 50710: /* CFAPlaneColor */ if (filters == 9) break; @@ -5979,10 +6060,7 @@ guess_cfa_pc: filters -= !filters; break; case 50711: /* CFALayout */ - if (get2() == 2) { - fuji_width = 1; - filters = 0x49494949; - } + if (get2() == 2) fuji_width = 1; break; case 291: case 50712: /* LinearizationTable */ @@ -6014,7 +6092,7 @@ guess_cfa_pc: break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ - for (num=i=0; i < len; i++) + for (num=i=0; i < (len & 0xffff); i++) num += getreal(type); black += num/len + 0.5; break; @@ -6144,7 +6222,7 @@ int CLASS parse_tiff (int base) void CLASS apply_tiff() { - int max_samp=0, raw=-1, thm=-1, i; + int max_samp=0, ties=0, os, ns, raw=-1, thm=-1, i; struct jhead jh; thumb_misc = 16; @@ -6156,13 +6234,26 @@ void CLASS apply_tiff() thumb_height = jh.high; } } + for (i=tiff_nifds; i--; ) { + if (tiff_ifd[i].shutter) + shutter = tiff_ifd[i].shutter; + tiff_ifd[i].shutter = shutter; + } + for (i=0; i < tiff_nifds; i++) { if (max_samp < tiff_ifd[i].samples) max_samp = tiff_ifd[i].samples; if (max_samp > 3) max_samp = 3; + os = raw_width*raw_height; + ns = tiff_ifd[i].width*tiff_ifd[i].height; + if (tiff_bps) { + os *= tiff_bps; + ns *= tiff_ifd[i].bps; + } if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && - tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + ns && ((ns > os && (ties = 1)) || + (ns == os && shot_select == ties++))) { raw_width = tiff_ifd[i].width; raw_height = tiff_ifd[i].height; tiff_bps = tiff_ifd[i].bps; @@ -6172,9 +6263,11 @@ void CLASS apply_tiff() tiff_samples = tiff_ifd[i].samples; tile_width = tiff_ifd[i].tile_width; tile_length = tiff_ifd[i].tile_length; + shutter = tiff_ifd[i].shutter; raw = i; } } + if (is_raw == 1 && ties) is_raw = ties; if (!tile_width ) tile_width = INT_MAX; if (!tile_length) tile_length = INT_MAX; for (i=tiff_nifds; i--; ) @@ -6257,8 +6350,8 @@ void CLASS apply_tiff() if (!dng_version) if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 && (tiff_compress & -16) != 32768) - || (tiff_bps == 8 && !strcasestr(make,"Kodak") && - !strstr(model2,"DEBUG RAW"))) + || (tiff_bps == 8 && strncmp(make,"Phase",5) && + !strcasestr(make,"Kodak") && !strstr(model2,"DEBUG RAW"))) is_raw = 0; for (i=0; i < tiff_nifds; i++) if (i != raw && tiff_ifd[i].samples == max_samp && @@ -6400,9 +6493,7 @@ void CLASS ciff_block_1030() bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); vbits += 16; } - white[row][col] = - bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); - vbits -= bpp; + white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp); } } @@ -6682,7 +6773,7 @@ void CLASS parse_fuji (int offset) } else if (tag == 0xc000) { c = order; order = 0x4949; - while ((tag = get4()) > 10000); + while ((tag = get4()) > raw_width); width = tag; height = get4(); order = c; @@ -6704,7 +6795,7 @@ int CLASS parse_jpeg (int offset) order = 0x4d4d; len = get2() - 2; save = ftell(ifp); - if (mark == 0xc0 || mark == 0xc3) { + if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9) { fgetc(ifp); raw_height = get2(); raw_width = get2(); @@ -7003,8 +7094,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, { "Canon EOS D60", 0, 0xfa0, { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, - { "Canon EOS 5DS", 0, 0x3c96, /* DJC */ - { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, + { "Canon EOS 5DS", 0, 0x3c96, + { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, { "Canon EOS 5D Mark III", 0, 0x3c80, { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { "Canon EOS 5D Mark II", 0, 0x3cf0, @@ -7033,6 +7124,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, { "Canon EOS 70D", 0, 0x3bc7, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 80D", 0, 0, + { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -7053,12 +7146,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 700D", 0, 0x3c00, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 750D", 0, 0x368e, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS 760D", 0, 0x350f, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { "Canon EOS 1000D", 0, 0xe43, { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, { "Canon EOS 1100D", 0, 0x3510, { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, { "Canon EOS 1200D", 0, 0x37c2, { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS 1300D", 0, 0x3510, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { "Canon EOS M3", 0, 0, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS M10", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, { "Canon EOS M", 0, 0, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS-1Ds Mark III", 0, 0x3bb0, @@ -7077,6 +7180,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, { "Canon EOS-1D C", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D X Mark II", 0, 0, + { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, { "Canon EOS-1D X", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, { "Canon EOS-1D", 0, 0xe20, @@ -7105,14 +7210,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, { "Canon PowerShot G2", 0, 0, { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3 X", 0, 0, + { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, { "Canon PowerShot G3", 0, 0, { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G5", 0, 0, { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, { "Canon PowerShot G6", 0, 0, { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, { "Canon PowerShot G7 X", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { "Canon PowerShot G9 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G9", 0, 0, { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, { "Canon PowerShot Pro1", 0, 0, @@ -7171,6 +7282,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, { "Canon PowerShot SX220", 0, 0, /* DJC */ { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, + { "Canon IXUS 160", 0, 0, /* DJC */ + { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, { "Casio EX-S20", 0, 0, /* DJC */ { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, { "Casio EX-Z750", 0, 0, /* DJC */ @@ -7185,6 +7298,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, { "Contax N Digital", 0, 0xf1e, { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "DXO ONE", 0, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Epson R-D1", 0, 0, { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, { "Fujifilm E550", 0, 0, @@ -7265,25 +7380,31 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, { "Fujifilm X30", 0, 0, { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { "Fujifilm X70", 0, 0, + { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-Pro2", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { "Fujifilm X-A1", 0, 0, { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, { "Fujifilm X-A2", 0, 0, { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E2S", 0, 0, + { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, { "Fujifilm X-E2", 0, 0, { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm X-M1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm X-T1", 0, 0, + { "Fujifilm X-T1", 0, 0, /* also X-T10 */ { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 + { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */ { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, @@ -7425,8 +7546,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D5500", 0, 0, { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { "Nikon D500", 0, 0, + { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D5", 0, 0, + { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } }, { "Nikon D600", 0, 0x3e07, { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D610", 0, 0, @@ -7437,8 +7562,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D7100", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, - { "Nikon D7200", 0, 0, /* DJC */ - { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D7200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { "Nikon D750", 0, 0, { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { "Nikon D700", 0, 0, @@ -7503,8 +7628,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, { "Nikon 1 J4", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, - { "Nikon 1 J5", 0, 0, /* DJC */ - { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, + { "Nikon 1 J5", 0, 0, + { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } }, { "Nikon 1 S2", 200, 0, { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, { "Nikon 1 V2", 0, 0, @@ -7515,6 +7640,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */ { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, + { "Olympus AIR A01", 0, 0, + { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } }, { "Olympus C5050", 0, 0, { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, { "Olympus C5060", 0, 0, @@ -7585,7 +7712,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, - { "Olympus E-M10", 0, 0, + { "Olympus E-M10", 0, 0, /* also E-M10 Mark II */ { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, @@ -7593,6 +7720,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus PEN-F", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, + { "Olympus SH-2", 0, 0, + { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } }, { "Olympus SP350", 0, 0, { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, { "Olympus SP3", 0, 0, @@ -7609,6 +7740,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, { "Olympus STYLUS1", 0, 0, { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, + { "Olympus TG-4", 0, 0, + { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "Olympus XZ-1", 0, 0, @@ -7643,6 +7776,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, { "Pentax K-r", 0, 0, { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, + { "Pentax K-1", 0, 0, + { 8566,-2746,-1201,-3612,12204,1550,-893,1680,6264 } }, + { "Pentax K-30", 0, 0, + { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } }, + { "Pentax K-3 II", 0, 0, + { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } }, { "Pentax K-3", 0, 0, { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, { "Pentax K-5 II", 0, 0, @@ -7653,6 +7792,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, { "Pentax K-S1", 0, 0, { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, + { "Pentax K-S2", 0, 0, + { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } }, + { "Pentax Q-S1", 0, 0, + { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } }, { "Pentax 645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, { "Panasonic DMC-CM1", 15, 0, @@ -7663,6 +7806,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, { "Panasonic DMC-FZ28", 15, 0xf96, { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ330", 15, 0, + { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, + { "Panasonic DMC-FZ300", 15, 0, + { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, { "Panasonic DMC-FZ30", 0, 0xf94, { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, { "Panasonic DMC-FZ3", 15, 0, @@ -7743,6 +7890,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, { "Panasonic DMC-G6", 15, 0xfff, { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, + { "Panasonic DMC-G7", 15, 0xfff, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GF1", 15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { "Panasonic DMC-GF2", 15, 0xfff, @@ -7755,6 +7904,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, { "Panasonic DMC-GF7", 15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GF8", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GH1", 15, 0xf92, { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, { "Panasonic DMC-GH2", 15, 0xf95, @@ -7771,6 +7922,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-GX7", 15, 0, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GX8", 15, 0, + { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, + { "Panasonic DMC-TZ1", 15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + { "Panasonic DMC-ZS1", 15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { "Panasonic DMC-TZ6", 15, 0, { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, { "Panasonic DMC-ZS4", 15, 0, @@ -7779,6 +7936,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, { "Panasonic DMC-ZS5", 15, 0, { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-TZ8", 15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { "Panasonic DMC-ZS6", 15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { "Leica S (Typ 007)", 0, 0, + { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } }, + { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */ + { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } }, + { "Leica Q (Typ 116)", 0, 0, + { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, + { "Leica M (Typ 262)", 0, 0, + { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } }, + { "Leica SL (Typ 601)", 0, 0, + { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830} }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -7793,8 +7964,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { "Phase One P65", 0, 0, { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Photron BC2-HD", 0, 0, /* DJC */ + { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } }, { "Red One", 704, 0xffff, /* DJC */ { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, + { "Ricoh GR II", 0, 0, + { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } }, + { "Ricoh GR", 0, 0, + { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } }, { "Samsung EX1", 0, 0x3e00, { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { "Samsung EX2F", 0, 0x7ff, @@ -7803,6 +7980,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + { "Samsung NX3300", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { "Samsung NX3000", 0, 0, { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ @@ -7819,8 +7998,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { "Samsung NX10", 0, 0, /* also NX100 */ { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, - { "Samsung NX500", 0, 0, /* DJC */ - { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX500", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { "Samsung NX5", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, { "Samsung NX1", 0, 0, @@ -7837,18 +8016,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, { "Sony DSC-F828", 0, 0, { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, - { "Sony DSC-R1", 512, 0, + { "Sony DSC-R1", 0, 0, { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, - { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ + { "Sony DSC-RX100M", 0, 0, /* M2, M3, and M4 */ { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, - { "Sony DSC-RX100", 200, 0, + { "Sony DSC-RX100", 0, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, - { "Sony DSC-RX10", 200, 0, + { "Sony DSC-RX10", 0, 0, { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, - { "Sony DSC-RX1", 128, 0, - { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { "Sony DSC-RX1RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony DSC-RX1", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { "Sony DSLR-A100", 0, 0xfeb, { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, { "Sony DSLR-A290", 0, 0, @@ -7865,71 +8046,77 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, { "Sony DSLR-A390", 0, 0, { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, - { "Sony DSLR-A450", 128, 0xfeb, + { "Sony DSLR-A450", 0, 0xfeb, { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, - { "Sony DSLR-A580", 128, 0xfeb, + { "Sony DSLR-A580", 0, 0xfeb, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, - { "Sony DSLR-A500", 128, 0xfeb, + { "Sony DSLR-A500", 0, 0xfeb, { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, - { "Sony DSLR-A5", 128, 0xfeb, + { "Sony DSLR-A5", 0, 0xfeb, { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, - { "Sony DSLR-A700", 128, 0, + { "Sony DSLR-A700", 0, 0, { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, - { "Sony DSLR-A850", 128, 0, + { "Sony DSLR-A850", 0, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, - { "Sony DSLR-A900", 128, 0, + { "Sony DSLR-A900", 0, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, - { "Sony ILCA-77M2", 128, 0, + { "Sony ILCA-68", 0, 0, + { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } }, + { "Sony ILCA-77M2", 0, 0, { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, - { "Sony ILCE-7M2", 128, 0, + { "Sony ILCE-6300", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { "Sony ILCE-7M2", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE-7S", 128, 0, + { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */ { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, - { "Sony ILCE-7R", 128, 0, + { "Sony ILCE-7RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony ILCE-7R", 0, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, - { "Sony ILCE-7", 128, 0, + { "Sony ILCE-7", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ + { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony NEX-5N", 128, 0, + { "Sony NEX-5N", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony NEX-5R", 128, 0, + { "Sony NEX-5R", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-5T", 128, 0, + { "Sony NEX-5T", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-3N", 128, 0, + { "Sony NEX-3N", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-3", 138, 0, /* DJC */ { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, { "Sony NEX-5", 116, 0, /* DJC */ { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, - { "Sony NEX-3", 128, 0, /* Adobe */ + { "Sony NEX-3", 0, 0, /* Adobe */ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, - { "Sony NEX-5", 128, 0, /* Adobe */ + { "Sony NEX-5", 0, 0, /* Adobe */ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, - { "Sony NEX-6", 128, 0, + { "Sony NEX-6", 0, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "Sony NEX-7", 128, 0, + { "Sony NEX-7", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony NEX", 128, 0, /* NEX-C3, NEX-F3 */ + { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A33", 128, 0, + { "Sony SLT-A33", 0, 0, { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, - { "Sony SLT-A35", 128, 0, + { "Sony SLT-A35", 0, 0, { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, - { "Sony SLT-A37", 128, 0, + { "Sony SLT-A37", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A55", 128, 0, + { "Sony SLT-A55", 0, 0, { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, - { "Sony SLT-A57", 128, 0, + { "Sony SLT-A57", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A58", 128, 0, + { "Sony SLT-A58", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony SLT-A65", 128, 0, + { "Sony SLT-A65", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony SLT-A77", 128, 0, + { "Sony SLT-A77", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony SLT-A99", 128, 0, + { "Sony SLT-A99", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, }; double cam_xyz[4][3]; @@ -8113,6 +8300,8 @@ void CLASS identify() { 5712, 3774, 62, 20, 10, 2 }, { 5792, 3804, 158, 51, 0, 0 }, { 5920, 3950, 122, 80, 2, 0 }, + { 6096, 4056, 72, 34, 0, 0 }, + { 6288, 4056, 264, 34, 0, 0 }, { 8896, 5920, 160, 64, 0, 0 }, }; static const struct { @@ -8126,6 +8315,7 @@ void CLASS identify() { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, { 0x325, "EOS 70D" }, + { 0x350, "EOS 80D" }, { 0x328, "EOS-1D X Mark II" }, { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, @@ -8135,9 +8325,12 @@ void CLASS identify() { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" }, { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" }, { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" }, + { 0x393, "EOS 750D" }, { 0x289, "EOS 7D Mark II" }, + { 0x347, "EOS 760D" }, { 0x254, "EOS 1000D" }, { 0x288, "EOS 1100D" }, - { 0x327, "EOS 1200D" }, + { 0x327, "EOS 1200D" }, { 0x382, "Canon EOS 5DS" }, + { 0x404, "EOS 1300D" }, { 0x401, "Canon EOS 5DS R" }, { 0x346, "EOS 100D" }, }, sonique[] = { { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, @@ -8165,7 +8358,10 @@ void CLASS identify() { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, - { 0x15a, "ILCE-QX1" }, + { 0x155, "DSC-RX100M4" },{ 0x156, "DSC-RX10M2" }, + { 0x158, "DSC-RX1RM2" }, { 0x15a, "ILCE-QX1" }, + { 0x15b, "ILCE-7RM2" }, { 0x15e, "ILCE-7SM2" }, + { 0x161, "ILCA-68" }, { 0x165, "ILCE-6300" }, }; static const struct { unsigned fsize; @@ -8202,6 +8398,7 @@ void CLASS identify() { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, + { 30858240,5248,3920, 8,16,56,16,40,0x94,0,2,"Canon","IXUS 160" }, { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" }, { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" }, @@ -8260,6 +8457,8 @@ void CLASS identify() { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" }, { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" }, { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" }, + { 4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" }, + { 4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 }, { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" }, { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" }, { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" }, @@ -8276,7 +8475,7 @@ void CLASS identify() static const char *corp[] = { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm", "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", - "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", + "Nikon", "Nokia", "Olympus", "Ricoh", "Pentax", "Phase One", "Samsung", "Sigma", "Sinar", "Sony" }; char head[32], *cp; int hlen, flen, fsize, zero_fsize=1, i, c; @@ -8451,7 +8650,7 @@ void CLASS identify() parse_foveon(); else if (!memcmp (head,"CI",2)) parse_cine(); - else + if (make[0] == 0) for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) if (fsize == table[i].fsize) { strcpy (make, table[i].make ); @@ -8548,9 +8747,10 @@ void CLASS identify() width = 4014; if (dng_version) { if (filters == UINT_MAX) filters = 0; - if (filters) is_raw = tiff_samples; - else colors = tiff_samples; + if (filters) is_raw *= tiff_samples; + else colors = tiff_samples; switch (tiff_compress) { + case 0: case 1: load_raw = &CLASS packed_dng_load_raw; break; case 7: load_raw = &CLASS lossless_dng_load_raw; break; case 8: load_raw = &CLASS deflate_dng_load_raw; break; @@ -8603,6 +8803,8 @@ void CLASS identify() top_margin = filters = 0; strcpy (model,"C603"); } + if (!strcmp(make,"Sony") && raw_width > 3888) + black = 128 << (tiff_bps - 12); if (is_foveon) { if (height*2 < width) pixel_aspect = 0.5; if (height > width) pixel_aspect = 2; @@ -8618,6 +8820,10 @@ void CLASS identify() SWAP(height,width); SWAP(raw_height,raw_width); } + if (width == 7200 && height == 3888) { + raw_width = width = 6480; + raw_height = height = 4320; + } filters = 0; tiff_samples = colors = 3; load_raw = &CLASS canon_sraw_load_raw; @@ -8793,7 +8999,7 @@ canon_a5: top_margin = (raw_height - height) >> 2 << 1; left_margin = (raw_width - width ) >> 2 << 1; if (width == 2848 || width == 3664) filters = 0x16161616; - if (width == 4032 || width == 4952) left_margin = 0; + if (width == 4032 || width == 4952 || width == 6032) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; if (width == 4936) left_margin = 4; if (!strcmp(model,"HS50EXR") || @@ -9067,6 +9273,8 @@ konica_400z: thumb_length = flen - (thumb_offset = 0xa39800); thumb_height = 480; thumb_width = 640; + } else if (!strcmp(model,"TG-4")) { + width -= 16; } } else if (!strcmp(model,"N Digital")) { height = 2047; @@ -9094,16 +9302,31 @@ konica_400z: order = 0x4d4d; } else if (!strcmp(make,"Sony") && raw_width == 4288) { width -= 32; + } else if (!strcmp(make,"Sony") && raw_width == 4600) { + if (!strcmp(model,"DSLR-A350")) + height -= 4; + black = 0; } else if (!strcmp(make,"Sony") && raw_width == 4928) { if (height < 3280) width -= 8; } else if (!strcmp(make,"Sony") && raw_width == 5504) { width -= height > 3664 ? 8 : 32; + if (!strncmp(model,"DSC",3)) + black = 200 << (tiff_bps - 12); } else if (!strcmp(make,"Sony") && raw_width == 6048) { width -= 24; if (strstr(model,"RX1") || strstr(model,"A99")) width -= 6; } else if (!strcmp(make,"Sony") && raw_width == 7392) { width -= 30; +// this was introduced with update to dcraw 9.27 +// but led to broken decode for compressed files from Sony DSC-RX1RM2 +// } else if (!strcmp(make,"Sony") && raw_width == 8000) { +// width -= 32; +// if (!strncmp(model,"DSC",3)) { +// tiff_bps = 14; +// load_raw = &CLASS unpacked_load_raw; +// black = 512; +// } } else if (!strcmp(model,"DSLR-A100")) { if (width == 3880) { height--; @@ -9115,8 +9338,6 @@ konica_400z: load_flags = 2; } filters = 0x61616161; - } else if (!strcmp(model,"DSLR-A350")) { - height -= 4; } else if (!strcmp(model,"PIXL")) { height -= top_margin = 4; width -= left_margin = 32; @@ -9181,6 +9402,7 @@ bw: colors = 1; width = 768; data_offset = 1152; load_raw = &CLASS kodak_radc_load_raw; + tiff_bps = 12; } else if (strstr(model,"DC50")) { strcpy (model, "DC50"); height = 512; @@ -9271,7 +9493,7 @@ dng_skip: if (raw_color) adobe_coeff ("Apple","Quicktake"); if (fuji_width) { fuji_width = width >> !fuji_layout; - if (~fuji_width & 1) filters = 0x49494949; + filters = fuji_width & 1 ? 0x94949494 : 0x49494949; width = (height >> fuji_layout) + fuji_width; height = width - 1; pixel_aspect = 1; diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 856da84d1..405f202bd 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -127,6 +127,7 @@ protected: struct tiff_ifd { int width, height, bps, comp, phint, offset, flip, samples, bytes; int tile_width, tile_length, sample_format, predictor; + float shutter; } tiff_ifd[10]; struct ph1 { @@ -139,8 +140,8 @@ protected: } hbd; struct jhead { - int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; - ushort *huff[6], *free[4], *row; + int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort quant[64], idct[64], *huff[20], *free[20], *row; }; struct tiff_tag { @@ -217,6 +218,8 @@ void ljpeg_end (struct jhead *jh); int ljpeg_diff (ushort *huff); ushort * ljpeg_row (int jrow, struct jhead *jh); void lossless_jpeg_load_raw(); +void ljpeg_idct (struct jhead *jh); + void canon_sraw_load_raw(); void adobe_copy_pixel (unsigned row, unsigned col, ushort **rp); diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 88a56068c..82f2ec9b8 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,6 +1,6 @@ ---- dcraw.c 2016-02-11 22:56:58.043957200 +0100 -+++ dcraw.cc 2016-02-11 23:13:28.708268000 +0100 -@@ -1,3 +1,15 @@ +--- dcraw.c 2016-09-30 21:19:28.312191811 +0200 ++++ dcraw.cc 2016-09-30 22:41:28.157442526 +0200 +@@ -1,3 +1,16 @@ +/*RT*/#include +/*RT*/#include +/*RT*/#undef MAX @@ -13,10 +13,11 @@ +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP + ++#include "opthelper.h" /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net -@@ -29,17 +41,17 @@ + Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net +@@ -29,17 +42,17 @@ #define _GNU_SOURCE #endif #define _USE_MATH_DEFINES @@ -44,7 +45,7 @@ #include #if defined(DJGPP) || defined(__MINGW32__) -@@ -54,7 +66,6 @@ +@@ -54,7 +67,6 @@ #ifdef WIN32 #include #include @@ -52,8 +53,8 @@ #define snprintf _snprintf #define strcasecmp stricmp #define strncasecmp strnicmp -@@ -98,88 +109,38 @@ - #define LONG_BIT (8 * sizeof (long)) +@@ -89,89 +101,38 @@ + #define _(String) (String) #endif -#if !defined(uchar) @@ -123,6 +124,7 @@ -struct tiff_ifd { - int width, height, bps, comp, phint, offset, flip, samples, bytes; - int tile_width, tile_length; +- float shutter; -} tiff_ifd[10]; - -struct ph1 { @@ -147,16 +149,16 @@ -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define LIM(x,min,max) MAX(min,MIN(x,max)) -#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) --#define CLIP(x) LIM(x,0,65535) +-#define CLIP(x) LIM((int)(x),0,65535) +#define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) +#define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) +#define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) -+#define ULIM(x,y,z) rtengine::ULIM(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) ++#define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) +#define CLIP(x) rtengine::CLIP(x) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } /* -@@ -255,6 +216,7 @@ +@@ -247,6 +208,7 @@ if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; @@ -164,7 +166,7 @@ return FC(row,col); } -@@ -297,6 +259,7 @@ +@@ -289,6 +251,7 @@ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); } data_error++; @@ -172,7 +174,7 @@ } ushort CLASS sget2 (uchar *s) -@@ -370,7 +333,7 @@ +@@ -362,7 +325,7 @@ { if (fread (pixel, 2, count, ifp) < count) derror(); if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) @@ -181,12 +183,12 @@ } void CLASS cubic_spline (const int *x_, const int *y_, const int len) -@@ -597,10 +560,10 @@ +@@ -589,13 +552,13 @@ return 0; } -unsigned CLASS getbithuff (int nbits, ushort *huff) -+unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) ++inline unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) { - static unsigned bitbuf=0; - static int vbits=0, reset=0; @@ -194,18 +196,154 @@ +/*RT static int vbits=0, reset=0; */ unsigned c; - if (nbits > 25) return 0; -@@ -824,7 +787,8 @@ +- if (nbits > 25) return 0; ++ if (UNLIKELY(nbits > 25)) return 0; + if (nbits < 0) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; +@@ -805,9 +768,13 @@ + FORC(2) free (huff[c]); + } + ++/* ++ Not a full implementation of Lossless JPEG, just ++ enough to decode Canon, Kodak and Adobe DNG images. ++ */ + struct jhead { +- int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6]; +- ushort quant[64], idct[64], *huff[20], *free[20], *row; ++ int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; ++ ushort *huff[6], *free[4], *row; + }; int CLASS ljpeg_start (struct jhead *jh, int info_only) - { -- int c, tag, len; -+ int c, tag; -+ ushort len; - uchar data[0x10000]; - const uchar *dp; +@@ -828,9 +795,9 @@ + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; +- case 0xffc1: ++ case 0xffc1: + case 0xffc0: +- jh->algo = tag & 0xff; ++ jh->algo = tag & 0xff; + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; +@@ -862,7 +829,7 @@ + FORC(4) jh->huff[2+c] = jh->huff[1]; + FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; + } +- jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); ++ jh->row = (ushort *) calloc (2 * jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); + return zero_after_ff = 1; + } +@@ -874,7 +841,7 @@ + free (jh->row); + } -@@ -1284,14 +1248,14 @@ +-int CLASS ljpeg_diff (ushort *huff) ++inline int CLASS ljpeg_diff (ushort *huff) + { + int len, diff; + +@@ -901,7 +868,7 @@ + } + getbits(-1); + } +- FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); ++ FORC3 row[c] = (jh->row + ((jrow & 1) + 1) * (jh->wide*jh->clrs*((jrow+c) & 1))); + for (col=0; col < jh->wide; col++) + FORC(jh->clrs) { + diff = ljpeg_diff (jh->huff[c]); +@@ -909,8 +876,7 @@ + pred = spred; + else if (col) pred = row[0][-jh->clrs]; + else pred = (jh->vpred[c] += diff) - diff; +- if (jrow && col) switch (jh->psv) { +- case 1: break; ++ if (jh->psv != 1 && jrow && col) switch (jh->psv) { + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; +@@ -919,7 +885,7 @@ + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } +- if ((**row = pred + diff) >> jh->bits) derror(); ++ if (UNLIKELY((**row = pred + diff) >> jh->bits)) derror(); + if (c <= jh->sraw) spred = **row; + row[0]++; row[1]++; + } +@@ -928,22 +894,38 @@ + + void CLASS lossless_jpeg_load_raw() + { +- int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; + struct jhead jh; +- ushort *rp; ++ int row=0, col=0; + + if (!ljpeg_start (&jh, 0)) return; +- jwide = jh.wide * jh.clrs; +- +- for (jrow=0; jrow < jh.high; jrow++) { +- rp = ljpeg_row (jrow, &jh); ++ int jwide = jh.wide * jh.clrs; ++ ushort *rp[2]; ++ rp[0] = ljpeg_row (0, &jh); ++ ++ for (int jrow=0; jrow < jh.high; jrow++) { ++#ifdef _OPENMP ++#pragma omp parallel sections ++#endif ++{ ++#ifdef _OPENMP ++ #pragma omp section ++#endif ++ { ++ if(jrow < jh.high - 1) ++ rp[(jrow + 1)&1] = ljpeg_row (jrow + 1, &jh); ++ } ++#ifdef _OPENMP ++ #pragma omp section ++#endif ++ { + if (load_flags & 1) + row = jrow & 1 ? height-1-jrow/2 : jrow/2; +- for (jcol=0; jcol < jwide; jcol++) { +- val = curve[*rp++]; ++ for (int jcol=0; jcol < jwide; jcol++) { ++ int val = curve[*rp[jrow&1]++]; + if (cr2_slice[0]) { +- jidx = jrow*jwide + jcol; +- i = jidx / (cr2_slice[1]*raw_height); ++ int jidx = jrow*jwide + jcol; ++ int i = jidx / (cr2_slice[1]*raw_height); ++ int j; + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*raw_height); +@@ -956,6 +938,8 @@ + if (++col >= raw_width) + col = (row++,0); + } ++ } ++} + } + ljpeg_end (&jh); + } +@@ -1124,8 +1108,7 @@ + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } +- } +- } ++ } } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); +@@ -1332,14 +1315,14 @@ int i, nz; char tail[424]; @@ -222,7 +360,7 @@ void CLASS ppm_thumb() { -@@ -1653,10 +1617,10 @@ +@@ -1701,10 +1684,10 @@ } } @@ -236,17 +374,7 @@ unsigned c; if (nbits == -1) -@@ -1721,7 +1685,8 @@ - pixel[col] = curve[pixel[col]]; - } - for (col=0; col < raw_width; col++) { -- i = (pixel[col] << 2) - ph1.black -+ if (ph1.format != 8) pixel[col] <<= 2; -+ i = pixel[col] - ph1.black - + cblack[row][col >= ph1.split_col] - + rblack[col][row >= ph1.split_row]; - if (i > 0) RAW(row,col) = i; -@@ -1731,6 +1696,338 @@ +@@ -1779,6 +1762,338 @@ maximum = 0xfffc - ph1.black; } @@ -585,7 +713,7 @@ void CLASS hasselblad_load_raw() { struct jhead jh; -@@ -1954,10 +2251,10 @@ +@@ -2002,10 +2317,10 @@ maximum = curve[0x3ff]; } @@ -599,7 +727,7 @@ int byte; if (!nbits) return vbits=0; -@@ -2140,7 +2437,7 @@ +@@ -2188,7 +2503,7 @@ void CLASS kodak_radc_load_raw() { @@ -608,7 +736,7 @@ 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, -@@ -2246,11 +2543,11 @@ +@@ -2294,11 +2609,11 @@ METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { @@ -622,7 +750,7 @@ cinfo->src->next_input_byte = jpeg_buffer; cinfo->src->bytes_in_buffer = nbytes; return TRUE; -@@ -2600,10 +2897,9 @@ +@@ -2648,10 +2963,9 @@ maximum = (1 << (thumb_misc & 31)) - 1; } @@ -635,7 +763,7 @@ if (start) { for (p=0; p < 4; p++) pad[p] = key = key * 48828125 + 1; -@@ -2688,11 +2984,13 @@ +@@ -2736,11 +3050,13 @@ bit += 7; } for (i=0; i < 16; i++, col+=2) @@ -650,7 +778,19 @@ } void CLASS samsung_load_raw() -@@ -2988,7 +3286,7 @@ +@@ -2905,7 +3221,10 @@ + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; +- raw_image[pix] = pred[pix & 1] += diff; ++ if(pix>=raw_width*raw_height) ++ derror(); ++ else ++ raw_image[pix] = pred[pix & 1] += diff; + if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; + } + maximum = 0xff; +@@ -3038,7 +3357,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code) { @@ -659,7 +799,7 @@ struct decode *cur; int i, len; -@@ -3085,7 +3383,7 @@ +@@ -3135,7 +3454,7 @@ pred[c] += diff[dindex->leaf]; if (pred[c] >> 16 && ~pred[c] >> 16) derror(); } @@ -668,7 +808,7 @@ } } } -@@ -3696,6 +3994,8 @@ +@@ -3746,6 +4065,8 @@ if (load_raw == &CLASS phase_one_load_raw || load_raw == &CLASS phase_one_load_raw_c) phase_one_correct(); @@ -677,7 +817,7 @@ if (fuji_width) { for (row=0; row < raw_height-top_margin*2; row++) { for (col=0; col < fuji_width << !fuji_layout; col++) { -@@ -3711,10 +4011,13 @@ +@@ -3761,10 +4082,13 @@ } } } else { @@ -693,7 +833,7 @@ if (mask[0][3] > 0) goto mask_set; if (load_raw == &CLASS canon_load_raw || load_raw == &CLASS lossless_jpeg_load_raw) { -@@ -4316,239 +4619,8 @@ +@@ -4366,239 +4690,8 @@ } } @@ -702,8 +842,7 @@ - int code[16][16][32], size=16, *ip, sum[4]; - int f, c, i, x, y, row, col, shift, color; - ushort *pix; -+/* RT: delete interpolation functions */ - +- - if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); - if (filters == 9) size = 6; - border_interpolate(1); @@ -745,7 +884,8 @@ - This algorithm is officially called: - - "Interpolation using a Threshold-based variable number of gradients" -- ++/* RT: delete interpolation functions */ + - described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html - - I've extended the basic idea to work with non-Bayer filter arrays. @@ -934,7 +1074,7 @@ void CLASS cielab (ushort rgb[3], short lab[3]) { -@@ -4814,112 +4886,7 @@ +@@ -4864,112 +4957,7 @@ } #undef fcol @@ -952,7 +1092,7 @@ - char (*homo)[TS][TS], *buffer; - - if (verbose) fprintf (stderr,_("AHD interpolation...\n")); - +- - cielab (0,0); - border_interpolate(5); - buffer = (char *) malloc (26*TS*TS); @@ -963,7 +1103,7 @@ - - for (top=2; top < height-5; top += TS-6) - for (left=2; left < width-5; left += TS-6) { -- + -/* Interpolate green horizontally and vertically: */ - for (row=top; row < top+TS && row < height-2; row++) { - col = left + (FC(row,left) & 1); @@ -1047,7 +1187,7 @@ #undef TS void CLASS median_filter() -@@ -5089,7 +5056,7 @@ +@@ -5139,7 +5127,7 @@ } } @@ -1056,7 +1196,7 @@ void CLASS parse_makernote (int base, int uptag) { -@@ -5194,6 +5161,11 @@ +@@ -5244,6 +5232,11 @@ tag |= uptag << 16; if (tag == 2 && strstr(make,"NIKON") && !iso_speed) iso_speed = (get2(),get2()); @@ -1068,7 +1208,7 @@ if (tag == 4 && len > 26 && len < 35) { if ((i=(get4(),get2())) != 0x7fff && !iso_speed) iso_speed = 50 * pow (2, i/32.0 - 4); -@@ -5246,12 +5218,16 @@ +@@ -5296,12 +5289,16 @@ cam_mul[2] = get4() << 2; } } @@ -1086,15 +1226,25 @@ if (tag == 0x1d) while ((c = fgetc(ifp)) && c != EOF) serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); -@@ -5442,6 +5418,7 @@ - case 33434: shutter = getreal(type); break; +@@ -5491,14 +5488,14 @@ + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { +- case 33434: tiff_ifd[tiff_nifds-1].shutter = +- shutter = getreal(type); break; ++ case 33434: tiff_ifd[tiff_nifds-1].shutter = shutter = getreal(type); break; case 33437: aperture = getreal(type); break; case 34855: iso_speed = get2(); break; + case 34866: if((!iso_speed) || iso_speed == 65535) iso_speed = get4();break; case 36867: case 36868: get_timestamp(0); break; case 37377: if ((expo = -getreal(type)) < 128) -@@ -5613,28 +5590,33 @@ +- tiff_ifd[tiff_nifds-1].shutter = ++ tiff_ifd[tiff_nifds-1].shutter = + shutter = pow (2, expo); break; + case 37378: aperture = pow (2, getreal(type)/2); break; + case 37386: focal_len = getreal(type); break; +@@ -5667,28 +5664,33 @@ } } @@ -1134,7 +1284,7 @@ entries = get2(); if (entries > 512) return 1; while (entries--) { -@@ -5702,7 +5684,8 @@ +@@ -5758,7 +5760,8 @@ fgets (make, 64, ifp); break; case 272: /* Model */ @@ -1144,7 +1294,7 @@ break; case 280: /* Panasonic RW2 offset */ if (type != 4) break; -@@ -5762,6 +5745,9 @@ +@@ -5818,6 +5821,9 @@ case 315: /* Artist */ fread (artist, 64, 1, ifp); break; @@ -1154,7 +1304,7 @@ case 322: /* TileWidth */ tiff_ifd[ifd].tile_width = getint(type); break; -@@ -5777,6 +5763,9 @@ +@@ -5833,6 +5839,9 @@ is_raw = 5; } break; @@ -1164,7 +1314,7 @@ case 330: /* SubIFDs */ if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { load_raw = &CLASS sony_arw_load_raw; -@@ -5790,6 +5779,9 @@ +@@ -5846,6 +5855,9 @@ fseek (ifp, i+4, SEEK_SET); } break; @@ -1174,17 +1324,7 @@ case 400: strcpy (make, "Sarnoff"); maximum = 0xfff; -@@ -5971,6 +5963,9 @@ - if (!make[0]) strcpy (make, "DNG"); - is_raw = 1; - break; -+ case 50708: /* UniqueCameraModel */ -+ fgets (model3, 64, ifp); -+ break; - case 50710: /* CFAPlaneColor */ - if (filters == 9) break; - if (len > 4) len = 4; -@@ -6002,12 +5997,21 @@ +@@ -6063,12 +6075,21 @@ case 61450: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ @@ -1211,8 +1351,8 @@ + break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ - for (num=i=0; i < len; i++) -@@ -6024,13 +6028,13 @@ + for (num=i=0; i < (len & 0xffff); i++) +@@ -6085,13 +6106,13 @@ case 50721: /* ColorMatrix1 */ case 50722: /* ColorMatrix2 */ FORCC for (j=0; j < 3; j++) @@ -1228,7 +1368,7 @@ break; case 50727: /* AnalogBalance */ FORCC ab[c] = getreal(type); -@@ -6053,6 +6057,11 @@ +@@ -6114,6 +6135,11 @@ case 50752: read_shorts (cr2_slice, 3); break; @@ -1240,7 +1380,7 @@ case 50829: /* ActiveArea */ top_margin = getint(type); left_margin = getint(type); -@@ -6085,21 +6094,27 @@ +@@ -6146,21 +6172,27 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -1276,7 +1416,7 @@ cam_xyz_coeff (cmatrix, cam_xyz); } if (asn[0]) { -@@ -6107,13 +6122,14 @@ +@@ -6168,13 +6200,14 @@ FORCC cam_mul[c] = 1 / asn[c]; } if (!use_cm) @@ -1292,7 +1432,15 @@ fseek (ifp, base, SEEK_SET); order = get2(); -@@ -6191,7 +6207,12 @@ +@@ -6206,6 +6239,7 @@ + shutter = tiff_ifd[i].shutter; + tiff_ifd[i].shutter = shutter; + } ++ + for (i=0; i < tiff_nifds; i++) { + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; +@@ -6266,7 +6300,12 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; @@ -1306,7 +1454,7 @@ case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && -@@ -6230,6 +6251,7 @@ +@@ -6305,6 +6344,7 @@ case 32803: load_raw = &CLASS kodak_65000_load_raw; } case 32867: case 34892: break; @@ -1314,7 +1462,7 @@ default: is_raw = 0; } if (!dng_version) -@@ -6315,7 +6337,7 @@ +@@ -6390,7 +6430,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -1323,7 +1471,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -6337,13 +6359,14 @@ +@@ -6412,13 +6452,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { @@ -1340,7 +1488,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -6620,6 +6643,7 @@ +@@ -6693,6 +6734,7 @@ load_raw = ph1.format < 3 ? &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; maximum = 0xffff; @@ -1348,16 +1496,7 @@ strcpy (make, "Phase One"); if (model[0]) return; switch (raw_height) { -@@ -6658,7 +6682,7 @@ - } else if (tag == 0xc000) { - c = order; - order = 0x4949; -- if ((tag = get4()) > 10000) tag = get4(); -+ while ((tag = get4()) > 10000); - width = tag; - height = get4(); - order = c; -@@ -6688,7 +6712,11 @@ +@@ -6761,7 +6803,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -1369,7 +1508,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6960,7 +6988,8 @@ +@@ -7033,7 +7079,8 @@ { static const struct { const char *prefix; @@ -1379,7 +1518,22 @@ } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, -@@ -7919,6 +7948,33 @@ +@@ -7977,12 +8024,12 @@ + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + { "Sony DSC-RX100", 0, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, +- { "Sony DSC-RX10", 0, 0, /* also RX10M2 */ ++ { "Sony DSC-RX10", 0, 0, + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, + { "Sony DSC-RX1RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony DSC-RX1", 0, 0, +- { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, ++ { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { "Sony DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { "Sony DSLR-A290", 0, 0, +@@ -8088,6 +8135,33 @@ } break; } @@ -1413,7 +1567,7 @@ } void CLASS simple_coeff (int index) -@@ -8229,7 +8285,7 @@ +@@ -8410,7 +8484,7 @@ tiff_flip = flip = filters = UINT_MAX; /* unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; @@ -1422,7 +1576,7 @@ iso_speed = shutter = aperture = focal_len = unique_id = 0; tiff_nifds = 0; memset (tiff_ifd, 0, sizeof tiff_ifd); -@@ -8261,13 +8317,20 @@ +@@ -8442,13 +8516,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -1445,7 +1599,7 @@ parse_ciff (hlen, flen-hlen, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); -@@ -8313,6 +8376,7 @@ +@@ -8494,6 +8575,7 @@ fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); @@ -1453,7 +1607,7 @@ apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); -@@ -8426,9 +8490,10 @@ +@@ -8607,9 +8689,10 @@ if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); @@ -1467,7 +1621,7 @@ strcpy (make, "OmniVision"); data_offset = ftell(ifp) + 0x8000-32; width = raw_width; -@@ -8437,6 +8502,7 @@ +@@ -8618,6 +8701,7 @@ filters = 0x16161616; } else is_raw = 0; } @@ -1475,7 +1629,7 @@ for (i=0; i < sizeof corp / sizeof *corp; i++) if (strcasestr (make, corp[i])) /* Simplify company names */ -@@ -8468,7 +8534,7 @@ +@@ -8649,7 +8733,7 @@ if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ { height = 3124; width = 4688; filters = 0x16161616; } if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) @@ -1484,15 +1638,15 @@ if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) -@@ -8487,6 +8553,7 @@ - switch (tiff_compress) { +@@ -8669,6 +8753,7 @@ + case 0: case 1: load_raw = &CLASS packed_dng_load_raw; break; case 7: load_raw = &CLASS lossless_dng_load_raw; break; + case 8: load_raw = &CLASS deflate_dng_load_raw; break; case 34892: load_raw = &CLASS lossy_dng_load_raw; break; default: load_raw = 0; } -@@ -8541,6 +8608,7 @@ +@@ -8725,6 +8810,7 @@ if (height > width) pixel_aspect = 2; filters = 0; simple_coeff(0); @@ -1500,7 +1654,7 @@ } else if (!strcmp(make,"Canon") && tiff_bps == 15) { switch (width) { case 3344: width -= 66; -@@ -8846,24 +8914,53 @@ +@@ -9034,24 +9120,53 @@ if (load_raw == &CLASS lossless_jpeg_load_raw) load_raw = &CLASS hasselblad_load_raw; if (raw_width == 7262) { @@ -1559,7 +1713,7 @@ } else if (raw_width == 4090) { strcpy (model, "V96C"); height -= (top_margin = 6); -@@ -8921,6 +9018,7 @@ +@@ -9109,6 +9224,7 @@ filters = 0x16161616; } } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { @@ -1567,7 +1721,7 @@ if ((flen - data_offset) / (raw_width*8/7) == raw_height) load_raw = &CLASS panasonic_load_raw; if (!load_raw) { -@@ -8938,6 +9036,7 @@ +@@ -9126,6 +9242,7 @@ } filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; @@ -1575,7 +1729,30 @@ } else if (!strcmp(model,"C770UZ")) { height = 1718; width = 2304; -@@ -9155,6 +9254,18 @@ +@@ -9201,13 +9318,15 @@ + width -= 6; + } else if (!strcmp(make,"Sony") && raw_width == 7392) { + width -= 30; +- } else if (!strcmp(make,"Sony") && raw_width == 8000) { +- width -= 32; +- if (!strncmp(model,"DSC",3)) { +- tiff_bps = 14; +- load_raw = &CLASS unpacked_load_raw; +- black = 512; +- } ++// this was introduced with update to dcraw 9.27 ++// but led to broken decode for compressed files from Sony DSC-RX1RM2 ++// } else if (!strcmp(make,"Sony") && raw_width == 8000) { ++// width -= 32; ++// if (!strncmp(model,"DSC",3)) { ++// tiff_bps = 14; ++// load_raw = &CLASS unpacked_load_raw; ++// black = 512; ++// } + } else if (!strcmp(model,"DSLR-A100")) { + if (width == 3880) { + height--; +@@ -9357,6 +9476,18 @@ memcpy (rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; } @@ -1594,7 +1771,7 @@ if (raw_color) adobe_coeff (make, model); if (load_raw == &CLASS kodak_radc_load_raw) if (raw_color) adobe_coeff ("Apple","Quicktake"); -@@ -9169,9 +9280,9 @@ +@@ -9371,9 +9502,9 @@ if (raw_width < width ) raw_width = width; } if (!tiff_bps) tiff_bps = 12; @@ -1606,7 +1783,7 @@ is_raw = 0; #ifdef NO_JASPER if (load_raw == &CLASS redcine_load_raw) { -@@ -9250,194 +9361,249 @@ +@@ -9452,199 +9583,250 @@ } #endif @@ -1634,10 +1811,14 @@ - { { 0.529317, 0.330092, 0.140588 }, - { 0.098368, 0.873465, 0.028169 }, - { 0.016879, 0.117663, 0.865457 } }; +- static const double aces_rgb[3][3] = +- { { 0.432996, 0.375380, 0.189317 }, +- { 0.089427, 0.816523, 0.102989 }, +- { 0.019165, 0.118150, 0.941914 } }; - static const double (*out_rgb[])[3] = -- { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; +- { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb, aces_rgb }; - static const char *name[] = -- { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; +- { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ", "ACES" }; - static const unsigned phead[] = - { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, - 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; @@ -1658,7 +1839,7 @@ - gamma_curve (gamm[0], gamm[1], 0, 0); - memcpy (out_cam, rgb_cam, sizeof out_cam); - raw_color |= colors == 1 || document_mode || -- output_color < 1 || output_color > 5; +- output_color < 1 || output_color > 6; - if (!raw_color) { - oprof = (unsigned *) calloc (phead[0], 1); - merror (oprof, "convert_to_rgb()"); @@ -2023,37 +2204,42 @@ + + delete [] cBuffer; + delete [] uBuffer; - } ++} + } + + if (ifd->sample_format == 3) { // Floating point data + copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maximum); + } -+} -+ -+/* RT: removed unused functions */ + } ++/* RT: removed unused functions */ ++ struct tiff_tag { ushort tag, type; -@@ -9461,590 +9627,11 @@ + int count; +@@ -9667,594 +9849,11 @@ char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; --void CLASS tiff_set (ushort *ntag, +-void CLASS tiff_set (struct tiff_hdr *th, ushort *ntag, - ushort tag, ushort type, int count, int val) -{ - struct tiff_tag *tt; - int c; - - tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; -- tt->tag = tag; -- tt->type = type; -- tt->count = count; -- if (type < 3 && count <= 4) +- tt->val.i = val; +- if (type == 1 && count <= 4) - FORC(4) tt->val.c[c] = val >> (c << 3); -- else if (type == 3 && count <= 2) +- else if (type == 2) { +- count = strnlen((char *)th + val, count-1) + 1; +- if (count <= 4) +- FORC(4) tt->val.c[c] = ((char *)th)[val+c]; +- } else if (type == 3 && count <= 2) - FORC(2) tt->val.s[c] = val >> (c << 4); -- else tt->val.i = val; +- tt->count = count; +- tt->type = type; +- tt->tag = tag; -} - -#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) @@ -2067,55 +2253,6 @@ - th->order = htonl(0x4d4d4949) >> 16; - th->magic = 42; - th->ifd = 10; -- if (full) { -- tiff_set (&th->ntag, 254, 4, 1, 0); -- tiff_set (&th->ntag, 256, 4, 1, width); -- tiff_set (&th->ntag, 257, 4, 1, height); -- tiff_set (&th->ntag, 258, 3, colors, output_bps); -- if (colors > 2) -- th->tag[th->ntag-1].val.i = TOFF(th->bps); -- FORC4 th->bps[c] = output_bps; -- tiff_set (&th->ntag, 259, 3, 1, 1); -- tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); -- } -- tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); -- tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); -- tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); -- if (full) { -- if (oprof) psize = ntohl(oprof[0]); -- tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); -- tiff_set (&th->ntag, 277, 3, 1, colors); -- tiff_set (&th->ntag, 278, 4, 1, height); -- tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); -- } else -- tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); -- tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); -- tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); -- tiff_set (&th->ntag, 284, 3, 1, 1); -- tiff_set (&th->ntag, 296, 3, 1, 2); -- tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); -- tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); -- tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); -- tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); -- if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); -- tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); -- tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); -- tiff_set (&th->nexif, 34855, 3, 1, iso_speed); -- tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); -- if (gpsdata[1]) { -- tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); -- tiff_set (&th->ngps, 0, 1, 4, 0x202); -- tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); -- tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); -- tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); -- tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); -- tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); -- tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); -- tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); -- tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); -- tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); -- memcpy (th->gps, gpsdata, sizeof th->gps); -- } - th->rat[0] = th->rat[2] = 300; - th->rat[1] = th->rat[3] = 1; - FORC(6) th->rat[4+c] = 1000000; @@ -2130,6 +2267,55 @@ - sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", - t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); - strncpy (th->artist, artist, 64); +- if (full) { +- tiff_set (th, &th->ntag, 254, 4, 1, 0); +- tiff_set (th, &th->ntag, 256, 4, 1, width); +- tiff_set (th, &th->ntag, 257, 4, 1, height); +- tiff_set (th, &th->ntag, 258, 3, colors, output_bps); +- if (colors > 2) +- th->tag[th->ntag-1].val.i = TOFF(th->bps); +- FORC4 th->bps[c] = output_bps; +- tiff_set (th, &th->ntag, 259, 3, 1, 1); +- tiff_set (th, &th->ntag, 262, 3, 1, 1 + (colors > 1)); +- } +- tiff_set (th, &th->ntag, 270, 2, 512, TOFF(th->desc)); +- tiff_set (th, &th->ntag, 271, 2, 64, TOFF(th->make)); +- tiff_set (th, &th->ntag, 272, 2, 64, TOFF(th->model)); +- if (full) { +- if (oprof) psize = ntohl(oprof[0]); +- tiff_set (th, &th->ntag, 273, 4, 1, sizeof *th + psize); +- tiff_set (th, &th->ntag, 277, 3, 1, colors); +- tiff_set (th, &th->ntag, 278, 4, 1, height); +- tiff_set (th, &th->ntag, 279, 4, 1, height*width*colors*output_bps/8); +- } else +- tiff_set (th, &th->ntag, 274, 3, 1, "12435867"[flip]-'0'); +- tiff_set (th, &th->ntag, 282, 5, 1, TOFF(th->rat[0])); +- tiff_set (th, &th->ntag, 283, 5, 1, TOFF(th->rat[2])); +- tiff_set (th, &th->ntag, 284, 3, 1, 1); +- tiff_set (th, &th->ntag, 296, 3, 1, 2); +- tiff_set (th, &th->ntag, 305, 2, 32, TOFF(th->soft)); +- tiff_set (th, &th->ntag, 306, 2, 20, TOFF(th->date)); +- tiff_set (th, &th->ntag, 315, 2, 64, TOFF(th->artist)); +- tiff_set (th, &th->ntag, 34665, 4, 1, TOFF(th->nexif)); +- if (psize) tiff_set (th, &th->ntag, 34675, 7, psize, sizeof *th); +- tiff_set (th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4])); +- tiff_set (th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6])); +- tiff_set (th, &th->nexif, 34855, 3, 1, iso_speed); +- tiff_set (th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8])); +- if (gpsdata[1]) { +- tiff_set (th, &th->ntag, 34853, 4, 1, TOFF(th->ngps)); +- tiff_set (th, &th->ngps, 0, 1, 4, 0x202); +- tiff_set (th, &th->ngps, 1, 2, 2, gpsdata[29]); +- tiff_set (th, &th->ngps, 2, 5, 3, TOFF(th->gps[0])); +- tiff_set (th, &th->ngps, 3, 2, 2, gpsdata[30]); +- tiff_set (th, &th->ngps, 4, 5, 3, TOFF(th->gps[6])); +- tiff_set (th, &th->ngps, 5, 1, 1, gpsdata[31]); +- tiff_set (th, &th->ngps, 6, 5, 1, TOFF(th->gps[18])); +- tiff_set (th, &th->ngps, 7, 5, 3, TOFF(th->gps[12])); +- tiff_set (th, &th->ngps, 18, 2, 12, TOFF(th->gps[20])); +- tiff_set (th, &th->ngps, 29, 2, 12, TOFF(th->gps[23])); +- memcpy (th->gps, gpsdata, sizeof th->gps); +- } -} - -void CLASS jpeg_thumb() @@ -2250,7 +2436,7 @@ - puts(_("-n Set threshold for wavelet denoising")); - puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); - puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); -- puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); +- puts(_("-o [0-6] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)")); -#ifndef NO_LCMS - puts(_("-o Apply output ICC profile from file")); - puts(_("-p Apply camera ICC profile from file or \"embed\"")); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index ac571d057..8f855ff0f 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -191,9 +191,6 @@ void Crop::update (int todo) parent->ipf.Tile_calc (tilesize, overlap, kall, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); kall = 0; - float *ch_M = new float [9];//allocate memory - float *max_r = new float [9]; - float *max_b = new float [9]; float *min_b = new float [9]; float *min_r = new float [9]; float *lumL = new float [9]; @@ -380,7 +377,7 @@ void Crop::update (int todo) } } - if(skip == 1 && params.dirpyrDenoise.enabled && ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO"))) { + if(skip == 1 && params.dirpyrDenoise.enabled && !parent->denoiseInfoStore.valid && ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO"))) { MyTime t1aue, t2aue; t1aue.set(); @@ -462,9 +459,9 @@ void Crop::update (int todo) //printf("DCROP skip=%d cha=%f red=%f bl=%f redM=%f bluM=%f chrom=%f sigm=%f lum=%f\n",skip, chaut,redaut,blueaut, maxredaut, maxblueaut, chromina, sigma, lumema); Nb[hcr * 3 + wcr] = nb; - ch_M[hcr * 3 + wcr] = pondcorrec * chaut; - max_r[hcr * 3 + wcr] = pondcorrec * maxredaut; - max_b[hcr * 3 + wcr] = pondcorrec * maxblueaut; + parent->denoiseInfoStore.ch_M[hcr * 3 + wcr] = pondcorrec * chaut; + parent->denoiseInfoStore.max_r[hcr * 3 + wcr] = pondcorrec * maxredaut; + parent->denoiseInfoStore.max_b[hcr * 3 + wcr] = pondcorrec * maxblueaut; min_r[hcr * 3 + wcr] = pondcorrec * minredaut; min_b[hcr * 3 + wcr] = pondcorrec * minblueaut; lumL[hcr * 3 + wcr] = lumema; @@ -524,20 +521,20 @@ void Crop::update (int todo) int lissage = settings->leveldnliss; for (int k = 0; k < 9; k++) { - float maxmax = max(max_r[k], max_b[k]); - parent->ipf.calcautodn_info (ch_M[k], delta[k], Nb[k], levaut, maxmax, lumL[k], chromC[k], mode, lissage, ry[k], sk[k], pcsk[k]); + float maxmax = max(parent->denoiseInfoStore.max_r[k], parent->denoiseInfoStore.max_b[k]); + parent->ipf.calcautodn_info (parent->denoiseInfoStore.ch_M[k], delta[k], Nb[k], levaut, maxmax, lumL[k], chromC[k], mode, lissage, ry[k], sk[k], pcsk[k]); // printf("ch_M=%f delta=%f\n",ch_M[k], delta[k]); } for (int k = 0; k < 9; k++) { - if(max_r[k] > max_b[k]) { + if(parent->denoiseInfoStore.max_r[k] > parent->denoiseInfoStore.max_b[k]) { Max_R[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); - Min_B[k] = -(ch_M[k] - min_b[k]) / (autoNRmax * multip * adjustr * lowdenoise); + Min_B[k] = -(parent->denoiseInfoStore.ch_M[k] - min_b[k]) / (autoNRmax * multip * adjustr * lowdenoise); Max_B[k] = 0.f; Min_R[k] = 0.f; } else { Max_B[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); - Min_R[k] = - (ch_M[k] - min_r[k]) / (autoNRmax * multip * adjustr * lowdenoise); + Min_R[k] = - (parent->denoiseInfoStore.ch_M[k] - min_r[k]) / (autoNRmax * multip * adjustr * lowdenoise); Min_B[k] = 0.f; Max_R[k] = 0.f; } @@ -545,7 +542,7 @@ void Crop::update (int todo) for (int k = 0; k < 9; k++) { // printf("ch_M= %f Max_R=%f Max_B=%f min_r=%f min_b=%f\n",ch_M[k],Max_R[k], Max_B[k],Min_R[k], Min_B[k]); - chM += ch_M[k]; + chM += parent->denoiseInfoStore.ch_M[k]; MaxBMoy += Max_B[k]; MaxRMoy += Max_R[k]; MinRMoy += Min_R[k]; @@ -587,7 +584,7 @@ void Crop::update (int todo) params.dirpyrDenoise.chroma = chM / (autoNR * multip * adjustr); params.dirpyrDenoise.redchro = maxr; params.dirpyrDenoise.bluechro = maxb; - + parent->denoiseInfoStore.valid = true; if(parent->adnListener) { parent->adnListener->chromaChanged(params.dirpyrDenoise.chroma, params.dirpyrDenoise.redchro, params.dirpyrDenoise.bluechro); } @@ -644,7 +641,7 @@ void Crop::update (int todo) int kall = 0; float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; - parent->ipf.RGB_denoise(kall, baseCrop, baseCrop, calclum, ch_M, max_r, max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + parent->ipf.RGB_denoise(kall, baseCrop, baseCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); if (parent->adnListener) { parent->adnListener->noiseChanged(nresi, highresi); @@ -665,9 +662,6 @@ void Crop::update (int todo) parent->imgsrc->convertColorSpace(baseCrop, params.icm, parent->currWB); - delete [] ch_M; - delete [] max_r; - delete [] max_b; delete [] min_r; delete [] min_b; delete [] lumL; @@ -749,27 +743,6 @@ void Crop::update (int todo) baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256, parent->imgsrc->getGamma()); }*/ - float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; - float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); - - if(params.colorToning.enabled && params.colorToning.autosat) { //for colortoning evaluation of saturation settings - float moyS = 0.f; - float eqty = 0.f; - parent->ipf.moyeqt (baseCrop, moyS, eqty);//return image : mean saturation and standard dev of saturation - //printf("moy=%f ET=%f\n", moyS,eqty); - float satp = ((moyS + 1.5f * eqty) - 0.3f) / 0.7f; //1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale - - if(satp >= 0.92f) { - satp = 0.92f; //avoid values too high (out of gamut) - } - - if(satp <= 0.15f) { - satp = 0.15f; //avoid too low values - } - - satLimit = 100.f * satp; - satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation - } if (params.spot.enabled) { if (todo & M_SPOT) { @@ -794,11 +767,13 @@ void Crop::update (int todo) if (todo & M_RGBCURVE) { double rrm, ggm, bbm; - DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, parent->currWB); + DCPProfile::ApplyState as; + DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, parent->currWB, as); + parent->ipf.rgbProc (baseCrop, laboCrop, this, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, - params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, satLimit , satLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve, parent->cl2Toningcurve, + params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->colourToningSatLimit , parent->colourToningSatLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve, parent->cl2Toningcurve, parent->customToneCurve1, parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW, rrm, ggm, bbm, - parent->bwAutoR, parent->bwAutoG, parent->bwAutoB, dcpProf); + parent->bwAutoR, parent->bwAutoG, parent->bwAutoB, dcpProf, as); } /*xref=000;yref=000; @@ -835,7 +810,7 @@ void Crop::update (int todo) LUTu dummy; int moderetinex; // parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1); - parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); parent->ipf.vibrance (labnCrop); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { @@ -907,14 +882,9 @@ void Crop::update (int todo) realtile = 12; } - int tilesize; - int overlap; - tilesize = 1024; - overlap = 128; - tilesize = 128 * realtile; - //overlap=(int) tilesize*params->wavelet.overl; - overlap = (int) tilesize * 0.125f; - // printf("overl=%d\n",overlap); + int tilesize = 128 * realtile; + int overlap = (int) tilesize * 0.125f; + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; parent->ipf.Tile_calc (tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index c6d66e4bf..405a34118 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -36,6 +36,7 @@ #include "procparams.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" //#define BENCHMARK #include "StopWatch.h" #ifdef _OPENMP @@ -58,9 +59,6 @@ namespace rtengine #define x00625(a) xdivf(a, 4) #define x0125(a) xdivf(a, 3) - -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } -#define PIX_SORTV(av,bv) tempv = _mm_min_ps(av,bv); bv = _mm_max_ps(av,bv); av = tempv; extern const Settings* settings; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -929,7 +927,7 @@ void RawImageSource::ppg_demosaic() } d = dir[i = diff[0] > diff[1]]; - pix[0][1] = ULIM(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); + pix[0][1] = median(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); } if(plistener) { @@ -1253,8 +1251,8 @@ void RawImageSource::jdl_interpolate_omp() // from "Lassus" 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] = ULIM(0.725f * dif[indx][0] + 0.1375f * dif[indx - v][0] + 0.1375f * dif[indx + v][0], dif[indx - v][0], dif[indx + v][0]); - g[1] = ULIM(0.725f * dif[indx][1] + 0.1375f * dif[indx - 2][1] + 0.1375f * dif[indx + 2][1], dif[indx - 2][1], dif[indx + 2][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]); } @@ -1268,10 +1266,10 @@ void RawImageSource::jdl_interpolate_omp() // from "Lassus" 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] = ULIM(chr[indx - u - 1][c], chr[indx - w - 1][c], chr[indx - u - 3][c]); - g[1] = ULIM(chr[indx - u + 1][c], chr[indx - w + 1][c], chr[indx - u + 3][c]); - g[2] = ULIM(chr[indx + u - 1][c], chr[indx + w - 1][c], chr[indx + u - 3][c]); - g[3] = ULIM(chr[indx + u + 1][c], chr[indx + w + 1][c], chr[indx + u + 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]); @@ -1414,10 +1412,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i gamtab = &(Color::gammatab_24_17a); } else { gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); - - for(int i = 0; i < 65536; i++) { - (*gamtab)[i] = (float)i / 65535.f; - } + gamtab->makeIdentity(65535.f); } @@ -1462,7 +1457,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i float Y = v0 + xdiv2f(rix[0][0]); if (rix[4][0] > 1.75f * Y) { - rix[0][0] = ULIM(rix[0][0], rix[4][ -1], rix[4][ 1]); + 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); } @@ -1474,7 +1469,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i Y = v0 + xdiv2f(rix[1][0]); if (rix[4][0] > 1.75f * Y) { - rix[1][0] = ULIM(rix[1][0], rix[4][-w1], rix[4][w1]); + 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); } @@ -1767,83 +1762,45 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i int d = c + 3 - (c == 0 ? 0 : 1); int cc = 1; #ifdef __SSE2__ - __m128 p1v, p2v, p3v, p4v, p5v, p6v, p7v, p8v, p9v, tempv; 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 - p1v = LVFU(rix[c][-w1 - 1]) - LVFU(rix[1][-w1 - 1]); - p2v = LVFU(rix[c][-w1]) - LVFU(rix[1][-w1]); - p3v = LVFU(rix[c][-w1 + 1]) - LVFU(rix[1][-w1 + 1]); - p4v = LVFU(rix[c][ -1]) - LVFU(rix[1][ -1]); - p5v = LVFU(rix[c][ 0]) - LVFU(rix[1][ 0]); - p6v = LVFU(rix[c][ 1]) - LVFU(rix[1][ 1]); - p7v = LVFU(rix[c][ w1 - 1]) - LVFU(rix[1][ w1 - 1]); - p8v = LVFU(rix[c][ w1]) - LVFU(rix[1][ w1]); - p9v = LVFU(rix[c][ w1 + 1]) - LVFU(rix[1][ w1 + 1]); - // Sort for median of 9 values - PIX_SORTV(p2v, p3v); - PIX_SORTV(p5v, p6v); - PIX_SORTV(p8v, p9v); - PIX_SORTV(p1v, p2v); - PIX_SORTV(p4v, p5v); - PIX_SORTV(p7v, p8v); - PIX_SORTV(p2v, p3v); - PIX_SORTV(p5v, p6v); - PIX_SORTV(p8v, p9v); - p4v = _mm_max_ps(p1v, p4v); - p6v = _mm_min_ps(p6v, p9v); - PIX_SORTV(p5v, p8v); - p7v = _mm_max_ps(p4v, p7v); - p5v = _mm_max_ps(p5v, p2v); - p3v = _mm_min_ps(p3v, p6v); - p5v = _mm_min_ps(p5v, p8v); - PIX_SORTV(p5v, p3v); - p5v = _mm_max_ps(p7v, p5v); - p5v = _mm_min_ps(p3v, p5v); - _mm_storeu_ps(&rix[d][0], p5v); + 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++) { - float temp; 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 - float p1 = rix[c][-w1 - 1] - rix[1][-w1 - 1]; - float p2 = rix[c][-w1] - rix[1][-w1]; - float p3 = rix[c][-w1 + 1] - rix[1][-w1 + 1]; - float p4 = rix[c][ -1] - rix[1][ -1]; - float p5 = rix[c][ 0] - rix[1][ 0]; - float p6 = rix[c][ 1] - rix[1][ 1]; - float p7 = rix[c][ w1 - 1] - rix[1][ w1 - 1]; - float p8 = rix[c][ w1] - rix[1][ w1]; - float p9 = rix[c][ w1 + 1] - rix[1][ w1 + 1]; - // Sort for median of 9 values - PIX_SORT(p2, p3); - PIX_SORT(p5, p6); - PIX_SORT(p8, p9); - PIX_SORT(p1, p2); - PIX_SORT(p4, p5); - PIX_SORT(p7, p8); - PIX_SORT(p2, p3); - PIX_SORT(p5, p6); - PIX_SORT(p8, p9); - PIX_SORT(p1, p4); - PIX_SORT(p6, p9); - PIX_SORT(p5, p8); - PIX_SORT(p4, p7); - PIX_SORT(p2, p5); - PIX_SORT(p3, p6); - PIX_SORT(p5, p8); - PIX_SORT(p5, p3); - PIX_SORT(p7, p5); - PIX_SORT(p5, p3); - rix[d][0] = p5; + 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); } } } @@ -2161,8 +2118,8 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) egv = LIMV(epssqv + c78v * SQRV(LVFU(hdif[indx1])) + c69v * (SQRV(LVFU(hdif[indx1 - h1])) + SQRV(LVFU(hdif[indx1 + h1]))) + c51v * (SQRV(LVFU(hdif[indx1 - h2])) + SQRV(LVFU(hdif[indx1 + h2]))) + c21v * (SQRV(LVFU(hdif[indx1 - h3])) + SQRV(LVFU(hdif[indx1 + h3]))) - c6v * SQRV(LVFU(hdif[indx1 - h1]) + LVFU(hdif[indx1]) + LVFU(hdif[indx1 + h1])) - c10v * (SQRV(LVFU(hdif[indx1 - h2]) + LVFU(hdif[indx1 - h1]) + LVFU(hdif[indx1])) + SQRV(LVFU(hdif[indx1]) + LVFU(hdif[indx1 + h1]) + LVFU(hdif[indx1 + h2]))) - c7v * (SQRV(LVFU(hdif[indx1 - h3]) + LVFU(hdif[indx1 - h2]) + LVFU(hdif[indx1 - h1])) + SQRV(LVFU(hdif[indx1 + h1]) + LVFU(hdif[indx1 + h2]) + LVFU(hdif[indx1 + h3]))), zerov, onev); //Limit chrominance using H/V neighbourhood - nvv = ULIMV(d725v * LVFU(vdif[indx1]) + d1375v * LVFU(vdif[indx1 - v1]) + d1375v * LVFU(vdif[indx1 + v1]), LVFU(vdif[indx1 - v1]), LVFU(vdif[indx1 + v1])); - evv = ULIMV(d725v * LVFU(hdif[indx1]) + d1375v * LVFU(hdif[indx1 - h1]) + d1375v * LVFU(hdif[indx1 + h1]), LVFU(hdif[indx1 - h1]), LVFU(hdif[indx1 + h1])); + nvv = median(d725v * LVFU(vdif[indx1]) + d1375v * LVFU(vdif[indx1 - v1]) + d1375v * LVFU(vdif[indx1 + v1]), LVFU(vdif[indx1 - v1]), LVFU(vdif[indx1 + v1])); + evv = median(d725v * LVFU(hdif[indx1]) + d1375v * LVFU(hdif[indx1 - h1]) + d1375v * LVFU(hdif[indx1 + h1]), LVFU(hdif[indx1 - h1]), LVFU(hdif[indx1 + h1])); //Chrominance estimation tempv = (egv * nvv + ngv * evv) / (ngv + egv); _mm_storeu_ps(&(chr[d][indx1]), tempv); @@ -2179,8 +2136,8 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) eg = LIM(epssq + 78.0f * SQR(hdif[indx1]) + 69.0f * (SQR(hdif[indx1 - h1]) + SQR(hdif[indx1 + h1])) + 51.0f * (SQR(hdif[indx1 - h2]) + SQR(hdif[indx1 + h2])) + 21.0f * (SQR(hdif[indx1 - h3]) + SQR(hdif[indx1 + h3])) - 6.0f * SQR(hdif[indx1 - h1] + hdif[indx1] + hdif[indx1 + h1]) - 10.0f * (SQR(hdif[indx1 - h2] + hdif[indx1 - h1] + hdif[indx1]) + SQR(hdif[indx1] + hdif[indx1 + h1] + hdif[indx1 + h2])) - 7.0f * (SQR(hdif[indx1 - h3] + hdif[indx1 - h2] + hdif[indx1 - h1]) + SQR(hdif[indx1 + h1] + hdif[indx1 + h2] + hdif[indx1 + h3])), 0.f, 1.f); //Limit chrominance using H/V neighbourhood - nv = ULIM(0.725f * vdif[indx1] + 0.1375f * vdif[indx1 - v1] + 0.1375f * vdif[indx1 + v1], vdif[indx1 - v1], vdif[indx1 + v1]); - ev = ULIM(0.725f * hdif[indx1] + 0.1375f * hdif[indx1 - h1] + 0.1375f * hdif[indx1 + h1], hdif[indx1 - h1], hdif[indx1 + h1]); + nv = median(0.725f * vdif[indx1] + 0.1375f * vdif[indx1 - v1] + 0.1375f * vdif[indx1 + v1], vdif[indx1 - v1], vdif[indx1 + v1]); + ev = median(0.725f * hdif[indx1] + 0.1375f * hdif[indx1 - h1] + 0.1375f * hdif[indx1 + h1], hdif[indx1 - h1], hdif[indx1 + h1]); //Chrominance estimation chr[d][indx1] = (eg * nv + ng * ev) / (ng + eg); //Green channel population @@ -2210,10 +2167,10 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) swgv = onev / (epsv + vabsf(LVFU(chr[c][(indx + v1 - h1) >> 1]) - LVFU(chr[c][(indx + v3 + h3) >> 1])) + vabsf(LVFU(chr[c][(indx - v1 + h1) >> 1]) - LVFU(chr[c][(indx + v3 - h3) >> 1]))); segv = onev / (epsv + vabsf(LVFU(chr[c][(indx + v1 + h1) >> 1]) - LVFU(chr[c][(indx + v3 - h3) >> 1])) + vabsf(LVFU(chr[c][(indx - v1 - h1) >> 1]) - LVFU(chr[c][(indx + v3 + h3) >> 1]))); //Limit NW,NE,SW,SE Color differences - nwvv = ULIMV(LVFU(chr[c][(indx - v1 - h1) >> 1]), LVFU(chr[c][(indx - v3 - h1) >> 1]), LVFU(chr[c][(indx - v1 - h3) >> 1])); - nevv = ULIMV(LVFU(chr[c][(indx - v1 + h1) >> 1]), LVFU(chr[c][(indx - v3 + h1) >> 1]), LVFU(chr[c][(indx - v1 + h3) >> 1])); - swvv = ULIMV(LVFU(chr[c][(indx + v1 - h1) >> 1]), LVFU(chr[c][(indx + v3 - h1) >> 1]), LVFU(chr[c][(indx + v1 - h3) >> 1])); - sevv = ULIMV(LVFU(chr[c][(indx + v1 + h1) >> 1]), LVFU(chr[c][(indx + v3 + h1) >> 1]), LVFU(chr[c][(indx + v1 + h3) >> 1])); + nwvv = median(LVFU(chr[c][(indx - v1 - h1) >> 1]), LVFU(chr[c][(indx - v3 - h1) >> 1]), LVFU(chr[c][(indx - v1 - h3) >> 1])); + nevv = median(LVFU(chr[c][(indx - v1 + h1) >> 1]), LVFU(chr[c][(indx - v3 + h1) >> 1]), LVFU(chr[c][(indx - v1 + h3) >> 1])); + swvv = median(LVFU(chr[c][(indx + v1 - h1) >> 1]), LVFU(chr[c][(indx + v3 - h1) >> 1]), LVFU(chr[c][(indx + v1 - h3) >> 1])); + sevv = median(LVFU(chr[c][(indx + v1 + h1) >> 1]), LVFU(chr[c][(indx + v3 + h1) >> 1]), LVFU(chr[c][(indx + v1 + h3) >> 1])); //Interpolate chrominance: R@B and B@R tempv = (nwgv * nwvv + negv * nevv + swgv * swvv + segv * sevv) / (nwgv + negv + swgv + segv); _mm_storeu_ps( &(chr[c][indx >> 1]), tempv); @@ -2226,10 +2183,10 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][(indx + v1 - h1) >> 1] - chr[c][(indx + v3 + h3) >> 1]) + fabsf(chr[c][(indx - v1 + h1) >> 1] - chr[c][(indx + v3 - h3) >> 1])); seg = 1.0f / (eps + fabsf(chr[c][(indx + v1 + h1) >> 1] - chr[c][(indx + v3 - h3) >> 1]) + fabsf(chr[c][(indx - v1 - h1) >> 1] - chr[c][(indx + v3 + h3) >> 1])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][(indx - v1 - h1) >> 1], chr[c][(indx - v3 - h1) >> 1], chr[c][(indx - v1 - h3) >> 1]); - nev = ULIM(chr[c][(indx - v1 + h1) >> 1], chr[c][(indx - v3 + h1) >> 1], chr[c][(indx - v1 + h3) >> 1]); - swv = ULIM(chr[c][(indx + v1 - h1) >> 1], chr[c][(indx + v3 - h1) >> 1], chr[c][(indx + v1 - h3) >> 1]); - sev = ULIM(chr[c][(indx + v1 + h1) >> 1], chr[c][(indx + v3 + h1) >> 1], chr[c][(indx + v1 + h3) >> 1]); + nwv = median(chr[c][(indx - v1 - h1) >> 1], chr[c][(indx - v3 - h1) >> 1], chr[c][(indx - v1 - h3) >> 1]); + nev = median(chr[c][(indx - v1 + h1) >> 1], chr[c][(indx - v3 + h1) >> 1], chr[c][(indx - v1 + h3) >> 1]); + swv = median(chr[c][(indx + v1 - h1) >> 1], chr[c][(indx + v3 - h1) >> 1], chr[c][(indx + v1 - h3) >> 1]); + sev = median(chr[c][(indx + v1 + h1) >> 1], chr[c][(indx + v3 + h1) >> 1], chr[c][(indx + v1 + h3) >> 1]); //Interpolate chrominance: R@B and B@R chr[c][indx >> 1] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2490,8 +2447,8 @@ void RawImageSource::igv_interpolate(int winw, int winh) eg = LIM(epssq + 78.0f * SQR(hdif[indx >> 1]) + 69.0f * (SQR(hdif[(indx - h2) >> 1]) + SQR(hdif[(indx + h2) >> 1])) + 51.0f * (SQR(hdif[(indx - h4) >> 1]) + SQR(hdif[(indx + h4) >> 1])) + 21.0f * (SQR(hdif[(indx - h6) >> 1]) + SQR(hdif[(indx + h6) >> 1])) - 6.0f * SQR(hdif[(indx - h2) >> 1] + hdif[indx >> 1] + hdif[(indx + h2) >> 1]) - 10.0f * (SQR(hdif[(indx - h4) >> 1] + hdif[(indx - h2) >> 1] + hdif[indx >> 1]) + SQR(hdif[indx >> 1] + hdif[(indx + h2) >> 1] + hdif[(indx + h4) >> 1])) - 7.0f * (SQR(hdif[(indx - h6) >> 1] + hdif[(indx - h4) >> 1] + hdif[(indx - h2) >> 1]) + SQR(hdif[(indx + h2) >> 1] + hdif[(indx + h4) >> 1] + hdif[(indx + h6) >> 1])), 0.f, 1.f); //Limit chrominance using H/V neighbourhood - nv = ULIM(0.725f * vdif[indx >> 1] + 0.1375f * vdif[(indx - v2) >> 1] + 0.1375f * vdif[(indx + v2) >> 1], vdif[(indx - v2) >> 1], vdif[(indx + v2) >> 1]); - ev = ULIM(0.725f * hdif[indx >> 1] + 0.1375f * hdif[(indx - h2) >> 1] + 0.1375f * hdif[(indx + h2) >> 1], hdif[(indx - h2) >> 1], hdif[(indx + h2) >> 1]); + nv = median(0.725f * vdif[indx >> 1] + 0.1375f * vdif[(indx - v2) >> 1] + 0.1375f * vdif[(indx + v2) >> 1], vdif[(indx - v2) >> 1], vdif[(indx + v2) >> 1]); + ev = median(0.725f * hdif[indx >> 1] + 0.1375f * hdif[(indx - h2) >> 1] + 0.1375f * hdif[(indx + h2) >> 1], hdif[(indx - h2) >> 1], hdif[(indx + h2) >> 1]); //Chrominance estimation chr[d][indx] = (eg * nv + ng * ev) / (ng + eg); //Green channel population @@ -2520,10 +2477,10 @@ void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][indx + v1 - h1] - chr[c][indx + v3 + h3]) + fabsf(chr[c][indx - v1 + h1] - chr[c][indx + v3 - h3])); seg = 1.0f / (eps + fabsf(chr[c][indx + v1 + h1] - chr[c][indx + v3 - h3]) + fabsf(chr[c][indx - v1 - h1] - chr[c][indx + v3 + h3])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); - nev = ULIM(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); - swv = ULIM(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); - sev = ULIM(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); + nwv = median(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); + nev = median(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); + swv = median(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); + sev = median(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); //Interpolate chrominance: R@B and B@R chr[c][indx] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2548,10 +2505,10 @@ void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][indx + v1 - h1] - chr[c][indx + v3 + h3]) + fabsf(chr[c][indx - v1 + h1] - chr[c][indx + v3 - h3])); seg = 1.0f / (eps + fabsf(chr[c][indx + v1 + h1] - chr[c][indx + v3 - h3]) + fabsf(chr[c][indx - v1 - h1] - chr[c][indx + v3 + h3])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); - nev = ULIM(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); - swv = ULIM(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); - sev = ULIM(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); + nwv = median(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); + nev = median(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); + swv = median(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); + sev = median(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); //Interpolate chrominance: R@B and B@R chr[c][indx] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2733,10 +2690,10 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) pix = image + (row * width + col); val = 0.25 * ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 - pix[-2][c] - pix[2][c]) ; - rgb[0][row - top][col - left][1] = ULIM(static_cast(val), pix[-1][1], pix[1][1]); + rgb[0][row - top][col - left][1] = median(static_cast(val), pix[-1][1], pix[1][1]); val = 0.25 * ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 - pix[-2 * width][c] - pix[2 * width][c]) ; - rgb[1][row - top][col - left][1] = ULIM(static_cast(val), pix[-width][1], pix[width][1]); + rgb[1][row - top][col - left][1] = median(static_cast(val), pix[-width][1], pix[width][1]); } } @@ -3218,39 +3175,21 @@ void RawImageSource::refinement_lassus(int PassCount) 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]); - float p[9]; - p[0] = (pix[-u - 1][1] - pix[-u - 1][c]); - p[1] = (pix[-u + 0][1] - pix[-u + 0][c]); - p[2] = (pix[-u + 1][1] - pix[-u + 1][c]); - p[3] = (pix[+0 - 1][1] - pix[+0 - 1][c]); - p[4] = (pix[+0 + 0][1] - pix[+0 + 0][c]); - p[5] = (pix[+0 + 1][1] - pix[+0 + 1][c]); - p[6] = (pix[+u - 1][1] - pix[+u - 1][c]); - p[7] = (pix[+u + 0][1] - pix[+u + 0][c]); - p[8] = (pix[+u + 1][1] - pix[+u + 1][c]); + 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] + }; - // sort p[] - float temp; // used in PIX_SORT macro; - PIX_SORT(p[1], p[2]); - PIX_SORT(p[4], p[5]); - PIX_SORT(p[7], p[8]); - PIX_SORT(p[0], p[1]); - PIX_SORT(p[3], p[4]); - PIX_SORT(p[6], p[7]); - PIX_SORT(p[1], p[2]); - PIX_SORT(p[4], p[5]); - PIX_SORT(p[7], p[8]); - PIX_SORT(p[0], p[3]); - PIX_SORT(p[5], p[8]); - PIX_SORT(p[4], p[7]); - PIX_SORT(p[3], p[6]); - PIX_SORT(p[1], p[4]); - PIX_SORT(p[2], p[5]); - PIX_SORT(p[4], p[7]); - PIX_SORT(p[4], p[2]); - PIX_SORT(p[6], p[4]); - PIX_SORT(p[4], p[2]); - pix[0][c] = LIM(pix[0][1] - (1.30f * g[4] - 0.30f * (pix[0][1] - pix[0][c])), 0.99f * (pix[0][1] - p[4]), 1.01f * (pix[0][1] - p[4])); + 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)); } } diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 10d2dff30..e06ac27e2 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -158,7 +158,7 @@ void dfInfo::updateRawImage() int nFiles = 1; // First file data already loaded - for( iName++; iName != pathNames.end(); iName++) { + for( ++iName; iName != pathNames.end(); ++iName) { RawImage* temp = new RawImage(*iName); if( !temp->loadRaw(true)) { @@ -300,7 +300,7 @@ void DFManager::init( Glib::ustring pathname ) } // Where multiple shots exist for same group, move filename to list - for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); iter++ ) { + for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) { dfInfo &i = iter->second; if( !i.pathNames.empty() && !i.pathname.empty() ) { @@ -314,7 +314,7 @@ void DFManager::init( Glib::ustring pathname ) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); iter++ ) { + for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { printf( "%s, ", iter->c_str() ); } @@ -391,7 +391,7 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) ); } else { while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6 ) { // 6 hour difference - iter++; + ++iter; } if( iter != dfList.end() ) { @@ -414,7 +414,7 @@ void DFManager::getStat( int &totFiles, int &totTemplates) totFiles = 0; totTemplates = 0; - for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); iter++ ) { + for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) { dfInfo &i = iter->second; if( i.pathname.empty() ) { @@ -443,7 +443,7 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso dfList_t::iterator bestMatch = iter; time_t bestDeltaTime = ABS(iter->second.timestamp - t); - for(iter++; iter != dfList.end() && !key.compare( iter->second.key() ); iter++ ) { + for(++iter; iter != dfList.end() && !key.compare( iter->second.key() ); ++iter ) { time_t d = ABS(iter->second.timestamp - t ); if( d < bestDeltaTime ) { @@ -458,7 +458,7 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso dfList_t::iterator bestMatch = iter; double bestD = iter->second.distance( mak, mod, isospeed, shut ); - for( iter++; iter != dfList.end(); iter++ ) { + for( ++iter; iter != dfList.end(); ++iter ) { double d = iter->second.distance( mak, mod, isospeed, shut ); if( d < bestD ) { @@ -484,7 +484,7 @@ RawImage* DFManager::searchDarkFrame( const std::string &mak, const std::string RawImage* DFManager::searchDarkFrame( const Glib::ustring filename ) { - for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); iter++ ) { + for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) { if( iter->second.pathname.compare( filename ) == 0 ) { return iter->second.getRawImage(); } @@ -500,7 +500,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename ) } std::vector *DFManager::getHotPixels ( const Glib::ustring filename ) { - for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); iter++ ) { + for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) { if( iter->second.pathname.compare( filename ) == 0 ) { return &iter->second.getHotPixels(); } diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index f09eb3459..a5505391e 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -72,11 +72,15 @@ DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) if(x[0] == 0.f && x[1] == 0.f) // Avoid crash when first two points are at x = 0 (git Issue 2888) + { x[1] = 0.01f; + } if(x[0] == 1.f && x[1] == 1.f) // Avoid crash when first two points are at x = 1 (100 in gui) (git Issue 2923) + { x[0] = 0.99f; + } if (!identity) { if (kind == DCT_Spline && N > 2) { @@ -260,6 +264,8 @@ void DiagonalCurve::NURBS_set () // adding the final horizontal segment, always (see under) poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) poly_y.push_back(y[N - 1]); + + fillDyByDx(); } double DiagonalCurve::getVal (double t) const @@ -301,10 +307,10 @@ double DiagonalCurve::getVal (double t) const } // do a binary search for the right interval: - int k_lo = 0, k_hi = N - 1; + unsigned int k_lo = 0, k_hi = N - 1; - while (k_hi - k_lo > 1) { - int k = (k_hi + k_lo) / 2; + while (k_hi > 1 + k_lo) { + unsigned int k = (k_hi + k_lo) / 2; if (x[k] > t) { k_hi = k; @@ -323,7 +329,7 @@ double DiagonalCurve::getVal (double t) const else { // if (kind==Spline) { double a = (x[k_hi] - t) / h; double b = (t - x[k_lo]) / h; - double r = a * y[k_lo] + b * y[k_hi] + ((a * a * a - a) * ypp[k_lo] + (b * b * b - b) * ypp[k_hi]) * (h * h) / 6.0; + double r = a * y[k_lo] + b * y[k_hi] + ((a * a * a - a) * ypp[k_lo] + (b * b * b - b) * ypp[k_hi]) * (h * h) * 0.1666666666666666666666666666666; return CLIPD(r); } @@ -334,7 +340,7 @@ double DiagonalCurve::getVal (double t) const // get the hash table entry by rounding the value (previously multiplied by "hashSize") unsigned short int i = (unsigned short int)(t * hashSize); - if (i > (hashSize + 1)) { + if (UNLIKELY(i > (hashSize + 1))) { //printf("\nOVERFLOW: hash #%d is used while seeking for value %.8f, corresponding polygon's point #%d (out of %d point) x value: %.8f\n\n", i, t, hash.at(i), poly_x.size(), poly_x[hash.at(i)]); printf("\nOVERFLOW: hash #%d is used while seeking for value %.8f\n\n", i, t); return t; @@ -347,7 +353,7 @@ double DiagonalCurve::getVal (double t) const k_hi = hash.at(i).higherValue; // do a binary search for the right interval : - while (k_hi - k_lo > 1) { + while (k_hi > 1 + k_lo) { unsigned int k = (k_hi + k_lo) / 2; if (poly_x[k] > t) { @@ -357,13 +363,7 @@ double DiagonalCurve::getVal (double t) const } } - if (k_lo == k_hi) { - k_hi = k_lo + 1; - } - - double dx = poly_x[k_hi] - poly_x[k_lo]; - double dy = poly_y[k_hi] - poly_y[k_lo]; - return poly_y[k_lo] + (t - poly_x[k_lo]) * ( dy ) / dx; + return poly_y[k_lo] + (t - poly_x[k_lo]) * dyByDx[k_lo]; break; } diff --git a/rtengine/dirpyrLab_denoise.cc b/rtengine/dirpyrLab_denoise.cc deleted file mode 100644 index ee434d75f..000000000 --- a/rtengine/dirpyrLab_denoise.cc +++ /dev/null @@ -1,751 +0,0 @@ -/* - * 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 . - * - * � 2010 Emil Martinec - * - */ - -#include -#include -#include "curves.h" -#include "labimage.h" -#include "improcfun.h" -#include "array2D.h" -#include "rt_math.h" - -#ifdef _OPENMP -#include -#endif - -#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) - -#define DIRWT_L(i1,j1,i,j) ( rangefn_L[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] ) - -#define DIRWT_AB(i1,j1,i,j) ( rangefn_ab[(data_fine->a[i1][j1]-data_fine->a[i][j]+32768)] * \ -rangefn_ab[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] * \ -rangefn_ab[(data_fine->b[i1][j1]-data_fine->b[i][j]+32768)] ) - -//#define NRWT_L(a) (nrwt_l[a] ) - -#define NRWT_AB (nrwt_ab[(hipass[1]+32768)] * nrwt_ab[(hipass[2]+32768)]) - - -#define med3(a,b,c) (a(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ -PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ -PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ -PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median - - -namespace rtengine -{ - -static const int maxlevel = 4; - -//sequence of scales -//static const int scales[8] = {1,2,4,8,16,32,64,128}; -//sequence of pitches -//static const int pitches[8] = {1,1,1,1,1,1,1,1}; - -//sequence of scales -//static const int scales[8] = {1,1,1,1,1,1,1,1}; -//sequence of pitches -//static const int pitches[8] = {2,2,2,2,2,2,2,2}; - -//sequence of scales -//static const int scales[8] = {1,1,2,2,4,4,8,8}; -//sequence of pitches -//static const int pitches[8] = {2,1,2,1,2,1,2,1}; - -//sequence of scales -static const int scales[8] = {1, 1, 2, 4, 8, 16, 32, 64}; -//sequence of pitches -static const int pitches[8] = {2, 1, 1, 1, 1, 1, 1, 1}; - -//pitch is spacing of subsampling -//scale is spacing of directional averaging weights -//example 1: no subsampling at any level -- pitch=1, scale=2^n -//example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level -//example 3: no subsampling at first level, subsampling by 2 thereafter -- -// pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter - - - - -void ImProcFunctions :: dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams ) -{ - float gam = dnparams.gamma / 3.0; - //float gam = 2.0;//min(3.0, 0.1*fabs(c[4])/3.0+0.001); - float gamthresh = 0.03; - float gamslope = exp(log((double)gamthresh) / gam) / gamthresh; - - LUTf gamcurve(65536, 0); - - //DiagonalCurve* lumacurve = new DiagonalCurve (dnparams.lumcurve, CURVES_MIN_POLY_POINTS); - //DiagonalCurve* chromacurve = new DiagonalCurve (dnparams.chromcurve, CURVES_MIN_POLY_POINTS); - //LUTf Lcurve(65536); - //LUTf abcurve(65536); - for (int i = 0; i < 65536; i++) { - int g = (int)(CurveFactory::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 65535.0); - gamcurve[i] = CLIP(g); - /*float val = (float)i/65535.0; - float Lval = (2*(lumacurve->getVal(val))); - float abval = (2*(chromacurve->getVal(val))); - - Lcurve[i] = SQR(Lval); - abcurve[i] = SQR(abval); - if (i % 1000 ==0) printf("%d Lmult=%f abmult=%f \n",i,Lcurve[i],abcurve[i]);*/ - } - - //delete lumacurve; - //delete chromacurve; - - - - //#pragma omp parallel for if (multiThread) - for (int i = 0; i < src->H; i++) { - for (int j = 0; j < src->W; j++) { - //src->L[i][j] = CurveFactory::flinterp(gamcurve,src->L[i][j]); - src->L[i][j] = gamcurve[src->L[i][j]]; - } - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - LUTf rangefn_L(65536); - LUTf nrwt_l(65536); - - LUTf rangefn_ab(65536); - LUTf nrwt_ab(65536); - - //set up NR weight functions - - //gamma correction for chroma in shadows - float nrwtl_norm = ((CurveFactory::gamma((double)65535.0 / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) - - (CurveFactory::gamma((double)75535.0 / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0))); - - for (int i = 0; i < 65536; i++) { - nrwt_l[i] = ((CurveFactory::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) - - CurveFactory::gamma((double)(i + 10000) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) ) / nrwtl_norm; - //if (i % 100 ==0) printf("%d %f \n",i,nrwt_l[i]); - } - - float tonefactor = nrwt_l[32768]; - - float noise_L = 10.0 * dnparams.luma; - float noisevar_L = SQR(noise_L); - - float noise_ab = 100.0 * dnparams.chroma; - float noisevar_ab = SQR(noise_ab); - - - //set up range functions - for (int i = 0; i < 65536; i++) { - rangefn_L[i] = (( exp(-(double)fabs(i - 32768) * tonefactor / (1.0 + noise_L)) * (1.0 + noisevar_L) / ((double)(i - 32768) * (double)(i - 32768) + noisevar_L + 1.0))); - } - - for (int i = 0; i < 65536; i++) { - rangefn_ab[i] = (( exp(-(double)fabs(i - 32768) * tonefactor / (1.0 + 3 * noise_ab)) * (1.0 + noisevar_ab) / ((double)(i - 32768) * (double)(i - 32768) + noisevar_ab + 1.0))); - } - - - for (int i = 0; i < 65536; i++) { - nrwt_ab[i] = ((1.0 + abs(i - 32768) / (1.0 + 8 * noise_ab)) * exp(-(double)fabs(i - 32768) / (1.0 + 8 * noise_ab) ) ); - } - - - //for (int i=0; i<65536; i+=100) printf("%d %d \n",i,gamcurve[i]); - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - int level; - - LabImage * dirpyrLablo[maxlevel]; - int w = (int)((src->W - 1) / pitches[0]) + 1; - int h = (int)((src->H - 1) / pitches[0]) + 1; - dirpyrLablo[0] = new LabImage(w, h); - - for (level = 1; level < maxlevel; level++) { - w = (int)((w - 1) / pitches[level]) + 1; - h = (int)((h - 1) / pitches[level]) + 1; - dirpyrLablo[level] = new LabImage(w, h); - }; - - - ////////////////////////////////////////////////////////////////////////////// - - - // c[0] = luma = noise_L - // c[1] = chroma = noise_ab - // c[2] decrease of noise var with scale - // c[3] radius of domain blur at each level - // c[4] shadow smoothing - // c[5] edge preservation - - level = 0; - - int scale = scales[level]; - - int pitch = pitches[level]; - - //int thresh = 10 * c[8]; - //impulse_nr (src, src, m_w1, m_h1, thresh, noisevar); - - dirpyr(src, dirpyrLablo[0], 0, rangefn_L, rangefn_ab, pitch, scale, dnparams.luma, dnparams.chroma ); - - level = 1; - - while(level < maxlevel) { - scale = scales[level]; - pitch = pitches[level]; - - dirpyr(dirpyrLablo[level - 1], dirpyrLablo[level], level, rangefn_L, rangefn_ab, pitch, scale, dnparams.luma, dnparams.chroma ); - - level ++; - } - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - for(int level = maxlevel - 1; level > 0; level--) { - - int scale = scales[level]; - int pitch = pitches[level]; - idirpyr(dirpyrLablo[level], dirpyrLablo[level - 1], level, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); - } - - - scale = scales[0]; - pitch = pitches[0]; - - // freeing as much memory as possible since the next call to idirpyr will need lots - for(int i = 1; i < maxlevel; i++) { - delete dirpyrLablo[i]; - } - - idirpyr(dirpyrLablo[0], dst, 0, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); - - // freeing the last bunch of memory - delete dirpyrLablo[0]; - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - float igam = 1 / gam; - float igamthresh = gamthresh * gamslope; - float igamslope = 1 / gamslope; - - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (CurveFactory::gamma((float)i / 65535.0, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0); - } - - - if (dnparams.luma > 0) { - for (int i = 0; i < dst->H; i++) - for (int j = 0; j < dst->W; j++) { - dst->L[i][j] = gamcurve[dst->L[i][j]]; - } - } else { - for (int i = 0; i < dst->H; i++) - for (int j = 0; j < dst->W; j++) { - dst->L[i][j] = gamcurve[src->L[i][j]]; - } - } - -} - -void ImProcFunctions::dirpyr(LabImage* data_fine, LabImage* data_coarse, int level, - LUTf & rangefn_L, LUTf & rangefn_ab, int pitch, int scale, - const int luma, const int chroma ) -{ - - //pitch is spacing of subsampling - //scale is spacing of directional averaging weights - //example 1: no subsampling at any level -- pitch=1, scale=2^n - //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level - //example 3: no subsampling at first level, subsampling by 2 thereafter -- - // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // calculate weights, compute directionally weighted average - - int width = data_fine->W; - int height = data_fine->H; - - //generate domain kernel - int halfwin = 3;//min(ceil(2*sig),3); - int scalewin = halfwin * scale; - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < height; i += pitch ) { - int i1 = i / pitch; - - for(int j = 0, j1 = 0; j < width; j += pitch, j1++) { - float dirwt_l, dirwt_ab, norm_l, norm_ab; - //float lops,aops,bops; - float Lout, aout, bout; - norm_l = norm_ab = 0;//if we do want to include the input pixel in the sum - Lout = 0; - aout = 0; - bout = 0; - - for(int inbr = (i - scalewin); inbr <= (i + scalewin); inbr += scale) { - if (inbr < 0 || inbr > height - 1) { - continue; - } - - for (int jnbr = (j - scalewin); jnbr <= (j + scalewin); jnbr += scale) { - if (jnbr < 0 || jnbr > width - 1) { - continue; - } - - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - dirwt_ab = DIRWT_AB(inbr, jnbr, i, j); - Lout += dirwt_l * data_fine->L[inbr][jnbr]; - aout += dirwt_ab * data_fine->a[inbr][jnbr]; - bout += dirwt_ab * data_fine->b[inbr][jnbr]; - norm_l += dirwt_l; - norm_ab += dirwt_ab; - } - } - - //lops = Lout/norm;//diagnostic - //aops = aout/normab;//diagnostic - //bops = bout/normab;//diagnostic - - data_coarse->L[i1][j1] = Lout / norm_l; //low pass filter - data_coarse->a[i1][j1] = aout / norm_ab; - data_coarse->b[i1][j1] = bout / norm_ab; - - - /*if (level<2 && i>0 && i0 && jL[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ - data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ - data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1]); - //med3x3(data_fine->L[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ - data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ - data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1],Lmed); - - data_coarse->L[i1][j1] = Lhmf; - }*/ - } - } - - - - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void ImProcFunctions::idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, - int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/ ) -{ - - int width = data_fine->W; - int height = data_fine->H; - - array2D nrfactorL (width, height); - - //float eps = 0.0; - - // c[0] noise_L - // c[1] noise_ab (relative to noise_L) - // c[2] decrease of noise var with scale - // c[3] radius of domain blur at each level - // c[4] shadow smoothing - - float noisevar_L = 4 * SQR(25.0 * luma); - float noisevar_ab = 2 * SQR(100.0 * chroma); - float scalefactor = 1.0 / pow(2.0, (level + 1) * 2); //change the last 2 to 1 for longer tail of higher scale NR - - noisevar_L *= scalefactor; - - // for coarsest level, take non-subsampled lopass image and subtract from lopass_fine to generate hipass image - - // denoise hipass image, add back into lopass_fine to generate denoised image at fine scale - - // now iterate: - // (1) take denoised image at level n, expand and smooth using gradient weights from lopass image at level n-1 - // the result is the smoothed image at level n-1 - // (2) subtract smoothed image at level n-1 from lopass image at level n-1 to make hipass image at level n-1 - // (3) denoise the hipass image at level n-1 - // (4) add the denoised image at level n-1 to the smoothed image at level n-1 to make the denoised image at level n-1 - - // note that the coarsest level amounts to skipping step (1) and doing (2,3,4). - // in other words, skip step one if pitch=1 - - // step (1) - - if (pitch == 1) { - - // step (1-2-3-4) - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) - { - float hipass[3], hpffluct[3], tonefactor, nrfactor; - - tonefactor = (nrwt_l[data_coarse->L[i][j]]); - - hipass[1] = data_fine->a[i][j] - data_coarse->a[i][j]; - hipass[2] = data_fine->b[i][j] - data_coarse->b[i][j]; - - //Wiener filter - //luma - if (level < 2) { - hipass[0] = data_fine->L[i][j] - data_coarse->L[i][j]; - hpffluct[0] = SQR(hipass[0]) + SQR(hipass[1]) + SQR(hipass[2]) + 0.001; - nrfactorL[i][j] = (1.0 + hpffluct[0]) / (1.0 + hpffluct[0] + noisevar_L /* * Lcurve[data_coarse->L[i][j]]*/); - //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); - //data_fine->L[i][j] = CLIP(hipass[0]+data_coarse->L[i][j]); - } - - //chroma - //hipass[1] = data_fine->a[i][j]-data_coarse->a[i][j]; - //hipass[2] = data_fine->b[i][j]-data_coarse->b[i][j]; - hpffluct[1] = SQR(hipass[1] * tonefactor) + 0.001; - hpffluct[2] = SQR(hipass[2] * tonefactor) + 0.001; - nrfactor = (hpffluct[1] + hpffluct[2]) / ((hpffluct[1] + hpffluct[2]) + noisevar_ab * NRWT_AB); - - hipass[1] *= nrfactor; - hipass[2] *= nrfactor; - - data_fine->a[i][j] = hipass[1] + data_coarse->a[i][j]; - data_fine->b[i][j] = hipass[2] + data_coarse->b[i][j]; - } - - if (level < 2) - { -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float dirwt_l, norm_l; - float nrfctrave = 0; - norm_l = 0;//if we do want to include the input pixel in the sum - - for(int inbr = max(0, i - 1); inbr <= min(height - 1, i + 1); inbr++) { - for (int jnbr = max(0, j - 1); jnbr <= min(width - 1, j + 1); jnbr++) { - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - nrfctrave += dirwt_l * nrfactorL[inbr][jnbr]; - norm_l += dirwt_l; - } - } - - nrfctrave /= norm_l; - //nrfctrave = nrfactorL[i][j]; - //nrfctrave=1; - - float hipass[3]; - - //luma - - /*if (i>0 && i0 && jL[i][j] - data_coarse->L[i][j]); - //hipass[0] = median*(data_fine->L[i][j]-data_coarse->L[i][j]); - //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); - data_fine->L[i][j] = CLIP(hipass[0] + data_coarse->L[i][j]); - - //chroma - //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); - //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); - - //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; - //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; - } - }//end of luminance correction - - - - }//end of pitch=1 - - } else {//pitch>1 - - LabImage* smooth; - - smooth = new LabImage(width, height); -#ifdef _OPENMP - #pragma omp parallel -#endif - - { - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i += pitch) { - int ix = i / pitch; - - for(int j = 0, jx = 0; j < width; j += pitch, jx++) { - - //copy common pixels - smooth->L[i][j] = data_coarse->L[ix][jx]; - smooth->a[i][j] = data_coarse->a[ix][jx]; - smooth->b[i][j] = data_coarse->b[ix][jx]; - } - } - - //if (pitch>1) {//pitch=2; step (1) expand coarse image, fill in missing data -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height - 1; i += 2) - for(int j = 0; j < width - 1; j += 2) { - //do midpoint first - double norm = 0.0, wtdsum[3] = {0.0, 0.0, 0.0}; - - //wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; - for(int ix = i; ix < min(height, i + 3); ix += 2) - for (int jx = j; jx < min(width, j + 3); jx += 2) { - wtdsum[0] += smooth->L[ix][jx]; - wtdsum[1] += smooth->a[ix][jx]; - wtdsum[2] += smooth->b[ix][jx]; - norm++; - } - - norm = 1 / norm; - smooth->L[i + 1][j + 1] = wtdsum[0] * norm; - smooth->a[i + 1][j + 1] = wtdsum[1] * norm; - smooth->b[i + 1][j + 1] = wtdsum[2] * norm; - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height - 1; i += 2) - for(int j = 0; j < width - 1; j += 2) { - //now right neighbor - if (j + 1 == width) { - continue; - } - - double norm = 0.0, wtdsum[3] = {0.0, 0.0, 0.0}; - - for (int jx = j; jx < min(width, j + 3); jx += 2) { - wtdsum[0] += smooth->L[i][jx]; - wtdsum[1] += smooth->a[i][jx]; - wtdsum[2] += smooth->b[i][jx]; - norm++; - } - - for (int ix = max(0, i - 1); ix < min(height, i + 2); ix += 2) { - wtdsum[0] += smooth->L[ix][j + 1]; - wtdsum[1] += smooth->a[ix][j + 1]; - wtdsum[2] += smooth->b[ix][j + 1]; - norm++; - } - - norm = 1 / norm; - smooth->L[i][j + 1] = wtdsum[0] * norm; - smooth->a[i][j + 1] = wtdsum[1] * norm; - smooth->b[i][j + 1] = wtdsum[2] * norm; - - //now down neighbor - if (i + 1 == height) { - continue; - } - - norm = 0.0; - wtdsum[0] = wtdsum[1] = wtdsum[2] = 0.0; - - for (int ix = i; ix < min(height, i + 3); ix += 2) { - wtdsum[0] += smooth->L[ix][j]; - wtdsum[1] += smooth->a[ix][j]; - wtdsum[2] += smooth->b[ix][j]; - norm++; - } - - for (int jx = max(0, j - 1); jx < min(width, j + 2); jx += 2) { - wtdsum[0] += smooth->L[i + 1][jx]; - wtdsum[1] += smooth->a[i + 1][jx]; - wtdsum[2] += smooth->b[i + 1][jx]; - norm++; - } - - norm = 1 / norm; - smooth->L[i + 1][j] = wtdsum[0] * norm; - smooth->a[i + 1][j] = wtdsum[1] * norm; - smooth->b[i + 1][j] = wtdsum[2] * norm; - - } - -#ifdef _OPENMP - #pragma omp for -#endif - - // step (2-3-4) - for( int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float tonefactor = (nrwt_l[smooth->L[i][j]]); - //double wtdsum[3], norm; - float hipass[3], hpffluct[3], nrfactor; - - hipass[1] = data_fine->a[i][j] - smooth->a[i][j]; - hipass[2] = data_fine->b[i][j] - smooth->b[i][j]; - - //Wiener filter - //luma - if (level < 2) { - hipass[0] = data_fine->L[i][j] - smooth->L[i][j]; - hpffluct[0] = SQR(hipass[0]) + SQR(hipass[1]) + SQR(hipass[2]) + 0.001; - nrfactorL[i][j] = (1.0 + hpffluct[0]) / (1.0 + hpffluct[0] + noisevar_L /* * Lcurve[smooth->L[i][j]]*/); - //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); - //data_fine->L[i][j] = CLIP(hipass[0]+smooth->L[i][j]); - } - - //chroma - //hipass[1] = data_fine->a[i][j]-smooth->a[i][j]; - //hipass[2] = data_fine->b[i][j]-smooth->b[i][j]; - hpffluct[1] = SQR(hipass[1] * tonefactor) + 0.001; - hpffluct[2] = SQR(hipass[2] * tonefactor) + 0.001; - nrfactor = (hpffluct[1] + hpffluct[2]) / ((hpffluct[1] + hpffluct[2]) + noisevar_ab * NRWT_AB /* * abcurve[smooth->L[i][j]]*/); - - hipass[1] *= nrfactor; - hipass[2] *= nrfactor; - - data_fine->a[i][j] = hipass[1] + smooth->a[i][j]; - data_fine->b[i][j] = hipass[2] + smooth->b[i][j]; - } - - - if (level < 2) { -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float dirwt_l, norm_l; - float nrfctrave = 0; - norm_l = 0;//if we do want to include the input pixel in the sum - - for(int inbr = (i - pitch); inbr <= (i + pitch); inbr += pitch) { - if (inbr < 0 || inbr > height - 1) { - continue; - } - - for (int jnbr = (j - pitch); jnbr <= (j + pitch); jnbr += pitch) { - if (jnbr < 0 || jnbr > width - 1) { - continue; - } - - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - nrfctrave += dirwt_l * nrfactorL[inbr][jnbr]; - norm_l += dirwt_l; - } - } - - nrfctrave /= norm_l; - //nrfctrave = nrfactorL[i][j]; - //nrfctrave=1; - - - float hipass[3]; - - //luma - - /*if (i>0 && i0 && jL[i][j] - smooth->L[i][j]); - //hipass[0] = median*(data_fine->L[i][j]-smooth->L[i][j]); - //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); - data_fine->L[i][j] = CLIP(hipass[0] + smooth->L[i][j]); - - - //chroma - //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); - //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); - - //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; - //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; - } - }//end of luminance correction - - - } // end parallel - delete smooth; - }//end of pitch>1 - -} - - -#undef DIRWT_L -#undef DIRWT_AB - -//#undef NRWT_L -#undef NRWT_AB - -} - diff --git a/rtengine/dirpyrLab_equalizer.cc b/rtengine/dirpyrLab_equalizer.cc index 93a1b1ff1..fc5fc70a0 100644 --- a/rtengine/dirpyrLab_equalizer.cc +++ b/rtengine/dirpyrLab_equalizer.cc @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * © 2010 Emil Martinec + * (C) 2010 Emil Martinec * */ diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index f82b7f8bf..a3a6d81b0 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * © 2010 Emil Martinec + * (C) 2010 Emil Martinec * */ diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 783c18bf7..8b26c3121 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -18,11 +18,9 @@ */ #include "ffmanager.h" #include "../rtgui/options.h" -#include #include "rawimage.h" -#include -#include #include "imagedata.h" +#include "median.h" namespace rtengine { @@ -153,7 +151,7 @@ void ffInfo::updateRawImage() int nFiles = 1; // First file data already loaded - for( iName++; iName != pathNames.end(); iName++) { + for( ++iName; iName != pathNames.end(); ++iName) { RawImage* temp = new RawImage(*iName); if( !temp->loadRaw(true)) { @@ -200,8 +198,35 @@ void ffInfo::updateRawImage() ri->compress_image(); } } -} + if(ri) { + // apply median to avoid this step being executed each time a flat field gets applied + int H = ri->get_height(); + int W = ri->get_width(); + float *cfatmp = (float (*)) malloc (H * W * sizeof * cfatmp); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int i = 0; i < H; i++) { + int iprev = i < 2 ? i + 2 : i - 2; + int inext = i > H - 3 ? i - 2 : i + 2; + + for (int j = 0; j < W; j++) { + int jprev = j < 2 ? j + 2 : j - 2; + int jnext = j > W - 3 ? j - 2 : j + 2; + + cfatmp[i * W + j] = median(ri->data[iprev][j], ri->data[i][jprev], ri->data[i][j], ri->data[i][jnext], ri->data[inext][j]); + } + } + + memcpy(ri->data[0], cfatmp, W * H * sizeof(float)); + + free (cfatmp); + + } +} // ************************* class FFManager ********************************* @@ -210,6 +235,7 @@ void FFManager::init( Glib::ustring pathname ) std::vector names; auto dir = Gio::File::create_for_path (pathname); + if (!dir || !dir->query_exists()) { return; } @@ -233,7 +259,7 @@ void FFManager::init( Glib::ustring pathname ) } // Where multiple shots exist for same group, move filename to list - for( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); iter++ ) { + for( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); ++iter ) { ffInfo &i = iter->second; if( !i.pathNames.empty() && !i.pathname.empty() ) { @@ -247,7 +273,7 @@ void FFManager::init( Glib::ustring pathname ) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); iter++ ) { + for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { printf( "%s, ", iter->c_str() ); } @@ -287,6 +313,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) Glib::ustring ext; auto lastdot = info->get_name ().find_last_of ('.'); + if (lastdot != Glib::ustring::npos) { ext = info->get_name ().substr (lastdot + 1); } @@ -325,7 +352,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) ); } else { while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6 ) { // 6 hour difference - iter++; + ++iter; } if( iter != ffList.end() ) { @@ -348,7 +375,7 @@ void FFManager::getStat( int &totFiles, int &totTemplates) totFiles = 0; totTemplates = 0; - for( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); iter++ ) { + for( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); ++iter ) { ffInfo &i = iter->second; if( i.pathname.empty() ) { @@ -377,7 +404,7 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const s ffList_t::iterator bestMatch = iter; time_t bestDeltaTime = ABS(iter->second.timestamp - t); - for(iter++; iter != ffList.end() && !key.compare( iter->second.key() ); iter++ ) { + for(++iter; iter != ffList.end() && !key.compare( iter->second.key() ); ++iter ) { time_t d = ABS(iter->second.timestamp - t ); if( d < bestDeltaTime ) { @@ -392,7 +419,7 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const s ffList_t::iterator bestMatch = iter; double bestD = iter->second.distance( mak, mod, len, focal, apert ); - for( iter++; iter != ffList.end(); iter++ ) { + for( ++iter; iter != ffList.end(); ++iter ) { double d = iter->second.distance( mak, mod, len, focal, apert ); if( d < bestD ) { @@ -418,7 +445,7 @@ RawImage* FFManager::searchFlatField( const std::string &mak, const std::string RawImage* FFManager::searchFlatField( const Glib::ustring filename ) { - for ( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); iter++ ) { + for ( ffList_t::iterator iter = ffList.begin(); iter != ffList.end(); ++iter ) { if( iter->second.pathname.compare( filename ) == 0 ) { return iter->second.getRawImage(); } diff --git a/rtengine/flatcurves.cc b/rtengine/flatcurves.cc index ee4d6d29c..5a4dfeacf 100644 --- a/rtengine/flatcurves.cc +++ b/rtengine/flatcurves.cc @@ -16,21 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include -#include #include "curves.h" #include #include -#include "mytime.h" -#include - -#include -#include namespace rtengine { -FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : kind(FCT_Empty), leftTangent(NULL), rightTangent(NULL), identityValue(0.5), periodic(isPeriodic) +FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : kind(FCT_Empty), leftTangent(nullptr), rightTangent(nullptr), identityValue(0.5), periodic(isPeriodic) { ppn = poly_pn > 65500 ? 65500 : poly_pn; @@ -341,17 +334,7 @@ void FlatCurve::CtrlPoints_set () poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) poly_y.push_back(sc_y[j - 1]); - /* - // Checking the values - Glib::ustring fname = "Curve.xyz"; // TopSolid'Design "plot" file format - std::ofstream f (fname.c_str()); - f << "$" << std::endl;; - for (unsigned int iter = 0; iter < poly_x.size(); iter++) { - f << poly_x[iter] << ", " << poly_y[iter] << ", 0." << std::endl;; - } - f << "$" << std::endl;; - f.close (); - */ + fillDyByDx(); } double FlatCurve::getVal (double t) const @@ -367,10 +350,10 @@ double FlatCurve::getVal (double t) const } // do a binary search for the right interval: - int k_lo = 0, k_hi = poly_x.size() - 1; + unsigned int k_lo = 0, k_hi = poly_x.size() - 1; - while (k_hi - k_lo > 1) { - int k = (k_hi + k_lo) / 2; + while (k_hi > 1 + k_lo) { + unsigned int k = (k_hi + k_lo) / 2; if (poly_x[k] > t) { k_hi = k; @@ -379,9 +362,7 @@ double FlatCurve::getVal (double t) const } } - double dx = poly_x[k_hi] - poly_x[k_lo]; - double dy = poly_y[k_hi] - poly_y[k_lo]; - return poly_y[k_lo] + (t - poly_x[k_lo]) * dy / dx; + return poly_y[k_lo] + (t - poly_x[k_lo]) * dyByDx[k_lo]; break; } diff --git a/rtengine/helperavx.h b/rtengine/helperavx.h index eb32277c3..528760a92 100644 --- a/rtengine/helperavx.h +++ b/rtengine/helperavx.h @@ -1,3 +1,9 @@ +//////////////////////////////////////////////////////////////// +// +// this code was taken from http://shibatch.sourceforge.net/ +// Many thanks to the author: Naoki Shibata +// +//////////////////////////////////////////////////////////////// #ifndef __AVX__ #error Please specify -mavx. #endif diff --git a/rtengine/helpersse2.h b/rtengine/helpersse2.h index da1691748..23dd016fa 100644 --- a/rtengine/helpersse2.h +++ b/rtengine/helpersse2.h @@ -1,3 +1,12 @@ +//////////////////////////////////////////////////////////////// +// +// 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 __SSE2__ #error Please specify -msse2. #endif @@ -26,17 +35,20 @@ typedef __m128i vint2; #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) #define STVFU(x,y) _mm_storeu_ps(&x,y) +#define LVI(x) _mm_load_si128((__m128i*)&x) #else // there is a bug in gcc 4.7.x when using openmp and aligned memory and -O3, also need to map the aligned functions to unaligned functions for WIN32 builds #define LVF(x) _mm_loadu_ps((float*)&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_storeu_ps(&x,y) #define STVFU(x,y) _mm_storeu_ps(&x,y) +#define LVI(x) _mm_loadu_si128((__m128i*)&x) #endif #else #define LVF(x) _mm_load_ps((float*)&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) #define STVFU(x,y) _mm_storeu_ps(&x,y) +#define LVI(x) _mm_load_si128((__m128i*)&x) #endif #if defined(__x86_64__) && defined(__AVX__) diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h index 9e9682a73..a6fd8d9e6 100644 --- a/rtengine/iccmatrices.h +++ b/rtengine/iccmatrices.h @@ -20,164 +20,242 @@ #define _ICCMATRICES_ // Bradford transform between illuminants -const double d65_d50[3][3] = {{0.9555766, -0.0230393, 0.0631636}, +constexpr double d65_d50[3][3] = { + {0.9555766, -0.0230393, 0.0631636}, { -0.0282895, 1.0099416, 0.0210077}, {0.0122982, -0.0204830, 1.3299098} }; -const double d50_d65[3][3] = {{ 1.0478112, 0.0228866, -0.0501270}, +constexpr double d50_d65[3][3] = { + { 1.0478112, 0.0228866, -0.0501270}, {0.0295424, 0.9904844, -0.0170491}, { -0.0092345, 0.0150436, 0.7521316} }; // Color space conversion to/from XYZ; color spaces adapted to D65 -const double xyz_sRGBd65[3][3] = {{0.4124564, 0.3575761, 0.1804375}, +constexpr double xyz_sRGBd65[3][3] = { + {0.4124564, 0.3575761, 0.1804375}, {0.2126729, 0.7151522, 0.0721750}, // WARNING: the summ of this line is > 1.0 {0.0193339, 0.1191920, 0.9503041} }; -const double sRGBd65_xyz[3][3] = {{ 3.2404542, -1.5371385, -0.4985314}, +constexpr double sRGBd65_xyz[3][3] = { + { 3.2404542, -1.5371385, -0.4985314}, { -0.9692660, 1.8760108, 0.0415560}, {0.0556434, -0.2040259, 1.0572252} }; //%%%%%%%%%%%%%%%%%%%%%%%% // TEST using Gabor's matrices -/*const double xyz_sRGB[3][3] = {{0.435859, 0.385336, 0.143023}, +/*constexpr double xyz_sRGB[3][3] = { + {0.435859, 0.385336, 0.143023}, {0.222385, 0.717021, 0.0605936 }, {0.0139162, 0.0971389, 0.713817}}; -const double sRGB_xyz[3][3] = {{3.13593293538656, -1.61878246026431, -0.490913888760734}, +constexpr double sRGB_xyz[3][3] = { + {3.13593293538656, -1.61878246026431, -0.490913888760734}, {-0.978702373022194, 1.91609508555177, 0.0334453372795315}, {0.0720490013929888, -0.22919049060526, 1.40593851447263}};*/ //%%%%%%%%%%%%%%%%%%%%%%%% // Color space conversion to/from XYZ; color spaces adapted to D50 using Bradford transform -const double xyz_sRGB[3][3] = {{0.4360747, 0.3850649, 0.1430804}, +constexpr double xyz_sRGB[3][3] = { + {0.4360747, 0.3850649, 0.1430804}, {0.2225045, 0.7168786, 0.0606169}, {0.0139322, 0.0971045, 0.7141733} }; -const double sRGB_xyz[3][3] = {{3.1338561, -1.6168667, -0.4906146}, +constexpr double sRGB_xyz[3][3] = { + {3.1338561, -1.6168667, -0.4906146}, { -0.9787684, 1.9161415, 0.0334540}, {0.0719453, -0.2289914, 1.4052427} }; -const double xyz_adobe[3][3] = {{0.6097559, 0.2052401, 0.1492240}, +constexpr double xyz_adobe[3][3] = { + {0.6097559, 0.2052401, 0.1492240}, {0.3111242, 0.6256560, 0.0632197}, {0.0194811, 0.0608902, 0.7448387} }; -const double adobe_xyz[3][3] = {{1.9624274, -0.6105343, -0.3413404}, +constexpr double adobe_xyz[3][3] = { + {1.9624274, -0.6105343, -0.3413404}, { -0.9787684, 1.9161415, 0.0334540}, {0.0286869, -0.1406752, 1.3487655} }; -const double xyz_prophoto[3][3] = {{0.7976749, 0.1351917, 0.0313534}, +constexpr double xyz_prophoto[3][3] = { + {0.7976749, 0.1351917, 0.0313534}, {0.2880402, 0.7118741, 0.0000857}, {0.0000000, 0.0000000, 0.8252100} }; -const double prophoto_xyz[3][3] = {{1.3459433, -0.2556075, -0.0511118}, +constexpr double prophoto_xyz[3][3] = { + {1.3459433, -0.2556075, -0.0511118}, { -0.5445989, 1.5081673, 0.0205351}, {0.0000000, 0.0000000, 1.2118128} }; +/* +constexpr double xyz_rec2020[3][3] = { + {0.636958, 0.144617, 0.168881}, + {0.262700, 0.677998, 0.059302}, + {0.0000000, 0.028073, 1.060985} +}; -const double xyz_widegamut[3][3] = {{0.7161046, 0.1009296, 0.1471858}, +constexpr double rec2020_xyz[3][3] = { + {1.716651, -0.355671, -0.253366}, + { -0.666684, 1.616481, 0.015769}, + {0.017640, -0.042771, 0.942103} +}; +*/ +constexpr double xyz_rec2020[3][3] = { + {0.6734241, 0.1656411, 0.1251286}, + {0.2790177, 0.6753402, 0.0456377}, + { -0.0019300, 0.0299784, 0.7973330} +}; + +constexpr double rec2020_xyz[3][3] = { + {1.6473376, -0.3935675, -0.2359961}, + { -0.6826036, 1.6475887, 0.0128190}, + {0.0296524, -0.0628993, 1.2531279} +}; + +constexpr double xyz_widegamut[3][3] = { + {0.7161046, 0.1009296, 0.1471858}, {0.2581874, 0.7249378, 0.0168748}, {0.0000000, 0.0517813, 0.7734287} }; -const double widegamut_xyz[3][3] = {{ 1.4628067, -0.1840623, -0.2743606}, +constexpr double widegamut_xyz[3][3] = { + { 1.4628067, -0.1840623, -0.2743606}, { -0.5217933, 1.4472381, 0.0677227}, {0.0349342, -0.0968930, 1.2884099} }; -const double xyz_bruce[3][3] = {{0.4941816, 0.3204834, 0.1495550}, +constexpr double xyz_bruce[3][3] = { + {0.4941816, 0.3204834, 0.1495550}, {0.2521531, 0.6844869, 0.0633600}, {0.0157886, 0.0629304, 0.7464909} }; -const double bruce_xyz[3][3] = {{2.6502856, -1.2014485, -0.4289936}, +constexpr double bruce_xyz[3][3] = { + {2.6502856, -1.2014485, -0.4289936}, { -0.9787684, 1.9161415, 0.0334540}, {0.0264570, -0.1361227, 1.3458542} }; -const double xyz_beta[3][3] = {{0.6712537, 0.1745834, 0.1183829}, +constexpr double xyz_beta[3][3] = { + {0.6712537, 0.1745834, 0.1183829}, {0.3032726, 0.6637861, 0.0329413}, {0.0000000, 0.0407010, 0.7845090} }; -const double beta_xyz[3][3] = {{1.6832270, -0.4282363, -0.2360185}, +constexpr double beta_xyz[3][3] = { + {1.6832270, -0.4282363, -0.2360185}, { -0.7710229, 1.7065571, 0.0446900}, {0.0400013, -0.0885376, 1.2723640} }; -const double xyz_best[3][3] = {{0.6326696, 0.2045558, 0.1269946}, +constexpr double xyz_best[3][3] = { + {0.6326696, 0.2045558, 0.1269946}, {0.2284569, 0.7373523, 0.0341908}, {0.0000000, 0.0095142, 0.8156958} }; -const double best_xyz[3][3] = {{1.7552599, -0.4836786, -0.2530000}, +constexpr double best_xyz[3][3] = { + {1.7552599, -0.4836786, -0.2530000}, { -0.5441336, 1.5068789, 0.0215528}, {0.0063467, -0.0175761, 1.2256959} }; -/*const double sRGB_d50[3][3] = {{0.4360520246092, 0.2224915978656, 0.0139291219896}, - {0.38508159282, 0.716886060114, 0.09709700166}, - {0.1430874138552, 0.0606214863936, 0.714185469944}}; +/* +constexpr double sRGB_d50[3][3] = { + {0.4360520246092, 0.2224915978656, 0.0139291219896}, + {0.38508159282, 0.716886060114, 0.09709700166}, + {0.1430874138552, 0.0606214863936, 0.714185469944} +}; -const double d50_sRGB[3][3] = {{3.13405134405167,-0.978762729953942, 0.0719425766617001}, - {-1.61702771153574,1.91614222810656, -0.228971178679309}, - {-0.49065220876631,0.0334496273068589, 1.40521830559074}};*/ +constexpr double d50_sRGB[3][3] = { + {3.13405134405167,-0.978762729953942, 0.0719425766617001}, + {-1.61702771153574,1.91614222810656, -0.228971178679309}, + {-0.49065220876631,0.0334496273068589, 1.40521830559074} +}; +*/ /* // Gabor's matrices -const double sRGB_d50[3][3] = {{0.435859, 0.222385, 0.0139162}, - {0.385336, 0.717021, 0.0971389}, - {0.143023, 0.0605936, 0.713817}}; +constexpr double sRGB_d50[3][3] = { + {0.435859, 0.222385, 0.0139162}, + {0.385336, 0.717021, 0.0971389}, + {0.143023, 0.0605936, 0.713817} +}; -const double d50_sRGB[3][3] = {{3.13593293538656, -0.978702373022194, 0.0720490013929888}, - {-1.61878246026431, 1.91609508555177, -0.22919049060526}, - {-0.490913888760734, 0.0334453372795315, 1.40593851447263}}; +constexpr double d50_sRGB[3][3] = { + {3.13593293538656, -0.978702373022194, 0.0720490013929888}, + {-1.61878246026431, 1.91609508555177, -0.22919049060526}, + {-0.490913888760734, 0.0334453372795315, 1.40593851447263} +}; -const double adobe_d50[3][3] = {{0.6097395054954, 0.3111142944042, 0.0194773131652}, - {0.2052518325737, 0.6256618480686, 0.0608872306106}, - {0.1492308013399, 0.0632241329247, 0.744846530711}}; -const double d50_adobe[3][3] = {{1.9624959949628, -0.978762712052774, 0.0286904764959749}, - {-0.610587687828765,1.91614073756734, -0.140667763143042}, - {-0.34136021627766, 0.0334501217627688, 1.34875045144924}}; -const double prophoto_d50[3][3] = {{0.797675, 0.288040, 0.000000}, - {0.135192, 0.711874, 0.000000}, - {0.0313534,0.000086, 0.825210}}; -const double d50_prophoto[3][3] = {{1.34594335079331, -0.544598514291158, 0}, - {-0.255608118122657, 1.50816768465213, 0}, - {-0.0511117387775285, 0.0205345459181255, 1.21181275069376}}; -const double widegamut_d50[3][3] = {{0.716105, 0.258187, 0.000000}, - {0.100930, 0.724938, 0.0517813}, - {0.147186, 0.0168748, 0.773429}}; -const double d50_widegamut[3][3] = {{1.46280597103052, -0.521792197260068, 0.0349341417298585}, - {-0.184062984909417, 1.44723786022891, -0.0968930022172314}, - {-0.27436071519732, 0.0677226440980744,1.28840945122198}}; -const double bruce_d50[3][3] = {{0.4941607255908, 0.2521412970174, 0.0157852934504}, - {0.3204990468435, 0.684494580042, 0.062927176507}, - {0.1495612990809, 0.0633643619597, 0.746498914581}}; -const double d50_bruce[3][3] = {{2.65042308164152, -0.978762745761462, 0.0264609493245811}, - {-1.20155941925411, 1.9161402914007, -0.136115844662896}, - {-0.42902228923717, 0.0334495071197919, 1.34583900936772}}; -const double beta_d50[3][3] = {{0.671254, 0.303273, 0.000000}, - {0.174583, 0.663786, 0.040701}, - {0.118383, 0.0329413, 0.784509}}; -const double d50_beta[3][3] = {{1.68322591962771, -0.771023599950842, 0.0400013658754702}, - {-0.428235060337656, 1.70655704781303, -0.0885376438040078}, - {-0.236018598193503, 0.0446902191738489,1.27236406897742}}; -const double best_d50[3][3] = {{0.632670, 0.228457, 0.000000}, - {0.204556, 0.737352, 0.00951424}, - {0.126995, 0.0341908, 0.815696}}; -const double d50_best[3][3] = {{1.75525923340349, -0.544133953997468, 0.00634675299435191}, - {-0.483679025800866, 1.50687975713407, -0.017576175021718}, - {-0.253000840399762, 0.0215532098817316,1.22569552576991}}; +constexpr double adobe_d50[3][3] = { + {0.6097395054954, 0.3111142944042, 0.0194773131652}, + {0.2052518325737, 0.6256618480686, 0.0608872306106}, + {0.1492308013399, 0.0632241329247, 0.744846530711} +}; +constexpr double d50_adobe[3][3] = { + {1.9624959949628, -0.978762712052774, 0.0286904764959749}, + {-0.610587687828765,1.91614073756734, -0.140667763143042}, + {-0.34136021627766, 0.0334501217627688, 1.34875045144924} +}; +constexpr double prophoto_d50[3][3] = { + {0.797675, 0.288040, 0.000000}, + {0.135192, 0.711874, 0.000000}, + {0.0313534,0.000086, 0.825210} +}; +constexpr double d50_prophoto[3][3] = { + {1.34594335079331, -0.544598514291158, 0}, + {-0.255608118122657, 1.50816768465213, 0}, + {-0.0511117387775285, 0.0205345459181255, 1.21181275069376} +}; +constexpr double widegamut_d50[3][3] = { + {0.716105, 0.258187, 0.000000}, + {0.100930, 0.724938, 0.0517813}, + {0.147186, 0.0168748, 0.773429} +}; +constexpr double d50_widegamut[3][3] = { + {1.46280597103052, -0.521792197260068, 0.0349341417298585}, + {-0.184062984909417, 1.44723786022891, -0.0968930022172314}, + {-0.27436071519732, 0.0677226440980744,1.28840945122198} +}; +constexpr double bruce_d50[3][3] = { + {0.4941607255908, 0.2521412970174, 0.0157852934504}, + {0.3204990468435, 0.684494580042, 0.062927176507}, + {0.1495612990809, 0.0633643619597, 0.746498914581} +}; +constexpr double d50_bruce[3][3] = { + {2.65042308164152, -0.978762745761462, 0.0264609493245811}, + {-1.20155941925411, 1.9161402914007, -0.136115844662896}, + {-0.42902228923717, 0.0334495071197919, 1.34583900936772} +}; +constexpr double beta_d50[3][3] = { + {0.671254, 0.303273, 0.000000}, + {0.174583, 0.663786, 0.040701}, + {0.118383, 0.0329413, 0.784509} +}; +constexpr double d50_beta[3][3] = { + {1.68322591962771, -0.771023599950842, 0.0400013658754702}, + {-0.428235060337656, 1.70655704781303, -0.0885376438040078}, + {-0.236018598193503, 0.0446902191738489,1.27236406897742} +}; +constexpr double best_d50[3][3] = { + {0.632670, 0.228457, 0.000000}, + {0.204556, 0.737352, 0.00951424}, + {0.126995, 0.0341908, 0.815696} +}; +constexpr double d50_best[3][3] = { + {1.75525923340349, -0.544133953997468, 0.00634675299435191}, + {-0.483679025800866, 1.50687975713407, -0.017576175021718}, + {-0.253000840399762, 0.0215532098817316,1.22569552576991} +}; */ #endif diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index cb5314489..82f280e54 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -41,8 +41,9 @@ void loadProfiles (const Glib::ustring& dirName, std::map* profileNames, bool nameUpper, bool onlyRgb) { - if (dirName.empty ()) + if (dirName.empty ()) { return; + } try { @@ -52,23 +53,27 @@ void loadProfiles (const Glib::ustring& dirName, const Glib::ustring fileName = *entry; - if (fileName.size () < 4) + if (fileName.size () < 4) { continue; + } const Glib::ustring extension = fileName.substr (fileName.size () - 4).casefold (); - if (extension.compare (".icc") != 0 && extension.compare (".icm") != 0) + if (extension.compare (".icc") != 0 && extension.compare (".icm") != 0) { continue; + } const Glib::ustring filePath = Glib::build_filename (dirName, fileName); - if (!Glib::file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) + if (!Glib::file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) { continue; + } Glib::ustring name = fileName.substr (0, fileName.size() - 4); - if (nameUpper) + if (nameUpper) { name = name.uppercase (); + } if (profiles) { const rtengine::ProfileContent content (filePath); @@ -77,28 +82,31 @@ void loadProfiles (const Glib::ustring& dirName, if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) { profiles->insert (std::make_pair (name, profile)); - if (profileContents) + if (profileContents) { profileContents->insert (std::make_pair (name, content)); + } } } - if (profileNames) + if (profileNames) { profileNames->insert (std::make_pair (name, filePath)); + } } - } - catch (Glib::Exception&) {} + } catch (Glib::Exception&) {} } inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result) { - if (cmsIsIntentSupported (profile, intent, direction)) + if (cmsIsIntentSupported (profile, intent, direction)) { result |= 1 << intent; + } } inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) { - if (!profile) + if (!profile) { return 0; + } std::uint8_t result = 0; @@ -116,9 +124,9 @@ inline cmsHPROFILE createXYZProfile () return rtengine::ICCStore::createFromMatrix (mat, false, "XYZ"); } -const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; -const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; -const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; +const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best, xyz_rec2020}; +const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz, rec2020_xyz}; +const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB", "Rec2020"}; const char* wpgamma[] = {"default", "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"}; //gamma free //default = gamma inside profile //BT709 g=2.22 s=4.5 sRGB g=2.4 s=12.92 @@ -163,8 +171,9 @@ std::vector ICCStore::getProfiles () const std::vector res; - for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) + for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) { res.push_back (profile->first); + } return res; } @@ -181,8 +190,9 @@ std::vector ICCStore::getProfilesFromDir (const Glib::ustring& di loadProfiles (profilesDir, &profiles, NULL, NULL, false, true); loadProfiles (dirName, &profiles, NULL, NULL, false, true); - for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) { res.push_back (profile->first); + } return res; } @@ -253,7 +263,7 @@ cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof) tags[i].sig == 0x6B545243) { // kTRC if (gamma_offset == 0) { gamma_offset = offset; - uint32_t pcurve[] = { htonl(0x63757276), htonl(0), htonl(gamma_size == 12 ? 0 : 1) }; + uint32_t pcurve[] = { htonl(0x63757276), htonl(0), htonl(gamma_size == 12 ? 0U : 1U) }; memcpy(&nd[offset], pcurve, 12); if (gamma_size == 14) { @@ -388,22 +398,25 @@ cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const const ProfileMap::const_iterator r = fileStdProfiles.find (nameUpper); // return profile from store - if (r != fileStdProfiles.end ()) + if (r != fileStdProfiles.end ()) { return r->second; + } // profile is not yet in store const NameMap::const_iterator f = fileStdProfilesFileNames.find (nameUpper); // profile does not exist - if (f == fileStdProfilesFileNames.end ()) + if (f == fileStdProfilesFileNames.end ()) { return NULL; + } // but there exists one => load it const ProfileContent content (f->second); const cmsHPROFILE profile = content.toProfile (); - if (profile) + if (profile) { const_cast(fileStdProfiles).insert (std::make_pair (f->first, profile)); + } // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames const_cast(fileStdProfilesFileNames).erase (f); @@ -481,6 +494,7 @@ void ICCStore::findDefaultMonitorProfile () defaultMonitorProfile = Glib::ustring(profileName); defaultMonitorProfile = Glib::path_get_basename(defaultMonitorProfile); size_t pos = defaultMonitorProfile.rfind("."); + if (pos != Glib::ustring::npos) { defaultMonitorProfile = defaultMonitorProfile.substr(0, pos); } diff --git a/rtengine/iimage.h b/rtengine/iimage.h index 1bf0ab97f..932f55ee7 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -58,10 +58,10 @@ enum TypeInterpolation { TI_Nearest, TI_Bilinear }; class ImageDatas : virtual public ImageDimensions { public: - template - void convertTo (S srcValue, D &dstValue) + template + void convertTo(S src, D& dst) const { - dstValue = static_cast(srcValue); + dst = src; } // parameters that will never be used, replaced by the subclasses r, g and b parameters! @@ -100,30 +100,30 @@ public: }; -template <> -inline void ImageDatas::convertTo (const unsigned short srcValue, unsigned char &dstValue) +template<> +inline void ImageDatas::convertTo(unsigned short src, unsigned char& dst) const { - dstValue = (unsigned char)(srcValue >> 8); + dst = uint16ToUint8Rounded(src); } -template <> -inline void ImageDatas::convertTo (const unsigned char srcValue, int &dstValue) +template<> +inline void ImageDatas::convertTo(unsigned char src, int& dst) const { - dstValue = (int)(srcValue) << 8; + dst = src * 257; } -template <> -inline void ImageDatas::convertTo (const unsigned char srcValue, unsigned short &dstValue) +template<> +inline void ImageDatas::convertTo(unsigned char src, unsigned short& dst) const { - dstValue = (unsigned short)(srcValue) << 8; + dst = src * 257; } -template <> -inline void ImageDatas::convertTo (const float srcValue, unsigned char &dstValue) +template<> +inline void ImageDatas::convertTo(float src, unsigned char& dst) const { - dstValue = (unsigned char)( (unsigned short)(srcValue) >> 8 ); + dst = uint16ToUint8Rounded(src); } -template <> -inline void ImageDatas::convertTo (const unsigned char srcValue, float &dstValue) +template<> +inline void ImageDatas::convertTo(unsigned char src, float& dst) const { - dstValue = float( (unsigned short)(srcValue) << 8 ); + dst = src * 257; } // -------------------------------------------------------------------- @@ -854,33 +854,21 @@ public: } } } else if (interp == TI_Bilinear) { - for (int i = 0; i < nh; i++) { - int sy = i * height / nh; + float heightByNh = float(height) / float(nh); + float widthByNw = float(width) / float(nw); + float syf = 0.f; - if (sy >= height) { - sy = height - 1; - } + for (int i = 0; i < nh; i++, syf += heightByNh) { + int sy = syf; + float dy = syf - float(sy); + int ny = sy < height - 1 ? sy + 1 : sy; - float dy = float(i) * float(height) / float(nh) - float(sy); - int ny = sy + 1; + float sxf = 0.f; - if (ny >= height) { - ny = sy; - } - - for (int j = 0; j < nw; j++) { - int sx = j * width / nw; - - if (sx >= width) { - sx = width; - } - - float dx = float(j) * float(width) / float(nw) - float(sx); - int nx = sx + 1; - - if (nx >= width) { - nx = sx; - } + for (int j = 0; j < nw; j++, sxf += widthByNw) { + int sx = sxf; + float dx = sxf - float(sx); + int nx = sx < width - 1 ? sx + 1 : sx; convertTo(r(sy, sx) * (1.f - dx) * (1.f - dy) + r(sy, nx)*dx * (1.f - dy) + r(ny, sx) * (1.f - dx)*dy + r(ny, nx)*dx * dy, imgPtr->r(i, j)); convertTo(g(sy, sx) * (1.f - dx) * (1.f - dy) + g(sy, nx)*dx * (1.f - dy) + g(ny, sx) * (1.f - dx)*dy + g(ny, nx)*dx * dy, imgPtr->g(i, j)); @@ -1046,9 +1034,6 @@ public: avg_r += double(r_); avg_g += double(g_); avg_b += double(b_); - /*avg_r += intpow( (double)r(i, j), p); - avg_g += intpow( (double)g(i, j), p); - avg_b += intpow( (double)b(i, j), p);*/ n++; } @@ -1669,9 +1654,6 @@ public: avg_r += double(r_); avg_g += double(g_); avg_b += double(b_); - /*avg_r += intpow( (double)r(i, j), p); - avg_g += intpow( (double)g(i, j), p); - avg_b += intpow( (double)b(i, j), p);*/ n++; } diff --git a/rtengine/image16.cc b/rtengine/image16.cc index a822d6aac..c4bf310bb 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -19,10 +19,32 @@ #include "image16.h" #include "imagefloat.h" #include "image8.h" -#include #include #include "rtengine.h" +namespace +{ + +void getScanline8 (const uint16_t *red, const uint16_t *green, const uint16_t *blue, int width, unsigned char* buffer) +{ + for (int i = 0, ix = 0; i < width; i++) { + buffer[ix++] = rtengine::uint16ToUint8Rounded(red[i]); + buffer[ix++] = rtengine::uint16ToUint8Rounded(green[i]); + buffer[ix++] = rtengine::uint16ToUint8Rounded(blue[i]); + } +} + +void getScanline16 (const uint16_t *red, const uint16_t *green, const uint16_t *blue, int width, unsigned short* buffer) +{ + for (int i = 0, ix = 0; i < width; i++) { + buffer[ix++] = red[i]; + buffer[ix++] = green[i]; + buffer[ix++] = blue[i]; + } +} + +} + using namespace rtengine; Image16::Image16 () @@ -41,27 +63,14 @@ Image16::~Image16 () void Image16::getScanline (int row, unsigned char* buffer, int bps) { - if (data == NULL) { + if (data == nullptr) { return; } if (bps == 16) { - int ix = 0; - unsigned short* sbuffer = (unsigned short*) buffer; - - for (int i = 0; i < width; i++) { - sbuffer[ix++] = r(row, i); - sbuffer[ix++] = g(row, i); - sbuffer[ix++] = b(row, i); - } + getScanline16 (r(row), g(row), b(row), width, (unsigned short*)buffer); } else if (bps == 8) { - int ix = 0; - - for (int i = 0; i < width; i++) { - buffer[ix++] = r(row, i) >> 8; - buffer[ix++] = g(row, i) >> 8; - buffer[ix++] = b(row, i) >> 8; - } + getScanline8 (r(row), g(row), b(row), width, buffer); } } @@ -72,42 +81,42 @@ void Image16::getScanline (int row, unsigned char* buffer, int bps) void Image16::setScanline (int row, unsigned char* buffer, int bps, float *minValue, float *maxValue) { - if (data == NULL) { + if (data == nullptr) { return; } - // For optimization purpose, we're assuming that this class never have to provide min/max bound + // For optimization purpose, we're assuming that this class never has to provide min/max bounds assert(!minValue); switch (sampleFormat) { - case (IIOSF_UNSIGNED_CHAR): { - int ix = 0; + case (IIOSF_UNSIGNED_CHAR): { + int ix = 0; - for (int i = 0; i < width; i++) { - r(row, i) = (unsigned short)(buffer[ix++]) << 8; - g(row, i) = (unsigned short)(buffer[ix++]) << 8; - b(row, i) = (unsigned short)(buffer[ix++]) << 8; + for (int i = 0; i < width; ++i) { + r(row, i) = static_cast(buffer[ix++]) * 257; + g(row, i) = static_cast(buffer[ix++]) * 257; + b(row, i) = static_cast(buffer[ix++]) * 257; + } + + break; } - break; - } + case (IIOSF_UNSIGNED_SHORT): { + unsigned short* sbuffer = (unsigned short*) buffer; + int ix = 0; - case (IIOSF_UNSIGNED_SHORT): { - unsigned short* sbuffer = (unsigned short*) buffer; - int ix = 0; + for (int i = 0; i < width; ++i) { + r(row, i) = sbuffer[ix++]; + g(row, i) = sbuffer[ix++]; + b(row, i) = sbuffer[ix++]; + } - for (int i = 0; i < width; i++) { - r(row, i) = sbuffer[ix++]; - g(row, i) = sbuffer[ix++]; - b(row, i) = sbuffer[ix++]; + break; } - break; - } - - default: - // Other type are ignored, but could be implemented if necessary - break; + default: + // Other types are ignored, but could be implemented if necessary + break; } /* @@ -303,11 +312,11 @@ Image16::to8() { Image8* img8 = new Image8(width, height); - for ( int h = 0; h < height; ++h ) { - for ( int w = 0; w < width; ++w ) { - img8->r(h, w) = (unsigned char)( r(h, w) >> 8); - img8->g(h, w) = (unsigned char)( g(h, w) >> 8); - img8->b(h, w) = (unsigned char)( b(h, w) >> 8); + for (int h = 0; h < height; ++h) { + for (int w = 0; w < width; ++w) { + img8->r(h, w) = uint16ToUint8Rounded(r(h, w)); + img8->g(h, w) = uint16ToUint8Rounded(g(h, w)); + img8->b(h, w) = uint16ToUint8Rounded(b(h, w)); } } @@ -319,11 +328,11 @@ Image16::tofloat() { Imagefloat* imgfloat = new Imagefloat(width, height); - for ( int h = 0; h < height; ++h ) { - for ( int w = 0; w < width; ++w ) { - imgfloat->r(h, w) = (float)r(h, w); - imgfloat->g(h, w) = (float)g(h, w); - imgfloat->b(h, w) = (float)b(h, w); + for (int h = 0; h < height; ++h) { + for (int w = 0; w < width; ++w) { + imgfloat->r(h, w) = r(h, w); + imgfloat->g(h, w) = g(h, w); + imgfloat->b(h, w) = b(h, w); } } diff --git a/rtengine/image8.cc b/rtengine/image8.cc index da4bea6ef..1070514b3 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -49,8 +49,8 @@ void Image8::getScanline (int row, unsigned char* buffer, int bps) } else if (bps == 16) { unsigned short* sbuffer = (unsigned short*) buffer; - for (int i = 0, ix = row * width * 3; i < width * 3; i++, ix++) { - sbuffer[i] = (unsigned short)(data[ix]) << 8; + for (int i = 0, ix = row * width * 3; i < width * 3; ++i, ++ix) { + sbuffer[i] = static_cast(data[ix]) * 257; } } } @@ -73,8 +73,8 @@ void Image8::setScanline (int row, unsigned char* buffer, int bps, float *minVal case (IIOSF_UNSIGNED_SHORT): { unsigned short* sbuffer = (unsigned short*) buffer; - for (int i = 0, ix = row * width * 3; i < width * 3; i++, ix++) { - data[ix] = sbuffer[i] >> 8; + for (int i = 0, ix = row * width * 3; i < width * 3; ++i, ++ix) { + data[ix] = uint16ToUint8Rounded(sbuffer[i]); } break; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index c0da10761..2622ffcf7 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -44,7 +44,7 @@ ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataL return new ImageData (fname, rml); } -ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) +ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) : iso_speed(0), aperture(0.), shutter(0.) { size_t dotpos = fname.find_last_of ('.'); @@ -121,61 +121,80 @@ void ImageData::extractInfo () return; } - make = ""; - model = ""; - serial = ""; - orientation = ""; - expcomp = 0; - shutter = 0; - aperture = 0; - focal_len = focal_len35mm = 0; - focus_dist = 0; - iso_speed = 0; - memset (&time, 0, sizeof(time)); + memset(&time, 0, sizeof(time)); timeStamp = 0; + iso_speed = 0; + aperture = 0.0; + focal_len = 0.0; + focal_len35mm = 0.0; + focus_dist = 0.0f; + shutter = 0.0; + expcomp = 0.0; + make.clear(); + model.clear(); + serial.clear(); + orientation.clear(); + lens.clear(); - if (root->getTag ("Make")) { - make = root->getTag ("Make")->valueToString (); - // same dcraw treatment - static const char *corp[] = { - "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", "RICOH", - "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", - "SAMSUNG", "Mamiya", "MOTOROLA", "Leaf" - }; - - for (size_t i = 0; i < (sizeof(corp) / sizeof(*corp)); i++) - if ( make.find( corp[i] ) != std::string::npos ) { /* Simplify company names */ - make = corp[i]; + if (root->getTag("Make")) { + make = root->getTag ("Make")->valueToString(); + // Same dcraw treatment + for (const auto& corp : { + "Canon", + "NIKON", + "EPSON", + "KODAK", + "Kodak", + "OLYMPUS", + "PENTAX", + "RICOH", + "MINOLTA", + "Minolta", + "Konica", + "CASIO", + "Sinar", + "Phase One", + "SAMSUNG", + "Mamiya", + "MOTOROLA", + "Leaf" + }) { + if (make.find(corp) != std::string::npos) { // Simplify company names + make = corp; break; } - - make.erase( make.find_last_not_of(' ') + 1 ); - } - - if (root->getTag ("Model")) { - model = root->getTag ("Model")->valueToString (); - } - - if (!(model.size() == 0)) { - std::size_t i = 0; - - if ( make.find("KODAK") != std::string::npos ) { - if( (i = model.find(" DIGITAL CAMERA")) != std::string::npos || - (i = model.find(" Digital Camera")) != std::string::npos || - (i = model.find("FILE VERSION")) ) { - model.resize( i ); - } } - model.erase( model.find_last_not_of(' ') + 1 ); + make.erase(make.find_last_not_of(' ') + 1); + } - //if( (i=model.find( make )) != std::string::npos ) - if( !strncasecmp (model.c_str(), make.c_str(), make.size()) ) - if( model.at( make.size() ) == ' ') { + if (root->getTag("Model")) { + model = root->getTag("Model")->valueToString(); + } + + if (!model.empty()) { + std::string::size_type i = 0; + + if ( + make.find("KODAK") != std::string::npos + && ( + (i = model.find(" DIGITAL CAMERA")) != std::string::npos + || (i = model.find(" Digital Camera")) != std::string::npos + || (i = model.find("FILE VERSION")) != std::string::npos + ) + ) { + model.resize(i); + } + + model.erase(model.find_last_not_of(' ') + 1); + + if (!strncasecmp(model.c_str(), make.c_str(), make.size())) { + if (model.size() >= make.size() && model[make.size()] == ' ') { model.erase(0, make.size() + 1); } + } - if( model.find( "Digital Camera ") != std::string::npos ) { + if (model.find( "Digital Camera ") != std::string::npos) { model.erase(0, 15); } } else { diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index fae39069b..5920fff85 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -347,11 +347,11 @@ Imagefloat::to8() #pragma omp parallel for schedule(static) #endif - for ( int h = 0; h < height; ++h ) { - for ( int w = 0; w < width; ++w ) { - img8->r(h, w) = (unsigned char)( (unsigned short)(r(h, w)) >> 8); - img8->g(h, w) = (unsigned char)( (unsigned short)(g(h, w)) >> 8); - img8->b(h, w) = (unsigned char)( (unsigned short)(b(h, w)) >> 8); + for (int h = 0; h < height; ++h) { + for (int w = 0; w < width; ++w) { + img8->r(h, w) = uint16ToUint8Rounded(r(h, w)); + img8->g(h, w) = uint16ToUint8Rounded(g(h, w)); + img8->b(h, w) = uint16ToUint8Rounded(b(h, w)); } } @@ -366,11 +366,11 @@ Imagefloat::to16() #pragma omp parallel for schedule(static) #endif - for ( int h = 0; h < height; ++h ) { - for ( int w = 0; w < width; ++w ) { - img16->r( h, w) = (unsigned short)(r(h, w)); - img16->g( h, w) = (unsigned short)(g(h, w)); - img16->b( h, w) = (unsigned short)(b(h, w)); + for (int h = 0; h < height; ++h) { + for (int w = 0; w < width; ++w) { + img16->r(h, w) = r(h, w); + img16->g(h, w) = g(h, w); + img16->b(h, w) = b(h, w); } } diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 4fa5a5a93..a9be4e7e3 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -61,6 +61,7 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) std::unique_ptr wfname (reinterpret_cast(g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free); HANDLE hFile = CreateFileW ( wfname.get (), GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) { f = _fdopen (_open_osfhandle ((intptr_t)hFile, 0), "wb"); } @@ -135,7 +136,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr iptc = iptc_data_new (); - for (rtengine::procparams::IPTCPairs::const_iterator i = iptcc.begin(); i != iptcc.end(); i++) { + for (rtengine::procparams::IPTCPairs::const_iterator i = iptcc.begin(); i != iptcc.end(); ++i) { if (i->first == "Keywords" && !(i->second.empty())) { for (unsigned int j = 0; j < i->second.size(); j++) { IptcDataSet * ds = iptc_dataset_new (); @@ -1081,7 +1082,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp) cinfo.comp_info[2].h_samp_factor = cinfo.comp_info[2].v_samp_factor = 1; if (subSamp == 1) { - // Best compression, default of the JPEG library: 2x2, 1x1, 1x1 (4:1:1) + // Best compression, default of the JPEG library: 2x2, 1x1, 1x1 (4:2:0) cinfo.comp_info[0].h_samp_factor = cinfo.comp_info[0].v_samp_factor = 2; } else if (subSamp == 2) { // Widely used normal ratio 2x1, 1x1, 1x1 (4:2:2) @@ -1226,20 +1227,17 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } // buffer for the exif and iptc - int bufferSize = 165535; //TODO: Is it really 165535... or 65535 ? - if(profileData) - bufferSize += profileLength; - - unsigned char* buffer = new unsigned char[bufferSize]; - unsigned char* iptcdata = NULL; + unsigned int bufferSize; + unsigned char* buffer = nullptr; // buffer will be allocated in createTIFFHeader + unsigned char* iptcdata = nullptr; unsigned int iptclen = 0; if (iptc && iptc_data_save (iptc, &iptcdata, &iptclen) && iptcdata) { iptc_data_free_buf (iptc, iptcdata); - iptcdata = NULL; + iptcdata = nullptr; } - int size = rtexif::ExifManager::createTIFFHeader (exifRoot, exifChange, width, height, bps, profileData, profileLength, (char*)iptcdata, iptclen, buffer); + int size = rtexif::ExifManager::createTIFFHeader (exifRoot, exifChange, width, height, bps, profileData, profileLength, (char*)iptcdata, iptclen, buffer, bufferSize); if (iptcdata) { iptc_data_free_buf (iptc, iptcdata); @@ -1247,7 +1245,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) // The maximum lenght is strangely not the same than for the JPEG file... // Which maximum length is the good one ? - if (size > 0 && size < bufferSize) { + if (size > 0 && size <= bufferSize) { fwrite (buffer, size, 1, file); } @@ -1274,7 +1272,9 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } } - delete [] buffer; + if(buffer) { + delete [] buffer; + } if (ferror(file)) { writeOk = false; @@ -1285,11 +1285,13 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) // little hack to get libTiff to use proper byte order (see TIFFClienOpen()): const char *mode = !exifRoot ? "w" : (exifRoot->getOrder() == rtexif::INTEL ? "wl" : "wb"); #ifdef WIN32 - wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); - TIFF* out = TIFFOpenW (wfilename, mode); - g_free (wfilename); + FILE *file = g_fopen_withBinaryAndLock (fname); + int fileno = _fileno(file); + int osfileno = _get_osfhandle(fileno); + TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode); #else TIFF* out = TIFFOpen(fname.c_str(), mode); + int fileno = TIFFFileno (out); #endif if (!out) { @@ -1314,7 +1316,9 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) // TIFFOpen writes out the header and sets file pointer at position 8 exif->write (8, buffer); - write (TIFFFileno (out), buffer + 8, exif_size); + + write (fileno, buffer + 8, exif_size); + delete [] buffer; // let libtiff know that scanlines or any other following stuff should go // at a different offset: @@ -1347,14 +1351,12 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } - Glib::ustring rtVersion("RawTherapee "); - rtVersion += VERSION; - TIFFSetField (out, TIFFTAG_SOFTWARE, rtVersion.c_str()); + TIFFSetField (out, TIFFTAG_SOFTWARE, "RawTherapee " VERSION); TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width); TIFFSetField (out, TIFFTAG_IMAGELENGTH, height); TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 3); - TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, height); + TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, height); TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, bps); TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); @@ -1388,6 +1390,9 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } TIFFClose (out); +#ifdef WIN32 + fclose (file); +#endif } delete [] linebuffer; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 21317452e..305c67da5 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -66,22 +66,22 @@ public: embProfile(NULL), idata(NULL), dirpyrdenoiseExpComp(INFINITY) {} virtual ~ImageSource () {} - virtual int load (Glib::ustring fname, bool batch = false) = 0; - virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {}; + virtual int load (const Glib::ustring &fname, bool batch = false) = 0; + virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void demosaic (const RAWParams &raw) {}; - virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, 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 (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; + virtual void retinex (ColorManagementParams cmp, RetinexParams deh, 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 (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; virtual void flushRawData () {}; virtual void flushRGB () {}; virtual void HLRecovery_Global (ToneCurveParams hrp) {}; virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; - virtual void MSR(LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; + virtual void MSR(LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; - virtual bool IsrgbSourceModified() = 0; // tracks whether cached rgb output of demosaic has been modified + virtual bool IsrgbSourceModified() const = 0; // tracks whether cached rgb output of demosaic has been modified // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* - virtual void getImage (ColorTemp ctemp, int tran, Imagefloat* image, const PreviewProps & pp, ToneCurveParams hlp, ColorManagementParams cmp, RAWParams raw) {} + virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hlp, const ColorManagementParams &cmp, const RAWParams &raw) = 0; virtual eSensorType getSensorType () { return ST_NONE; @@ -89,12 +89,12 @@ public: // 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, ColorManagementParams cmp, 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 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 () = 0; + virtual ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) = 0; - virtual double getDefGain () + virtual double getDefGain () const { return 1.0; } @@ -109,7 +109,7 @@ public: virtual ImageData* getImageData () = 0; virtual ImageMatrices* getImageMatrices () = 0; virtual bool isRAW() const = 0; - virtual DCPProfile* getDCP(ColorManagementParams cmp, ColorTemp &wb) + virtual DCPProfile* getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as) { return NULL; }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 0ff75ba38..1b04080c7 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -23,7 +23,9 @@ #include "../rtgui/ppversion.h" #include "colortemp.h" #include "improcfun.h" - +#ifdef _OPENMP +#include +#endif namespace rtengine { @@ -33,14 +35,14 @@ ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), spotprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), previewProps(-1, -1, -1, -1, 1), monitorIntent(RI_RELATIVE), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), - bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(NAN), hltonecurve(65536), shtonecurve(65536), tonecurve(65536, 0), //,1); chaut(0.f), redaut(0.f), blueaut(0.f), maxredaut(0.f), maxblueaut(0.f), minredaut(0.f), minblueaut(0.f), nresi(0.f), chromina(0.f), sigma(0.f), lumema(0.f), - lumacurve(65536, 0), + lumacurve(32770, 0), // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation chroma_acurve(65536, 0), chroma_bcurve(65536, 0), satcurve(65536, 0), @@ -52,13 +54,10 @@ ImProcCoordinator::ImProcCoordinator () Noisecurve(65536, 0), NoiseCCcurve(65536, 0), vhist16(65536), vhist16bw(65536), - lhist16(65536), lhist16Cropped(65536), - lhist16CAM(65536), lhist16CroppedCAM(65536), + lhist16CAM(65536), lhist16CCAM(65536), - lhist16RETI(65536), - histCropped(65536), - lhist16Clad(65536), lhist16CLlad(65536), - lhist16LClad(65536), lhist16LLClad(65536), + lhist16RETI(), + lhist16LClad(65536), histRed(256), histRedRaw(256), histGreen(256), histGreenRaw(256), histBlue(256), histBlueRaw(256), @@ -67,7 +66,6 @@ ImProcCoordinator::ImProcCoordinator () histToneCurveBW(256), histLCurve(256), histCCurve(256), - histCLurve(256), histLLCurve(256), histLCAM(256), @@ -236,6 +234,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } if (params.retinex.enabled) { + lhist16RETI(32768); lhist16RETI.clear(); imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, lhist16RETI); @@ -249,9 +248,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) LUTf cdcurve (65536, 0); LUTf mapcurve (65536, 0); - imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, lhist16RETI, histLRETI); + imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, dehacontlutili, mapcontlutili, useHsl, lhist16RETI, histLRETI); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex if(dehaListener) { dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -321,6 +320,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) ipf.setScale (scale); imgsrc->getImage (currWB, tr, orig_prev, previewProps, params.toneCurve, params.icm, params.raw); + denoiseInfoStore.valid = false; //ColorTemp::CAT02 (orig_prev, ¶ms) ; // printf("orig_prevW=%d\n scale=%d",orig_prev->width, scale); /* Issue 2785, disabled some 1:1 tools @@ -366,7 +366,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) */ imgsrc->convertColorSpace(orig_prev, params.icm, currWB); - ipf.firstAnalysis (orig_prev, ¶ms, vhist16); + ipf.firstAnalysis (orig_prev, params, vhist16); } readyphase++; @@ -461,39 +461,39 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, - vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale == 1 ? 1 : 1); + vhist16, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale == 1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, /*scale==1 ? 1 :*/ 1); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, /*scale==1 ? 1 :*/ 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, /*scale==1 ? 1 :*/ 1); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - bool clctoningutili = false; - bool llctoningutili = false; - CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); - // clToningcurve.dump("CLToning3"); - CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); + if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); + CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); + } - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); + } - - float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; - float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); + colourToningSatLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; + colourToningSatLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); int satTH = 80; int satPR = 30; @@ -516,10 +516,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //satTH=(int) 100.f*satp; //satPR=(int) 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation - satLimit = 100.f * satp; + colourToningSatLimit = 100.f * satp; satTH = (int) 100.f * satp; - satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation + colourToningSatLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation satPR = (int) 100.f * (moyS - 0.85f * eqty); } @@ -554,9 +554,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) double ggm = 33.; double bbm = 33.; - DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB); + DCPProfile::ApplyState as; + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as); + ipf.rgbProc (spotprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, - rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf); + rCurve, gCurve, bCurve, colourToningSatLimit , colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf, as); if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) { if (settings->verbose) { @@ -568,65 +570,56 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if(params.colorToning.autosat && actListener) { if (settings->verbose) { - printf("ImProcCoordinator / Auto CT: indi=%d satH=%d satPR=%d\n", indi, (int)satLimit , (int) satLimitOpacity); + printf("ImProcCoordinator / Auto CT: indi=%d satH=%d satPR=%d\n", indi, (int)colourToningSatLimit , (int) colourToningSatLimitOpacity); } - actListener->autoColorTonChanged(indi, (int) satLimit, (int)satLimitOpacity);//change sliders autosat + actListener->autoColorTonChanged(indi, (int) colourToningSatLimit, (int)colourToningSatLimitOpacity);//change sliders autosat } // correct GUI black and white with value } // compute L channel histogram - int x1, y1, x2, y2, pos; + int x1, y1, x2, y2; params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); - lhist16.clear(); - lhist16Cropped.clear(); - lhist16Clad.clear(); - lhist16CLlad.clear(); - lhist16LLClad.clear(); - - for (int x = 0; x < pH; x++) - for (int y = 0; y < pW; y++) { - pos = CLIP((int)(oprevl->L[x][y])); - lhist16[pos]++; - - if (y >= y1 && y < y2 && x >= x1 && x < x2) { - lhist16Cropped[pos]++; - } - } } readyphase++; - if ((todo & M_LUMACURVE) || (todo & M_CROP)) { - utili = false; - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped, - lumacurve, histLCurve, scale == 1 ? 1 : 16, utili); + if (todo & (M_LUMACURVE | M_CROP)) { + LUTu lhist16(32768); + lhist16.clear(); +#ifdef _OPENMP + const int numThreads = min(max(pW * pH / (int)lhist16.getSize(), 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu lhist16thr(lhist16.getSize()); + lhist16thr.clear(); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int x = 0; x < pH; x++) + for (int y = 0; y < pW; y++) { + int pos = (int)(oprevl->L[x][y]); + lhist16thr[pos]++; + } + +#ifdef _OPENMP + #pragma omp critical +#endif + lhist16 += lhist16thr; + } + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale == 1 ? 1 : 16, utili); } if (todo & M_LUMACURVE) { - autili = false; - butili = false; - ccutili = false; - cclutili = false; - clcutili = false; - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, lhist16CLlad, histCLurve, scale == 1 ? 1 : 16); - float adjustr = 1.0f; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, scale == 1 ? 1 : 16); - - /* if (params.icm.working=="ProPhoto") {adjustr = adjustbg = 1.2f;}// 1.2 instead 1.0 because it's very rare to have C>170.. - else if (params.icm.working=="Adobe RGB") {adjustr = 1.8f; adjustbg = 1.4f;} - else if (params.icm.working=="sRGB") {adjustr = 2.0f; adjustbg = 1.7f;} - else if (params.icm.working=="WideGamut") {adjustr = adjustbg = 1.2f;} - else if (params.icm.working=="Beta RGB") {adjustr = adjustbg = 1.4f;} - else if (params.icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;} - else if (params.icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;} - */ - CurveFactory::complexsgnCurve (adjustr, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, - params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, - lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale == 1 ? 1 : 16); + CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, + params.labCurve.lccurve, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, scale == 1 ? 1 : 16); } if (todo & (M_LUMINANCE + M_COLOR) ) { @@ -634,8 +627,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Applying Color Boost...", 100 * readyphase / numofphases); // ipf.MSR(nprevl, nprevl->W, nprevl->H, 1); - - ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histCLurve, histLLCurve, histLCurve); + histCCurve.clear(); + histLCurve.clear(); + ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve); ipf.vibrance(nprevl); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { @@ -697,7 +691,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) wavcontlutili = false; //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); - CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve , /*lhist16CLlad, histCLurve,*/ scale == 1 ? 1 : 16); + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16); if((params.wavelet.enabled)) { @@ -716,39 +710,24 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if(params.colorappearance.enabled) { //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, pos, posc; + int x1, y1, x2, y2; params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); lhist16CAM.clear(); - lhist16CroppedCAM.clear(); lhist16CCAM.clear(); - for (int x = 0; x < pH; x++) - for (int y = 0; y < pW; y++) { - pos = CLIP((int)(nprevl->L[x][y])); - - if(!params.colorappearance.datacie) { - posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y])); + if(!params.colorappearance.datacie) { + for (int x = 0; x < pH; x++) + for (int y = 0; y < pW; y++) { + int pos = CLIP((int)(nprevl->L[x][y])); + int posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y])); lhist16CAM[pos]++; lhist16CCAM[posc]++; } + } - if (y >= y1 && y < y2 && x >= x1 && x < x2) { - lhist16CroppedCAM[pos]++; - } - } - - LUTu dummy; - CurveFactory::curveLightBrightColor ( - params.colorappearance.curveMode, params.colorappearance.curve, - params.colorappearance.curveMode2, params.colorappearance.curve2, - params.colorappearance.curveMode3, params.colorappearance.curve3, - lhist16CAM, lhist16CroppedCAM, histLCAM, - lhist16CCAM, histCCAM, - customColCurve1, - customColCurve2, - customColCurve3, - scale == 1 ? 1 : 1 - ); + CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3, + lhist16CAM, histLCAM, lhist16CCAM, histCCAM, + customColCurve1, customColCurve2, customColCurve3, 1); float fnum = imgsrc->getMetaData()->getFNumber (); // F number float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed @@ -783,6 +762,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } // Issue 2785, only float version of ciecam02 for navigator and pan background + CAMMean = NAN; + CAMBrightCurveJ.dirty = true; + CAMBrightCurveQ.dirty = true; + ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, execsharp, d, scale, 1); if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) { @@ -823,11 +806,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) crops[i]->update (todo); // may call ourselves } - // Flagging some LUT as dirty now, whether they have been freed up or not - CAMBrightCurveJ.dirty = true; - CAMBrightCurveQ.dirty = true; - - progress ("Conversion to RGB...", 100 * readyphase / numofphases); if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { @@ -1329,7 +1307,6 @@ void ImProcCoordinator::startProcessing(int changeCode) void ImProcCoordinator::process () { - if (plistener) { plistener->setProgressState (true); } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 4d9a5b5c1..e6ea6dcc3 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -109,16 +109,14 @@ protected: LUTf NoiseCCcurve; LUTu vhist16, vhist16bw; - LUTu lhist16, lhist16Cropped; - LUTu lhist16CAM, lhist16CroppedCAM; + LUTu lhist16CAM; LUTu lhist16CCAM; LUTu lhist16RETI; - LUTu histCropped; - LUTu lhist16Clad, lhist16CLlad, lhist16LClad, lhist16LLClad; + LUTu lhist16CLlad, lhist16LClad; LUTu histRed, histRedRaw; LUTu histGreen, histGreenRaw; LUTu histBlue, histBlueRaw; - LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve; + LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve; LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI; LUTf CAMBrightCurveJ, CAMBrightCurveQ; @@ -138,6 +136,7 @@ protected: WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; RetinextransmissionCurve dehatransmissionCurve; + RetinexgaintransmissionCurve dehagaintransmissionCurve; ColorAppearance customColCurve1; ColorAppearance customColCurve2; @@ -200,6 +199,8 @@ protected: bool wavcontlutili; void startProcessing (); void process (); + float colourToningSatLimit; + float colourToningSatLimitOpacity; public: @@ -326,6 +327,17 @@ public: { return imgsrc; } + + struct DenoiseInfoStore { + DenoiseInfoStore () : valid(false) {} + float chM; + float max_r[9]; + float max_b[9]; + float ch_M[9]; + bool valid; + + } denoiseInfoStore; + }; } #endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 989d9c6a7..b832951c3 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -19,6 +19,9 @@ #include #include #include +#ifdef _OPENMP +#include +#endif #include "rtengine.h" #include "improcfun.h" @@ -37,10 +40,11 @@ #include "improccoordinator.h" #include "clutstore.h" #include "ciecam02.h" +//#define BENCHMARK +#include "StopWatch.h" +#include "../rtgui/ppversion.h" +#include "../rtgui/guiutils.h" -#ifdef _OPENMP -#include -#endif #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -54,15 +58,15 @@ extern const Settings* settings; ImProcFunctions::~ImProcFunctions () { - if (monitorTransform != NULL) { + if (monitorTransform) { cmsDeleteTransform (monitorTransform); } - if (output2monitorTransform != NULL) { + if (output2monitorTransform) { cmsDeleteTransform (output2monitorTransform); } - if (lab2outputTransform != NULL) { + if (lab2outputTransform) { cmsDeleteTransform (lab2outputTransform); } } @@ -72,52 +76,24 @@ void ImProcFunctions::setScale (double iscale) scale = iscale; } -// Called from several threads -void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to) -{ - - TMatrix wprof = iccStore->workingSpaceMatrix (wprofile); - - lumimul[0] = wprof[1][0]; - lumimul[1] = wprof[1][1]; - lumimul[2] = wprof[1][2]; - - int W = original->width; - - for (int i = row_from; i < row_to; i++) { - for (int j = 0; j < W; j++) { - - int r = original->r(i, j); - int g = original->g(i, j); - int b = original->b(i, j); - - int y = CLIP((int)(lumimul[0] * r + lumimul[1] * g + lumimul[2] * b)) ; - - if (histogram) { - histogram[y]++; - } - } - } -} - void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) { // set up monitor transform - if (monitorTransform != NULL) { + if (monitorTransform) { cmsDeleteTransform (monitorTransform); } - if (output2monitorTransform != NULL) { + if (output2monitorTransform) { cmsDeleteTransform (output2monitorTransform); } - if (lab2outputTransform != NULL) { + if (lab2outputTransform) { cmsDeleteTransform (lab2outputTransform); } - monitorTransform = NULL; - output2monitorTransform = NULL; - lab2outputTransform = NULL; + monitorTransform = nullptr; + output2monitorTransform = nullptr; + lab2outputTransform = nullptr; #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB @@ -125,7 +101,7 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); - cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); + cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr); monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision @@ -147,59 +123,66 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con #endif } -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +void ImProcFunctions::firstAnalysis (const Imagefloat* const original, const ProcParams ¶ms, LUTu & histogram) { - Glib::ustring wprofile = params->icm.working; + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + + lumimul[0] = wprof[1][0]; + lumimul[1] = wprof[1][1]; + lumimul[2] = wprof[1][2]; + int W = original->width; + int H = original->height; + + float lumimulf[3] = {static_cast(lumimul[0]), static_cast(lumimul[1]), static_cast(lumimul[2])}; // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments - - int T = 1; -#ifdef _OPENMP - - if(multiThread) { - T = omp_get_max_threads(); - } - -#endif - - unsigned int** hist = new unsigned int* [T]; - - for (int i = 0; i < T; i++) { - hist[i] = new unsigned int[65536]; - memset (hist[i], 0, 65536 * sizeof(int)); - } - -#ifdef _OPENMP - #pragma omp parallel if (multiThread) - { - int H = original->height; - int tid = omp_get_thread_num(); - int nthreads = omp_get_num_threads(); - int blk = H / nthreads; - - if (tid < nthreads - 1) { - firstAnalysisThread (original, wprofile, hist[tid], tid * blk, (tid + 1)*blk); - } else { - firstAnalysisThread (original, wprofile, hist[tid], tid * blk, H); - } - } -#else - firstAnalysisThread (original, wprofile, hist[0], 0, original->height); -#endif - histogram.clear(); - for (int j = 0; j < T; j++) - for (int i = 0; i < 65536; i++) { - histogram[i] += hist[j][i]; + if(multiThread) { + +#ifdef _OPENMP + const int numThreads = min(max(W * H / (int)histogram.getSize(), 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu hist(histogram.getSize()); + hist.clear(); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int i = 0; i < H; i++) { + for (int j = 0; j < W; j++) { + + float r = original->r(i, j); + float g = original->g(i, j); + float b = original->b(i, j); + + int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b); + hist[y]++; + } + } + +#ifdef _OPENMP + #pragma omp critical +#endif + histogram += hist; + } + } else { + for (int i = 0; i < H; i++) { + for (int j = 0; j < W; j++) { - for (int i = 0; i < T; i++) { - delete [] hist[i]; + float r = original->r(i, j); + float g = original->g(i, j); + float b = original->b(i, j); + + int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b); + histogram[y]++; + } + } } - - delete [] hist; } // Copyright (c) 2012 Jacques Desmis @@ -628,8 +611,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Jpro = (CAMBrightCurveJ[(float)(Jpro * 327.68)]) / 327.68; //ligthness CIECAM02 + contrast double sres; double Sp = spro / 100.0; - double parsat = 1.5; - parsat = 1.5; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + double parsat = 1.5; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) if(schr == -100.0) { schr = -99.8; @@ -1460,41 +1442,20 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, float &d, int scalecd, int rtt) { if(params->colorappearance.enabled) { -//int lastskip; -//if(rtt==1) {lastskip=scalecd;} //not for Rtthumbnail #ifdef _DEBUG MyTime t1e, t2e; t1e.set(); #endif - LUTf dLcurve; - LUTu hist16JCAM; - float val; //preparate for histograms CIECAM - if(pW != 1) { //only with improccoordinator - dLcurve(65536, 0); - dLcurve.clear(); - hist16JCAM(65536); + LUTu hist16JCAM; + LUTu hist16_CCAM; + + if(pW != 1 && params->colorappearance.datacie) { //only with improccoordinator + hist16JCAM(32768); hist16JCAM.clear(); - - for (int i = 0; i < 32768; i++) { //# 32768*1.414 approximation maxi for chroma - val = (double)i / 32767.0; - dLcurve[i] = CLIPD(val); - } - } - - LUTf dCcurve(65536, 0); - LUTu hist16_CCAM(65536); - bool chropC = false; - float valc; - - if(pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma - valc = (double)i / 47999.0; - dCcurve[i] = CLIPD(valc); - } - + hist16_CCAM(48000); hist16_CCAM.clear(); } @@ -1505,15 +1466,16 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int float Yw; Yw = 1.0; double Xw, Zw; - float f, nc, yb, la, c, xw, yw, zw, f2, c2, nc2, yb2, la2; + float f, nc, yb, la, c, xw, yw, zw, f2, c2, nc2, yb2; float fl, n, nbb, ncb, aw; //d float xwd, ywd, zwd; int alg = 0; bool algepd = false; - float sum = 0.f; - const bool ciedata = (params->colorappearance.datacie && pW != 1); - bool jp = ciedata; + const bool epdEnabled = params->epd.enabled; + bool ciedata = (params->colorappearance.datacie && pW != 1) && !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) + || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) + || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB @@ -1555,7 +1517,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } else if(params->colorappearance.algo == "QM") { alg = 2; algepd = true; - } else if(params->colorappearance.algo == "ALL") { + } else { /*if(params->colorappearance.algo == "ALL")*/ alg = 3; algepd = true; } @@ -1589,7 +1551,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int xwd = 95.04f; //fluo F7 ywd = 100.0f; zwd = 108.75f; - } else if(settings->viewingdevice == 7) { + } else { /*if(settings->viewingdevice == 7) */ xwd = 100.96f; //fluo F11 ywd = 100.0f; zwd = 64.35f; @@ -1609,7 +1571,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int yb2 = 23.0f; } else if(settings->viewingdevicegrey == 5) { yb2 = 30.0f; - } else if(settings->viewingdevicegrey == 6) { + } else { /* if(settings->viewingdevicegrey == 6)*/ yb2 = 40.0f; } @@ -1622,7 +1584,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } } - la2 = float(params->colorappearance.adaplum); + const float la2 = float(params->colorappearance.adaplum); // level of adaptation const float deg = (params->colorappearance.degree) / 100.0f; @@ -1704,45 +1666,41 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int const ColorAppearanceParams::eCTCModeId curveMode3 = params->colorappearance.curveMode3; const bool hasColCurve3 = bool(customColCurve3); - bool c1s = false; - bool c1co = false; - if( hasColCurve3 && curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { - c1s = true; - } + bool needJ = (alg == 0 || alg == 1 || alg == 3); + bool needQ = (alg == 2 || alg == 3); + LUTu hist16J; + LUTu hist16Q; - if(hasColCurve3 && curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { - c1co = true; - } - - if(CAMBrightCurveJ.dirty || CAMBrightCurveQ.dirty) { - bool needJ = (alg == 0 || alg == 1 || alg == 3); - bool needQ = (alg == 2 || alg == 3); - LUTu hist16J; - LUTu hist16Q; + if((needJ && CAMBrightCurveJ.dirty) || (needQ && CAMBrightCurveQ.dirty) || (std::isnan(mean) && settings->viewinggreySc != 0)) { if (needJ) { - hist16J (65536); + hist16J (32768); hist16J.clear(); } if (needQ) { - hist16Q (65536); + hist16Q (32768); hist16Q.clear(); } - #pragma omp parallel + float sum = 0.f; + +#ifdef _OPENMP + const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif { LUTu hist16Jthr; LUTu hist16Qthr; if (needJ) { - hist16Jthr (65536); + hist16Jthr(hist16J.getSize()); hist16Jthr.clear(); } if (needQ) { - hist16Qthr(65536); + hist16Qthr(hist16Q.getSize()); hist16Qthr.clear(); } @@ -1751,37 +1709,48 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { //rough correspondence between L and J float currL = lab->L[i][j] / 327.68f; - float koef = 1.0f; //rough correspondence between L and J + float koef; //rough correspondence between L and J -// if (currL>95.f) koef=1.f; - if(currL > 85.f) { - koef = 0.97f; - } else if(currL > 80.f) { - koef = 0.93f; - } else if(currL > 70.f) { - koef = 0.87f; - } else if(currL > 60.f) { - koef = 0.85f; - } else if(currL > 50.f) { - koef = 0.8f; - } else if(currL > 40.f) { - koef = 0.75f; + if(currL > 50.f) { + if(currL > 70.f) { + if(currL > 80.f) { + if(currL > 85.f) { + koef = 0.97f; + } else { + koef = 0.93f; + } + } else { + koef = 0.87f; + } + } else { + if (currL > 60.f) { + koef = 0.85f; + } else { + koef = 0.8f; + } + } + } else { + if(currL > 10.f) { + if(currL > 20.f) { + if(currL > 40.f) { + koef = 0.75f; + } else { + koef = 0.7f; + } + } else { + koef = 0.9f; + } + } else { + koef = 1.0; + } } -// else if(currL>30.f) koef=0.7f; - else if(currL > 20.f) { - koef = 0.7f; - } else if(currL > 10.f) { - koef = 0.9f; - } - -// else if(currL>0.f) koef=1.0f; if (needJ) { - hist16Jthr[CLIP((int)((koef * lab->L[i][j])))]++; //evaluate histogram luminance L # J + hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J } if (needQ) { - hist16Qthr[CLIP((int) (sqrtf((koef * (lab->L[i][j])) * 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L + hist16Qthr[(int) (sqrtf((koef * (lab->L[i][j])) * 32768.f))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L } sum += koef * lab->L[i][j]; //evaluate mean J to calculate Yb @@ -1789,46 +1758,24 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int #pragma omp critical { - if(needJ) - for(int i = 0; i < 65536; i++) { - hist16J[i] += hist16Jthr[i]; - } + if(needJ) { + hist16J += hist16Jthr; + } - if(needQ) - for(int i = 0; i < 65536; i++) { - hist16Q[i] += hist16Qthr[i]; - } + if(needQ) { + hist16Q += hist16Qthr; + } } + + if(std::isnan(mean)) { + mean = (sum / ((height) * width)) / 327.68f; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone + } } - //mean=(sum/((endh-begh)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone - mean = (sum / ((height) * width)) / 327.68f; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone //evaluate lightness, contrast - if (needJ) { - if (!CAMBrightCurveJ) { - CAMBrightCurveJ(32768, LUT_CLIP_ABOVE); - CAMBrightCurveJ.dirty = false; - } - - float jli = params->colorappearance.jlight; - float contra = params->colorappearance.contrast; - Ciecam02::curveJfloat (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J - } - - if (needQ) { - if (!CAMBrightCurveQ) { - CAMBrightCurveQ(32768, LUT_CLIP_ABOVE); - CAMBrightCurveQ.clear(); - CAMBrightCurveQ.dirty = false; - } - - float qbri = params->colorappearance.qbright; - float qcontra = params->colorappearance.qcontrast; - Ciecam02::curveJfloat (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q - } } if(settings->viewinggreySc == 0) { //auto @@ -1855,13 +1802,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } else { yb = 90.0f; } - } - - if(settings->viewinggreySc == 1) { + } else if(settings->viewinggreySc == 1) { yb = 18.0f; //fixed } - const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated const int gamu = (params->colorappearance.gamut == true) ? 1 : 0; @@ -1897,16 +1841,42 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int const float epsil = 0.0001f; const float w_h = wh + epsil; + const float coefQ = 32767.f / wh; const float a_w = aw; const float c_ = c; const float f_l = fl; const float coe = pow_F(fl, 0.25f); const float QproFactor = ( 0.4f / c ) * ( aw + 4.0f ) ; - const bool epdEnabled = params->epd.enabled; const bool LabPassOne = !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); + + if (needJ) { + if (!CAMBrightCurveJ) { + CAMBrightCurveJ(32768, LUT_CLIP_ABOVE); + } + + if(CAMBrightCurveJ.dirty) { + Ciecam02::curveJfloat (params->colorappearance.jlight, params->colorappearance.contrast, hist16J, CAMBrightCurveJ);//lightness and contrast J + CAMBrightCurveJ /= 327.68f; + CAMBrightCurveJ.dirty = false; + } + } + + if (needQ) { + if (!CAMBrightCurveQ) { + CAMBrightCurveQ(32768, LUT_CLIP_ABOVE); + } + + if(CAMBrightCurveQ.dirty) { + Ciecam02::curveJfloat (params->colorappearance.qbright, params->colorappearance.qcontrast, hist16Q, CAMBrightCurveQ);//brightness and contrast Q + CAMBrightCurveQ /= coefQ; + CAMBrightCurveQ.dirty = false; + } + } + + //matrix for current working space TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); const float wip[3][3] = { @@ -2029,18 +1999,16 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int // we cannot have all algorithms with all chroma curves if(alg == 0) { - Jpro = CAMBrightCurveJ[Jpro * 327.68f] / 327.68f; //lightness CIECAM02 + contrast + Jpro = CAMBrightCurveJ[Jpro * 327.68f]; //lightness CIECAM02 + contrast Qpro = QproFactor * sqrtf(Jpro); float Cp = (spro * spro * Qpro) / (1000000.f); Cpro = Cp * 100.f; float sres; Ciecam02::curvecolorfloat(chr, Cp , sres, 1.8f); Color::skinredfloat(Jpro, hpro, sres, Cp, 55.f, 30.f, 1, rstprotection, 100.f, Cpro); - } - - if(alg == 1) { + } else if(alg == 1) { // Lightness saturation - Jpro = CAMBrightCurveJ[Jpro * 327.68f] / 327.68f; //lightness CIECAM02 + contrast + Jpro = CAMBrightCurveJ[Jpro * 327.68f]; //lightness CIECAM02 + contrast float sres; float Sp = spro / 100.0f; float parsat = 1.5f; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) @@ -2053,8 +2021,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Qpro = QproFactor * sqrtf(Jpro); Cpro = (spro * spro * Qpro) / (10000.0f); } else if(alg == 2) { - float coef = 32767.f / wh; - Qpro = (CAMBrightCurveQ[(float)(Qpro * coef)]) / coef; //brightness and contrast + Qpro = CAMBrightCurveQ[(float)(Qpro * coefQ)]; //brightness and contrast float Mp, sres; Mp = Mpro / 100.0f; Ciecam02::curvecolorfloat(mchr, Mp , sres, 2.5f); @@ -2067,14 +2034,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Cpro = Mpro / coe; Qpro = (Qpro == 0.f ? epsil : Qpro); // avoid division by zero spro = 100.0f * sqrtf( Mpro / Qpro ); - } else if(alg == 3) { - float coef = 32760.f / wh; - - if(Qpro * coef >= 32767.0f) { - Qpro = (CAMBrightCurveQ[32767]) / coef; //brightness and contrast - } else { - Qpro = (CAMBrightCurveQ[(float)(Qpro * coef)]) / coef; //brightness and contrast - } + } else { /*if(alg == 3) */ + Qpro = CAMBrightCurveQ[(float)(Qpro * coefQ)]; //brightness and contrast float Mp, sres; Mp = Mpro / 100.0f; @@ -2093,7 +2054,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Jpro = 99.9f; } - Jpro = (CAMBrightCurveJ[(float)(Jpro * 327.68f)]) / 327.68f; //lightness CIECAM02 + contrast + Jpro = CAMBrightCurveJ[(float)(Jpro * 327.68f)]; //lightness CIECAM02 + contrast float Sp = spro / 100.0f; Ciecam02::curvecolorfloat(schr, Sp , sres, 1.5f); dred = 100.f; // in C mode @@ -2284,17 +2245,17 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int int sk = 1; float ko = 1.f / coef; Color::skinredfloat(Jpro, hpro, Cc, Ccold, dred, protect_red, sk, rstprotection, ko, Cpro); - - if(Jpro < 1.f && Cpro > 12.f) { - Cpro = 12.f; //reduce artifacts by "pseudo gamut control CIECAM" - } else if(Jpro < 2.f && Cpro > 15.f) { - Cpro = 15.f; - } else if(Jpro < 4.f && Cpro > 30.f) { - Cpro = 30.f; - } else if(Jpro < 7.f && Cpro > 50.f) { - Cpro = 50.f; - } - + /* + if(Jpro < 1.f && Cpro > 12.f) { + Cpro = 12.f; //reduce artifacts by "pseudo gamut control CIECAM" + } else if(Jpro < 2.f && Cpro > 15.f) { + Cpro = 15.f; + } else if(Jpro < 4.f && Cpro > 30.f) { + Cpro = 30.f; + } else if(Jpro < 7.f && Cpro > 50.f) { + Cpro = 50.f; + } + */ } else if (curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { // float parsat = 0.8f; //0.6 float coef = 327.68f / parsat; @@ -2312,7 +2273,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Color::skinredfloat(Jpro, hpro, Ss, Sold, dred, protect_red, sk, rstprotection, ko, spro); Qpro = ( 4.0f / c ) * sqrtf( Jpro / 100.0f ) * ( aw + 4.0f ) ; Cpro = (spro * spro * Qpro) / (10000.0f); - } else if (curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { // float parsat = 0.8f; //0.68; float coef = 327.68f / parsat; @@ -2327,31 +2287,23 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int int sk = 0; float ko = 1.f / coef; Color::skinredfloat(Jpro, hpro, Mm, Mold, dred, protect_red, sk, rstprotection, ko, Mpro); + /* + if(Jpro < 1.f && Mpro > 12.f * coe) { + Mpro = 12.f * coe; //reduce artifacts by "pseudo gamut control CIECAM" + } else if(Jpro < 2.f && Mpro > 15.f * coe) { + Mpro = 15.f * coe; + } else if(Jpro < 4.f && Mpro > 30.f * coe) { + Mpro = 30.f * coe; + } else if(Jpro < 7.f && Mpro > 50.f * coe) { + Mpro = 50.f * coe; + } + */ Cpro = Mpro / coe; - - if(Jpro < 1.f && Mpro > 12.f * coe) { - Mpro = 12.f * coe; //reduce artifacts by "pseudo gamut control CIECAM" - } else if(Jpro < 2.f && Mpro > 15.f * coe) { - Mpro = 15.f * coe; - } else if(Jpro < 4.f && Mpro > 30.f * coe) { - Mpro = 30.f * coe; - } else if(Jpro < 7.f && Mpro > 50.f * coe) { - Mpro = 50.f * coe; - } } } //to retrieve the correct values of variables - if(c1s) { - Qpro = ( 4.0f / c ) * sqrtf( Jpro / 100.0f ) * ( aw + 4.0f ) ; //for saturation curve - Cpro = (spro * spro * Qpro) / (10000.0f); - } - - if(c1co) { - float coe = pow_F(fl, 0.25f); - Cpro = Mpro / coe; - } // for colorfullness curve //retrieve values C,J...s C = Cpro; @@ -2382,57 +2334,40 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled) { - if(ciedata) { + 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; - int libr = 0; - int colch = 0; + float libr; + float colch; + //update histogram if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { brli = 70.0f; - libr = 1; - } else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { + libr = Q; //40.0 to 100.0 approximative factor for Q - 327 for J + } else { /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ brli = 327.f; - libr = 0; + libr = J; //327 for J } + posl = (int)(libr * brli); + hist16JCAM[posl]++; + if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { chsacol = 327.f; - colch = 0; + colch = C; //450.0 approximative factor for s 320 for M } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { chsacol = 450.0f; - colch = 1; - } else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { + colch = s; + } else { /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ chsacol = 327.0f; - colch = 2; + colch = M; } - //update histogram - if(pW != 1) { //only with improccoordinator - if(libr == 1) { - posl = CLIP((int)(Q * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else if(libr == 0) { - posl = CLIP((int)(J * brli)); //327 for J - } + posc = (int)(colch * chsacol); + hist16_CCAM[posc]++; - hist16JCAM[posl]++; - } - - chropC = true; - - if(pW != 1) { //only with improccoordinator - if(colch == 0) { - posc = CLIP((int)(C * chsacol)); //450.0 approximative factor for s 320 for M - } else if(colch == 1) { - posc = CLIP((int)(s * chsacol)); - } else if(colch == 2) { - posc = CLIP((int)(M * chsacol)); - } - - hist16_CCAM[posc]++; - } } if(LabPassOne) { @@ -2450,9 +2385,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int xw2, yw2, zw2, f2, c2, nc2, gamu, pow1n, nbbj, ncbj, flj, czj, dj, awj); float x, y, z; - x = (float)xx * 655.35f; - y = (float)yy * 655.35f; - z = (float)zz * 655.35f; + x = xx * 655.35f; + y = yy * 655.35f; + z = zz * 655.35f; float Ll, aa, bb; //convert xyz=>lab Color::XYZ2Lab(x, y, z, Ll, aa, bb); @@ -2573,25 +2508,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } // End of parallelization - if(!params->colorappearance.tonecie || !settings->autocielab) { //normal + if(!params->colorappearance.tonecie || !settings->autocielab) { //normal if(ciedata) { //update histogram J - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int)(255.0f * CLIPD(hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } - - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int)(255.0f * CLIPD(hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } + hist16JCAM.compressTo(histLCAM); + //update histogram C + hist16_CCAM.compressTo(histCCAM); } } @@ -2723,6 +2646,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)) { + ciedata = (params->colorappearance.datacie && pW != 1); + if(epdEnabled && params->colorappearance.tonecie && algepd) { lab->deleteLab(); ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); @@ -2732,14 +2657,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int //EPDToneMapCIE adated to CIECAM - const float eps = 0.0001f; + constexpr float eps = 0.0001f; const float co_e = (pow_F(f_l, 0.25f)) + eps; - TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working); - const float wipa[3][3] = { - {float(wiprofa[0][0]), float(wiprofa[0][1]), float(wiprofa[0][2])}, - {float(wiprofa[1][0]), float(wiprofa[1][1]), float(wiprofa[1][2])}, - {float(wiprofa[2][0]), float(wiprofa[2][1]), float(wiprofa[2][2])} - }; #ifndef _DEBUG #pragma omp parallel @@ -2777,54 +2696,33 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int int posl, posc; float brli = 327.f; float chsacol = 327.f; - int libr = 0; - int colch = 0; - float sa_t; + float libr; + float colch; if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { brli = 70.0f; - libr = 1; - } else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { + libr = ncie->Q_p[i][j]; //40.0 to 100.0 approximative factor for Q - 327 for J + } else { /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ brli = 327.f; - libr = 0; + libr = ncie->J_p[i][j]; //327 for J } + posl = (int)(libr * brli); + hist16JCAM[posl]++; + if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { chsacol = 327.f; - colch = 0; + colch = ncie_C_p; } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { chsacol = 450.0f; - colch = 1; - } else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { + colch = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]); + } else { /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ chsacol = 327.0f; - colch = 2; + colch = ncie->M_p[i][j]; } - //update histogram - if(pW != 1) { //only with improccoordinator - if(libr == 1) { - posl = CLIP((int)(ncie->Q_p[i][j] * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else if(libr == 0) { - posl = CLIP((int)(ncie->J_p[i][j] * brli)); //327 for J - } - - hist16JCAM[posl]++; - } - - chropC = true; - - if(pW != 1) { //only with improccoordinator - if(colch == 0) { - posc = CLIP((int)(ncie_C_p * chsacol)); //450.0 approximative factor for s 320 for M - } else if(colch == 1) { - sa_t = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]); //Q_p always > 0 - posc = CLIP((int)(sa_t * chsacol)); - } else if(colch == 2) { - posc = CLIP((int)(ncie->M_p[i][j] * chsacol)); - } - - hist16_CCAM[posc]++; - } + posc = (int)(colch * chsacol); + hist16_CCAM[posc]++; } //end histograms @@ -2864,10 +2762,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int bool neg = false; bool more_rgb = false; //gamut control : Lab values are in gamut - Color::gamutLchonly(sincosval, Lprov1, Chprov1, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(sincosval, Lprov1, Chprov1, wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else //gamut control : Lab values are in gamut - Color::gamutLchonly(sincosval, Lprov1, Chprov1, wipa, highlight, 0.15f, 0.96f); + Color::gamutLchonly(sincosval, Lprov1, Chprov1, wip, highlight, 0.15f, 0.96f); #endif lab->L[i][j] = Lprov1 * 327.68f; @@ -2926,10 +2824,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int bool neg = false; bool more_rgb = false; //gamut control : Lab values are in gamut - Color::gamutLchonly(sincosval, Lprov1, Chprov1, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(sincosval, Lprov1, Chprov1, wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else //gamut control : Lab values are in gamut - Color::gamutLchonly(sincosval, Lprov1, Chprov1, wipa, highlight, 0.15f, 0.96f); + Color::gamutLchonly(sincosval, Lprov1, Chprov1, wip, highlight, 0.15f, 0.96f); #endif lab->L[i][j] = Lprov1 * 327.68f; lab->a[i][j] = 327.68f * Chprov1 * sincosval.y; @@ -2950,24 +2848,12 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int //show CIECAM histograms if(ciedata) { //update histogram J and Q - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int)(255.0f * CLIPD(hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } + //update histogram J + hist16JCAM.compressTo(histLCAM); //update color histogram M,s,C - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int)(255.0f * CLIPD(hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } + hist16_CCAM.compressTo(histCCAM); } - } } } @@ -2975,54 +2861,29 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) { -// MyTime t1e,t2e; -// t1e.set(); + BENCHFUN int tHh = working->height; int tWw = working->width; - float moy = 0.f; - float eqt = 0.f; - #pragma omp parallel - { - float mo = 0.f; -#ifndef _DEBUG - #pragma omp for reduction(+:moy) + double moy = 0.0; + double sqrs = 0.0; + +#ifdef _OPENMP + #pragma omp parallel for reduction(+:moy,sqrs) schedule(dynamic,16) #endif - for (int i = 0; i < tHh; i++) { - for (int j = 0; j < tWw; j++) { - float r = CLIP(working->r(i, j)); - float g = CLIP(working->g(i, j)); - float b = CLIP(working->b(i, j)); - float h, s, v; - Color::rgb2hsv(r, g, b, h, s, v); - moy += s; - } - } - - mo = moy / (tHh * tWw); - moyS = mo; -#ifndef _DEBUG - #pragma omp for reduction(+:eqt) -#endif - - for (int i = 0; i < tHh; i++) { - for (int j = 0; j < tWw; j++) { - float r = CLIP(working->r(i, j)); - float g = CLIP(working->g(i, j)); - float b = CLIP(working->b(i, j)); - float h, s, v; - Color::rgb2hsv(r, g, b, h, s, v); - eqt += SQR(s - mo); - } + for (int i = 0; i < tHh; i++) { + for (int j = 0; j < tWw; j++) { + float s = Color::rgb2s(CLIP(working->r(i, j)), CLIP(working->g(i, j)), CLIP(working->b(i, j))); + moy += s; + sqrs += SQR(s); } } - eqt = eqt / (tHh * tWw); - eqty = (sqrt(eqt)); - - // t2e.set(); - // printf("Moyeqt:%d\n", t2e.etime(t1e)); + moy /= (tHh * tWw); + sqrs /= (tHh * tWw); + eqty = sqrt(sqrs - SQR(moy)); + moyS = moy; } static inline void @@ -3067,38 +2928,38 @@ filmlike_clip(float *r, float *g, float *b) void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & 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 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 ) { - rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, shmap, 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); + rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, shmap, 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); } // Process RGB image and convert to LAB space void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & 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 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 ) { - LUTf fGammaLUTf; - Imagefloat *tmpImage = NULL; + BENCHFUN + Imagefloat *tmpImage = nullptr; // NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this - Imagefloat* editImgFloat = NULL; - LabImage* editLab = NULL; - PlanarWhateverData* editWhatever = NULL; + Imagefloat* editImgFloat = nullptr; + LabImage* editLab = nullptr; + PlanarWhateverData* editWhatever = nullptr; EditUniqueID editID = pipetteBuffer ? pipetteBuffer->getEditID() : EUID_None; if (editID != EUID_None) { switch (pipetteBuffer->getDataProvider()->getCurrSubscriber()->getPipetteBufferType()) { - case (BT_IMAGEFLOAT): - editImgFloat = pipetteBuffer->getImgFloatBuffer(); - break; + case (BT_IMAGEFLOAT): + editImgFloat = pipetteBuffer->getImgFloatBuffer(); + break; - case (BT_LABIMAGE): - editLab = pipetteBuffer->getLabBuffer(); - break; + case (BT_LABIMAGE): + editLab = pipetteBuffer->getLabBuffer(); + break; - case (BT_SINGLEPLANE_FLOAT): - editWhatever = pipetteBuffer->getSinglePlaneBuffer(); - break; + case (BT_SINGLEPLANE_FLOAT): + editWhatever = pipetteBuffer->getSinglePlaneBuffer(); + break; } } @@ -3109,28 +2970,32 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer s_th = params->sh.stonalwidth * (shmap->avg - shmap->min_f) / 100; } - bool processSH = params->sh.enabled && shmap != NULL && (params->sh.highlights > 0 || params->sh.shadows > 0); - bool processLCE = params->sh.enabled && shmap != NULL && params->sh.localcontrast > 0; + bool processSH = params->sh.enabled && shmap && (params->sh.highlights > 0 || params->sh.shadows > 0); + bool processLCE = params->sh.enabled && shmap && params->sh.localcontrast > 0; double lceamount = params->sh.localcontrast / 200.0; TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); - double toxyz[3][3] = { + float toxyz[3][3] = { { - ( wprof[0][0] / Color::D50x), - ( wprof[0][1] / Color::D50x), - ( wprof[0][2] / Color::D50x) + static_cast( wprof[0][0] / Color::D50x), + static_cast( wprof[0][1] / Color::D50x), + static_cast( wprof[0][2] / Color::D50x) }, { - ( wprof[1][0]), - ( wprof[1][1]), - ( wprof[1][2]) + static_cast( wprof[1][0]), + static_cast( wprof[1][1]), + static_cast( wprof[1][2]) }, { - ( wprof[2][0] / Color::D50z), - ( wprof[2][1] / Color::D50z), - ( wprof[2][2] / Color::D50z) + static_cast( wprof[2][0] / Color::D50z), + static_cast( wprof[2][1] / Color::D50z), + static_cast( wprof[2][2] / Color::D50z) } }; + float maxFactorToxyz = max(toxyz[1][0],toxyz[1][1],toxyz[1][2]); + float equalR = maxFactorToxyz / toxyz[1][0]; + float equalG = maxFactorToxyz / toxyz[1][1]; + float equalB = maxFactorToxyz / toxyz[1][2]; //inverse matrix user select double wip[3][3] = { @@ -3170,7 +3035,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (hCurve->isIdentity()) { delete hCurve; - hCurve = NULL; + hCurve = nullptr; hCurveEnabled = false; } } @@ -3180,7 +3045,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (sCurve->isIdentity()) { delete sCurve; - sCurve = NULL; + sCurve = nullptr; sCurveEnabled = false; } } @@ -3190,7 +3055,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (vCurve->isIdentity()) { delete vCurve; - vCurve = NULL; + vCurve = nullptr; vCurveEnabled = false; } } @@ -3200,32 +3065,49 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (bwlCurve->isIdentity()) { delete bwlCurve; - bwlCurve = NULL; + bwlCurve = nullptr; bwlCurveEnabled = false; } } - ClutPtr colorLUT; + std::shared_ptr hald_clut; bool clutAndWorkingProfilesAreSame = false; - TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work; + TMatrix xyz2clut, clut2xyz; +#ifdef __SSE2__ + vfloat v_work2xyz[3][3] ALIGNED16; + vfloat v_xyz2clut[3][3] ALIGNED16; + vfloat v_clut2xyz[3][3] ALIGNED16; + vfloat v_xyz2work[3][3] ALIGNED16; +#endif if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) { - colorLUT.set( clutStore.getClut( params->filmSimulation.clutFilename ) ); + hald_clut = CLUTStore::getInstance().getClut( params->filmSimulation.clutFilename ); - if ( colorLUT ) { - clutAndWorkingProfilesAreSame = colorLUT->profile() == params->icm.working; + if ( hald_clut ) { + clutAndWorkingProfilesAreSame = hald_clut->getProfile() == params->icm.working; if ( !clutAndWorkingProfilesAreSame ) { - work2xyz = iccStore->workingSpaceMatrix( params->icm.working ); - xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() ); - xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working ); - clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() ); + xyz2clut = iccStore->workingSpaceInverseMatrix( hald_clut->getProfile() ); + clut2xyz = iccStore->workingSpaceMatrix( hald_clut->getProfile() ); + +#ifdef __SSE2__ + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + v_work2xyz[i][j] = F2V(wprof[i][j]); + v_xyz2clut[i][j] = F2V(xyz2clut[i][j]); + v_xyz2work[i][j] = F2V(wiprof[i][j]); + v_clut2xyz[i][j] = F2V(clut2xyz[i][j]); + } + } + +#endif + } } } - double filmSimCorrectedStrength = double(params->filmSimulation.strength) / 100.; - double filmSimSourceStrength = double(100 - params->filmSimulation.strength) / 100.; + const float film_simulation_strength = static_cast(params->filmSimulation.strength) / 100.0f; const float exp_scale = pow (2.0, expcomp); const float comp = (max(0.0, expcomp) + 1.0) * hlcompr / 100.0; @@ -3373,13 +3255,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } bool hasgammabw = gammabwr != 1.f || gammabwg != 1.f || gammabwb != 1.f; - fGammaLUTf(65535); - #pragma omp parallel for - - for (int i = 0; i < 65536; i++) { - fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f; - } - if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) { tmpImage = new Imagefloat(working->width, working->height); } @@ -3387,15 +3262,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer int W = working->width; int H = working->height; - - - - - - - - - #define TS 112 #ifdef _OPENMP @@ -3403,8 +3269,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer #endif { char *buffer; - char *editIFloatBuffer = NULL; - char *editWhateverBuffer = NULL; + char *editIFloatBuffer = nullptr; + char *editWhateverBuffer = nullptr; buffer = (char *) malloc(3 * sizeof(float) * TS * TS + 20 * 64 + 63); char *data; @@ -3437,6 +3303,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer editWhateverTmp = (float(*))data; } + float out_rgbx[4 * TS] ALIGNED16; // Line buffer for CLUT #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) @@ -3546,8 +3413,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } } - if (dcpProf != NULL) { - dcpProf->step2ApplyTile(rtemp, gtemp, btemp, tW - jstart, tH - istart, TS); + if (dcpProf) { + dcpProf->step2ApplyTile(rtemp, gtemp, btemp, tW - jstart, tH - istart, TS, asIn); } for (int i = istart, ti = 0; i < tH; i++, ti++) { @@ -3592,9 +3459,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (editID == EUID_ToneCurve1) { // filling the pipette buffer for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f); + editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f; } } } @@ -3663,9 +3530,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (editID == EUID_ToneCurve2) { // filling the pipette buffer for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f); + editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f; } } } @@ -3722,19 +3589,19 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (editID == EUID_RGB_R) { for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editWhateverTmp[ti * TS + tj] = fGammaLUTf[rtemp[ti * TS + tj]] / 65536.f; + editWhateverTmp[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65536.f; } } } else if (editID == EUID_RGB_G) { for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editWhateverTmp[ti * TS + tj] = fGammaLUTf[gtemp[ti * TS + tj]] / 65536.f; + editWhateverTmp[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65536.f; } } } else if (editID == EUID_RGB_B) { for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editWhateverTmp[ti * TS + tj] = fGammaLUTf[btemp[ti * TS + tj]] / 65536.f; + editWhateverTmp[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65536.f; } } } @@ -3765,60 +3632,52 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float r1, g1, b1, r2, g2, b2, L_1, L_2, Lfactor, a_1, b_1, x_, y_, z_, R, G, B ; - float y, fy, yy, fyy, x, z, fx, fz; - // rgb values before RGB curves - r1 = rtemp[ti * TS + tj] ; - g1 = gtemp[ti * TS + tj] ; - b1 = btemp[ti * TS + tj] ; + float r = rtemp[ti * TS + tj] ; + float g = gtemp[ti * TS + tj] ; + float b = btemp[ti * TS + tj] ; //convert to Lab to get a&b before RGB curves - x = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; - y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; - z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; + float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF)); - fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF)); - fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF)); + float fx = x < MAXVALF ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF); + float fy = y < MAXVALF ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF); + float fz = z < MAXVALF ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF); - L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; - a_1 = (500.0f * (fx - fy) ); - b_1 = (200.0f * (fy - fz) ); + float a_1 = 500.0f * (fx - fy); + float b_1 = 200.0f * (fy - fz); // rgb values after RGB curves if (rCurve) { - r2 = rCurve[ rtemp[ti * TS + tj]]; - } else { - r2 = r1; + float rNew = rCurve[r]; + r += (rNew - r) * equalR; } if (gCurve) { - g2 = gCurve[ gtemp[ti * TS + tj]]; - } else { - g2 = g1; + float gNew = gCurve[g]; + g += (gNew - g) * equalG; } if (bCurve) { - b2 = bCurve[ btemp[ti * TS + tj]]; - } else { - b2 = b1; + float bNew = bCurve[b]; + b += (bNew - b) * equalB; } // Luminosity after // only Luminance in Lab - yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2; - fyy = (yy < 65535.0f ? Color::cachef[std::max(yy, 0.f)] : 327.68f * std::cbrt(yy / MAXVALF)); - L_2 = (116.0f * fyy - 5242.88f); + float newy = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float newfy = newy < MAXVALF ? Color::cachef[newy] : 327.68f * std::cbrt(newy / MAXVALF); + float L_2 = 116.0f * newfy - 5242.88f; //gamut control if(settings->rgbcurveslumamode_gamut) { - float RR, GG, BB; - float HH, Lpro, Chpro; - Lpro = L_2 / 327.68f; - Chpro = sqrt(SQR(a_1) + SQR(b_1)) / 327.68f; - HH = xatan2f(b_1, a_1); - // According to mathematical laws we can get the sin and cos of HH by simple operations - float2 sincosval; + float Lpro = L_2 / 327.68f; + float Chpro = sqrtf(SQR(a_1) + SQR(b_1)) / 327.68f; + float HH = NAN; // we set HH to NAN, because then it will be calculated in Color::gamutLchonly only if needed +// float HH = xatan2f(b_1, a_1); + // According to mathematical laws we can get the sin and cos of HH by simple operations even if we don't calculate HH + float2 sincosval; if(Chpro == 0.0f) { sincosval.y = 1.0f; @@ -3832,30 +3691,18 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer bool neg = false; bool more_rgb = false; //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lpro, Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(HH, sincosval, Lpro, Chpro, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lpro, Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); + Color::gamutLchonly(HH, sincosval, Lpro, Chpro, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip, highlight, 0.15f, 0.96f); #endif - - //Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); - - - -// float2 sincosval = xsincosf(HH); - - L_2 = Lpro * 327.68f; - a_1 = 327.68f * Chpro * sincosval.y; - b_1 = 327.68f * Chpro * sincosval.x; - } //end of gamut control - - //calculate RGB with L_2 and old value of a and b - Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; - Color::xyz2rgb(x_, y_, z_, R, G, B, wip); - - rtemp[ti * TS + tj] = R; - gtemp[ti * TS + tj] = G; - btemp[ti * TS + tj] = B; + //end of gamut control + } else { + float x_, y_, z_; + //calculate RGB with L_2 and old value of a and b + Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; + Color::xyz2rgb(x_, y_, z_, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip); + } } } } @@ -4167,9 +4014,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (editID == EUID_BlackWhiteBeforeCurve) { for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); - editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f); + editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f; + editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f; } } } else if (editID == EUID_BlackWhiteLuminance) { @@ -4251,36 +4098,47 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer // -------------------------------------------------- +#ifndef __SSE2__ //gamma correction: pseudo TRC curve if (hasgammabw) { Color::trcGammaBW (r, g, b, gammabwr, gammabwg, gammabwb); } - +#endif rtemp[ti * TS + tj] = r; gtemp[ti * TS + tj] = g; btemp[ti * TS + tj] = b; } +#ifdef __SSE2__ + if (hasgammabw) { + //gamma correction: pseudo TRC curve + Color::trcGammaBWRow (&rtemp[ti * TS], >emp[ti * TS], &btemp[ti * TS], tW - jstart, gammabwr, gammabwg, gammabwb); + } +#endif + } - } else if (algm == 1) { //Luminance mixer in Lab mode to avoid artifacts + } else if (algm == 1) { //Luminance mixer in Lab mode to avoid artefacts for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - //rgb=>lab - float r = rtemp[ti * TS + tj]; - float g = gtemp[ti * TS + tj]; - float b = btemp[ti * TS + tj]; + //rgb => xyz float X, Y, Z; + Color::rgbxyz(rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], X, Y, Z, wp); + //xyz => Lab float L, aa, bb; - Color::rgbxyz(r, g, b, X, Y, Z, wp); - //convert Lab Color::XYZ2Lab(X, Y, Z, L, aa, bb); - //end rgb=>lab - //lab ==> Ch - float CC = sqrt(SQR(aa / 327.68f) + SQR(bb / 327.68f)); //CC chromaticity in 0..180 or more + float CC = sqrtf(SQR(aa) + SQR(bb)) / 327.68f; //CC chromaticity in 0..180 or more float HH = xatan2f(bb, aa); // HH hue in -3.141 +3.141 - float l_r;//Luminance Lab in 0..1 - l_r = L / 32768.f; + float2 sincosval; + + if(CC == 0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa / (CC * 327.68f); + sincosval.x = bb / (CC * 327.68f); + } if (bwlCurveEnabled) { + L /= 32768.f; double hr = Color::huelab_to_huehsv2(HH); float valparam = float((bwlCurve->getVal(hr) - 0.5f) * 2.0f); //get l_r=f(H) float kcc = (CC / 70.f); //take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme @@ -4288,97 +4146,160 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer valparam *= kcc; if(valparam > 0.f) { - l_r = (1.f - valparam) * l_r + valparam * (1.f - SQR(SQR(SQR(SQR(1.f - min(l_r, 1.0f)))))); // SQR (SQR((SQR) to increase action in low light + L = (1.f - valparam) * L + valparam * (1.f - SQR(SQR(SQR(SQR(1.f - min(L, 1.0f)))))); // SQR (SQR((SQR) to increase action in low light } else { - l_r *= (1.f + valparam); //for negative + L *= (1.f + valparam); //for negative } + L *= 32768.f; } - L = l_r * 32768.f; float RR, GG, BB; - float Lr; - Lr = L / 327.68f; //for gamutlch + L /= 327.68f; #ifdef _DEBUG bool neg = false; bool more_rgb = false; //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lr, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(HH, sincosval, L, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lr, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f); + Color::gamutLchonly(HH, sincosval, L, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f); #endif - //convert CH ==> ab - L = Lr * 327.68f; - // float a_,b_; - // a_=0.f;//grey - // b_=0.f;//grey - //convert lab=>rgb - Color::Lab2XYZ(L, 0.f, 0.f, X, Y, Z); - float rr_, gg_, bb_; - Color::xyz2rgb(X, Y, Z, rr_, gg_, bb_, wip); - rtemp[ti * TS + tj] = gtemp[ti * TS + tj] = btemp[ti * TS + tj] = rr_; - // tmpImage->r(i,j) = tmpImage->g(i,j) = tmpImage->b(i,j) = CLIP(val[0]*kcorec); - + L *= 327.68f; + //convert l => rgb + Color::L2XYZ(L, X, Y, Z); + float newRed; // We use the red channel for bw + Color::xyz2r(X, Y, Z, newRed, wip); + rtemp[ti * TS + tj] = gtemp[ti * TS + tj] = btemp[ti * TS + tj] = newRed; +#ifndef __SSE2__ if (hasgammabw) { + //gamma correction: pseudo TRC curve Color::trcGammaBW (rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], gammabwr, gammabwg, gammabwb); } - - //gamma correction: pseudo TRC curve - // if (hasgammabw) - // Color::trcGammaBW (rr_, gg_, bb_, gammabwr, gammabwg, gammabwb); - // rtemp[ti*TS+tj] = rr_; - // gtemp[ti*TS+tj] = gg_; - // btemp[ti*TS+tj] = bb_; +#endif } +#ifdef __SSE2__ + if (hasgammabw) { + //gamma correction: pseudo TRC curve + Color::trcGammaBWRow (&rtemp[ti * TS], >emp[ti * TS], &btemp[ti * TS], tW - jstart, gammabwr, gammabwg, gammabwb); + } +#endif } } } - //Film Simulations - if ( colorLUT ) { + // Film Simulations + if (hald_clut) { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + if (!clutAndWorkingProfilesAreSame) { + // Convert from working to clut profile + int j = jstart; + int tj = 0; + +#ifdef __SSE2__ + + for (; j < tW - 3; j += 4, tj += 4) { + vfloat sourceR = LVF(rtemp[ti * TS + tj]); + vfloat sourceG = LVF(gtemp[ti * TS + tj]); + vfloat sourceB = LVF(btemp[ti * TS + tj]); + + vfloat x; + vfloat y; + vfloat z; + Color::rgbxyz(sourceR, sourceG, sourceB, x, y, z, v_work2xyz); + Color::xyz2rgb(x, y, z, sourceR, sourceG, sourceB, v_xyz2clut); + + STVF(rtemp[ti * TS + tj], sourceR); + STVF(gtemp[ti * TS + tj], sourceG); + STVF(btemp[ti * TS + tj], sourceB); + } + +#endif + + for (; j < tW; j++, tj++) { + float &sourceR = rtemp[ti * TS + tj]; + float &sourceG = gtemp[ti * TS + tj]; + float &sourceB = btemp[ti * TS + tj]; + + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, wprof ); + Color::xyz2rgb(x, y, z, sourceR, sourceG, sourceB, xyz2clut); + } + } + for (int j = jstart, tj = 0; j < tW; j++, tj++) { float &sourceR = rtemp[ti * TS + tj]; float &sourceG = gtemp[ti * TS + tj]; float &sourceB = btemp[ti * TS + tj]; - if (!clutAndWorkingProfilesAreSame) { - //convert from working to clut profile - float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); + // Apply gamma sRGB (default RT) + sourceR = Color::gamma_srgbclipped(sourceR); + sourceG = Color::gamma_srgbclipped(sourceG); + sourceB = Color::gamma_srgbclipped(sourceB); + } + + const std::size_t line_offset = ti * TS; + hald_clut->getRGB( + film_simulation_strength, + std::min(TS, tW - jstart), + rtemp + line_offset, + gtemp + line_offset, + btemp + line_offset, + out_rgbx + ); + + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + float &sourceR = rtemp[ti * TS + tj]; + float &sourceG = gtemp[ti * TS + tj]; + float &sourceB = btemp[ti * TS + tj]; + + // Apply inverse gamma sRGB + sourceR = Color::igamma_srgb(out_rgbx[tj * 4 + 0]); + sourceG = Color::igamma_srgb(out_rgbx[tj * 4 + 1]); + sourceB = Color::igamma_srgb(out_rgbx[tj * 4 + 2]); + } + + if (!clutAndWorkingProfilesAreSame) { + // Convert from clut to working profile + int j = jstart; + int tj = 0; + +#ifdef __SSE2__ + + for (; j < tW - 3; j += 4, tj += 4) { + vfloat sourceR = LVF(rtemp[ti * TS + tj]); + vfloat sourceG = LVF(gtemp[ti * TS + tj]); + vfloat sourceB = LVF(btemp[ti * TS + tj]); + + vfloat x; + vfloat y; + vfloat z; + Color::rgbxyz(sourceR, sourceG, sourceB, x, y, z, v_clut2xyz); + Color::xyz2rgb(x, y, z, sourceR, sourceG, sourceB, v_xyz2work); + + STVF(rtemp[ti * TS + tj], sourceR); + STVF(gtemp[ti * TS + tj], sourceG); + STVF(btemp[ti * TS + tj], sourceB); } - //appply gamma sRGB (default RT) - sourceR = CLIP( Color::gamma_srgb( sourceR ) ); - sourceG = CLIP( Color::gamma_srgb( sourceG ) ); - sourceB = CLIP( Color::gamma_srgb( sourceB ) ); +#endif - float r, g, b; - colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); - // apply strength - sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; - sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; - sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; - // apply inverse gamma sRGB - sourceR = Color::igamma_srgb( sourceR ); - sourceG = Color::igamma_srgb( sourceG ); - sourceB = Color::igamma_srgb( sourceB ); + for (; j < tW; j++, tj++) { + float &sourceR = rtemp[ti * TS + tj]; + float &sourceG = gtemp[ti * TS + tj]; + float &sourceB = btemp[ti * TS + tj]; - if (!clutAndWorkingProfilesAreSame) { - //convert from clut to working profile float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); + Color::rgbxyz(sourceR, sourceG, sourceB, x, y, z, clut2xyz); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, wiprof ); } - } } } - if(!blackwhite) { + if (!blackwhite) { // ready, fill lab for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { @@ -4402,9 +4323,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float fx, fy, fz; - fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF)); - fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF)); - fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF)); + fx = (x < 65535.0f ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF)); + fy = (y < 65535.0f ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF)); + fz = (z < 65535.0f ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF)); lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; lab->a[i][j] = (500.0f * (fx - fy) ); @@ -4467,13 +4388,10 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (algm == 2) { //channel-mixer //end auto chmix - float mix[3][3]; - if (computeMixerAuto) { // auto channel-mixer - #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 5) reduction(+:nr,ng,nb) + #pragma omp parallel for schedule(dynamic, 16) reduction(+:nr,ng,nb) #endif for (int i = 0; i < tH; i++) { @@ -4512,44 +4430,29 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer bwr, bwg, bwb, mixerOrange, mixerYellow, mixerCyan, mixerPurple, mixerMagenta, params->blackwhite.autoc, complem, kcorec, rrm, ggm, bbm); - mix[0][0] = bwr; - mix[1][0] = bwr; - mix[2][0] = bwr; - mix[0][1] = bwg; - mix[1][1] = bwg; - mix[2][1] = bwg; - mix[0][2] = bwb; - mix[1][2] = bwb; - mix[2][2] = bwb; - #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 5) + #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < tH; i++) { - float in[3], val[3]; - for (int j = 0; j < tW; j++) { - in[0] = tmpImage->r(i, j); - in[1] = tmpImage->g(i, j); - in[2] = tmpImage->b(i, j); //mix channel - for (int end = 0; end < 3 ; end++) { - val[end] = 0.f; - - for (int beg = 0; beg < 3 ; beg++) { - val[end] += mix[end][beg] * in[beg]; - } - } - - tmpImage->r(i, j) = tmpImage->g(i, j) = tmpImage->b(i, j) = CLIP(val[0] * kcorec); + tmpImage->r(i, j) = tmpImage->g(i, j) = tmpImage->b(i, j) = CLIP((bwr * tmpImage->r(i, j) + bwg * tmpImage->g(i, j) + bwb * tmpImage->b(i, j)) * kcorec); +#ifndef __SSE2__ //gamma correction: pseudo TRC curve if (hasgammabw) { Color::trcGammaBW (tmpImage->r(i, j), tmpImage->g(i, j), tmpImage->b(i, j), gammabwr, gammabwg, gammabwb); } +#endif } +#ifdef __SSE2__ + if (hasgammabw) { + //gamma correction: pseudo TRC curve + Color::trcGammaBWRow (tmpImage->r(i), tmpImage->g(i), tmpImage->b(i), tW, gammabwr, gammabwg, gammabwb); + } +#endif } } @@ -4560,7 +4463,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { for (int j = 0; j < tW; j++) { - editWhatever->v(i, j) = CLIP(fGammaLUTf[tmpImage->r(i, j)] / 65535.f); // assuming that r=g=b + editWhatever->v(i, j) = Color::gamma2curve[tmpImage->r(i, j)] / 65535.f; // assuming that r=g=b } } } @@ -4852,36 +4755,21 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float fx, fy, fz; - fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF)); - fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF)); - fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF)); - - lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; - lab->a[i][j] = (500.0f * (fx - fy) ); - lab->b[i][j] = (200.0f * (fy - fz) ); - - - //test for color accuracy - /*float fy = (0.00862069 * lab->L[i][j])/327.68 + 0.137932; // (L+16)/116 - float fx = (0.002 * lab->a[i][j])/327.68 + fy; - float fz = fy - (0.005 * lab->b[i][j])/327.68; - - float x_ = 65535*Lab2xyz(fx)*Color::D50x; - float y_ = 65535*Lab2xyz(fy); - float z_ = 65535*Lab2xyz(fz)*Color::D50z; - - int R,G,B; - xyz2srgb(x_,y_,z_,R,G,B); - r=(float)R; g=(float)G; b=(float)B; - float xxx=1;*/ + fx = (x < MAXVALF ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF)); + fy = (y < MAXVALF ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF)); + fz = (z < MAXVALF ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF)); + lab->L[i][j] = 116.0f * fy - 5242.88f; //5242.88=16.0*327.68; + lab->a[i][j] = 500.0f * (fx - fy); + lab->b[i][j] = 200.0f * (fy - fz); } } - if(tmpImage) { - delete tmpImage; - } + } + + if (tmpImage) { + delete tmpImage; } if (hCurveEnabled) { @@ -5014,7 +4902,6 @@ void ImProcFunctions::toningsmh (float r, float g, float b, float &ro, float &go if(s > s_1) ksat=SQR((1.f/(s_1-1.f))*s - (1.f/(s_1-1.f))); } */ - ksat = 1.f; float kl = 1.f; float rlo = 1.f; //0.4 0.5 float rlm = 1.5f; //1.1 @@ -5285,7 +5172,6 @@ void ImProcFunctions::toning2col (float r, float g, float b, float &ro, float &g if(s > s_1) ksat=SQR((1.f/(s_1-1.f))*s - (1.f/(s_1-1.f))); } */ - ksat = 1.f; float kl = 1.f; float rlo = 1.f; float rlh = 2.2f; @@ -5353,7 +5239,6 @@ void ImProcFunctions::toning2col (float r, float g, float b, float &ro, float &g //high tones float kh = 1.f; - kh = 1.f; float aa0, bb0; //fixed value of reducac ==0.4; secondeg_begin (reducac, iphigh, aa0, bb0); @@ -5525,7 +5410,7 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur -SSEFUNCTION 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 &histCLurve, LUTu &histLLCurve, LUTu &histLCurve) +SSEFUNCTION 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) { int W = lold->W; int H = lold->H; @@ -5533,9 +5418,9 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //init Flatcurve for C=f(H) // NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this - Imagefloat* editImgFloat = NULL; - LabImage* editLab = NULL; - PlanarWhateverData* editWhatever = NULL; + Imagefloat* editImgFloat = nullptr; + LabImage* editLab = nullptr; + PlanarWhateverData* editWhatever = nullptr; EditUniqueID editID = EUID_None; bool editPipette = false; @@ -5546,22 +5431,22 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu editPipette = true; switch (pipetteBuffer->getDataProvider()->getCurrSubscriber()->getPipetteBufferType()) { - case (BT_IMAGEFLOAT): - editImgFloat = pipetteBuffer->getImgFloatBuffer(); - break; + case (BT_IMAGEFLOAT): + editImgFloat = pipetteBuffer->getImgFloatBuffer(); + break; - case (BT_LABIMAGE): - editLab = pipetteBuffer->getLabBuffer(); - break; + case (BT_LABIMAGE): + editLab = pipetteBuffer->getLabBuffer(); + break; - case (BT_SINGLEPLANE_FLOAT): - editWhatever = pipetteBuffer->getSinglePlaneBuffer(); - break; + case (BT_SINGLEPLANE_FLOAT): + editWhatever = pipetteBuffer->getSinglePlaneBuffer(); + break; } } } - FlatCurve* chCurve = NULL;// curve C=f(H) + FlatCurve* chCurve = nullptr;// curve C=f(H) bool chutili = false; if (params->labCurve.chromaticity > -100) { @@ -5570,7 +5455,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu if (!chCurve || chCurve->isIdentity()) { if (chCurve) { delete chCurve; - chCurve = NULL; + chCurve = nullptr; } }//do not use "Munsell" if Chcurve not used else { @@ -5578,7 +5463,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } - FlatCurve* lhCurve = NULL;//curve L=f(H) + FlatCurve* lhCurve = nullptr;//curve L=f(H) bool lhutili = false; if (params->labCurve.chromaticity > -100) { @@ -5587,7 +5472,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu if (!lhCurve || lhCurve->isIdentity()) { if (lhCurve) { delete lhCurve; - lhCurve = NULL; + lhCurve = nullptr; } }//do not use "Munsell" if Chcurve not used else { @@ -5595,7 +5480,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } - FlatCurve* hhCurve = NULL;//curve H=f(H) + FlatCurve* hhCurve = nullptr;//curve H=f(H) bool hhutili = false; if (params->labCurve.chromaticity > -100) { @@ -5604,7 +5489,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu if (!hhCurve || hhCurve->isIdentity()) { if (hhCurve) { delete hhCurve; - hhCurve = NULL; + hhCurve = nullptr; } }//do not use "Munsell" if Chcurve not used else { @@ -5612,31 +5497,15 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } - LUTf dCcurve; - LUTf dLcurve; LUTu hist16Clad; LUTu hist16Llad; //preparate for histograms CIECAM if(pW != 1) { //only with improccoordinator - dCcurve(48000, 0); - dLcurve(65536, 0); hist16Clad(65536); - hist16Llad(65536); - float val; - - for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma - val = (double)i / 47999.0; - dCcurve[i] = CLIPD(val); - } - - for (int i = 0; i < 65535; i++) { // a - val = (double)i / 65534.0; - dLcurve[i] = CLIPD(val); - } - hist16Clad.clear(); + hist16Llad(65536); hist16Llad.clear(); } @@ -5674,7 +5543,10 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu const int chromaticity = params->labCurve.chromaticity; const float chromapro = (chromaticity + 100.0f) / 100.0f; const bool bwonly = params->blackwhite.enabled && !params->colorToning.enabled; - const bool bwToning = params->labCurve.chromaticity == - 100 /*|| params->blackwhite.method=="Ch" || params->blackwhite.enabled */ || bwonly; + bool bwq = false; +// if(params->ppVersion > 300 && params->labCurve.chromaticity == - 100) bwq = true; + // const bool bwToning = params->labCurve.chromaticity == - 100 /*|| params->blackwhite.method=="Ch" || params->blackwhite.enabled */ || bwonly; + const bool bwToning = bwq /*|| params->blackwhite.method=="Ch" || params->blackwhite.enabled */ || bwonly; //if(chromaticity==-100) chromaticity==-99; const bool LCredsk = params->labCurve.lcredsk; const bool ccut = ccutili; @@ -6132,7 +6004,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //update histogram C if(pW != 1) { //only with improccoordinator - int posp = CLIP((int)sqrt((atmp * atmp + btmp * btmp))); + int posp = (int)sqrt(atmp * atmp + btmp * btmp); hist16Clad[posp]++; } @@ -6188,7 +6060,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //update histo LC if(pW != 1) { //only with improccoordinator - int posl = CLIP((int(Lprov1 * 327.68f))); + int posl = Lprov1 * 327.68f; hist16Llad[posl]++; } @@ -6276,20 +6148,11 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } // end of parallelization - //update histogram C with data chromaticity and not with CC curve if(pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { //32768*1.414 + ... - float hval = dCcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); // - histCCurve[hi] += hist16Clad[i] ; - } - - //update histogram L with data luminance - for (int i = 0; i < 65535; i++) { - float hlval = dLcurve[i]; - int hli = (int)(255.0 * CLIPD(hlval)); - histLCurve[hli] += hist16Llad[i] ; - } + //update histogram C with data chromaticity and not with CC curve + hist16Clad.compressTo(histCCurve); + //update histogram L with data luminance + hist16Llad.compressTo(histLCurve); } #ifdef _DEBUG @@ -6690,15 +6553,15 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) #pragma omp parallel for // removed schedule(dynamic,10) #endif - for(int ii = 0; ii < N; ii++) - a[ii] *= s, - b[ii] *= s, - //L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL; - L[ii] = L[ii] * maxL * (1.f / gamm) + minL; + for(int ii = 0; ii < N; ii++) { + a[ii] *= s; + b[ii] *= s; + L[ii] = L[ii] * maxL * (1.f / gamm) + minL; + } } -void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, +void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh) { @@ -6711,12 +6574,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga float ave = 0.f, hidev = 0.f, lodev = 0.f; //find average luminance - for (int i = 0; i < imax; i++) { - sum += histogram[i]; - ave += histogram[i] * (float)i; - } - - ave /= (sum); + histogram.getSumAndAverage(sum, ave); //find median of luminance int median = 0, count = histogram[0]; @@ -6741,25 +6599,37 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga float octile[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}, ospread = 0.f; count = 0; - for (int i = 0; i < imax; i++) { + int i = 0; + + for (; i < min((int)ave, imax); i++) { if (count < 8) { octile[count] += histogram[i]; if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { - octile[count] = log(1. + (float)i) / log(2.f); + octile[count] = xlog(1. + (float)i) / log(2.f); count++;// = min(count+1,7); } } - if (i < ave) { - //lodev += SQR(ave-i)*histogram[i]; - lodev += (log(ave + 1.f) - log((float)i + 1.)) * histogram[i]; - losum += histogram[i]; - } else { - //hidev += SQR(i-ave)*histogram[i]; - hidev += (log((float)i + 1.) - log(ave + 1.f)) * histogram[i]; - hisum += histogram[i]; + //lodev += SQR(ave-i)*histogram[i]; + lodev += (xlog(ave + 1.f) - xlog((float)i + 1.)) * histogram[i]; + losum += histogram[i]; + } + + for (; i < imax; i++) { + if (count < 8) { + octile[count] += histogram[i]; + + if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { + octile[count] = xlog(1. + (float)i) / 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]; + } if (losum == 0 || hisum == 0) { //probably the image is a blackframe @@ -6822,7 +6692,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga int clipped = 0; int rawmax = (imax) - 1; - while (rawmax > 1 && histogram[rawmax] + clipped <= 0) { + while (histogram[rawmax] + clipped <= 0 && rawmax > 1) { clipped += histogram[rawmax]; rawmax--; } @@ -6914,12 +6784,18 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga //take gamma into account double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0); - double gavg = 0.; + float gavg = 0.; - for (int i = 0; i<65536 >> histcompr; i++) { - gavg += histogram[i] * CurveFactory::gamma2((float)(corr * (i << histcompr) < 65535 ? corr * (i << histcompr) : 65535)) / sum; + float val = 0.f; + float increment = corr * (1 << histcompr); + + for (int i = 0; i < 65536 >> histcompr; i++) { + gavg += histogram[i] * Color::gamma2curve[val]; + val += increment; } + gavg /= sum; + if (black < gavg) { int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4 @@ -6988,6 +6864,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga } bright = max(-100, min(bright, 100)); + } @@ -7002,13 +6879,13 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, w_thumb, h_thumb, 1, FALSE); - if (thumb == NULL) { + if (!thumb) { return 0.0; } Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, w_raw, h_raw, 1, 1.0, FALSE); - if (raw == NULL) { + if (!raw) { delete thumb; return 0.0; } @@ -7032,7 +6909,7 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si thumbGray = thumb->getGrayscaleHistEQ (width); rawGray = raw->getGrayscaleHistEQ (width); - if (thumbGray == NULL || rawGray == NULL) { + if (!thumbGray || !rawGray) { if (thumbGray) { delete thumbGray; } @@ -7108,6 +6985,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, wipv[i][j] = F2V(wiprof[i][j]); } } + #endif #ifdef _OPENMP @@ -7117,9 +6995,10 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, for(int i = 0; i < H; i++) { int j = 0; #ifdef __SSE2__ + for(; j < W - 3; j += 4) { vfloat X, Y, Z; - vfloat R,G,B; + vfloat R, G, B; Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z); Color::xyz2rgb(X, Y, Z, R, G, B, wipv); STVFU(dst.r(i, j), R); @@ -7128,6 +7007,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, } #endif + for(; j < W; j++) { float X, Y, Z; Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d67256a63..acecc9c1e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -35,20 +35,6 @@ #include "cplx_wavelet_dec.h" #include "pipettebuffer.h" -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - - namespace rtengine { @@ -75,7 +61,6 @@ class ImProcFunctions void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, int W, int H, const SharpeningParams &sharpenParam); void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam); void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H); - void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to); void dcdamping (float** aI, float** aO, float damping, int W, int H); bool needsCA (); @@ -199,6 +184,14 @@ class ImProcFunctions public: + enum class Median { + TYPE_3X3_SOFT, + TYPE_3X3_STRONG, + TYPE_5X5_SOFT, + TYPE_5X5_STRONG, + TYPE_7X7, + TYPE_9X9 + }; double lumimul[3]; // float chau; @@ -229,15 +222,15 @@ public: bool needsTransform (); bool needsPCVignetting (); - void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void firstAnalysis (const Imagefloat* const working, const ProcParams ¶ms, LUTu & vhist16); void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, - const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); + const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn ); void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, - double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf); + double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn ); 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 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, int preser, float strProtect); @@ -255,7 +248,7 @@ public: void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const 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, double &d, int scalecd, int rtt); - 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 &histCLurve, LUTu &histLCurve, LUTu &histLurve); + 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 vibrance (LabImage* lab);//Jacques' vibrance void colorCurve (LabImage* lold, LabImage* lnew); void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam); @@ -293,7 +286,6 @@ public: // pyramid denoise procparams::DirPyrDenoiseParams dnparams; - void dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams );//Emil's directional pyramid denoise void dirpyr (LabImage* data_fine, LabImage* data_coarse, int level, LUTf &rangefn_L, LUTf &rangefn_ab, int pitch, int scale, const int luma, int chroma ); void idirpyr (LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, @@ -326,13 +318,12 @@ public: - enum mediantype {MED_3X3SOFT, MED_3X3STRONG, MED_5X5SOFT, MED_5X5STRONG, MED_7X7, MED_9X9}; - void Median_Denoise( float **src, float **dst, int width, int height, mediantype medianType, int iterations, int numThreads, float **buffer = NULL); - 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 & ctNoisCurve , const NoiseCurve & ctNoisCCcurve , float &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &nresi, float &highresi); + void Median_Denoise( float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = NULL); + 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 &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, 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 * calclum, 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 &nresi, float &highresi, 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_L, float * nbrwt, float * blurbuffer ); //for DCT - void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); + 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 &nresi, float &highresi, 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 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, @@ -342,7 +333,7 @@ public: 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, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madaL, float * vari, int edge); + 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, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level, @@ -350,7 +341,7 @@ public: float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread); void Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); void calcautodn_info (float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); - float MadMax(float * HH_Coeffs, int &max, int datalen); + float MadMax(float * DataList, int &max, int datalen); float Mad(float * DataList, const int datalen); float MadRgb(float * DataList, const int datalen); @@ -380,7 +371,7 @@ public: bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); bool transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); - static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); + static void getAutoExp (const LUTu & histogram, int histcompr, double defgain, 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 LCPMapper *pLCPMap = NULL); void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); diff --git a/rtengine/init.cc b/rtengine/init.cc index d2509b620..3b2c5fbdc 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -42,7 +42,7 @@ int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDi settings = s; iccStore->init (s->iccDirectory, baseDir + "/iccprofiles"); iccStore->findDefaultMonitorProfile(); - dcpStore->init (baseDir + "/dcpprofiles"); + DCPStore::getInstance()->init (baseDir + "/dcpprofiles"); CameraConstantsStore::getInstance ()->init (baseDir, userSettingsDir); profileStore.init (); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 4510044aa..4c2da72a4 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -77,9 +77,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) cmsDoTransform (monitorTransform, buffer, data + ix, W); } } - } // End of parallelization - } else { int W = lab->W; @@ -90,36 +88,28 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int i = 0; i < H; i++) { + for (int i = 0; i < H; ++i) { float* rL = lab->L[i]; float* ra = lab->a[i]; float* rb = lab->b[i]; int ix = i * 3 * W; float R, G, B; - float fy, fx, fz, x_, y_, z_, LL; + float x_, y_, z_; - for (int j = 0; j < W; j++) { + for (int j = 0; j < W; ++j) { //float L1=rL[j],a1=ra[j],b1=rb[j];//for testing - fy = (0.00862069 * rL[j]) / 327.68 + 0.137932; // (L+16)/116 - fx = (0.002 * ra[j]) / 327.68 + fy; - fz = fy - (0.005 * rb[j]) / 327.68; - LL = rL[j] / 327.68; - - x_ = 65535.0 * Color::f2xyz(fx) * Color::D50x; - // y_ = 65535.0 * Color::f2xyz(fy); - z_ = 65535.0 * Color::f2xyz(fz) * Color::D50z; - y_ = (LL > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * LL / Color::kappa; + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_ ); Color::xyz2srgb(x_, y_, z_, R, G, B); /* copy RGB */ //int R1=((int)gamma2curve[(R)]) - data[ix++] = ((int)Color::gamma2curve[CLIP(R)]) >> 8; - data[ix++] = ((int)Color::gamma2curve[CLIP(G)]) >> 8; - data[ix++] = ((int)Color::gamma2curve[CLIP(B)]) >> 8; + data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[R]); + data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[G]); + data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[B]); } } } @@ -127,7 +117,6 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma) { - //gamutmap(lab); if (cx < 0) { cx = 0; @@ -202,36 +191,29 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, } } else { - const auto rgb_xyz = iccStore->workingSpaceMatrix (profile); + const auto xyz_rgb = iccStore->workingSpaceInverseMatrix (profile); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int i = cy; i < cy + ch; i++) { - float R, G, B; + for (int i = cy; i < cy + ch; ++i) { float* rL = lab->L[i]; float* ra = lab->a[i]; float* rb = lab->b[i]; int ix = 3 * i * cw; - for (int j = cx; j < cx + cw; j++) { + float R, G, B; + float x_, y_, z_; - float fy = (0.00862069 * rL[j]) / 327.68 + 0.137932; // (L+16)/116 - float fx = (0.002 * ra[j]) / 327.68 + fy; - float fz = fy - (0.005 * rb[j]) / 327.68; - float LL = rL[j] / 327.68; + for (int j = cx; j < cx + cw; ++j) { + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); - float x_ = 65535.0 * Color::f2xyz(fx) * Color::D50x; - //float y_ = 65535.0 * Color::f2xyz(fy); - float z_ = 65535.0 * Color::f2xyz(fz) * Color::D50z; - float y_ = (LL > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * LL / Color::kappa; + Color::xyz2rgb(x_, y_, z_, R, G, B, xyz_rgb); - Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyz); - - image->data[ix++] = (int)Color::gamma2curve[CLIP(R)] >> 8; - image->data[ix++] = (int)Color::gamma2curve[CLIP(G)] >> 8; - image->data[ix++] = (int)Color::gamma2curve[CLIP(B)] >> 8; + image->data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[R]); + image->data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[G]); + image->data[ix++] = uint16ToUint8Rounded(Color::gamma2curve[B]); } } } @@ -242,8 +224,6 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw) { - //gamutmap(lab); - if (cx < 0) { cx = 0; } @@ -263,10 +243,10 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int Image16* image = new Image16 (cw, ch); cmsHPROFILE oprof = iccStore->getProfile (profile); - - if (oprof) { +#ifdef _OPENMP #pragma omp parallel for if (multiThread) +#endif for (int i = cy; i < cy + ch; i++) { float* rL = lab->L[i]; @@ -277,26 +257,17 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int short* za = (short*)image->b(i - cy); for (int j = cx; j < cx + cw; j++) { + float x_, y_, z_; + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); - float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116 - float fx = (0.002 * ra[j]) / 327.68f + fy; - float fz = fy - (0.005f * rb[j]) / 327.68f; - float LL = rL[j] / 327.68f; - - float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x; - //float y_ = 65535.0 * Color::f2xyz(fy); - float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z; - float y_ = (LL > Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / Color::kappa; - - xa[j - cx] = CLIP((int) round(x_)); - ya[j - cx] = CLIP((int) round(y_)); - za[j - cx] = CLIP((int) round(z_)); + xa[j - cx] = float2uint16range(x_); + ya[j - cx] = float2uint16range(y_); + za[j - cx] = float2uint16range(z_); if(bw && y_ < 65535.f ) { //force Bw value and take highlight into account - xa[j - cx] = (int) round(y_ * Color::D50x ); - za[j - cx] = (int) round(y_ * Color::D50z); + xa[j - cx] = float2uint16range(y_ * Color::D50x); + za[j - cx] = float2uint16range(y_ * Color::D50z); } - } } @@ -309,7 +280,9 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsDeleteTransform(hTransform); } else { +#ifdef _OPENMP #pragma omp parallel for if (multiThread) +#endif for (int i = cy; i < cy + ch; i++) { float R, G, B; @@ -346,8 +319,6 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { - //gamutmap(lab); - if (cx < 0) { cx = 0; } @@ -429,6 +400,14 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int p5 = 0.1300; p6 = 0.0350; select_temp = 1; + } else if (profi == "Rec2020") { + p1 = 0.7080; // Rec2020 primaries + p2 = 0.2920; + p3 = 0.1700; + p4 = 0.7970; + p5 = 0.1310; + p6 = 0.0460; + select_temp = 2; } else { p1 = 0.7347; //ProPhoto and default primaries p2 = 0.2653; @@ -498,20 +477,18 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 ga4 = g_a3 * ts; - //printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); ga0 = gampos; ga1 = 1. / (1.0 + g_a4); ga2 = g_a4 / (1.0 + g_a4); ga3 = 1. / slpos; ga5 = 0.0; - //printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0,ga1,ga2,ga3,ga4); } if(select_temp == 1) { t50 = 5003; // for Widegamut, Prophoto Best, Beta D50 } else if (select_temp == 2) { - t50 = 6504; // for sRGB, AdobeRGB, Bruce D65 + t50 = 6504; // for sRGB, AdobeRGB, Bruce Rec2020 D65 } cmsCIExyY xyD; @@ -531,13 +508,14 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int // 7 parameters for smoother curves cmsWhitePointFromTemp(&xyD, t50); GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4 - cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile + cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC); //oprofdef becomes Outputprofile cmsFreeToneCurve(GammaTRC[0]); - if (oprofdef) { +#ifdef _OPENMP #pragma omp parallel for if (multiThread) +#endif for (int i = cy; i < cy + ch; i++) { float* rL = lab->L[i]; @@ -548,39 +526,32 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int short* za = (short*)image->b(i - cy); for (int j = cx; j < cx + cw; j++) { + float x_, y_, z_; + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); - float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116 - float fx = (0.002f * ra[j]) / 327.68f + fy; - float fz = fy - (0.005f * rb[j]) / 327.68f; - float LL = rL[j] / 327.68f; - - float x_ = 65535.0f * (float)Color::f2xyz(fx) * Color::D50x; - // float y_ = 65535.0 * Color::f2xyz(fy); - float z_ = 65535.0f * (float)Color::f2xyz(fz) * Color::D50z; - float y_ = (LL > Color::epskap) ? (float) 65535.0 * fy * fy * fy : 65535.0f * LL / Color::kappa; - - xa[j - cx] = CLIP((int) round(x_)) ; - ya[j - cx] = CLIP((int) round(y_)); - za[j - cx] = CLIP((int) round(z_)); + xa[j - cx] = float2uint16range(x_); + ya[j - cx] = float2uint16range(y_); + za[j - cx] = float2uint16range(z_); if(bw && y_ < 65535.f) { //force Bw value and take highlight into account - xa[j - cx] = (int) round(y_ * Color::D50x); - za[j - cx] = (int) round(y_ * Color::D50z); + xa[j - cx] = float2uint16range(y_ * Color::D50x); + za[j - cx] = float2uint16range(y_ * Color::D50z); } - } } cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); cmsDeleteTransform(hTransform); } else { - // +#ifdef _OPENMP #pragma omp parallel for if (multiThread) +#endif + for (int i = cy; i < cy + ch; i++) { float R, G, B; float* rL = lab->L[i]; @@ -611,6 +582,4 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int return image; } -//#include "sRGBgamutbdy.cc" - } diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 1cd1d56e1..06f779875 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -36,38 +36,22 @@ */ -#include -#include -#include -#include +#include +#include +#include +#include #include "rtengine.h" #include "gauss.h" #include "rawimagesource.h" #include "improcfun.h" #include "opthelper.h" -//#define BENCHMARK +#include "median.h" #include "StopWatch.h" -#define MAX_RETINEX_SCALES 8 #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - -namespace rtengine +namespace { - -extern const Settings* settings; - -static float RetinexScales[MAX_RETINEX_SCALES]; - void retinex_scales( float* scales, int nscales, int mode, int s, float high) { if ( nscales == 1 ) { @@ -103,6 +87,7 @@ void retinex_scales( float* scales, int nscales, int mode, int s, float high) } } } + void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, float &maxtr, float &mintr) { // summation using double precision to avoid too large summation error for large pictures @@ -124,14 +109,8 @@ void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, floa sum += dst[i][j]; vsquared += (dst[i][j] * dst[i][j]); - if ( dst[i][j] > lmax) { - lmax = dst[i][j] ; - } - - if ( dst[i][j] < lmin) { - lmin = dst[i][j] ; - } - + lmax = dst[i][j] > lmax ? dst[i][j] : lmax; + lmin = dst[i][j] < lmin ? dst[i][j] : lmin; } #ifdef _OPENMP @@ -149,82 +128,30 @@ void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, floa stddv = (float)sqrt(stddv); } - - - - - -void mean_stddv( float **dst, float &mean, float &stddv, int W_L, int H_L, const float factor, float &maxtr, float &mintr) - -{ - // summation using double precision to avoid too large summation error for large pictures - double vsquared = 0.f; - double sum = 0.f; - maxtr = 0.f; - mintr = 0.f; -#ifdef _OPENMP - #pragma omp parallel -#endif - { - float lmax = 0.f, lmin = 0.f; - -#ifdef _OPENMP - #pragma omp for reduction(+:sum,vsquared) // this can lead to differences, but parallel summation is more accurate -#endif - - for (int i = 0; i < H_L; i++ ) - for (int j = 0; j < W_L; j++) { - sum += dst[i][j]; - vsquared += (dst[i][j] * dst[i][j]); - - if ( dst[i][j] > lmax) { - lmax = dst[i][j] ; - } - - if ( dst[i][j] < lmin) { - lmin = dst[i][j] ; - } - - } - -#ifdef _OPENMP - #pragma omp critical -#endif - { - maxtr = maxtr > lmax ? maxtr : lmax; - mintr = mintr < lmin ? mintr : lmin; - } - - } - - sum *= factor; - maxtr *= factor; - mintr *= factor; - vsquared *= (factor * factor); - mean = sum / (float) (W_L * H_L); - vsquared /= (float) W_L * H_L; - stddv = ( vsquared - (mean * mean) ); - stddv = (float)sqrt(stddv); } -void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) + +namespace rtengine +{ + +extern const Settings* settings; + +void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, 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) {//enabled float mean, stddv, maxtr, mintr; - //float mini, delta, maxi; float delta; - float eps = 2.f; + constexpr float eps = 2.f; bool useHsl = deh.retinexcolorspace == "HSLLOG"; bool useHslLin = deh.retinexcolorspace == "HSLLIN"; float gain2 = (float) deh.gain / 100.f; //def =1 not use gain2 = useHslLin ? gain2 * 0.5f : gain2; float offse = (float) deh.offs; //def = 0 not use int iter = deh.iter; - int gradient = deh.scal; + int gradient = deh.scal; int scal = 3;//disabled scal - int nei = (int) 2.8f * deh.neigh; //def = 220 + 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; @@ -233,11 +160,10 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e limD = pow(limD, 1.7f);//about 2500 enough limD *= useHslLin ? 10.f : 1.f; float ilimD = 1.f / limD; - int moderetinex = 2; // default to 2 ( deh.retinexMethod == "high" ) float hig = ((float) deh.highl) / 100.f; - bool higplus = false ; float elogt; float hl = deh.baselog; + scal = deh.skal; if(hl >= 2.71828f) { elogt = 2.71828f + SQR(SQR(hl - 2.71828f)); @@ -249,52 +175,45 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e int W_L = width; float *tran[H_L] ALIGNED16; - float *tranBuffer; - int viewmet = 0; + float *tranBuffer = nullptr; elogt = 2.71828f;//disabled baselog - FlatCurve* shcurve = NULL;//curve L=f(H) bool lhutili = false; - if (deh.enabled) { - shcurve = new FlatCurve(deh.lhcurve); + FlatCurve* shcurve = new FlatCurve(deh.lhcurve); //curve L=f(H) - if (!shcurve || shcurve->isIdentity()) { - if (shcurve) { - delete shcurve; - shcurve = NULL; - } - } 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" ) + if(deh.retinexMethod == "highliplus") { higplus = true; - } - - if (deh.retinexMethod == "uni") { + moderetinex = 3; + } else if (deh.retinexMethod == "uni") { moderetinex = 0; - } - - if (deh.retinexMethod == "low") { + } else if (deh.retinexMethod == "low") { moderetinex = 1; - } - - if (deh.retinexMethod == "highli" || deh.retinexMethod == "highliplus") { + } else { /*if (deh.retinexMethod == "highli") */ moderetinex = 3; } - for(int it = 1; it < iter + 1; it++) { //iter nb max of iterations - float aahi = 49.f / 99.f; ////reduce sensibility 50% - float bbhi = 1.f - aahi; - float high; - high = bbhi + aahi * (float) deh.highl; + constexpr float aahi = 49.f / 99.f; ////reduce sensibility 50% + constexpr float bbhi = 1.f - aahi; + + for(int it = 1; it < iter + 1; it++) { //iter nb max of iterations + float high = bbhi + aahi * (float) deh.highl; - float grads; float grad = 1.f; - float sc = 3.f; + float sc = scal; if(gradient == 0) { grad = 1.f; @@ -338,6 +257,23 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e 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; + } + } + + if(scal > 4) { + sc += 1; + } + } + float varx; float limdx, ilimdx; @@ -366,7 +302,6 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } scal = round(sc); - float strengthx; float ks = 1.f; if(gradstr != 0) { @@ -397,7 +332,10 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } - strengthx = ks * strength; + float strengthx = ks * strength; + + constexpr auto maxRetinexScales = 8; + float RetinexScales[maxRetinexScales]; retinex_scales( RetinexScales, scal, moderetinex, nei / grad, high ); @@ -412,39 +350,28 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e int shHighlights = deh.highlights; int shShadows = deh.shadows; + int mapmet = 0; if(deh.mapMethod == "map") { mapmet = 2; - } - - if(deh.mapMethod == "mapT") { + } else if(deh.mapMethod == "mapT") { mapmet = 3; - } - - /*if(deh.mapMethod == "curv") { - mapmet = 1; - }*/ - - if(deh.mapMethod == "gaus") { + } 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; - } - - if(deh.viewMethod == "tran") { + } else if(deh.viewMethod == "tran") { viewmet = 2; - } - - if(deh.viewMethod == "tran2") { + } else if(deh.viewMethod == "tran2") { viewmet = 3; - } - - if(deh.viewMethod == "unsharp") { + } else if(deh.viewMethod == "unsharp") { viewmet = 4; } @@ -538,6 +465,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e #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 #ifdef _OPENMP #pragma omp parallel for #endif @@ -551,21 +484,21 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } 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; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic,16) #endif for (int i = 0; i < H_L; i++) { for (int j = 0; j < W_L; j++) { - double mapval = 1.0 + shmap->map[i][j]; - double factor = 1.0; + float mapval = 1.f + shmap->map[i][j]; + float factor = 1.f; if (mapval > h_th) { - factor = (h_th + (100.0 - shHighlights) * (mapval - h_th) / 100.0) / mapval; + factor = (h_th + hWeight * (mapval - h_th)) / mapval; } else if (mapval < s_th) { - factor = (s_th - (100.0 - shShadows) * (s_th - mapval) / 100.0) / mapval; + factor = (s_th - sWeight * (s_th - mapval)) / mapval; } out[i][j] *= factor; @@ -613,10 +546,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } - shmap = NULL; + shmap = nullptr; delete [] buffer; - //delete [] outBuffer; delete [] srcBuffer; mean = 0.f; @@ -641,6 +573,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e bmax *= 500.f; amin *= 500.f; bmin *= 500.f; + #ifdef _OPENMP #pragma omp parallel #endif @@ -660,6 +593,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e 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) { @@ -685,10 +619,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e #endif for (int i = borderL; i < hei - borderL; i++) { - float pp[9], temp; - for (int j = borderL; j < wid - borderL; j++) { - med3(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], tmL[i][j]); //3x3 + 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 } } @@ -733,7 +665,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e delta = 1.0f; } - float cdfactor = gain2 * 32768.f / delta; + // float cdfactor = gain2 * 32768.f / delta; + float cdfactor = 32768.f / delta; maxCD = -9999999.f; minCD = 9999999.f; // coeff for auto "transmission" with 2 sigma #95% datas @@ -742,34 +675,80 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e float bza = 16300.f / (2.f * stddv); float bzb = 16300.f - bza * (mean); +//prepare work for curve gain +#ifdef _OPENMP + #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; + } + } + + 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, bsig, amax, bmax, amin, bmin; + + 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; + } #ifdef _OPENMP #pragma omp parallel #endif { float cdmax = -999999.f, cdmin = 999999.f; - #ifdef _OPENMP - #pragma omp for + #pragma omp for schedule(dynamic,16) nowait #endif for ( int i = 0; i < H_L; i ++ ) for (int j = 0; j < W_L; j++) { - //float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse; - float cd = cdfactor * ( luminance[i][j] - mini ) + offse; + float gan; - if(cd > cdmax) { - cdmax = cd; + 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; } - if(cd < cdmin) { - cdmin = cd; - } + 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) + if(lhutili && it == 1) { // S=f(H) { float HH = exLuminance[i][j]; float valparam; @@ -784,31 +763,23 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } - if(exLuminance[i][j] > 65535.f * hig && higplus) { + if(higplus && exLuminance[i][j] > 65535.f * hig) { str *= hig; } if(viewmet == 0) { - luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; - } - - if(viewmet == 1) { + luminance[i][j] = intp(str, clipretinex( cd, 0.f, 32768.f ), originalLuminance[i][j]); + } else if(viewmet == 1) { luminance[i][j] = out[i][j]; - } - - if(viewmet == 4) { - luminance[i][j] = (1.f + str) * originalLuminance[i][j] - str * out[i][j]; //unsharp - } - - if(viewmet == 2) { + } 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]; } - } - - if(viewmet == 3) { + } 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 } @@ -823,23 +794,23 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } + delete [] outBuffer; - outBuffer = NULL; + outBuffer = nullptr; //printf("cdmin=%f cdmax=%f\n",minCD, maxCD); Tmean = mean; Tsigma = stddv; Tmin = mintr; Tmax = maxtr; - - if (shcurve && it == 1) { + if (shcurve) { delete shcurve; + shcurve = nullptr; } } - if(viewmet == 3 || viewmet == 2) { + if(tranBuffer) { delete [] tranBuffer; - tranBuffer = NULL; } } diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index 3e6ff97f2..1d152c737 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -59,9 +59,7 @@ void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve) outCurve[i] = 65535.f * diagCurve->getVal( double(i) / 65535.0 ); } } else { - for (int i = 0; i <= 0xffff; i++) { - outCurve[i] = float(i); - } + outCurve.makeIdentity(); } } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 4e433b453..d5aa54890 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -37,6 +37,7 @@ #include "mytime.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" #include "EdgePreservingDecomposition.h" #ifdef _OPENMP @@ -50,26 +51,6 @@ #define fTS ((TS/2+1)) // second dimension of Fourier tiles #define blkrad 1 // radius of block averaging -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - - #define epsilon 0.001f/(TS*TS) //tolerance @@ -574,15 +555,8 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int realtile = 12; } - int tilesize; - int overlap; - tilesize = 1024; - overlap = 128; - //tilesize=128*params->wavelet.tiles; - tilesize = 128 * realtile; - //overlap=(int) tilesize*params->wavelet.overl; - overlap = (int) tilesize * 0.125f; - // printf("overl=%d\n",overlap); + int tilesize = 128 * realtile; + int overlap = (int) tilesize * 0.125f; int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; if(params->wavelet.Tilesmethod == "full") { @@ -827,11 +801,9 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int #endif for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - for (int j = 1; j < wid - 1; j++) { if((varhue[i][j] < -1.3f && varhue[i][j] > - 2.5f) && (varchro[i][j] > 15.f && varchro[i][j] < 55.f) && labco->L[i][j] > 6000.f) { //blue sky + med3x3 ==> after for more effect use denoise - med3(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1], tmL[i][j]); //3x3 + tmL[i][j] = median(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1]); //3x3 } } } @@ -1828,8 +1800,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float maxkoeLi[12]; float *koeLibuffer = NULL; - bool lipschitz = false; - lipschitz = true; + bool lipschitz = true; if(lipschitz == true) { for(int y = 0; y < 12; y++) { @@ -2782,7 +2753,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit if (cp.reinforce == 3) { if(rad < lim0 / 60.f && level == 0) { - expkoef *= repart; //reduce effect for low values of rad and level=0==> quasi only level 1 is effective + expkoef *= abs(repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective } } @@ -3262,8 +3233,6 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit int ii = i / W_L; int jj = i - ii * W_L; float LL100 = labco->L[ii * 2][jj * 2] / 327.68f; - k1 = 600.f; - k2 = 300.f; k1 = 0.3f * (waOpacityCurveW[6.f * LL100] - 0.5f); //k1 between 0 and 0.5 0.5==> 1/6=0.16 k2 = k1 * 2.f; @@ -3525,8 +3494,6 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, int ii = i / W_ab; int jj = i - ii * W_ab; float LL100 = labco->L[ii * 2][jj * 2] / 327.68f; - k1 = 600.f; - k2 = 300.f; k1 = 0.3f * (waOpacityCurveW[6.f * LL100] - 0.5f); //k1 between 0 and 0.5 0.5==> 1/6=0.16 k2 = k1 * 2.f; diff --git a/rtengine/jdatasrc.cc b/rtengine/jdatasrc.cc index c8567387b..ff509301d 100644 --- a/rtengine/jdatasrc.cc +++ b/rtengine/jdatasrc.cc @@ -32,6 +32,8 @@ /* Expanded data source object for stdio input */ +namespace +{ typedef struct { struct jpeg_source_mgr pub; /* public fields */ @@ -44,6 +46,8 @@ typedef struct { typedef my_source_mgr * my_src_ptr; +} + #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ diff --git a/rtengine/jpeg_memsrc.cc b/rtengine/jpeg_memsrc.cc index 75a0b25bc..ab4ecf7d6 100644 --- a/rtengine/jpeg_memsrc.cc +++ b/rtengine/jpeg_memsrc.cc @@ -26,6 +26,8 @@ /* Expanded data source object for memory input */ +namespace +{ typedef struct { struct jpeg_source_mgr pub; /* public fields */ @@ -36,6 +38,7 @@ typedef struct { typedef my_source_mgr * my_src_ptr; +} /* * Initialize source --- called by jpeg_read_header diff --git a/rtengine/median.h b/rtengine/median.h index d5e88d9de..d7a6b37de 100644 --- a/rtengine/median.h +++ b/rtengine/median.h @@ -15,96 +15,6277 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . + * + * These median implementations from Flössie and Ingo Weyrich are inspired by this work: + * + * http://ndevilla.free.fr/median/median.pdf + * http://pages.ripco.net/~jgamble/nw.html + * https://github.com/hoytech/Algorithm-Networksort-Chooser + * + * Instead of using the PIX_SORT and PIX_SWAP macros we use std::min() and std::max() + * because it turned out that it generates much faster (branch free) code on machines which support SSE + * */ -#include "rt_math.h" -// middle 4 of 6 elements, -#define MIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \ -{\ -d1 = min(s1,s2);\ -d2 = max(s1,s2);\ -d0 = min(s0,d2);\ -d2 = max(s0,d2);\ -temp = min(d0,d1);\ -d1 = max(d0,d1);\ -d0 = temp;\ -d4 = min(s4,s5);\ -d5 = max(s4,s5);\ -d3 = min(s3,d5);\ -d5 = max(s3,d5);\ -temp = min(d3,d4);\ -d4 = max(d3,d4);\ -d3 = max(d0,temp);\ -d2 = min(d2,d5);\ +#pragma once + +#include +#include + +#include "opthelper.h" + +#if defined __GNUC__ && __GNUC__>=6 && defined __SSE2__ + #pragma GCC diagnostic ignored "-Wignored-attributes" +#endif + +template +inline T median(std::array array) +{ + const typename std::array::iterator middle = array.begin() + N / 2; + std::nth_element(array.begin(), middle, array.end()); + + return + N % 2 + ? *middle + : ((*middle + *std::max_element(array.begin(), middle)) / static_cast(2)); } -// middle 4 of 6 elements, vectorized -#define VMIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \ -{\ -d1 = vminf(s1,s2);\ -d2 = vmaxf(s1,s2);\ -d0 = vminf(s0,d2);\ -d2 = vmaxf(s0,d2);\ -temp = vminf(d0,d1);\ -d1 = vmaxf(d0,d1);\ -d0 = temp;\ -d4 = vminf(s4,s5);\ -d5 = vmaxf(s4,s5);\ -d3 = vminf(s3,d5);\ -d5 = vmaxf(s3,d5);\ -temp = vminf(d3,d4);\ -d4 = vmaxf(d3,d4);\ -d3 = vmaxf(d0,temp);\ -d2 = vminf(d2,d5);\ +template +inline T median(std::array array) +{ + return std::max(std::min(array[0], array[1]), std::min(array[2], std::max(array[0], array[1]))); } +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + return vmaxf(vminf(array[0], array[1]), vminf(array[2], vmaxf(array[0], array[1]))); +} +#endif -#define MEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \ -{\ -t0 = min(s0,s5);\ -t5 = max(s0,s5);\ -t3 = max(t0,s3);\ -t0 = min(t0,s3);\ -t1 = min(s1,s6);\ -t6 = max(s1,s6);\ -t2 = min(s2,s4);\ -t4 = max(s2,s4);\ -t1 = max(t0,t1);\ -median = min(t3,t5);\ -t5 = max(t3,t5);\ -t3 = median;\ -median = min(t2,t6);\ -t6 = max(t2,t6);\ -t3 = max(median,t3);\ -t3 = min(t3,t6);\ -t4 = min(t4,t5);\ -median = min(t1,t4);\ -t4 = max(t1,t4);\ -t3 = max(median,t3);\ -median = min(t3,t4);\ +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = std::max(array[0], tmp); + array[1] = std::min(array[1], array[4]); + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[2], array[3]); + return std::max(array[1], tmp); } -#define VMEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \ -{\ -t0 = vminf(s0,s5);\ -t5 = vmaxf(s0,s5);\ -t3 = vmaxf(t0,s3);\ -t0 = vminf(t0,s3);\ -t1 = vminf(s1,s6);\ -t6 = vmaxf(s1,s6);\ -t2 = vminf(s2,s4);\ -t4 = vmaxf(s2,s4);\ -t1 = vmaxf(t0,t1);\ -median = vminf(t3,t5);\ -t5 = vmaxf(t3,t5);\ -t3 = median;\ -median = vminf(t2,t6);\ -t6 = vmaxf(t2,t6);\ -t3 = vmaxf(median,t3);\ -t3 = vminf(t3,t6);\ -t4 = vminf(t4,t5);\ -median = vminf(t1,t4);\ -t4 = vmaxf(t1,t4);\ -t3 = vmaxf(median,t3);\ -median = vminf(t3,t4);\ +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = vmaxf(array[0], tmp); + array[1] = vminf(array[1], array[4]); + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[2], array[3]); + return vmaxf(array[1], tmp); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[5]); + array[5] = std::max(array[0], array[5]); + array[0] = tmp; + tmp = std::min(array[0], array[3]); + array[3] = std::max(array[0], array[3]); + array[0] = tmp; + tmp = std::min(array[1], array[6]); + array[6] = std::max(array[1], array[6]); + array[1] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + array[1] = std::max(array[0], array[1]); + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[3] = std::max(tmp, array[3]); + array[3] = std::min(array[3], array[6]); + tmp = std::min(array[4], array[5]); + array[4] = std::max(array[1], tmp); + tmp = std::min(array[1], tmp); + array[3] = std::max(tmp, array[3]); + return std::min(array[3], array[4]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[5]); + array[5] = vmaxf(array[0], array[5]); + array[0] = tmp; + tmp = vminf(array[0], array[3]); + array[3] = vmaxf(array[0], array[3]); + array[0] = tmp; + tmp = vminf(array[1], array[6]); + array[6] = vmaxf(array[1], array[6]); + array[1] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + array[1] = vmaxf(array[0], array[1]); + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[3] = vmaxf(tmp, array[3]); + array[3] = vminf(array[3], array[6]); + tmp = vminf(array[4], array[5]); + array[4] = vmaxf(array[1], tmp); + tmp = vminf(array[1], tmp); + array[3] = vmaxf(tmp, array[3]); + return vminf(array[3], array[4]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[7] = tmp; + tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[3] = std::max(array[0], array[3]); + array[5] = std::min(array[5], array[8]); + array[7] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[6] = std::max(array[3], array[6]); + array[4] = std::max(array[1], tmp); + array[2] = std::min(array[2], array[5]); + array[4] = std::min(array[4], array[7]); + tmp = std::min(array[4], array[2]); + array[2] = std::max(array[4], array[2]); + array[4] = std::max(array[6], tmp); + return std::min(array[4], array[2]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[7] = tmp; + tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[3] = vmaxf(array[0], array[3]); + array[5] = vminf(array[5], array[8]); + array[7] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[6] = vmaxf(array[3], array[6]); + array[4] = vmaxf(array[1], tmp); + array[2] = vminf(array[2], array[5]); + array[4] = vminf(array[4], array[7]); + tmp = vminf(array[4], array[2]); + array[2] = vmaxf(array[4], array[2]); + array[4] = vmaxf(array[6], tmp); + return vminf(array[4], array[2]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[5], array[8]); + array[8] = std::max(array[5], array[8]); + array[5] = tmp; + tmp = std::min(array[0], array[12]); + array[12] = std::max(array[0], array[12]); + array[0] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[2], array[3]); + array[3] = std::max(array[2], array[3]); + array[2] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[8], array[11]); + array[11] = std::max(array[8], array[11]); + array[8] = tmp; + tmp = std::min(array[7], array[12]); + array[12] = std::max(array[7], array[12]); + array[7] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[10], array[11]); + array[11] = std::max(array[10], array[11]); + array[10] = tmp; + tmp = std::min(array[1], array[4]); + array[4] = std::max(array[1], array[4]); + array[1] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[7] = tmp; + array[11] = std::min(array[11], array[12]); + tmp = std::min(array[4], array[9]); + array[9] = std::max(array[4], array[9]); + array[4] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[5], array[6]); + array[6] = std::max(array[5], array[6]); + array[5] = tmp; + array[8] = std::min(array[8], array[9]); + array[10] = std::min(array[10], array[11]); + tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + array[3] = std::max(array[1], array[3]); + tmp = std::min(array[4], array[7]); + array[7] = std::max(array[4], array[7]); + array[4] = tmp; + array[8] = std::min(array[8], array[10]); + array[5] = std::max(array[0], array[5]); + array[5] = std::max(array[2], array[5]); + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[5] = std::max(array[3], array[5]); + array[7] = std::min(array[7], array[8]); + array[6] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[5] = std::max(tmp, array[5]); + array[6] = std::min(array[6], array[7]); + return std::max(array[5], array[6]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[5], array[8]); + array[8] = vmaxf(array[5], array[8]); + array[5] = tmp; + tmp = vminf(array[0], array[12]); + array[12] = vmaxf(array[0], array[12]); + array[0] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[2], array[3]); + array[3] = vmaxf(array[2], array[3]); + array[2] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[8], array[11]); + array[11] = vmaxf(array[8], array[11]); + array[8] = tmp; + tmp = vminf(array[7], array[12]); + array[12] = vmaxf(array[7], array[12]); + array[7] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[10], array[11]); + array[11] = vmaxf(array[10], array[11]); + array[10] = tmp; + tmp = vminf(array[1], array[4]); + array[4] = vmaxf(array[1], array[4]); + array[1] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[7] = tmp; + array[11] = vminf(array[11], array[12]); + tmp = vminf(array[4], array[9]); + array[9] = vmaxf(array[4], array[9]); + array[4] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[5], array[6]); + array[6] = vmaxf(array[5], array[6]); + array[5] = tmp; + array[8] = vminf(array[8], array[9]); + array[10] = vminf(array[10], array[11]); + tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + array[3] = vmaxf(array[1], array[3]); + tmp = vminf(array[4], array[7]); + array[7] = vmaxf(array[4], array[7]); + array[4] = tmp; + array[8] = vminf(array[8], array[10]); + array[5] = vmaxf(array[0], array[5]); + array[5] = vmaxf(array[2], array[5]); + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[5] = vmaxf(array[3], array[5]); + array[7] = vminf(array[7], array[8]); + array[6] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[5] = vmaxf(tmp, array[5]); + array[6] = vminf(array[6], array[7]); + return vmaxf(array[5], array[6]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = std::min(tmp, array[6]); + array[6] = std::max(tmp, array[6]); + tmp = std::min(array[9], array[10]); + array[10] = std::max(array[9], array[10]); + array[9] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = std::min(tmp, array[9]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[12], array[13]); + array[13] = std::max(array[12], array[13]); + array[12] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[15], array[16]); + array[16] = std::max(array[15], array[16]); + array[15] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = std::min(tmp, array[15]); + array[15] = std::max(tmp, array[15]); + tmp = std::min(array[18], array[19]); + array[19] = std::max(array[18], array[19]); + array[18] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = std::min(tmp, array[18]); + array[18] = std::max(tmp, array[18]); + tmp = std::min(array[21], array[22]); + array[22] = std::max(array[21], array[22]); + array[21] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[23], array[24]); + array[24] = std::max(array[23], array[24]); + array[23] = tmp; + tmp = std::min(array[2], array[5]); + array[5] = std::max(array[2], array[5]); + array[2] = tmp; + tmp = std::min(array[3], array[6]); + array[6] = std::max(array[3], array[6]); + array[3] = tmp; + tmp = std::min(array[0], array[6]); + array[6] = std::max(array[0], array[6]); + array[0] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[4], array[7]); + array[7] = std::max(array[4], array[7]); + array[4] = tmp; + tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = std::min(tmp, array[4]); + array[4] = std::max(tmp, array[4]); + tmp = std::min(array[11], array[14]); + array[14] = std::max(array[11], array[14]); + array[11] = tmp; + tmp = std::min(array[8], array[14]); + array[14] = std::max(array[8], array[14]); + array[8] = std::min(tmp, array[11]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[15]); + array[15] = std::max(array[12], array[15]); + array[12] = tmp; + tmp = std::min(array[9], array[15]); + array[15] = std::max(array[9], array[15]); + array[9] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[16]); + array[16] = std::max(array[13], array[16]); + array[13] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = std::min(tmp, array[13]); + array[13] = std::max(tmp, array[13]); + tmp = std::min(array[20], array[23]); + array[23] = std::max(array[20], array[23]); + array[20] = tmp; + tmp = std::min(array[17], array[23]); + array[23] = std::max(array[17], array[23]); + array[17] = std::min(tmp, array[20]); + array[20] = std::max(tmp, array[20]); + tmp = std::min(array[21], array[24]); + array[24] = std::max(array[21], array[24]); + array[21] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[19], array[22]); + array[22] = std::max(array[19], array[22]); + array[19] = tmp; + array[17] = std::max(array[8], array[17]); + tmp = std::min(array[9], array[18]); + array[18] = std::max(array[9], array[18]); + array[9] = tmp; + tmp = std::min(array[0], array[18]); + array[18] = std::max(array[0], array[18]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[10], array[19]); + array[19] = std::max(array[10], array[19]); + array[10] = tmp; + tmp = std::min(array[1], array[19]); + array[19] = std::max(array[1], array[19]); + array[1] = std::min(tmp, array[10]); + array[10] = std::max(tmp, array[10]); + tmp = std::min(array[11], array[20]); + array[20] = std::max(array[11], array[20]); + array[11] = tmp; + tmp = std::min(array[2], array[20]); + array[20] = std::max(array[2], array[20]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[21]); + array[21] = std::max(array[12], array[21]); + array[12] = tmp; + tmp = std::min(array[3], array[21]); + array[21] = std::max(array[3], array[21]); + array[3] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[22]); + array[22] = std::max(array[13], array[22]); + array[4] = std::min(array[4], array[22]); + array[13] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[4] = tmp; + tmp = std::min(array[14], array[23]); + array[23] = std::max(array[14], array[23]); + array[14] = tmp; + tmp = std::min(array[5], array[23]); + array[23] = std::max(array[5], array[23]); + array[5] = std::min(tmp, array[14]); + array[14] = std::max(tmp, array[14]); + tmp = std::min(array[15], array[24]); + array[24] = std::max(array[15], array[24]); + array[15] = tmp; + array[6] = std::min(array[6], array[24]); + tmp = std::min(array[6], array[15]); + array[15] = std::max(array[6], array[15]); + array[6] = tmp; + tmp = std::min(array[7], array[16]); + array[7] = std::min(tmp, array[19]); + tmp = std::min(array[13], array[21]); + array[15] = std::min(array[15], array[23]); + tmp = std::min(array[7], tmp); + array[7] = std::min(tmp, array[15]); + array[9] = std::max(array[1], array[9]); + array[11] = std::max(array[3], array[11]); + array[17] = std::max(array[5], array[17]); + array[17] = std::max(array[11], array[17]); + array[17] = std::max(array[9], array[17]); + tmp = std::min(array[4], array[10]); + array[10] = std::max(array[4], array[10]); + array[4] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[14]); + array[14] = std::max(array[7], array[14]); + array[7] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[7] = std::max(tmp, array[7]); + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + array[10] = std::min(array[10], array[14]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = std::max(array[6], tmp); + tmp = std::min(array[6], tmp); + array[17] = std::max(tmp, array[17]); + tmp = std::min(array[12], array[17]); + array[17] = std::max(array[12], array[17]); + array[12] = tmp; + array[7] = std::min(array[7], array[17]); + tmp = std::min(array[7], array[10]); + array[10] = std::max(array[7], array[10]); + array[7] = tmp; + tmp = std::min(array[12], array[18]); + array[18] = std::max(array[12], array[18]); + array[12] = std::max(array[7], tmp); + array[10] = std::min(array[10], array[18]); + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[10], array[20]); + return std::max(tmp, array[12]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = vminf(tmp, array[6]); + array[6] = vmaxf(tmp, array[6]); + tmp = vminf(array[9], array[10]); + array[10] = vmaxf(array[9], array[10]); + array[9] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = vminf(tmp, array[9]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[12], array[13]); + array[13] = vmaxf(array[12], array[13]); + array[12] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[15], array[16]); + array[16] = vmaxf(array[15], array[16]); + array[15] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = vminf(tmp, array[15]); + array[15] = vmaxf(tmp, array[15]); + tmp = vminf(array[18], array[19]); + array[19] = vmaxf(array[18], array[19]); + array[18] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = vminf(tmp, array[18]); + array[18] = vmaxf(tmp, array[18]); + tmp = vminf(array[21], array[22]); + array[22] = vmaxf(array[21], array[22]); + array[21] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[23], array[24]); + array[24] = vmaxf(array[23], array[24]); + array[23] = tmp; + tmp = vminf(array[2], array[5]); + array[5] = vmaxf(array[2], array[5]); + array[2] = tmp; + tmp = vminf(array[3], array[6]); + array[6] = vmaxf(array[3], array[6]); + array[3] = tmp; + tmp = vminf(array[0], array[6]); + array[6] = vmaxf(array[0], array[6]); + array[0] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[4], array[7]); + array[7] = vmaxf(array[4], array[7]); + array[4] = tmp; + tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = vminf(tmp, array[4]); + array[4] = vmaxf(tmp, array[4]); + tmp = vminf(array[11], array[14]); + array[14] = vmaxf(array[11], array[14]); + array[11] = tmp; + tmp = vminf(array[8], array[14]); + array[14] = vmaxf(array[8], array[14]); + array[8] = vminf(tmp, array[11]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[15]); + array[15] = vmaxf(array[12], array[15]); + array[12] = tmp; + tmp = vminf(array[9], array[15]); + array[15] = vmaxf(array[9], array[15]); + array[9] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[16]); + array[16] = vmaxf(array[13], array[16]); + array[13] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = vminf(tmp, array[13]); + array[13] = vmaxf(tmp, array[13]); + tmp = vminf(array[20], array[23]); + array[23] = vmaxf(array[20], array[23]); + array[20] = tmp; + tmp = vminf(array[17], array[23]); + array[23] = vmaxf(array[17], array[23]); + array[17] = vminf(tmp, array[20]); + array[20] = vmaxf(tmp, array[20]); + tmp = vminf(array[21], array[24]); + array[24] = vmaxf(array[21], array[24]); + array[21] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[19], array[22]); + array[22] = vmaxf(array[19], array[22]); + array[19] = tmp; + array[17] = vmaxf(array[8], array[17]); + tmp = vminf(array[9], array[18]); + array[18] = vmaxf(array[9], array[18]); + array[9] = tmp; + tmp = vminf(array[0], array[18]); + array[18] = vmaxf(array[0], array[18]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[10], array[19]); + array[19] = vmaxf(array[10], array[19]); + array[10] = tmp; + tmp = vminf(array[1], array[19]); + array[19] = vmaxf(array[1], array[19]); + array[1] = vminf(tmp, array[10]); + array[10] = vmaxf(tmp, array[10]); + tmp = vminf(array[11], array[20]); + array[20] = vmaxf(array[11], array[20]); + array[11] = tmp; + tmp = vminf(array[2], array[20]); + array[20] = vmaxf(array[2], array[20]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[21]); + array[21] = vmaxf(array[12], array[21]); + array[12] = tmp; + tmp = vminf(array[3], array[21]); + array[21] = vmaxf(array[3], array[21]); + array[3] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[22]); + array[22] = vmaxf(array[13], array[22]); + array[4] = vminf(array[4], array[22]); + array[13] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[4] = tmp; + tmp = vminf(array[14], array[23]); + array[23] = vmaxf(array[14], array[23]); + array[14] = tmp; + tmp = vminf(array[5], array[23]); + array[23] = vmaxf(array[5], array[23]); + array[5] = vminf(tmp, array[14]); + array[14] = vmaxf(tmp, array[14]); + tmp = vminf(array[15], array[24]); + array[24] = vmaxf(array[15], array[24]); + array[15] = tmp; + array[6] = vminf(array[6], array[24]); + tmp = vminf(array[6], array[15]); + array[15] = vmaxf(array[6], array[15]); + array[6] = tmp; + tmp = vminf(array[7], array[16]); + array[7] = vminf(tmp, array[19]); + tmp = vminf(array[13], array[21]); + array[15] = vminf(array[15], array[23]); + tmp = vminf(array[7], tmp); + array[7] = vminf(tmp, array[15]); + array[9] = vmaxf(array[1], array[9]); + array[11] = vmaxf(array[3], array[11]); + array[17] = vmaxf(array[5], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[17] = vmaxf(array[9], array[17]); + tmp = vminf(array[4], array[10]); + array[10] = vmaxf(array[4], array[10]); + array[4] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[14]); + array[14] = vmaxf(array[7], array[14]); + array[7] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[7] = vmaxf(tmp, array[7]); + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + array[10] = vminf(array[10], array[14]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = vmaxf(array[6], tmp); + tmp = vminf(array[6], tmp); + array[17] = vmaxf(tmp, array[17]); + tmp = vminf(array[12], array[17]); + array[17] = vmaxf(array[12], array[17]); + array[12] = tmp; + array[7] = vminf(array[7], array[17]); + tmp = vminf(array[7], array[10]); + array[10] = vmaxf(array[7], array[10]); + array[7] = tmp; + tmp = vminf(array[12], array[18]); + array[18] = vmaxf(array[12], array[18]); + array[12] = vmaxf(array[7], tmp); + array[10] = vminf(array[10], array[18]); + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[10], array[20]); + return vmaxf(tmp, array[12]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[32]); + array[32] = std::max(array[0], array[32]); + array[0] = tmp; + tmp = std::min(array[1], array[33]); + array[33] = std::max(array[1], array[33]); + array[1] = tmp; + tmp = std::min(array[2], array[34]); + array[34] = std::max(array[2], array[34]); + array[2] = tmp; + tmp = std::min(array[3], array[35]); + array[35] = std::max(array[3], array[35]); + array[3] = tmp; + tmp = std::min(array[4], array[36]); + array[36] = std::max(array[4], array[36]); + array[4] = tmp; + tmp = std::min(array[5], array[37]); + array[37] = std::max(array[5], array[37]); + array[5] = tmp; + tmp = std::min(array[6], array[38]); + array[38] = std::max(array[6], array[38]); + array[6] = tmp; + tmp = std::min(array[7], array[39]); + array[39] = std::max(array[7], array[39]); + array[7] = tmp; + tmp = std::min(array[8], array[40]); + array[40] = std::max(array[8], array[40]); + array[8] = tmp; + tmp = std::min(array[9], array[41]); + array[41] = std::max(array[9], array[41]); + array[9] = tmp; + tmp = std::min(array[10], array[42]); + array[42] = std::max(array[10], array[42]); + array[10] = tmp; + tmp = std::min(array[11], array[43]); + array[43] = std::max(array[11], array[43]); + array[11] = tmp; + tmp = std::min(array[12], array[44]); + array[44] = std::max(array[12], array[44]); + array[12] = tmp; + tmp = std::min(array[13], array[45]); + array[45] = std::max(array[13], array[45]); + array[13] = tmp; + tmp = std::min(array[14], array[46]); + array[46] = std::max(array[14], array[46]); + array[14] = tmp; + tmp = std::min(array[15], array[47]); + array[47] = std::max(array[15], array[47]); + array[15] = tmp; + tmp = std::min(array[16], array[48]); + array[48] = std::max(array[16], array[48]); + array[16] = tmp; + tmp = std::min(array[0], array[16]); + array[16] = std::max(array[0], array[16]); + array[0] = tmp; + tmp = std::min(array[1], array[17]); + array[17] = std::max(array[1], array[17]); + array[1] = tmp; + tmp = std::min(array[2], array[18]); + array[18] = std::max(array[2], array[18]); + array[2] = tmp; + tmp = std::min(array[3], array[19]); + array[19] = std::max(array[3], array[19]); + array[3] = tmp; + tmp = std::min(array[4], array[20]); + array[20] = std::max(array[4], array[20]); + array[4] = tmp; + tmp = std::min(array[5], array[21]); + array[21] = std::max(array[5], array[21]); + array[5] = tmp; + tmp = std::min(array[6], array[22]); + array[22] = std::max(array[6], array[22]); + array[6] = tmp; + tmp = std::min(array[7], array[23]); + array[23] = std::max(array[7], array[23]); + array[7] = tmp; + tmp = std::min(array[8], array[24]); + array[24] = std::max(array[8], array[24]); + array[8] = tmp; + tmp = std::min(array[9], array[25]); + array[25] = std::max(array[9], array[25]); + array[9] = tmp; + tmp = std::min(array[10], array[26]); + array[26] = std::max(array[10], array[26]); + array[10] = tmp; + tmp = std::min(array[11], array[27]); + array[27] = std::max(array[11], array[27]); + array[11] = tmp; + tmp = std::min(array[12], array[28]); + array[28] = std::max(array[12], array[28]); + array[12] = tmp; + tmp = std::min(array[13], array[29]); + array[29] = std::max(array[13], array[29]); + array[13] = tmp; + tmp = std::min(array[14], array[30]); + array[30] = std::max(array[14], array[30]); + array[14] = tmp; + tmp = std::min(array[15], array[31]); + array[31] = std::max(array[15], array[31]); + array[15] = tmp; + tmp = std::min(array[32], array[48]); + array[48] = std::max(array[32], array[48]); + array[32] = tmp; + tmp = std::min(array[16], array[32]); + array[32] = std::max(array[16], array[32]); + array[16] = tmp; + tmp = std::min(array[17], array[33]); + array[33] = std::max(array[17], array[33]); + array[17] = tmp; + tmp = std::min(array[18], array[34]); + array[34] = std::max(array[18], array[34]); + array[18] = tmp; + tmp = std::min(array[19], array[35]); + array[35] = std::max(array[19], array[35]); + array[19] = tmp; + tmp = std::min(array[20], array[36]); + array[36] = std::max(array[20], array[36]); + array[20] = tmp; + tmp = std::min(array[21], array[37]); + array[37] = std::max(array[21], array[37]); + array[21] = tmp; + tmp = std::min(array[22], array[38]); + array[38] = std::max(array[22], array[38]); + array[22] = tmp; + tmp = std::min(array[23], array[39]); + array[39] = std::max(array[23], array[39]); + array[23] = tmp; + tmp = std::min(array[24], array[40]); + array[40] = std::max(array[24], array[40]); + array[24] = tmp; + tmp = std::min(array[25], array[41]); + array[41] = std::max(array[25], array[41]); + array[25] = tmp; + tmp = std::min(array[26], array[42]); + array[42] = std::max(array[26], array[42]); + array[26] = tmp; + tmp = std::min(array[27], array[43]); + array[43] = std::max(array[27], array[43]); + array[27] = tmp; + tmp = std::min(array[28], array[44]); + array[44] = std::max(array[28], array[44]); + array[28] = tmp; + tmp = std::min(array[29], array[45]); + array[45] = std::max(array[29], array[45]); + array[29] = tmp; + tmp = std::min(array[30], array[46]); + array[46] = std::max(array[30], array[46]); + array[30] = tmp; + tmp = std::min(array[31], array[47]); + array[47] = std::max(array[31], array[47]); + array[31] = tmp; + tmp = std::min(array[0], array[8]); + array[8] = std::max(array[0], array[8]); + array[0] = tmp; + tmp = std::min(array[1], array[9]); + array[9] = std::max(array[1], array[9]); + array[1] = tmp; + tmp = std::min(array[2], array[10]); + array[10] = std::max(array[2], array[10]); + array[2] = tmp; + tmp = std::min(array[3], array[11]); + array[11] = std::max(array[3], array[11]); + array[3] = tmp; + tmp = std::min(array[4], array[12]); + array[12] = std::max(array[4], array[12]); + array[4] = tmp; + tmp = std::min(array[5], array[13]); + array[13] = std::max(array[5], array[13]); + array[5] = tmp; + tmp = std::min(array[6], array[14]); + array[14] = std::max(array[6], array[14]); + array[6] = tmp; + tmp = std::min(array[7], array[15]); + array[15] = std::max(array[7], array[15]); + array[7] = tmp; + tmp = std::min(array[16], array[24]); + array[24] = std::max(array[16], array[24]); + array[16] = tmp; + tmp = std::min(array[17], array[25]); + array[25] = std::max(array[17], array[25]); + array[17] = tmp; + tmp = std::min(array[18], array[26]); + array[26] = std::max(array[18], array[26]); + array[18] = tmp; + tmp = std::min(array[19], array[27]); + array[27] = std::max(array[19], array[27]); + array[19] = tmp; + tmp = std::min(array[20], array[28]); + array[28] = std::max(array[20], array[28]); + array[20] = tmp; + tmp = std::min(array[21], array[29]); + array[29] = std::max(array[21], array[29]); + array[21] = tmp; + tmp = std::min(array[22], array[30]); + array[30] = std::max(array[22], array[30]); + array[22] = tmp; + tmp = std::min(array[23], array[31]); + array[31] = std::max(array[23], array[31]); + array[23] = tmp; + tmp = std::min(array[32], array[40]); + array[40] = std::max(array[32], array[40]); + array[32] = tmp; + tmp = std::min(array[33], array[41]); + array[41] = std::max(array[33], array[41]); + array[33] = tmp; + tmp = std::min(array[34], array[42]); + array[42] = std::max(array[34], array[42]); + array[34] = tmp; + tmp = std::min(array[35], array[43]); + array[43] = std::max(array[35], array[43]); + array[35] = tmp; + tmp = std::min(array[36], array[44]); + array[44] = std::max(array[36], array[44]); + array[36] = tmp; + tmp = std::min(array[37], array[45]); + array[45] = std::max(array[37], array[45]); + array[37] = tmp; + tmp = std::min(array[38], array[46]); + array[46] = std::max(array[38], array[46]); + array[38] = tmp; + tmp = std::min(array[39], array[47]); + array[47] = std::max(array[39], array[47]); + array[39] = tmp; + tmp = std::min(array[8], array[32]); + array[32] = std::max(array[8], array[32]); + array[8] = tmp; + tmp = std::min(array[9], array[33]); + array[33] = std::max(array[9], array[33]); + array[9] = tmp; + tmp = std::min(array[10], array[34]); + array[34] = std::max(array[10], array[34]); + array[10] = tmp; + tmp = std::min(array[11], array[35]); + array[35] = std::max(array[11], array[35]); + array[11] = tmp; + tmp = std::min(array[12], array[36]); + array[36] = std::max(array[12], array[36]); + array[12] = tmp; + tmp = std::min(array[13], array[37]); + array[37] = std::max(array[13], array[37]); + array[13] = tmp; + tmp = std::min(array[14], array[38]); + array[38] = std::max(array[14], array[38]); + array[14] = tmp; + tmp = std::min(array[15], array[39]); + array[39] = std::max(array[15], array[39]); + array[15] = tmp; + tmp = std::min(array[24], array[48]); + array[48] = std::max(array[24], array[48]); + array[24] = tmp; + tmp = std::min(array[8], array[16]); + array[16] = std::max(array[8], array[16]); + array[8] = tmp; + tmp = std::min(array[9], array[17]); + array[17] = std::max(array[9], array[17]); + array[9] = tmp; + tmp = std::min(array[10], array[18]); + array[18] = std::max(array[10], array[18]); + array[10] = tmp; + tmp = std::min(array[11], array[19]); + array[19] = std::max(array[11], array[19]); + array[11] = tmp; + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[13], array[21]); + array[21] = std::max(array[13], array[21]); + array[13] = tmp; + tmp = std::min(array[14], array[22]); + array[22] = std::max(array[14], array[22]); + array[14] = tmp; + tmp = std::min(array[15], array[23]); + array[23] = std::max(array[15], array[23]); + array[15] = tmp; + tmp = std::min(array[24], array[32]); + array[32] = std::max(array[24], array[32]); + array[24] = tmp; + tmp = std::min(array[25], array[33]); + array[33] = std::max(array[25], array[33]); + array[25] = tmp; + tmp = std::min(array[26], array[34]); + array[34] = std::max(array[26], array[34]); + array[26] = tmp; + tmp = std::min(array[27], array[35]); + array[35] = std::max(array[27], array[35]); + array[27] = tmp; + tmp = std::min(array[28], array[36]); + array[36] = std::max(array[28], array[36]); + array[28] = tmp; + tmp = std::min(array[29], array[37]); + array[37] = std::max(array[29], array[37]); + array[29] = tmp; + tmp = std::min(array[30], array[38]); + array[38] = std::max(array[30], array[38]); + array[30] = tmp; + tmp = std::min(array[31], array[39]); + array[39] = std::max(array[31], array[39]); + array[31] = tmp; + tmp = std::min(array[40], array[48]); + array[48] = std::max(array[40], array[48]); + array[40] = tmp; + tmp = std::min(array[0], array[4]); + array[4] = std::max(array[0], array[4]); + array[0] = tmp; + tmp = std::min(array[1], array[5]); + array[5] = std::max(array[1], array[5]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[8], array[12]); + array[12] = std::max(array[8], array[12]); + array[8] = tmp; + tmp = std::min(array[9], array[13]); + array[13] = std::max(array[9], array[13]); + array[9] = tmp; + tmp = std::min(array[10], array[14]); + array[14] = std::max(array[10], array[14]); + array[10] = tmp; + tmp = std::min(array[11], array[15]); + array[15] = std::max(array[11], array[15]); + array[11] = tmp; + tmp = std::min(array[16], array[20]); + array[20] = std::max(array[16], array[20]); + array[16] = tmp; + tmp = std::min(array[17], array[21]); + array[21] = std::max(array[17], array[21]); + array[17] = tmp; + tmp = std::min(array[18], array[22]); + array[22] = std::max(array[18], array[22]); + array[18] = tmp; + tmp = std::min(array[19], array[23]); + array[23] = std::max(array[19], array[23]); + array[19] = tmp; + tmp = std::min(array[24], array[28]); + array[28] = std::max(array[24], array[28]); + array[24] = tmp; + tmp = std::min(array[25], array[29]); + array[29] = std::max(array[25], array[29]); + array[25] = tmp; + tmp = std::min(array[26], array[30]); + array[30] = std::max(array[26], array[30]); + array[26] = tmp; + tmp = std::min(array[27], array[31]); + array[31] = std::max(array[27], array[31]); + array[27] = tmp; + tmp = std::min(array[32], array[36]); + array[36] = std::max(array[32], array[36]); + array[32] = tmp; + tmp = std::min(array[33], array[37]); + array[37] = std::max(array[33], array[37]); + array[33] = tmp; + tmp = std::min(array[34], array[38]); + array[38] = std::max(array[34], array[38]); + array[34] = tmp; + tmp = std::min(array[35], array[39]); + array[39] = std::max(array[35], array[39]); + array[35] = tmp; + tmp = std::min(array[40], array[44]); + array[44] = std::max(array[40], array[44]); + array[40] = tmp; + tmp = std::min(array[41], array[45]); + array[45] = std::max(array[41], array[45]); + array[41] = tmp; + tmp = std::min(array[42], array[46]); + array[46] = std::max(array[42], array[46]); + array[42] = tmp; + tmp = std::min(array[43], array[47]); + array[47] = std::max(array[43], array[47]); + array[43] = tmp; + tmp = std::min(array[4], array[32]); + array[32] = std::max(array[4], array[32]); + array[4] = tmp; + tmp = std::min(array[5], array[33]); + array[33] = std::max(array[5], array[33]); + array[5] = tmp; + tmp = std::min(array[6], array[34]); + array[34] = std::max(array[6], array[34]); + array[6] = tmp; + tmp = std::min(array[7], array[35]); + array[35] = std::max(array[7], array[35]); + array[7] = tmp; + tmp = std::min(array[12], array[40]); + array[40] = std::max(array[12], array[40]); + array[12] = tmp; + tmp = std::min(array[13], array[41]); + array[41] = std::max(array[13], array[41]); + array[13] = tmp; + tmp = std::min(array[14], array[42]); + array[42] = std::max(array[14], array[42]); + array[14] = tmp; + tmp = std::min(array[15], array[43]); + array[43] = std::max(array[15], array[43]); + array[15] = tmp; + tmp = std::min(array[20], array[48]); + array[48] = std::max(array[20], array[48]); + array[20] = tmp; + tmp = std::min(array[4], array[16]); + array[16] = std::max(array[4], array[16]); + array[4] = tmp; + tmp = std::min(array[5], array[17]); + array[17] = std::max(array[5], array[17]); + array[5] = tmp; + tmp = std::min(array[6], array[18]); + array[18] = std::max(array[6], array[18]); + array[6] = tmp; + tmp = std::min(array[7], array[19]); + array[19] = std::max(array[7], array[19]); + array[7] = tmp; + tmp = std::min(array[12], array[24]); + array[24] = std::max(array[12], array[24]); + array[12] = tmp; + tmp = std::min(array[13], array[25]); + array[25] = std::max(array[13], array[25]); + array[13] = tmp; + tmp = std::min(array[14], array[26]); + array[26] = std::max(array[14], array[26]); + array[14] = tmp; + tmp = std::min(array[15], array[27]); + array[27] = std::max(array[15], array[27]); + array[15] = tmp; + tmp = std::min(array[20], array[32]); + array[32] = std::max(array[20], array[32]); + array[20] = tmp; + tmp = std::min(array[21], array[33]); + array[33] = std::max(array[21], array[33]); + array[21] = tmp; + tmp = std::min(array[22], array[34]); + array[34] = std::max(array[22], array[34]); + array[22] = tmp; + tmp = std::min(array[23], array[35]); + array[35] = std::max(array[23], array[35]); + array[23] = tmp; + tmp = std::min(array[28], array[40]); + array[40] = std::max(array[28], array[40]); + array[28] = tmp; + tmp = std::min(array[29], array[41]); + array[41] = std::max(array[29], array[41]); + array[29] = tmp; + tmp = std::min(array[30], array[42]); + array[42] = std::max(array[30], array[42]); + array[30] = tmp; + tmp = std::min(array[31], array[43]); + array[43] = std::max(array[31], array[43]); + array[31] = tmp; + tmp = std::min(array[36], array[48]); + array[48] = std::max(array[36], array[48]); + array[36] = tmp; + tmp = std::min(array[4], array[8]); + array[8] = std::max(array[4], array[8]); + array[4] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[7], array[11]); + array[11] = std::max(array[7], array[11]); + array[7] = tmp; + tmp = std::min(array[12], array[16]); + array[16] = std::max(array[12], array[16]); + array[12] = tmp; + tmp = std::min(array[13], array[17]); + array[17] = std::max(array[13], array[17]); + array[13] = tmp; + tmp = std::min(array[14], array[18]); + array[18] = std::max(array[14], array[18]); + array[14] = tmp; + tmp = std::min(array[15], array[19]); + array[19] = std::max(array[15], array[19]); + array[15] = tmp; + tmp = std::min(array[20], array[24]); + array[24] = std::max(array[20], array[24]); + array[20] = tmp; + tmp = std::min(array[21], array[25]); + array[25] = std::max(array[21], array[25]); + array[21] = tmp; + tmp = std::min(array[22], array[26]); + array[26] = std::max(array[22], array[26]); + array[22] = tmp; + tmp = std::min(array[23], array[27]); + array[27] = std::max(array[23], array[27]); + array[23] = tmp; + tmp = std::min(array[28], array[32]); + array[32] = std::max(array[28], array[32]); + array[28] = tmp; + tmp = std::min(array[29], array[33]); + array[33] = std::max(array[29], array[33]); + array[29] = tmp; + tmp = std::min(array[30], array[34]); + array[34] = std::max(array[30], array[34]); + array[30] = tmp; + tmp = std::min(array[31], array[35]); + array[35] = std::max(array[31], array[35]); + array[31] = tmp; + tmp = std::min(array[36], array[40]); + array[40] = std::max(array[36], array[40]); + array[36] = tmp; + tmp = std::min(array[37], array[41]); + array[41] = std::max(array[37], array[41]); + array[37] = tmp; + tmp = std::min(array[38], array[42]); + array[42] = std::max(array[38], array[42]); + array[38] = tmp; + tmp = std::min(array[39], array[43]); + array[43] = std::max(array[39], array[43]); + array[39] = tmp; + tmp = std::min(array[44], array[48]); + array[48] = std::max(array[44], array[48]); + array[44] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[1], array[3]); + array[3] = std::max(array[1], array[3]); + array[1] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + tmp = std::min(array[13], array[15]); + array[15] = std::max(array[13], array[15]); + array[13] = tmp; + tmp = std::min(array[16], array[18]); + array[18] = std::max(array[16], array[18]); + array[16] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = tmp; + tmp = std::min(array[21], array[23]); + array[23] = std::max(array[21], array[23]); + array[21] = tmp; + tmp = std::min(array[24], array[26]); + array[26] = std::max(array[24], array[26]); + array[24] = tmp; + tmp = std::min(array[25], array[27]); + array[27] = std::max(array[25], array[27]); + array[25] = tmp; + tmp = std::min(array[28], array[30]); + array[30] = std::max(array[28], array[30]); + array[28] = tmp; + tmp = std::min(array[29], array[31]); + array[31] = std::max(array[29], array[31]); + array[29] = tmp; + tmp = std::min(array[32], array[34]); + array[34] = std::max(array[32], array[34]); + array[32] = tmp; + tmp = std::min(array[33], array[35]); + array[35] = std::max(array[33], array[35]); + array[33] = tmp; + tmp = std::min(array[36], array[38]); + array[38] = std::max(array[36], array[38]); + array[36] = tmp; + tmp = std::min(array[37], array[39]); + array[39] = std::max(array[37], array[39]); + array[37] = tmp; + tmp = std::min(array[40], array[42]); + array[42] = std::max(array[40], array[42]); + array[40] = tmp; + tmp = std::min(array[41], array[43]); + array[43] = std::max(array[41], array[43]); + array[41] = tmp; + tmp = std::min(array[44], array[46]); + array[46] = std::max(array[44], array[46]); + array[44] = tmp; + tmp = std::min(array[45], array[47]); + array[47] = std::max(array[45], array[47]); + array[45] = tmp; + tmp = std::min(array[2], array[32]); + array[32] = std::max(array[2], array[32]); + array[2] = tmp; + tmp = std::min(array[3], array[33]); + array[33] = std::max(array[3], array[33]); + array[3] = tmp; + tmp = std::min(array[6], array[36]); + array[36] = std::max(array[6], array[36]); + array[6] = tmp; + tmp = std::min(array[7], array[37]); + array[37] = std::max(array[7], array[37]); + array[7] = tmp; + tmp = std::min(array[10], array[40]); + array[40] = std::max(array[10], array[40]); + array[10] = tmp; + tmp = std::min(array[11], array[41]); + array[41] = std::max(array[11], array[41]); + array[11] = tmp; + tmp = std::min(array[14], array[44]); + array[44] = std::max(array[14], array[44]); + array[14] = tmp; + tmp = std::min(array[15], array[45]); + array[45] = std::max(array[15], array[45]); + array[15] = tmp; + tmp = std::min(array[18], array[48]); + array[48] = std::max(array[18], array[48]); + array[18] = tmp; + tmp = std::min(array[2], array[16]); + array[16] = std::max(array[2], array[16]); + array[2] = tmp; + tmp = std::min(array[3], array[17]); + array[17] = std::max(array[3], array[17]); + array[3] = tmp; + tmp = std::min(array[6], array[20]); + array[20] = std::max(array[6], array[20]); + array[6] = tmp; + tmp = std::min(array[7], array[21]); + array[21] = std::max(array[7], array[21]); + array[7] = tmp; + tmp = std::min(array[10], array[24]); + array[24] = std::max(array[10], array[24]); + array[10] = tmp; + tmp = std::min(array[11], array[25]); + array[25] = std::max(array[11], array[25]); + array[11] = tmp; + tmp = std::min(array[14], array[28]); + array[28] = std::max(array[14], array[28]); + array[14] = tmp; + tmp = std::min(array[15], array[29]); + array[29] = std::max(array[15], array[29]); + array[15] = tmp; + tmp = std::min(array[18], array[32]); + array[32] = std::max(array[18], array[32]); + array[18] = tmp; + tmp = std::min(array[19], array[33]); + array[33] = std::max(array[19], array[33]); + array[19] = tmp; + tmp = std::min(array[22], array[36]); + array[36] = std::max(array[22], array[36]); + array[22] = tmp; + tmp = std::min(array[23], array[37]); + array[37] = std::max(array[23], array[37]); + array[23] = tmp; + tmp = std::min(array[26], array[40]); + array[40] = std::max(array[26], array[40]); + array[26] = tmp; + tmp = std::min(array[27], array[41]); + array[41] = std::max(array[27], array[41]); + array[27] = tmp; + tmp = std::min(array[30], array[44]); + array[44] = std::max(array[30], array[44]); + array[30] = tmp; + tmp = std::min(array[31], array[45]); + array[45] = std::max(array[31], array[45]); + array[31] = tmp; + tmp = std::min(array[34], array[48]); + array[48] = std::max(array[34], array[48]); + array[34] = tmp; + tmp = std::min(array[2], array[8]); + array[8] = std::max(array[2], array[8]); + array[2] = tmp; + tmp = std::min(array[3], array[9]); + array[9] = std::max(array[3], array[9]); + array[3] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[13]); + array[13] = std::max(array[7], array[13]); + array[7] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = tmp; + tmp = std::min(array[11], array[17]); + array[17] = std::max(array[11], array[17]); + array[11] = tmp; + tmp = std::min(array[14], array[20]); + array[20] = std::max(array[14], array[20]); + array[14] = tmp; + tmp = std::min(array[15], array[21]); + array[21] = std::max(array[15], array[21]); + array[15] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = tmp; + tmp = std::min(array[19], array[25]); + array[25] = std::max(array[19], array[25]); + array[19] = tmp; + tmp = std::min(array[22], array[28]); + array[28] = std::max(array[22], array[28]); + array[22] = tmp; + tmp = std::min(array[23], array[29]); + array[29] = std::max(array[23], array[29]); + array[23] = tmp; + tmp = std::min(array[26], array[32]); + array[32] = std::max(array[26], array[32]); + array[26] = tmp; + tmp = std::min(array[27], array[33]); + array[33] = std::max(array[27], array[33]); + array[27] = tmp; + tmp = std::min(array[30], array[36]); + array[36] = std::max(array[30], array[36]); + array[30] = tmp; + tmp = std::min(array[31], array[37]); + array[37] = std::max(array[31], array[37]); + array[31] = tmp; + tmp = std::min(array[34], array[40]); + array[40] = std::max(array[34], array[40]); + array[34] = tmp; + tmp = std::min(array[35], array[41]); + array[41] = std::max(array[35], array[41]); + array[35] = tmp; + tmp = std::min(array[38], array[44]); + array[44] = std::max(array[38], array[44]); + array[38] = tmp; + tmp = std::min(array[39], array[45]); + array[45] = std::max(array[39], array[45]); + array[39] = tmp; + tmp = std::min(array[42], array[48]); + array[48] = std::max(array[42], array[48]); + array[42] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[6] = tmp; + tmp = std::min(array[7], array[9]); + array[9] = std::max(array[7], array[9]); + array[7] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = tmp; + tmp = std::min(array[15], array[17]); + array[17] = std::max(array[15], array[17]); + array[15] = tmp; + tmp = std::min(array[18], array[20]); + array[20] = std::max(array[18], array[20]); + array[18] = tmp; + tmp = std::min(array[19], array[21]); + array[21] = std::max(array[19], array[21]); + array[19] = tmp; + tmp = std::min(array[22], array[24]); + array[24] = std::max(array[22], array[24]); + array[22] = tmp; + tmp = std::min(array[23], array[25]); + array[25] = std::max(array[23], array[25]); + array[23] = tmp; + tmp = std::min(array[26], array[28]); + array[28] = std::max(array[26], array[28]); + array[26] = tmp; + tmp = std::min(array[27], array[29]); + array[29] = std::max(array[27], array[29]); + array[27] = tmp; + tmp = std::min(array[30], array[32]); + array[32] = std::max(array[30], array[32]); + array[30] = tmp; + tmp = std::min(array[31], array[33]); + array[33] = std::max(array[31], array[33]); + array[31] = tmp; + tmp = std::min(array[34], array[36]); + array[36] = std::max(array[34], array[36]); + array[34] = tmp; + tmp = std::min(array[35], array[37]); + array[37] = std::max(array[35], array[37]); + array[35] = tmp; + tmp = std::min(array[38], array[40]); + array[40] = std::max(array[38], array[40]); + array[38] = tmp; + tmp = std::min(array[39], array[41]); + array[41] = std::max(array[39], array[41]); + array[39] = tmp; + tmp = std::min(array[42], array[44]); + array[44] = std::max(array[42], array[44]); + array[42] = tmp; + tmp = std::min(array[43], array[45]); + array[45] = std::max(array[43], array[45]); + array[43] = tmp; + tmp = std::min(array[46], array[48]); + array[48] = std::max(array[46], array[48]); + array[46] = tmp; + array[1] = std::max(array[0], array[1]); + array[3] = std::max(array[2], array[3]); + array[5] = std::max(array[4], array[5]); + array[7] = std::max(array[6], array[7]); + array[9] = std::max(array[8], array[9]); + array[11] = std::max(array[10], array[11]); + array[13] = std::max(array[12], array[13]); + array[15] = std::max(array[14], array[15]); + array[17] = std::max(array[16], array[17]); + array[19] = std::max(array[18], array[19]); + array[21] = std::max(array[20], array[21]); + array[23] = std::max(array[22], array[23]); + array[24] = std::min(array[24], array[25]); + array[26] = std::min(array[26], array[27]); + array[28] = std::min(array[28], array[29]); + array[30] = std::min(array[30], array[31]); + array[32] = std::min(array[32], array[33]); + array[34] = std::min(array[34], array[35]); + array[36] = std::min(array[36], array[37]); + array[38] = std::min(array[38], array[39]); + array[40] = std::min(array[40], array[41]); + array[42] = std::min(array[42], array[43]); + array[44] = std::min(array[44], array[45]); + array[46] = std::min(array[46], array[47]); + array[32] = std::max(array[1], array[32]); + array[34] = std::max(array[3], array[34]); + array[36] = std::max(array[5], array[36]); + array[38] = std::max(array[7], array[38]); + array[9] = std::min(array[9], array[40]); + array[11] = std::min(array[11], array[42]); + array[13] = std::min(array[13], array[44]); + array[15] = std::min(array[15], array[46]); + array[17] = std::min(array[17], array[48]); + array[24] = std::max(array[9], array[24]); + array[26] = std::max(array[11], array[26]); + array[28] = std::max(array[13], array[28]); + array[30] = std::max(array[15], array[30]); + array[17] = std::min(array[17], array[32]); + array[19] = std::min(array[19], array[34]); + array[21] = std::min(array[21], array[36]); + array[23] = std::min(array[23], array[38]); + array[24] = std::max(array[17], array[24]); + array[26] = std::max(array[19], array[26]); + array[21] = std::min(array[21], array[28]); + array[23] = std::min(array[23], array[30]); + array[24] = std::max(array[21], array[24]); + array[23] = std::min(array[23], array[26]); + return std::max(array[23], array[24]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[32]); + array[32] = vmaxf(array[0], array[32]); + array[0] = tmp; + tmp = vminf(array[1], array[33]); + array[33] = vmaxf(array[1], array[33]); + array[1] = tmp; + tmp = vminf(array[2], array[34]); + array[34] = vmaxf(array[2], array[34]); + array[2] = tmp; + tmp = vminf(array[3], array[35]); + array[35] = vmaxf(array[3], array[35]); + array[3] = tmp; + tmp = vminf(array[4], array[36]); + array[36] = vmaxf(array[4], array[36]); + array[4] = tmp; + tmp = vminf(array[5], array[37]); + array[37] = vmaxf(array[5], array[37]); + array[5] = tmp; + tmp = vminf(array[6], array[38]); + array[38] = vmaxf(array[6], array[38]); + array[6] = tmp; + tmp = vminf(array[7], array[39]); + array[39] = vmaxf(array[7], array[39]); + array[7] = tmp; + tmp = vminf(array[8], array[40]); + array[40] = vmaxf(array[8], array[40]); + array[8] = tmp; + tmp = vminf(array[9], array[41]); + array[41] = vmaxf(array[9], array[41]); + array[9] = tmp; + tmp = vminf(array[10], array[42]); + array[42] = vmaxf(array[10], array[42]); + array[10] = tmp; + tmp = vminf(array[11], array[43]); + array[43] = vmaxf(array[11], array[43]); + array[11] = tmp; + tmp = vminf(array[12], array[44]); + array[44] = vmaxf(array[12], array[44]); + array[12] = tmp; + tmp = vminf(array[13], array[45]); + array[45] = vmaxf(array[13], array[45]); + array[13] = tmp; + tmp = vminf(array[14], array[46]); + array[46] = vmaxf(array[14], array[46]); + array[14] = tmp; + tmp = vminf(array[15], array[47]); + array[47] = vmaxf(array[15], array[47]); + array[15] = tmp; + tmp = vminf(array[16], array[48]); + array[48] = vmaxf(array[16], array[48]); + array[16] = tmp; + tmp = vminf(array[0], array[16]); + array[16] = vmaxf(array[0], array[16]); + array[0] = tmp; + tmp = vminf(array[1], array[17]); + array[17] = vmaxf(array[1], array[17]); + array[1] = tmp; + tmp = vminf(array[2], array[18]); + array[18] = vmaxf(array[2], array[18]); + array[2] = tmp; + tmp = vminf(array[3], array[19]); + array[19] = vmaxf(array[3], array[19]); + array[3] = tmp; + tmp = vminf(array[4], array[20]); + array[20] = vmaxf(array[4], array[20]); + array[4] = tmp; + tmp = vminf(array[5], array[21]); + array[21] = vmaxf(array[5], array[21]); + array[5] = tmp; + tmp = vminf(array[6], array[22]); + array[22] = vmaxf(array[6], array[22]); + array[6] = tmp; + tmp = vminf(array[7], array[23]); + array[23] = vmaxf(array[7], array[23]); + array[7] = tmp; + tmp = vminf(array[8], array[24]); + array[24] = vmaxf(array[8], array[24]); + array[8] = tmp; + tmp = vminf(array[9], array[25]); + array[25] = vmaxf(array[9], array[25]); + array[9] = tmp; + tmp = vminf(array[10], array[26]); + array[26] = vmaxf(array[10], array[26]); + array[10] = tmp; + tmp = vminf(array[11], array[27]); + array[27] = vmaxf(array[11], array[27]); + array[11] = tmp; + tmp = vminf(array[12], array[28]); + array[28] = vmaxf(array[12], array[28]); + array[12] = tmp; + tmp = vminf(array[13], array[29]); + array[29] = vmaxf(array[13], array[29]); + array[13] = tmp; + tmp = vminf(array[14], array[30]); + array[30] = vmaxf(array[14], array[30]); + array[14] = tmp; + tmp = vminf(array[15], array[31]); + array[31] = vmaxf(array[15], array[31]); + array[15] = tmp; + tmp = vminf(array[32], array[48]); + array[48] = vmaxf(array[32], array[48]); + array[32] = tmp; + tmp = vminf(array[16], array[32]); + array[32] = vmaxf(array[16], array[32]); + array[16] = tmp; + tmp = vminf(array[17], array[33]); + array[33] = vmaxf(array[17], array[33]); + array[17] = tmp; + tmp = vminf(array[18], array[34]); + array[34] = vmaxf(array[18], array[34]); + array[18] = tmp; + tmp = vminf(array[19], array[35]); + array[35] = vmaxf(array[19], array[35]); + array[19] = tmp; + tmp = vminf(array[20], array[36]); + array[36] = vmaxf(array[20], array[36]); + array[20] = tmp; + tmp = vminf(array[21], array[37]); + array[37] = vmaxf(array[21], array[37]); + array[21] = tmp; + tmp = vminf(array[22], array[38]); + array[38] = vmaxf(array[22], array[38]); + array[22] = tmp; + tmp = vminf(array[23], array[39]); + array[39] = vmaxf(array[23], array[39]); + array[23] = tmp; + tmp = vminf(array[24], array[40]); + array[40] = vmaxf(array[24], array[40]); + array[24] = tmp; + tmp = vminf(array[25], array[41]); + array[41] = vmaxf(array[25], array[41]); + array[25] = tmp; + tmp = vminf(array[26], array[42]); + array[42] = vmaxf(array[26], array[42]); + array[26] = tmp; + tmp = vminf(array[27], array[43]); + array[43] = vmaxf(array[27], array[43]); + array[27] = tmp; + tmp = vminf(array[28], array[44]); + array[44] = vmaxf(array[28], array[44]); + array[28] = tmp; + tmp = vminf(array[29], array[45]); + array[45] = vmaxf(array[29], array[45]); + array[29] = tmp; + tmp = vminf(array[30], array[46]); + array[46] = vmaxf(array[30], array[46]); + array[30] = tmp; + tmp = vminf(array[31], array[47]); + array[47] = vmaxf(array[31], array[47]); + array[31] = tmp; + tmp = vminf(array[0], array[8]); + array[8] = vmaxf(array[0], array[8]); + array[0] = tmp; + tmp = vminf(array[1], array[9]); + array[9] = vmaxf(array[1], array[9]); + array[1] = tmp; + tmp = vminf(array[2], array[10]); + array[10] = vmaxf(array[2], array[10]); + array[2] = tmp; + tmp = vminf(array[3], array[11]); + array[11] = vmaxf(array[3], array[11]); + array[3] = tmp; + tmp = vminf(array[4], array[12]); + array[12] = vmaxf(array[4], array[12]); + array[4] = tmp; + tmp = vminf(array[5], array[13]); + array[13] = vmaxf(array[5], array[13]); + array[5] = tmp; + tmp = vminf(array[6], array[14]); + array[14] = vmaxf(array[6], array[14]); + array[6] = tmp; + tmp = vminf(array[7], array[15]); + array[15] = vmaxf(array[7], array[15]); + array[7] = tmp; + tmp = vminf(array[16], array[24]); + array[24] = vmaxf(array[16], array[24]); + array[16] = tmp; + tmp = vminf(array[17], array[25]); + array[25] = vmaxf(array[17], array[25]); + array[17] = tmp; + tmp = vminf(array[18], array[26]); + array[26] = vmaxf(array[18], array[26]); + array[18] = tmp; + tmp = vminf(array[19], array[27]); + array[27] = vmaxf(array[19], array[27]); + array[19] = tmp; + tmp = vminf(array[20], array[28]); + array[28] = vmaxf(array[20], array[28]); + array[20] = tmp; + tmp = vminf(array[21], array[29]); + array[29] = vmaxf(array[21], array[29]); + array[21] = tmp; + tmp = vminf(array[22], array[30]); + array[30] = vmaxf(array[22], array[30]); + array[22] = tmp; + tmp = vminf(array[23], array[31]); + array[31] = vmaxf(array[23], array[31]); + array[23] = tmp; + tmp = vminf(array[32], array[40]); + array[40] = vmaxf(array[32], array[40]); + array[32] = tmp; + tmp = vminf(array[33], array[41]); + array[41] = vmaxf(array[33], array[41]); + array[33] = tmp; + tmp = vminf(array[34], array[42]); + array[42] = vmaxf(array[34], array[42]); + array[34] = tmp; + tmp = vminf(array[35], array[43]); + array[43] = vmaxf(array[35], array[43]); + array[35] = tmp; + tmp = vminf(array[36], array[44]); + array[44] = vmaxf(array[36], array[44]); + array[36] = tmp; + tmp = vminf(array[37], array[45]); + array[45] = vmaxf(array[37], array[45]); + array[37] = tmp; + tmp = vminf(array[38], array[46]); + array[46] = vmaxf(array[38], array[46]); + array[38] = tmp; + tmp = vminf(array[39], array[47]); + array[47] = vmaxf(array[39], array[47]); + array[39] = tmp; + tmp = vminf(array[8], array[32]); + array[32] = vmaxf(array[8], array[32]); + array[8] = tmp; + tmp = vminf(array[9], array[33]); + array[33] = vmaxf(array[9], array[33]); + array[9] = tmp; + tmp = vminf(array[10], array[34]); + array[34] = vmaxf(array[10], array[34]); + array[10] = tmp; + tmp = vminf(array[11], array[35]); + array[35] = vmaxf(array[11], array[35]); + array[11] = tmp; + tmp = vminf(array[12], array[36]); + array[36] = vmaxf(array[12], array[36]); + array[12] = tmp; + tmp = vminf(array[13], array[37]); + array[37] = vmaxf(array[13], array[37]); + array[13] = tmp; + tmp = vminf(array[14], array[38]); + array[38] = vmaxf(array[14], array[38]); + array[14] = tmp; + tmp = vminf(array[15], array[39]); + array[39] = vmaxf(array[15], array[39]); + array[15] = tmp; + tmp = vminf(array[24], array[48]); + array[48] = vmaxf(array[24], array[48]); + array[24] = tmp; + tmp = vminf(array[8], array[16]); + array[16] = vmaxf(array[8], array[16]); + array[8] = tmp; + tmp = vminf(array[9], array[17]); + array[17] = vmaxf(array[9], array[17]); + array[9] = tmp; + tmp = vminf(array[10], array[18]); + array[18] = vmaxf(array[10], array[18]); + array[10] = tmp; + tmp = vminf(array[11], array[19]); + array[19] = vmaxf(array[11], array[19]); + array[11] = tmp; + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[13], array[21]); + array[21] = vmaxf(array[13], array[21]); + array[13] = tmp; + tmp = vminf(array[14], array[22]); + array[22] = vmaxf(array[14], array[22]); + array[14] = tmp; + tmp = vminf(array[15], array[23]); + array[23] = vmaxf(array[15], array[23]); + array[15] = tmp; + tmp = vminf(array[24], array[32]); + array[32] = vmaxf(array[24], array[32]); + array[24] = tmp; + tmp = vminf(array[25], array[33]); + array[33] = vmaxf(array[25], array[33]); + array[25] = tmp; + tmp = vminf(array[26], array[34]); + array[34] = vmaxf(array[26], array[34]); + array[26] = tmp; + tmp = vminf(array[27], array[35]); + array[35] = vmaxf(array[27], array[35]); + array[27] = tmp; + tmp = vminf(array[28], array[36]); + array[36] = vmaxf(array[28], array[36]); + array[28] = tmp; + tmp = vminf(array[29], array[37]); + array[37] = vmaxf(array[29], array[37]); + array[29] = tmp; + tmp = vminf(array[30], array[38]); + array[38] = vmaxf(array[30], array[38]); + array[30] = tmp; + tmp = vminf(array[31], array[39]); + array[39] = vmaxf(array[31], array[39]); + array[31] = tmp; + tmp = vminf(array[40], array[48]); + array[48] = vmaxf(array[40], array[48]); + array[40] = tmp; + tmp = vminf(array[0], array[4]); + array[4] = vmaxf(array[0], array[4]); + array[0] = tmp; + tmp = vminf(array[1], array[5]); + array[5] = vmaxf(array[1], array[5]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[8], array[12]); + array[12] = vmaxf(array[8], array[12]); + array[8] = tmp; + tmp = vminf(array[9], array[13]); + array[13] = vmaxf(array[9], array[13]); + array[9] = tmp; + tmp = vminf(array[10], array[14]); + array[14] = vmaxf(array[10], array[14]); + array[10] = tmp; + tmp = vminf(array[11], array[15]); + array[15] = vmaxf(array[11], array[15]); + array[11] = tmp; + tmp = vminf(array[16], array[20]); + array[20] = vmaxf(array[16], array[20]); + array[16] = tmp; + tmp = vminf(array[17], array[21]); + array[21] = vmaxf(array[17], array[21]); + array[17] = tmp; + tmp = vminf(array[18], array[22]); + array[22] = vmaxf(array[18], array[22]); + array[18] = tmp; + tmp = vminf(array[19], array[23]); + array[23] = vmaxf(array[19], array[23]); + array[19] = tmp; + tmp = vminf(array[24], array[28]); + array[28] = vmaxf(array[24], array[28]); + array[24] = tmp; + tmp = vminf(array[25], array[29]); + array[29] = vmaxf(array[25], array[29]); + array[25] = tmp; + tmp = vminf(array[26], array[30]); + array[30] = vmaxf(array[26], array[30]); + array[26] = tmp; + tmp = vminf(array[27], array[31]); + array[31] = vmaxf(array[27], array[31]); + array[27] = tmp; + tmp = vminf(array[32], array[36]); + array[36] = vmaxf(array[32], array[36]); + array[32] = tmp; + tmp = vminf(array[33], array[37]); + array[37] = vmaxf(array[33], array[37]); + array[33] = tmp; + tmp = vminf(array[34], array[38]); + array[38] = vmaxf(array[34], array[38]); + array[34] = tmp; + tmp = vminf(array[35], array[39]); + array[39] = vmaxf(array[35], array[39]); + array[35] = tmp; + tmp = vminf(array[40], array[44]); + array[44] = vmaxf(array[40], array[44]); + array[40] = tmp; + tmp = vminf(array[41], array[45]); + array[45] = vmaxf(array[41], array[45]); + array[41] = tmp; + tmp = vminf(array[42], array[46]); + array[46] = vmaxf(array[42], array[46]); + array[42] = tmp; + tmp = vminf(array[43], array[47]); + array[47] = vmaxf(array[43], array[47]); + array[43] = tmp; + tmp = vminf(array[4], array[32]); + array[32] = vmaxf(array[4], array[32]); + array[4] = tmp; + tmp = vminf(array[5], array[33]); + array[33] = vmaxf(array[5], array[33]); + array[5] = tmp; + tmp = vminf(array[6], array[34]); + array[34] = vmaxf(array[6], array[34]); + array[6] = tmp; + tmp = vminf(array[7], array[35]); + array[35] = vmaxf(array[7], array[35]); + array[7] = tmp; + tmp = vminf(array[12], array[40]); + array[40] = vmaxf(array[12], array[40]); + array[12] = tmp; + tmp = vminf(array[13], array[41]); + array[41] = vmaxf(array[13], array[41]); + array[13] = tmp; + tmp = vminf(array[14], array[42]); + array[42] = vmaxf(array[14], array[42]); + array[14] = tmp; + tmp = vminf(array[15], array[43]); + array[43] = vmaxf(array[15], array[43]); + array[15] = tmp; + tmp = vminf(array[20], array[48]); + array[48] = vmaxf(array[20], array[48]); + array[20] = tmp; + tmp = vminf(array[4], array[16]); + array[16] = vmaxf(array[4], array[16]); + array[4] = tmp; + tmp = vminf(array[5], array[17]); + array[17] = vmaxf(array[5], array[17]); + array[5] = tmp; + tmp = vminf(array[6], array[18]); + array[18] = vmaxf(array[6], array[18]); + array[6] = tmp; + tmp = vminf(array[7], array[19]); + array[19] = vmaxf(array[7], array[19]); + array[7] = tmp; + tmp = vminf(array[12], array[24]); + array[24] = vmaxf(array[12], array[24]); + array[12] = tmp; + tmp = vminf(array[13], array[25]); + array[25] = vmaxf(array[13], array[25]); + array[13] = tmp; + tmp = vminf(array[14], array[26]); + array[26] = vmaxf(array[14], array[26]); + array[14] = tmp; + tmp = vminf(array[15], array[27]); + array[27] = vmaxf(array[15], array[27]); + array[15] = tmp; + tmp = vminf(array[20], array[32]); + array[32] = vmaxf(array[20], array[32]); + array[20] = tmp; + tmp = vminf(array[21], array[33]); + array[33] = vmaxf(array[21], array[33]); + array[21] = tmp; + tmp = vminf(array[22], array[34]); + array[34] = vmaxf(array[22], array[34]); + array[22] = tmp; + tmp = vminf(array[23], array[35]); + array[35] = vmaxf(array[23], array[35]); + array[23] = tmp; + tmp = vminf(array[28], array[40]); + array[40] = vmaxf(array[28], array[40]); + array[28] = tmp; + tmp = vminf(array[29], array[41]); + array[41] = vmaxf(array[29], array[41]); + array[29] = tmp; + tmp = vminf(array[30], array[42]); + array[42] = vmaxf(array[30], array[42]); + array[30] = tmp; + tmp = vminf(array[31], array[43]); + array[43] = vmaxf(array[31], array[43]); + array[31] = tmp; + tmp = vminf(array[36], array[48]); + array[48] = vmaxf(array[36], array[48]); + array[36] = tmp; + tmp = vminf(array[4], array[8]); + array[8] = vmaxf(array[4], array[8]); + array[4] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[7], array[11]); + array[11] = vmaxf(array[7], array[11]); + array[7] = tmp; + tmp = vminf(array[12], array[16]); + array[16] = vmaxf(array[12], array[16]); + array[12] = tmp; + tmp = vminf(array[13], array[17]); + array[17] = vmaxf(array[13], array[17]); + array[13] = tmp; + tmp = vminf(array[14], array[18]); + array[18] = vmaxf(array[14], array[18]); + array[14] = tmp; + tmp = vminf(array[15], array[19]); + array[19] = vmaxf(array[15], array[19]); + array[15] = tmp; + tmp = vminf(array[20], array[24]); + array[24] = vmaxf(array[20], array[24]); + array[20] = tmp; + tmp = vminf(array[21], array[25]); + array[25] = vmaxf(array[21], array[25]); + array[21] = tmp; + tmp = vminf(array[22], array[26]); + array[26] = vmaxf(array[22], array[26]); + array[22] = tmp; + tmp = vminf(array[23], array[27]); + array[27] = vmaxf(array[23], array[27]); + array[23] = tmp; + tmp = vminf(array[28], array[32]); + array[32] = vmaxf(array[28], array[32]); + array[28] = tmp; + tmp = vminf(array[29], array[33]); + array[33] = vmaxf(array[29], array[33]); + array[29] = tmp; + tmp = vminf(array[30], array[34]); + array[34] = vmaxf(array[30], array[34]); + array[30] = tmp; + tmp = vminf(array[31], array[35]); + array[35] = vmaxf(array[31], array[35]); + array[31] = tmp; + tmp = vminf(array[36], array[40]); + array[40] = vmaxf(array[36], array[40]); + array[36] = tmp; + tmp = vminf(array[37], array[41]); + array[41] = vmaxf(array[37], array[41]); + array[37] = tmp; + tmp = vminf(array[38], array[42]); + array[42] = vmaxf(array[38], array[42]); + array[38] = tmp; + tmp = vminf(array[39], array[43]); + array[43] = vmaxf(array[39], array[43]); + array[39] = tmp; + tmp = vminf(array[44], array[48]); + array[48] = vmaxf(array[44], array[48]); + array[44] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[1], array[3]); + array[3] = vmaxf(array[1], array[3]); + array[1] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + tmp = vminf(array[13], array[15]); + array[15] = vmaxf(array[13], array[15]); + array[13] = tmp; + tmp = vminf(array[16], array[18]); + array[18] = vmaxf(array[16], array[18]); + array[16] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = tmp; + tmp = vminf(array[21], array[23]); + array[23] = vmaxf(array[21], array[23]); + array[21] = tmp; + tmp = vminf(array[24], array[26]); + array[26] = vmaxf(array[24], array[26]); + array[24] = tmp; + tmp = vminf(array[25], array[27]); + array[27] = vmaxf(array[25], array[27]); + array[25] = tmp; + tmp = vminf(array[28], array[30]); + array[30] = vmaxf(array[28], array[30]); + array[28] = tmp; + tmp = vminf(array[29], array[31]); + array[31] = vmaxf(array[29], array[31]); + array[29] = tmp; + tmp = vminf(array[32], array[34]); + array[34] = vmaxf(array[32], array[34]); + array[32] = tmp; + tmp = vminf(array[33], array[35]); + array[35] = vmaxf(array[33], array[35]); + array[33] = tmp; + tmp = vminf(array[36], array[38]); + array[38] = vmaxf(array[36], array[38]); + array[36] = tmp; + tmp = vminf(array[37], array[39]); + array[39] = vmaxf(array[37], array[39]); + array[37] = tmp; + tmp = vminf(array[40], array[42]); + array[42] = vmaxf(array[40], array[42]); + array[40] = tmp; + tmp = vminf(array[41], array[43]); + array[43] = vmaxf(array[41], array[43]); + array[41] = tmp; + tmp = vminf(array[44], array[46]); + array[46] = vmaxf(array[44], array[46]); + array[44] = tmp; + tmp = vminf(array[45], array[47]); + array[47] = vmaxf(array[45], array[47]); + array[45] = tmp; + tmp = vminf(array[2], array[32]); + array[32] = vmaxf(array[2], array[32]); + array[2] = tmp; + tmp = vminf(array[3], array[33]); + array[33] = vmaxf(array[3], array[33]); + array[3] = tmp; + tmp = vminf(array[6], array[36]); + array[36] = vmaxf(array[6], array[36]); + array[6] = tmp; + tmp = vminf(array[7], array[37]); + array[37] = vmaxf(array[7], array[37]); + array[7] = tmp; + tmp = vminf(array[10], array[40]); + array[40] = vmaxf(array[10], array[40]); + array[10] = tmp; + tmp = vminf(array[11], array[41]); + array[41] = vmaxf(array[11], array[41]); + array[11] = tmp; + tmp = vminf(array[14], array[44]); + array[44] = vmaxf(array[14], array[44]); + array[14] = tmp; + tmp = vminf(array[15], array[45]); + array[45] = vmaxf(array[15], array[45]); + array[15] = tmp; + tmp = vminf(array[18], array[48]); + array[48] = vmaxf(array[18], array[48]); + array[18] = tmp; + tmp = vminf(array[2], array[16]); + array[16] = vmaxf(array[2], array[16]); + array[2] = tmp; + tmp = vminf(array[3], array[17]); + array[17] = vmaxf(array[3], array[17]); + array[3] = tmp; + tmp = vminf(array[6], array[20]); + array[20] = vmaxf(array[6], array[20]); + array[6] = tmp; + tmp = vminf(array[7], array[21]); + array[21] = vmaxf(array[7], array[21]); + array[7] = tmp; + tmp = vminf(array[10], array[24]); + array[24] = vmaxf(array[10], array[24]); + array[10] = tmp; + tmp = vminf(array[11], array[25]); + array[25] = vmaxf(array[11], array[25]); + array[11] = tmp; + tmp = vminf(array[14], array[28]); + array[28] = vmaxf(array[14], array[28]); + array[14] = tmp; + tmp = vminf(array[15], array[29]); + array[29] = vmaxf(array[15], array[29]); + array[15] = tmp; + tmp = vminf(array[18], array[32]); + array[32] = vmaxf(array[18], array[32]); + array[18] = tmp; + tmp = vminf(array[19], array[33]); + array[33] = vmaxf(array[19], array[33]); + array[19] = tmp; + tmp = vminf(array[22], array[36]); + array[36] = vmaxf(array[22], array[36]); + array[22] = tmp; + tmp = vminf(array[23], array[37]); + array[37] = vmaxf(array[23], array[37]); + array[23] = tmp; + tmp = vminf(array[26], array[40]); + array[40] = vmaxf(array[26], array[40]); + array[26] = tmp; + tmp = vminf(array[27], array[41]); + array[41] = vmaxf(array[27], array[41]); + array[27] = tmp; + tmp = vminf(array[30], array[44]); + array[44] = vmaxf(array[30], array[44]); + array[30] = tmp; + tmp = vminf(array[31], array[45]); + array[45] = vmaxf(array[31], array[45]); + array[31] = tmp; + tmp = vminf(array[34], array[48]); + array[48] = vmaxf(array[34], array[48]); + array[34] = tmp; + tmp = vminf(array[2], array[8]); + array[8] = vmaxf(array[2], array[8]); + array[2] = tmp; + tmp = vminf(array[3], array[9]); + array[9] = vmaxf(array[3], array[9]); + array[3] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[13]); + array[13] = vmaxf(array[7], array[13]); + array[7] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = tmp; + tmp = vminf(array[11], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[11] = tmp; + tmp = vminf(array[14], array[20]); + array[20] = vmaxf(array[14], array[20]); + array[14] = tmp; + tmp = vminf(array[15], array[21]); + array[21] = vmaxf(array[15], array[21]); + array[15] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = tmp; + tmp = vminf(array[19], array[25]); + array[25] = vmaxf(array[19], array[25]); + array[19] = tmp; + tmp = vminf(array[22], array[28]); + array[28] = vmaxf(array[22], array[28]); + array[22] = tmp; + tmp = vminf(array[23], array[29]); + array[29] = vmaxf(array[23], array[29]); + array[23] = tmp; + tmp = vminf(array[26], array[32]); + array[32] = vmaxf(array[26], array[32]); + array[26] = tmp; + tmp = vminf(array[27], array[33]); + array[33] = vmaxf(array[27], array[33]); + array[27] = tmp; + tmp = vminf(array[30], array[36]); + array[36] = vmaxf(array[30], array[36]); + array[30] = tmp; + tmp = vminf(array[31], array[37]); + array[37] = vmaxf(array[31], array[37]); + array[31] = tmp; + tmp = vminf(array[34], array[40]); + array[40] = vmaxf(array[34], array[40]); + array[34] = tmp; + tmp = vminf(array[35], array[41]); + array[41] = vmaxf(array[35], array[41]); + array[35] = tmp; + tmp = vminf(array[38], array[44]); + array[44] = vmaxf(array[38], array[44]); + array[38] = tmp; + tmp = vminf(array[39], array[45]); + array[45] = vmaxf(array[39], array[45]); + array[39] = tmp; + tmp = vminf(array[42], array[48]); + array[48] = vmaxf(array[42], array[48]); + array[42] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[6] = tmp; + tmp = vminf(array[7], array[9]); + array[9] = vmaxf(array[7], array[9]); + array[7] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = tmp; + tmp = vminf(array[15], array[17]); + array[17] = vmaxf(array[15], array[17]); + array[15] = tmp; + tmp = vminf(array[18], array[20]); + array[20] = vmaxf(array[18], array[20]); + array[18] = tmp; + tmp = vminf(array[19], array[21]); + array[21] = vmaxf(array[19], array[21]); + array[19] = tmp; + tmp = vminf(array[22], array[24]); + array[24] = vmaxf(array[22], array[24]); + array[22] = tmp; + tmp = vminf(array[23], array[25]); + array[25] = vmaxf(array[23], array[25]); + array[23] = tmp; + tmp = vminf(array[26], array[28]); + array[28] = vmaxf(array[26], array[28]); + array[26] = tmp; + tmp = vminf(array[27], array[29]); + array[29] = vmaxf(array[27], array[29]); + array[27] = tmp; + tmp = vminf(array[30], array[32]); + array[32] = vmaxf(array[30], array[32]); + array[30] = tmp; + tmp = vminf(array[31], array[33]); + array[33] = vmaxf(array[31], array[33]); + array[31] = tmp; + tmp = vminf(array[34], array[36]); + array[36] = vmaxf(array[34], array[36]); + array[34] = tmp; + tmp = vminf(array[35], array[37]); + array[37] = vmaxf(array[35], array[37]); + array[35] = tmp; + tmp = vminf(array[38], array[40]); + array[40] = vmaxf(array[38], array[40]); + array[38] = tmp; + tmp = vminf(array[39], array[41]); + array[41] = vmaxf(array[39], array[41]); + array[39] = tmp; + tmp = vminf(array[42], array[44]); + array[44] = vmaxf(array[42], array[44]); + array[42] = tmp; + tmp = vminf(array[43], array[45]); + array[45] = vmaxf(array[43], array[45]); + array[43] = tmp; + tmp = vminf(array[46], array[48]); + array[48] = vmaxf(array[46], array[48]); + array[46] = tmp; + array[1] = vmaxf(array[0], array[1]); + array[3] = vmaxf(array[2], array[3]); + array[5] = vmaxf(array[4], array[5]); + array[7] = vmaxf(array[6], array[7]); + array[9] = vmaxf(array[8], array[9]); + array[11] = vmaxf(array[10], array[11]); + array[13] = vmaxf(array[12], array[13]); + array[15] = vmaxf(array[14], array[15]); + array[17] = vmaxf(array[16], array[17]); + array[19] = vmaxf(array[18], array[19]); + array[21] = vmaxf(array[20], array[21]); + array[23] = vmaxf(array[22], array[23]); + array[24] = vminf(array[24], array[25]); + array[26] = vminf(array[26], array[27]); + array[28] = vminf(array[28], array[29]); + array[30] = vminf(array[30], array[31]); + array[32] = vminf(array[32], array[33]); + array[34] = vminf(array[34], array[35]); + array[36] = vminf(array[36], array[37]); + array[38] = vminf(array[38], array[39]); + array[40] = vminf(array[40], array[41]); + array[42] = vminf(array[42], array[43]); + array[44] = vminf(array[44], array[45]); + array[46] = vminf(array[46], array[47]); + array[32] = vmaxf(array[1], array[32]); + array[34] = vmaxf(array[3], array[34]); + array[36] = vmaxf(array[5], array[36]); + array[38] = vmaxf(array[7], array[38]); + array[9] = vminf(array[9], array[40]); + array[11] = vminf(array[11], array[42]); + array[13] = vminf(array[13], array[44]); + array[15] = vminf(array[15], array[46]); + array[17] = vminf(array[17], array[48]); + array[24] = vmaxf(array[9], array[24]); + array[26] = vmaxf(array[11], array[26]); + array[28] = vmaxf(array[13], array[28]); + array[30] = vmaxf(array[15], array[30]); + array[17] = vminf(array[17], array[32]); + array[19] = vminf(array[19], array[34]); + array[21] = vminf(array[21], array[36]); + array[23] = vminf(array[23], array[38]); + array[24] = vmaxf(array[17], array[24]); + array[26] = vmaxf(array[19], array[26]); + array[21] = vminf(array[21], array[28]); + array[23] = vminf(array[23], array[30]); + array[24] = vmaxf(array[21], array[24]); + array[23] = vminf(array[23], array[26]); + return vmaxf(array[23], array[24]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[64]); + array[64] = std::max(array[0], array[64]); + array[0] = tmp; + tmp = std::min(array[1], array[65]); + array[65] = std::max(array[1], array[65]); + array[1] = tmp; + tmp = std::min(array[2], array[66]); + array[66] = std::max(array[2], array[66]); + array[2] = tmp; + tmp = std::min(array[3], array[67]); + array[67] = std::max(array[3], array[67]); + array[3] = tmp; + tmp = std::min(array[4], array[68]); + array[68] = std::max(array[4], array[68]); + array[4] = tmp; + tmp = std::min(array[5], array[69]); + array[69] = std::max(array[5], array[69]); + array[5] = tmp; + tmp = std::min(array[6], array[70]); + array[70] = std::max(array[6], array[70]); + array[6] = tmp; + tmp = std::min(array[7], array[71]); + array[71] = std::max(array[7], array[71]); + array[7] = tmp; + tmp = std::min(array[8], array[72]); + array[72] = std::max(array[8], array[72]); + array[8] = tmp; + tmp = std::min(array[9], array[73]); + array[73] = std::max(array[9], array[73]); + array[9] = tmp; + tmp = std::min(array[10], array[74]); + array[74] = std::max(array[10], array[74]); + array[10] = tmp; + tmp = std::min(array[11], array[75]); + array[75] = std::max(array[11], array[75]); + array[11] = tmp; + tmp = std::min(array[12], array[76]); + array[76] = std::max(array[12], array[76]); + array[12] = tmp; + tmp = std::min(array[13], array[77]); + array[77] = std::max(array[13], array[77]); + array[13] = tmp; + tmp = std::min(array[14], array[78]); + array[78] = std::max(array[14], array[78]); + array[14] = tmp; + tmp = std::min(array[15], array[79]); + array[79] = std::max(array[15], array[79]); + array[15] = tmp; + tmp = std::min(array[16], array[80]); + array[80] = std::max(array[16], array[80]); + array[16] = tmp; + tmp = std::min(array[0], array[32]); + array[32] = std::max(array[0], array[32]); + array[0] = tmp; + tmp = std::min(array[1], array[33]); + array[33] = std::max(array[1], array[33]); + array[1] = tmp; + tmp = std::min(array[2], array[34]); + array[34] = std::max(array[2], array[34]); + array[2] = tmp; + tmp = std::min(array[3], array[35]); + array[35] = std::max(array[3], array[35]); + array[3] = tmp; + tmp = std::min(array[4], array[36]); + array[36] = std::max(array[4], array[36]); + array[4] = tmp; + tmp = std::min(array[5], array[37]); + array[37] = std::max(array[5], array[37]); + array[5] = tmp; + tmp = std::min(array[6], array[38]); + array[38] = std::max(array[6], array[38]); + array[6] = tmp; + tmp = std::min(array[7], array[39]); + array[39] = std::max(array[7], array[39]); + array[7] = tmp; + tmp = std::min(array[8], array[40]); + array[40] = std::max(array[8], array[40]); + array[8] = tmp; + tmp = std::min(array[9], array[41]); + array[41] = std::max(array[9], array[41]); + array[9] = tmp; + tmp = std::min(array[10], array[42]); + array[42] = std::max(array[10], array[42]); + array[10] = tmp; + tmp = std::min(array[11], array[43]); + array[43] = std::max(array[11], array[43]); + array[11] = tmp; + tmp = std::min(array[12], array[44]); + array[44] = std::max(array[12], array[44]); + array[12] = tmp; + tmp = std::min(array[13], array[45]); + array[45] = std::max(array[13], array[45]); + array[13] = tmp; + tmp = std::min(array[14], array[46]); + array[46] = std::max(array[14], array[46]); + array[14] = tmp; + tmp = std::min(array[15], array[47]); + array[47] = std::max(array[15], array[47]); + array[15] = tmp; + tmp = std::min(array[16], array[48]); + array[48] = std::max(array[16], array[48]); + array[16] = tmp; + tmp = std::min(array[17], array[49]); + array[49] = std::max(array[17], array[49]); + array[17] = tmp; + tmp = std::min(array[18], array[50]); + array[50] = std::max(array[18], array[50]); + array[18] = tmp; + tmp = std::min(array[19], array[51]); + array[51] = std::max(array[19], array[51]); + array[19] = tmp; + tmp = std::min(array[20], array[52]); + array[52] = std::max(array[20], array[52]); + array[20] = tmp; + tmp = std::min(array[21], array[53]); + array[53] = std::max(array[21], array[53]); + array[21] = tmp; + tmp = std::min(array[22], array[54]); + array[54] = std::max(array[22], array[54]); + array[22] = tmp; + tmp = std::min(array[23], array[55]); + array[55] = std::max(array[23], array[55]); + array[23] = tmp; + tmp = std::min(array[24], array[56]); + array[56] = std::max(array[24], array[56]); + array[24] = tmp; + tmp = std::min(array[25], array[57]); + array[57] = std::max(array[25], array[57]); + array[25] = tmp; + tmp = std::min(array[26], array[58]); + array[58] = std::max(array[26], array[58]); + array[26] = tmp; + tmp = std::min(array[27], array[59]); + array[59] = std::max(array[27], array[59]); + array[27] = tmp; + tmp = std::min(array[28], array[60]); + array[60] = std::max(array[28], array[60]); + array[28] = tmp; + tmp = std::min(array[29], array[61]); + array[61] = std::max(array[29], array[61]); + array[29] = tmp; + tmp = std::min(array[30], array[62]); + array[62] = std::max(array[30], array[62]); + array[30] = tmp; + tmp = std::min(array[31], array[63]); + array[63] = std::max(array[31], array[63]); + array[31] = tmp; + tmp = std::min(array[32], array[64]); + array[64] = std::max(array[32], array[64]); + array[32] = tmp; + tmp = std::min(array[33], array[65]); + array[65] = std::max(array[33], array[65]); + array[33] = tmp; + tmp = std::min(array[34], array[66]); + array[66] = std::max(array[34], array[66]); + array[34] = tmp; + tmp = std::min(array[35], array[67]); + array[67] = std::max(array[35], array[67]); + array[35] = tmp; + tmp = std::min(array[36], array[68]); + array[68] = std::max(array[36], array[68]); + array[36] = tmp; + tmp = std::min(array[37], array[69]); + array[69] = std::max(array[37], array[69]); + array[37] = tmp; + tmp = std::min(array[38], array[70]); + array[70] = std::max(array[38], array[70]); + array[38] = tmp; + tmp = std::min(array[39], array[71]); + array[71] = std::max(array[39], array[71]); + array[39] = tmp; + tmp = std::min(array[40], array[72]); + array[72] = std::max(array[40], array[72]); + array[40] = tmp; + tmp = std::min(array[41], array[73]); + array[73] = std::max(array[41], array[73]); + array[41] = tmp; + tmp = std::min(array[42], array[74]); + array[74] = std::max(array[42], array[74]); + array[42] = tmp; + tmp = std::min(array[43], array[75]); + array[75] = std::max(array[43], array[75]); + array[43] = tmp; + tmp = std::min(array[44], array[76]); + array[76] = std::max(array[44], array[76]); + array[44] = tmp; + tmp = std::min(array[45], array[77]); + array[77] = std::max(array[45], array[77]); + array[45] = tmp; + tmp = std::min(array[46], array[78]); + array[78] = std::max(array[46], array[78]); + array[46] = tmp; + tmp = std::min(array[47], array[79]); + array[79] = std::max(array[47], array[79]); + array[47] = tmp; + tmp = std::min(array[48], array[80]); + array[80] = std::max(array[48], array[80]); + array[48] = tmp; + tmp = std::min(array[0], array[16]); + array[16] = std::max(array[0], array[16]); + array[0] = tmp; + tmp = std::min(array[1], array[17]); + array[17] = std::max(array[1], array[17]); + array[1] = tmp; + tmp = std::min(array[2], array[18]); + array[18] = std::max(array[2], array[18]); + array[2] = tmp; + tmp = std::min(array[3], array[19]); + array[19] = std::max(array[3], array[19]); + array[3] = tmp; + tmp = std::min(array[4], array[20]); + array[20] = std::max(array[4], array[20]); + array[4] = tmp; + tmp = std::min(array[5], array[21]); + array[21] = std::max(array[5], array[21]); + array[5] = tmp; + tmp = std::min(array[6], array[22]); + array[22] = std::max(array[6], array[22]); + array[6] = tmp; + tmp = std::min(array[7], array[23]); + array[23] = std::max(array[7], array[23]); + array[7] = tmp; + tmp = std::min(array[8], array[24]); + array[24] = std::max(array[8], array[24]); + array[8] = tmp; + tmp = std::min(array[9], array[25]); + array[25] = std::max(array[9], array[25]); + array[9] = tmp; + tmp = std::min(array[10], array[26]); + array[26] = std::max(array[10], array[26]); + array[10] = tmp; + tmp = std::min(array[11], array[27]); + array[27] = std::max(array[11], array[27]); + array[11] = tmp; + tmp = std::min(array[12], array[28]); + array[28] = std::max(array[12], array[28]); + array[12] = tmp; + tmp = std::min(array[13], array[29]); + array[29] = std::max(array[13], array[29]); + array[13] = tmp; + tmp = std::min(array[14], array[30]); + array[30] = std::max(array[14], array[30]); + array[14] = tmp; + tmp = std::min(array[15], array[31]); + array[31] = std::max(array[15], array[31]); + array[15] = tmp; + tmp = std::min(array[32], array[48]); + array[48] = std::max(array[32], array[48]); + array[32] = tmp; + tmp = std::min(array[33], array[49]); + array[49] = std::max(array[33], array[49]); + array[33] = tmp; + tmp = std::min(array[34], array[50]); + array[50] = std::max(array[34], array[50]); + array[34] = tmp; + tmp = std::min(array[35], array[51]); + array[51] = std::max(array[35], array[51]); + array[35] = tmp; + tmp = std::min(array[36], array[52]); + array[52] = std::max(array[36], array[52]); + array[36] = tmp; + tmp = std::min(array[37], array[53]); + array[53] = std::max(array[37], array[53]); + array[37] = tmp; + tmp = std::min(array[38], array[54]); + array[54] = std::max(array[38], array[54]); + array[38] = tmp; + tmp = std::min(array[39], array[55]); + array[55] = std::max(array[39], array[55]); + array[39] = tmp; + tmp = std::min(array[40], array[56]); + array[56] = std::max(array[40], array[56]); + array[40] = tmp; + tmp = std::min(array[41], array[57]); + array[57] = std::max(array[41], array[57]); + array[41] = tmp; + tmp = std::min(array[42], array[58]); + array[58] = std::max(array[42], array[58]); + array[42] = tmp; + tmp = std::min(array[43], array[59]); + array[59] = std::max(array[43], array[59]); + array[43] = tmp; + tmp = std::min(array[44], array[60]); + array[60] = std::max(array[44], array[60]); + array[44] = tmp; + tmp = std::min(array[45], array[61]); + array[61] = std::max(array[45], array[61]); + array[45] = tmp; + tmp = std::min(array[46], array[62]); + array[62] = std::max(array[46], array[62]); + array[46] = tmp; + tmp = std::min(array[47], array[63]); + array[63] = std::max(array[47], array[63]); + array[47] = tmp; + tmp = std::min(array[64], array[80]); + array[80] = std::max(array[64], array[80]); + array[64] = tmp; + tmp = std::min(array[16], array[64]); + array[64] = std::max(array[16], array[64]); + array[16] = tmp; + tmp = std::min(array[17], array[65]); + array[65] = std::max(array[17], array[65]); + array[17] = tmp; + tmp = std::min(array[18], array[66]); + array[66] = std::max(array[18], array[66]); + array[18] = tmp; + tmp = std::min(array[19], array[67]); + array[67] = std::max(array[19], array[67]); + array[19] = tmp; + tmp = std::min(array[20], array[68]); + array[68] = std::max(array[20], array[68]); + array[20] = tmp; + tmp = std::min(array[21], array[69]); + array[69] = std::max(array[21], array[69]); + array[21] = tmp; + tmp = std::min(array[22], array[70]); + array[70] = std::max(array[22], array[70]); + array[22] = tmp; + tmp = std::min(array[23], array[71]); + array[71] = std::max(array[23], array[71]); + array[23] = tmp; + tmp = std::min(array[24], array[72]); + array[72] = std::max(array[24], array[72]); + array[24] = tmp; + tmp = std::min(array[25], array[73]); + array[73] = std::max(array[25], array[73]); + array[25] = tmp; + tmp = std::min(array[26], array[74]); + array[74] = std::max(array[26], array[74]); + array[26] = tmp; + tmp = std::min(array[27], array[75]); + array[75] = std::max(array[27], array[75]); + array[27] = tmp; + tmp = std::min(array[28], array[76]); + array[76] = std::max(array[28], array[76]); + array[28] = tmp; + tmp = std::min(array[29], array[77]); + array[77] = std::max(array[29], array[77]); + array[29] = tmp; + tmp = std::min(array[30], array[78]); + array[78] = std::max(array[30], array[78]); + array[30] = tmp; + tmp = std::min(array[31], array[79]); + array[79] = std::max(array[31], array[79]); + array[31] = tmp; + tmp = std::min(array[16], array[32]); + array[32] = std::max(array[16], array[32]); + array[16] = tmp; + tmp = std::min(array[17], array[33]); + array[33] = std::max(array[17], array[33]); + array[17] = tmp; + tmp = std::min(array[18], array[34]); + array[34] = std::max(array[18], array[34]); + array[18] = tmp; + tmp = std::min(array[19], array[35]); + array[35] = std::max(array[19], array[35]); + array[19] = tmp; + tmp = std::min(array[20], array[36]); + array[36] = std::max(array[20], array[36]); + array[20] = tmp; + tmp = std::min(array[21], array[37]); + array[37] = std::max(array[21], array[37]); + array[21] = tmp; + tmp = std::min(array[22], array[38]); + array[38] = std::max(array[22], array[38]); + array[22] = tmp; + tmp = std::min(array[23], array[39]); + array[39] = std::max(array[23], array[39]); + array[23] = tmp; + tmp = std::min(array[24], array[40]); + array[40] = std::max(array[24], array[40]); + array[24] = tmp; + tmp = std::min(array[25], array[41]); + array[41] = std::max(array[25], array[41]); + array[25] = tmp; + tmp = std::min(array[26], array[42]); + array[42] = std::max(array[26], array[42]); + array[26] = tmp; + tmp = std::min(array[27], array[43]); + array[43] = std::max(array[27], array[43]); + array[27] = tmp; + tmp = std::min(array[28], array[44]); + array[44] = std::max(array[28], array[44]); + array[28] = tmp; + tmp = std::min(array[29], array[45]); + array[45] = std::max(array[29], array[45]); + array[29] = tmp; + tmp = std::min(array[30], array[46]); + array[46] = std::max(array[30], array[46]); + array[30] = tmp; + tmp = std::min(array[31], array[47]); + array[47] = std::max(array[31], array[47]); + array[31] = tmp; + tmp = std::min(array[48], array[64]); + array[64] = std::max(array[48], array[64]); + array[48] = tmp; + tmp = std::min(array[49], array[65]); + array[65] = std::max(array[49], array[65]); + array[49] = tmp; + tmp = std::min(array[50], array[66]); + array[66] = std::max(array[50], array[66]); + array[50] = tmp; + tmp = std::min(array[51], array[67]); + array[67] = std::max(array[51], array[67]); + array[51] = tmp; + tmp = std::min(array[52], array[68]); + array[68] = std::max(array[52], array[68]); + array[52] = tmp; + tmp = std::min(array[53], array[69]); + array[69] = std::max(array[53], array[69]); + array[53] = tmp; + tmp = std::min(array[54], array[70]); + array[70] = std::max(array[54], array[70]); + array[54] = tmp; + tmp = std::min(array[55], array[71]); + array[71] = std::max(array[55], array[71]); + array[55] = tmp; + tmp = std::min(array[56], array[72]); + array[72] = std::max(array[56], array[72]); + array[56] = tmp; + tmp = std::min(array[57], array[73]); + array[73] = std::max(array[57], array[73]); + array[57] = tmp; + tmp = std::min(array[58], array[74]); + array[74] = std::max(array[58], array[74]); + array[58] = tmp; + tmp = std::min(array[59], array[75]); + array[75] = std::max(array[59], array[75]); + array[59] = tmp; + tmp = std::min(array[60], array[76]); + array[76] = std::max(array[60], array[76]); + array[60] = tmp; + tmp = std::min(array[61], array[77]); + array[77] = std::max(array[61], array[77]); + array[61] = tmp; + tmp = std::min(array[62], array[78]); + array[78] = std::max(array[62], array[78]); + array[62] = tmp; + tmp = std::min(array[63], array[79]); + array[79] = std::max(array[63], array[79]); + array[63] = tmp; + tmp = std::min(array[0], array[8]); + array[8] = std::max(array[0], array[8]); + array[0] = tmp; + tmp = std::min(array[1], array[9]); + array[9] = std::max(array[1], array[9]); + array[1] = tmp; + tmp = std::min(array[2], array[10]); + array[10] = std::max(array[2], array[10]); + array[2] = tmp; + tmp = std::min(array[3], array[11]); + array[11] = std::max(array[3], array[11]); + array[3] = tmp; + tmp = std::min(array[4], array[12]); + array[12] = std::max(array[4], array[12]); + array[4] = tmp; + tmp = std::min(array[5], array[13]); + array[13] = std::max(array[5], array[13]); + array[5] = tmp; + tmp = std::min(array[6], array[14]); + array[14] = std::max(array[6], array[14]); + array[6] = tmp; + tmp = std::min(array[7], array[15]); + array[15] = std::max(array[7], array[15]); + array[7] = tmp; + tmp = std::min(array[16], array[24]); + array[24] = std::max(array[16], array[24]); + array[16] = tmp; + tmp = std::min(array[17], array[25]); + array[25] = std::max(array[17], array[25]); + array[17] = tmp; + tmp = std::min(array[18], array[26]); + array[26] = std::max(array[18], array[26]); + array[18] = tmp; + tmp = std::min(array[19], array[27]); + array[27] = std::max(array[19], array[27]); + array[19] = tmp; + tmp = std::min(array[20], array[28]); + array[28] = std::max(array[20], array[28]); + array[20] = tmp; + tmp = std::min(array[21], array[29]); + array[29] = std::max(array[21], array[29]); + array[21] = tmp; + tmp = std::min(array[22], array[30]); + array[30] = std::max(array[22], array[30]); + array[22] = tmp; + tmp = std::min(array[23], array[31]); + array[31] = std::max(array[23], array[31]); + array[23] = tmp; + tmp = std::min(array[32], array[40]); + array[40] = std::max(array[32], array[40]); + array[32] = tmp; + tmp = std::min(array[33], array[41]); + array[41] = std::max(array[33], array[41]); + array[33] = tmp; + tmp = std::min(array[34], array[42]); + array[42] = std::max(array[34], array[42]); + array[34] = tmp; + tmp = std::min(array[35], array[43]); + array[43] = std::max(array[35], array[43]); + array[35] = tmp; + tmp = std::min(array[36], array[44]); + array[44] = std::max(array[36], array[44]); + array[36] = tmp; + tmp = std::min(array[37], array[45]); + array[45] = std::max(array[37], array[45]); + array[37] = tmp; + tmp = std::min(array[38], array[46]); + array[46] = std::max(array[38], array[46]); + array[38] = tmp; + tmp = std::min(array[39], array[47]); + array[47] = std::max(array[39], array[47]); + array[39] = tmp; + tmp = std::min(array[48], array[56]); + array[56] = std::max(array[48], array[56]); + array[48] = tmp; + tmp = std::min(array[49], array[57]); + array[57] = std::max(array[49], array[57]); + array[49] = tmp; + tmp = std::min(array[50], array[58]); + array[58] = std::max(array[50], array[58]); + array[50] = tmp; + tmp = std::min(array[51], array[59]); + array[59] = std::max(array[51], array[59]); + array[51] = tmp; + tmp = std::min(array[52], array[60]); + array[60] = std::max(array[52], array[60]); + array[52] = tmp; + tmp = std::min(array[53], array[61]); + array[61] = std::max(array[53], array[61]); + array[53] = tmp; + tmp = std::min(array[54], array[62]); + array[62] = std::max(array[54], array[62]); + array[54] = tmp; + tmp = std::min(array[55], array[63]); + array[63] = std::max(array[55], array[63]); + array[55] = tmp; + tmp = std::min(array[64], array[72]); + array[72] = std::max(array[64], array[72]); + array[64] = tmp; + tmp = std::min(array[65], array[73]); + array[73] = std::max(array[65], array[73]); + array[65] = tmp; + tmp = std::min(array[66], array[74]); + array[74] = std::max(array[66], array[74]); + array[66] = tmp; + tmp = std::min(array[67], array[75]); + array[75] = std::max(array[67], array[75]); + array[67] = tmp; + tmp = std::min(array[68], array[76]); + array[76] = std::max(array[68], array[76]); + array[68] = tmp; + tmp = std::min(array[69], array[77]); + array[77] = std::max(array[69], array[77]); + array[69] = tmp; + tmp = std::min(array[70], array[78]); + array[78] = std::max(array[70], array[78]); + array[70] = tmp; + tmp = std::min(array[71], array[79]); + array[79] = std::max(array[71], array[79]); + array[71] = tmp; + tmp = std::min(array[8], array[64]); + array[64] = std::max(array[8], array[64]); + array[8] = tmp; + tmp = std::min(array[9], array[65]); + array[65] = std::max(array[9], array[65]); + array[9] = tmp; + tmp = std::min(array[10], array[66]); + array[66] = std::max(array[10], array[66]); + array[10] = tmp; + tmp = std::min(array[11], array[67]); + array[67] = std::max(array[11], array[67]); + array[11] = tmp; + tmp = std::min(array[12], array[68]); + array[68] = std::max(array[12], array[68]); + array[12] = tmp; + tmp = std::min(array[13], array[69]); + array[69] = std::max(array[13], array[69]); + array[13] = tmp; + tmp = std::min(array[14], array[70]); + array[70] = std::max(array[14], array[70]); + array[14] = tmp; + tmp = std::min(array[15], array[71]); + array[71] = std::max(array[15], array[71]); + array[15] = tmp; + tmp = std::min(array[24], array[80]); + array[80] = std::max(array[24], array[80]); + array[24] = tmp; + tmp = std::min(array[8], array[32]); + array[32] = std::max(array[8], array[32]); + array[8] = tmp; + tmp = std::min(array[9], array[33]); + array[33] = std::max(array[9], array[33]); + array[9] = tmp; + tmp = std::min(array[10], array[34]); + array[34] = std::max(array[10], array[34]); + array[10] = tmp; + tmp = std::min(array[11], array[35]); + array[35] = std::max(array[11], array[35]); + array[11] = tmp; + tmp = std::min(array[12], array[36]); + array[36] = std::max(array[12], array[36]); + array[12] = tmp; + tmp = std::min(array[13], array[37]); + array[37] = std::max(array[13], array[37]); + array[13] = tmp; + tmp = std::min(array[14], array[38]); + array[38] = std::max(array[14], array[38]); + array[14] = tmp; + tmp = std::min(array[15], array[39]); + array[39] = std::max(array[15], array[39]); + array[15] = tmp; + tmp = std::min(array[24], array[48]); + array[48] = std::max(array[24], array[48]); + array[24] = tmp; + tmp = std::min(array[25], array[49]); + array[49] = std::max(array[25], array[49]); + array[25] = tmp; + tmp = std::min(array[26], array[50]); + array[50] = std::max(array[26], array[50]); + array[26] = tmp; + tmp = std::min(array[27], array[51]); + array[51] = std::max(array[27], array[51]); + array[27] = tmp; + tmp = std::min(array[28], array[52]); + array[52] = std::max(array[28], array[52]); + array[28] = tmp; + tmp = std::min(array[29], array[53]); + array[53] = std::max(array[29], array[53]); + array[29] = tmp; + tmp = std::min(array[30], array[54]); + array[54] = std::max(array[30], array[54]); + array[30] = tmp; + tmp = std::min(array[31], array[55]); + array[55] = std::max(array[31], array[55]); + array[31] = tmp; + tmp = std::min(array[40], array[64]); + array[64] = std::max(array[40], array[64]); + array[40] = tmp; + tmp = std::min(array[41], array[65]); + array[65] = std::max(array[41], array[65]); + array[41] = tmp; + tmp = std::min(array[42], array[66]); + array[66] = std::max(array[42], array[66]); + array[42] = tmp; + tmp = std::min(array[43], array[67]); + array[67] = std::max(array[43], array[67]); + array[43] = tmp; + tmp = std::min(array[44], array[68]); + array[68] = std::max(array[44], array[68]); + array[44] = tmp; + tmp = std::min(array[45], array[69]); + array[69] = std::max(array[45], array[69]); + array[45] = tmp; + tmp = std::min(array[46], array[70]); + array[70] = std::max(array[46], array[70]); + array[46] = tmp; + tmp = std::min(array[47], array[71]); + array[71] = std::max(array[47], array[71]); + array[47] = tmp; + tmp = std::min(array[56], array[80]); + array[80] = std::max(array[56], array[80]); + array[56] = tmp; + tmp = std::min(array[8], array[16]); + array[16] = std::max(array[8], array[16]); + array[8] = tmp; + tmp = std::min(array[9], array[17]); + array[17] = std::max(array[9], array[17]); + array[9] = tmp; + tmp = std::min(array[10], array[18]); + array[18] = std::max(array[10], array[18]); + array[10] = tmp; + tmp = std::min(array[11], array[19]); + array[19] = std::max(array[11], array[19]); + array[11] = tmp; + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[13], array[21]); + array[21] = std::max(array[13], array[21]); + array[13] = tmp; + tmp = std::min(array[14], array[22]); + array[22] = std::max(array[14], array[22]); + array[14] = tmp; + tmp = std::min(array[15], array[23]); + array[23] = std::max(array[15], array[23]); + array[15] = tmp; + tmp = std::min(array[24], array[32]); + array[32] = std::max(array[24], array[32]); + array[24] = tmp; + tmp = std::min(array[25], array[33]); + array[33] = std::max(array[25], array[33]); + array[25] = tmp; + tmp = std::min(array[26], array[34]); + array[34] = std::max(array[26], array[34]); + array[26] = tmp; + tmp = std::min(array[27], array[35]); + array[35] = std::max(array[27], array[35]); + array[27] = tmp; + tmp = std::min(array[28], array[36]); + array[36] = std::max(array[28], array[36]); + array[28] = tmp; + tmp = std::min(array[29], array[37]); + array[37] = std::max(array[29], array[37]); + array[29] = tmp; + tmp = std::min(array[30], array[38]); + array[38] = std::max(array[30], array[38]); + array[30] = tmp; + tmp = std::min(array[31], array[39]); + array[39] = std::max(array[31], array[39]); + array[31] = tmp; + tmp = std::min(array[40], array[48]); + array[48] = std::max(array[40], array[48]); + array[40] = tmp; + tmp = std::min(array[41], array[49]); + array[49] = std::max(array[41], array[49]); + array[41] = tmp; + tmp = std::min(array[42], array[50]); + array[50] = std::max(array[42], array[50]); + array[42] = tmp; + tmp = std::min(array[43], array[51]); + array[51] = std::max(array[43], array[51]); + array[43] = tmp; + tmp = std::min(array[44], array[52]); + array[52] = std::max(array[44], array[52]); + array[44] = tmp; + tmp = std::min(array[45], array[53]); + array[53] = std::max(array[45], array[53]); + array[45] = tmp; + tmp = std::min(array[46], array[54]); + array[54] = std::max(array[46], array[54]); + array[46] = tmp; + tmp = std::min(array[47], array[55]); + array[55] = std::max(array[47], array[55]); + array[47] = tmp; + tmp = std::min(array[56], array[64]); + array[64] = std::max(array[56], array[64]); + array[56] = tmp; + tmp = std::min(array[57], array[65]); + array[65] = std::max(array[57], array[65]); + array[57] = tmp; + tmp = std::min(array[58], array[66]); + array[66] = std::max(array[58], array[66]); + array[58] = tmp; + tmp = std::min(array[59], array[67]); + array[67] = std::max(array[59], array[67]); + array[59] = tmp; + tmp = std::min(array[60], array[68]); + array[68] = std::max(array[60], array[68]); + array[60] = tmp; + tmp = std::min(array[61], array[69]); + array[69] = std::max(array[61], array[69]); + array[61] = tmp; + tmp = std::min(array[62], array[70]); + array[70] = std::max(array[62], array[70]); + array[62] = tmp; + tmp = std::min(array[63], array[71]); + array[71] = std::max(array[63], array[71]); + array[63] = tmp; + tmp = std::min(array[72], array[80]); + array[80] = std::max(array[72], array[80]); + array[72] = tmp; + tmp = std::min(array[0], array[4]); + array[4] = std::max(array[0], array[4]); + array[0] = tmp; + tmp = std::min(array[1], array[5]); + array[5] = std::max(array[1], array[5]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[8], array[12]); + array[12] = std::max(array[8], array[12]); + array[8] = tmp; + tmp = std::min(array[9], array[13]); + array[13] = std::max(array[9], array[13]); + array[9] = tmp; + tmp = std::min(array[10], array[14]); + array[14] = std::max(array[10], array[14]); + array[10] = tmp; + tmp = std::min(array[11], array[15]); + array[15] = std::max(array[11], array[15]); + array[11] = tmp; + tmp = std::min(array[16], array[20]); + array[20] = std::max(array[16], array[20]); + array[16] = tmp; + tmp = std::min(array[17], array[21]); + array[21] = std::max(array[17], array[21]); + array[17] = tmp; + tmp = std::min(array[18], array[22]); + array[22] = std::max(array[18], array[22]); + array[18] = tmp; + tmp = std::min(array[19], array[23]); + array[23] = std::max(array[19], array[23]); + array[19] = tmp; + tmp = std::min(array[24], array[28]); + array[28] = std::max(array[24], array[28]); + array[24] = tmp; + tmp = std::min(array[25], array[29]); + array[29] = std::max(array[25], array[29]); + array[25] = tmp; + tmp = std::min(array[26], array[30]); + array[30] = std::max(array[26], array[30]); + array[26] = tmp; + tmp = std::min(array[27], array[31]); + array[31] = std::max(array[27], array[31]); + array[27] = tmp; + tmp = std::min(array[32], array[36]); + array[36] = std::max(array[32], array[36]); + array[32] = tmp; + tmp = std::min(array[33], array[37]); + array[37] = std::max(array[33], array[37]); + array[33] = tmp; + tmp = std::min(array[34], array[38]); + array[38] = std::max(array[34], array[38]); + array[34] = tmp; + tmp = std::min(array[35], array[39]); + array[39] = std::max(array[35], array[39]); + array[35] = tmp; + tmp = std::min(array[40], array[44]); + array[44] = std::max(array[40], array[44]); + array[40] = tmp; + tmp = std::min(array[41], array[45]); + array[45] = std::max(array[41], array[45]); + array[41] = tmp; + tmp = std::min(array[42], array[46]); + array[46] = std::max(array[42], array[46]); + array[42] = tmp; + tmp = std::min(array[43], array[47]); + array[47] = std::max(array[43], array[47]); + array[43] = tmp; + tmp = std::min(array[48], array[52]); + array[52] = std::max(array[48], array[52]); + array[48] = tmp; + tmp = std::min(array[49], array[53]); + array[53] = std::max(array[49], array[53]); + array[49] = tmp; + tmp = std::min(array[50], array[54]); + array[54] = std::max(array[50], array[54]); + array[50] = tmp; + tmp = std::min(array[51], array[55]); + array[55] = std::max(array[51], array[55]); + array[51] = tmp; + tmp = std::min(array[56], array[60]); + array[60] = std::max(array[56], array[60]); + array[56] = tmp; + tmp = std::min(array[57], array[61]); + array[61] = std::max(array[57], array[61]); + array[57] = tmp; + tmp = std::min(array[58], array[62]); + array[62] = std::max(array[58], array[62]); + array[58] = tmp; + tmp = std::min(array[59], array[63]); + array[63] = std::max(array[59], array[63]); + array[59] = tmp; + tmp = std::min(array[64], array[68]); + array[68] = std::max(array[64], array[68]); + array[64] = tmp; + tmp = std::min(array[65], array[69]); + array[69] = std::max(array[65], array[69]); + array[65] = tmp; + tmp = std::min(array[66], array[70]); + array[70] = std::max(array[66], array[70]); + array[66] = tmp; + tmp = std::min(array[67], array[71]); + array[71] = std::max(array[67], array[71]); + array[67] = tmp; + tmp = std::min(array[72], array[76]); + array[76] = std::max(array[72], array[76]); + array[72] = tmp; + tmp = std::min(array[73], array[77]); + array[77] = std::max(array[73], array[77]); + array[73] = tmp; + tmp = std::min(array[74], array[78]); + array[78] = std::max(array[74], array[78]); + array[74] = tmp; + tmp = std::min(array[75], array[79]); + array[79] = std::max(array[75], array[79]); + array[75] = tmp; + tmp = std::min(array[4], array[64]); + array[64] = std::max(array[4], array[64]); + array[4] = tmp; + tmp = std::min(array[5], array[65]); + array[65] = std::max(array[5], array[65]); + array[5] = tmp; + tmp = std::min(array[6], array[66]); + array[66] = std::max(array[6], array[66]); + array[6] = tmp; + tmp = std::min(array[7], array[67]); + array[67] = std::max(array[7], array[67]); + array[7] = tmp; + tmp = std::min(array[12], array[72]); + array[72] = std::max(array[12], array[72]); + array[12] = tmp; + tmp = std::min(array[13], array[73]); + array[73] = std::max(array[13], array[73]); + array[13] = tmp; + tmp = std::min(array[14], array[74]); + array[74] = std::max(array[14], array[74]); + array[14] = tmp; + tmp = std::min(array[15], array[75]); + array[75] = std::max(array[15], array[75]); + array[15] = tmp; + tmp = std::min(array[20], array[80]); + array[80] = std::max(array[20], array[80]); + array[20] = tmp; + tmp = std::min(array[4], array[32]); + array[32] = std::max(array[4], array[32]); + array[4] = tmp; + tmp = std::min(array[5], array[33]); + array[33] = std::max(array[5], array[33]); + array[5] = tmp; + tmp = std::min(array[6], array[34]); + array[34] = std::max(array[6], array[34]); + array[6] = tmp; + tmp = std::min(array[7], array[35]); + array[35] = std::max(array[7], array[35]); + array[7] = tmp; + tmp = std::min(array[12], array[40]); + array[40] = std::max(array[12], array[40]); + array[12] = tmp; + tmp = std::min(array[13], array[41]); + array[41] = std::max(array[13], array[41]); + array[13] = tmp; + tmp = std::min(array[14], array[42]); + array[42] = std::max(array[14], array[42]); + array[14] = tmp; + tmp = std::min(array[15], array[43]); + array[43] = std::max(array[15], array[43]); + array[15] = tmp; + tmp = std::min(array[20], array[48]); + array[48] = std::max(array[20], array[48]); + array[20] = tmp; + tmp = std::min(array[21], array[49]); + array[49] = std::max(array[21], array[49]); + array[21] = tmp; + tmp = std::min(array[22], array[50]); + array[50] = std::max(array[22], array[50]); + array[22] = tmp; + tmp = std::min(array[23], array[51]); + array[51] = std::max(array[23], array[51]); + array[23] = tmp; + tmp = std::min(array[28], array[56]); + array[56] = std::max(array[28], array[56]); + array[28] = tmp; + tmp = std::min(array[29], array[57]); + array[57] = std::max(array[29], array[57]); + array[29] = tmp; + tmp = std::min(array[30], array[58]); + array[58] = std::max(array[30], array[58]); + array[30] = tmp; + tmp = std::min(array[31], array[59]); + array[59] = std::max(array[31], array[59]); + array[31] = tmp; + tmp = std::min(array[36], array[64]); + array[64] = std::max(array[36], array[64]); + array[36] = tmp; + tmp = std::min(array[37], array[65]); + array[65] = std::max(array[37], array[65]); + array[37] = tmp; + tmp = std::min(array[38], array[66]); + array[66] = std::max(array[38], array[66]); + array[38] = tmp; + tmp = std::min(array[39], array[67]); + array[67] = std::max(array[39], array[67]); + array[39] = tmp; + tmp = std::min(array[44], array[72]); + array[72] = std::max(array[44], array[72]); + array[44] = tmp; + tmp = std::min(array[45], array[73]); + array[73] = std::max(array[45], array[73]); + array[45] = tmp; + tmp = std::min(array[46], array[74]); + array[74] = std::max(array[46], array[74]); + array[46] = tmp; + tmp = std::min(array[47], array[75]); + array[75] = std::max(array[47], array[75]); + array[47] = tmp; + tmp = std::min(array[52], array[80]); + array[80] = std::max(array[52], array[80]); + array[52] = tmp; + tmp = std::min(array[4], array[16]); + array[16] = std::max(array[4], array[16]); + array[4] = tmp; + tmp = std::min(array[5], array[17]); + array[17] = std::max(array[5], array[17]); + array[5] = tmp; + tmp = std::min(array[6], array[18]); + array[18] = std::max(array[6], array[18]); + array[6] = tmp; + tmp = std::min(array[7], array[19]); + array[19] = std::max(array[7], array[19]); + array[7] = tmp; + tmp = std::min(array[12], array[24]); + array[24] = std::max(array[12], array[24]); + array[12] = tmp; + tmp = std::min(array[13], array[25]); + array[25] = std::max(array[13], array[25]); + array[13] = tmp; + tmp = std::min(array[14], array[26]); + array[26] = std::max(array[14], array[26]); + array[14] = tmp; + tmp = std::min(array[15], array[27]); + array[27] = std::max(array[15], array[27]); + array[15] = tmp; + tmp = std::min(array[20], array[32]); + array[32] = std::max(array[20], array[32]); + array[20] = tmp; + tmp = std::min(array[21], array[33]); + array[33] = std::max(array[21], array[33]); + array[21] = tmp; + tmp = std::min(array[22], array[34]); + array[34] = std::max(array[22], array[34]); + array[22] = tmp; + tmp = std::min(array[23], array[35]); + array[35] = std::max(array[23], array[35]); + array[23] = tmp; + tmp = std::min(array[28], array[40]); + array[40] = std::max(array[28], array[40]); + array[28] = tmp; + tmp = std::min(array[29], array[41]); + array[41] = std::max(array[29], array[41]); + array[29] = tmp; + tmp = std::min(array[30], array[42]); + array[42] = std::max(array[30], array[42]); + array[30] = tmp; + tmp = std::min(array[31], array[43]); + array[43] = std::max(array[31], array[43]); + array[31] = tmp; + tmp = std::min(array[36], array[48]); + array[48] = std::max(array[36], array[48]); + array[36] = tmp; + tmp = std::min(array[37], array[49]); + array[49] = std::max(array[37], array[49]); + array[37] = tmp; + tmp = std::min(array[38], array[50]); + array[50] = std::max(array[38], array[50]); + array[38] = tmp; + tmp = std::min(array[39], array[51]); + array[51] = std::max(array[39], array[51]); + array[39] = tmp; + tmp = std::min(array[44], array[56]); + array[56] = std::max(array[44], array[56]); + array[44] = tmp; + tmp = std::min(array[45], array[57]); + array[57] = std::max(array[45], array[57]); + array[45] = tmp; + tmp = std::min(array[46], array[58]); + array[58] = std::max(array[46], array[58]); + array[46] = tmp; + tmp = std::min(array[47], array[59]); + array[59] = std::max(array[47], array[59]); + array[47] = tmp; + tmp = std::min(array[52], array[64]); + array[64] = std::max(array[52], array[64]); + array[52] = tmp; + tmp = std::min(array[53], array[65]); + array[65] = std::max(array[53], array[65]); + array[53] = tmp; + tmp = std::min(array[54], array[66]); + array[66] = std::max(array[54], array[66]); + array[54] = tmp; + tmp = std::min(array[55], array[67]); + array[67] = std::max(array[55], array[67]); + array[55] = tmp; + tmp = std::min(array[60], array[72]); + array[72] = std::max(array[60], array[72]); + array[60] = tmp; + tmp = std::min(array[61], array[73]); + array[73] = std::max(array[61], array[73]); + array[61] = tmp; + tmp = std::min(array[62], array[74]); + array[74] = std::max(array[62], array[74]); + array[62] = tmp; + tmp = std::min(array[63], array[75]); + array[75] = std::max(array[63], array[75]); + array[63] = tmp; + tmp = std::min(array[68], array[80]); + array[80] = std::max(array[68], array[80]); + array[68] = tmp; + tmp = std::min(array[4], array[8]); + array[8] = std::max(array[4], array[8]); + array[4] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[7], array[11]); + array[11] = std::max(array[7], array[11]); + array[7] = tmp; + tmp = std::min(array[12], array[16]); + array[16] = std::max(array[12], array[16]); + array[12] = tmp; + tmp = std::min(array[13], array[17]); + array[17] = std::max(array[13], array[17]); + array[13] = tmp; + tmp = std::min(array[14], array[18]); + array[18] = std::max(array[14], array[18]); + array[14] = tmp; + tmp = std::min(array[15], array[19]); + array[19] = std::max(array[15], array[19]); + array[15] = tmp; + tmp = std::min(array[20], array[24]); + array[24] = std::max(array[20], array[24]); + array[20] = tmp; + tmp = std::min(array[21], array[25]); + array[25] = std::max(array[21], array[25]); + array[21] = tmp; + tmp = std::min(array[22], array[26]); + array[26] = std::max(array[22], array[26]); + array[22] = tmp; + tmp = std::min(array[23], array[27]); + array[27] = std::max(array[23], array[27]); + array[23] = tmp; + tmp = std::min(array[28], array[32]); + array[32] = std::max(array[28], array[32]); + array[28] = tmp; + tmp = std::min(array[29], array[33]); + array[33] = std::max(array[29], array[33]); + array[29] = tmp; + tmp = std::min(array[30], array[34]); + array[34] = std::max(array[30], array[34]); + array[30] = tmp; + tmp = std::min(array[31], array[35]); + array[35] = std::max(array[31], array[35]); + array[31] = tmp; + tmp = std::min(array[36], array[40]); + array[40] = std::max(array[36], array[40]); + array[36] = tmp; + tmp = std::min(array[37], array[41]); + array[41] = std::max(array[37], array[41]); + array[37] = tmp; + tmp = std::min(array[38], array[42]); + array[42] = std::max(array[38], array[42]); + array[38] = tmp; + tmp = std::min(array[39], array[43]); + array[43] = std::max(array[39], array[43]); + array[39] = tmp; + tmp = std::min(array[44], array[48]); + array[48] = std::max(array[44], array[48]); + array[44] = tmp; + tmp = std::min(array[45], array[49]); + array[49] = std::max(array[45], array[49]); + array[45] = tmp; + tmp = std::min(array[46], array[50]); + array[50] = std::max(array[46], array[50]); + array[46] = tmp; + tmp = std::min(array[47], array[51]); + array[51] = std::max(array[47], array[51]); + array[47] = tmp; + tmp = std::min(array[52], array[56]); + array[56] = std::max(array[52], array[56]); + array[52] = tmp; + tmp = std::min(array[53], array[57]); + array[57] = std::max(array[53], array[57]); + array[53] = tmp; + tmp = std::min(array[54], array[58]); + array[58] = std::max(array[54], array[58]); + array[54] = tmp; + tmp = std::min(array[55], array[59]); + array[59] = std::max(array[55], array[59]); + array[55] = tmp; + tmp = std::min(array[60], array[64]); + array[64] = std::max(array[60], array[64]); + array[60] = tmp; + tmp = std::min(array[61], array[65]); + array[65] = std::max(array[61], array[65]); + array[61] = tmp; + tmp = std::min(array[62], array[66]); + array[66] = std::max(array[62], array[66]); + array[62] = tmp; + tmp = std::min(array[63], array[67]); + array[67] = std::max(array[63], array[67]); + array[63] = tmp; + tmp = std::min(array[68], array[72]); + array[72] = std::max(array[68], array[72]); + array[68] = tmp; + tmp = std::min(array[69], array[73]); + array[73] = std::max(array[69], array[73]); + array[69] = tmp; + tmp = std::min(array[70], array[74]); + array[74] = std::max(array[70], array[74]); + array[70] = tmp; + tmp = std::min(array[71], array[75]); + array[75] = std::max(array[71], array[75]); + array[71] = tmp; + tmp = std::min(array[76], array[80]); + array[80] = std::max(array[76], array[80]); + array[76] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[1], array[3]); + array[3] = std::max(array[1], array[3]); + array[1] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + tmp = std::min(array[13], array[15]); + array[15] = std::max(array[13], array[15]); + array[13] = tmp; + tmp = std::min(array[16], array[18]); + array[18] = std::max(array[16], array[18]); + array[16] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = tmp; + tmp = std::min(array[21], array[23]); + array[23] = std::max(array[21], array[23]); + array[21] = tmp; + tmp = std::min(array[24], array[26]); + array[26] = std::max(array[24], array[26]); + array[24] = tmp; + tmp = std::min(array[25], array[27]); + array[27] = std::max(array[25], array[27]); + array[25] = tmp; + tmp = std::min(array[28], array[30]); + array[30] = std::max(array[28], array[30]); + array[28] = tmp; + tmp = std::min(array[29], array[31]); + array[31] = std::max(array[29], array[31]); + array[29] = tmp; + tmp = std::min(array[32], array[34]); + array[34] = std::max(array[32], array[34]); + array[32] = tmp; + tmp = std::min(array[33], array[35]); + array[35] = std::max(array[33], array[35]); + array[33] = tmp; + tmp = std::min(array[36], array[38]); + array[38] = std::max(array[36], array[38]); + array[36] = tmp; + tmp = std::min(array[37], array[39]); + array[39] = std::max(array[37], array[39]); + array[37] = tmp; + tmp = std::min(array[40], array[42]); + array[42] = std::max(array[40], array[42]); + array[40] = tmp; + tmp = std::min(array[41], array[43]); + array[43] = std::max(array[41], array[43]); + array[41] = tmp; + tmp = std::min(array[44], array[46]); + array[46] = std::max(array[44], array[46]); + array[44] = tmp; + tmp = std::min(array[45], array[47]); + array[47] = std::max(array[45], array[47]); + array[45] = tmp; + tmp = std::min(array[48], array[50]); + array[50] = std::max(array[48], array[50]); + array[48] = tmp; + tmp = std::min(array[49], array[51]); + array[51] = std::max(array[49], array[51]); + array[49] = tmp; + tmp = std::min(array[52], array[54]); + array[54] = std::max(array[52], array[54]); + array[52] = tmp; + tmp = std::min(array[53], array[55]); + array[55] = std::max(array[53], array[55]); + array[53] = tmp; + tmp = std::min(array[56], array[58]); + array[58] = std::max(array[56], array[58]); + array[56] = tmp; + tmp = std::min(array[57], array[59]); + array[59] = std::max(array[57], array[59]); + array[57] = tmp; + tmp = std::min(array[60], array[62]); + array[62] = std::max(array[60], array[62]); + array[60] = tmp; + tmp = std::min(array[61], array[63]); + array[63] = std::max(array[61], array[63]); + array[61] = tmp; + tmp = std::min(array[64], array[66]); + array[66] = std::max(array[64], array[66]); + array[64] = tmp; + tmp = std::min(array[65], array[67]); + array[67] = std::max(array[65], array[67]); + array[65] = tmp; + tmp = std::min(array[68], array[70]); + array[70] = std::max(array[68], array[70]); + array[68] = tmp; + tmp = std::min(array[69], array[71]); + array[71] = std::max(array[69], array[71]); + array[69] = tmp; + tmp = std::min(array[72], array[74]); + array[74] = std::max(array[72], array[74]); + array[72] = tmp; + tmp = std::min(array[73], array[75]); + array[75] = std::max(array[73], array[75]); + array[73] = tmp; + tmp = std::min(array[76], array[78]); + array[78] = std::max(array[76], array[78]); + array[76] = tmp; + tmp = std::min(array[77], array[79]); + array[79] = std::max(array[77], array[79]); + array[77] = tmp; + tmp = std::min(array[2], array[64]); + array[64] = std::max(array[2], array[64]); + array[2] = tmp; + tmp = std::min(array[3], array[65]); + array[65] = std::max(array[3], array[65]); + array[3] = tmp; + tmp = std::min(array[6], array[68]); + array[68] = std::max(array[6], array[68]); + array[6] = tmp; + tmp = std::min(array[7], array[69]); + array[69] = std::max(array[7], array[69]); + array[7] = tmp; + tmp = std::min(array[10], array[72]); + array[72] = std::max(array[10], array[72]); + array[10] = tmp; + tmp = std::min(array[11], array[73]); + array[73] = std::max(array[11], array[73]); + array[11] = tmp; + tmp = std::min(array[14], array[76]); + array[76] = std::max(array[14], array[76]); + array[14] = tmp; + tmp = std::min(array[15], array[77]); + array[77] = std::max(array[15], array[77]); + array[15] = tmp; + tmp = std::min(array[18], array[80]); + array[80] = std::max(array[18], array[80]); + array[18] = tmp; + tmp = std::min(array[2], array[32]); + array[32] = std::max(array[2], array[32]); + array[2] = tmp; + tmp = std::min(array[3], array[33]); + array[33] = std::max(array[3], array[33]); + array[3] = tmp; + tmp = std::min(array[6], array[36]); + array[36] = std::max(array[6], array[36]); + array[6] = tmp; + tmp = std::min(array[7], array[37]); + array[37] = std::max(array[7], array[37]); + array[7] = tmp; + tmp = std::min(array[10], array[40]); + array[40] = std::max(array[10], array[40]); + array[10] = tmp; + tmp = std::min(array[11], array[41]); + array[41] = std::max(array[11], array[41]); + array[11] = tmp; + tmp = std::min(array[14], array[44]); + array[44] = std::max(array[14], array[44]); + array[14] = tmp; + tmp = std::min(array[15], array[45]); + array[45] = std::max(array[15], array[45]); + array[15] = tmp; + tmp = std::min(array[18], array[48]); + array[48] = std::max(array[18], array[48]); + array[18] = tmp; + tmp = std::min(array[19], array[49]); + array[49] = std::max(array[19], array[49]); + array[19] = tmp; + tmp = std::min(array[22], array[52]); + array[52] = std::max(array[22], array[52]); + array[22] = tmp; + tmp = std::min(array[23], array[53]); + array[53] = std::max(array[23], array[53]); + array[23] = tmp; + tmp = std::min(array[26], array[56]); + array[56] = std::max(array[26], array[56]); + array[26] = tmp; + tmp = std::min(array[27], array[57]); + array[57] = std::max(array[27], array[57]); + array[27] = tmp; + tmp = std::min(array[30], array[60]); + array[60] = std::max(array[30], array[60]); + array[30] = tmp; + tmp = std::min(array[31], array[61]); + array[61] = std::max(array[31], array[61]); + array[31] = tmp; + tmp = std::min(array[34], array[64]); + array[64] = std::max(array[34], array[64]); + array[34] = tmp; + tmp = std::min(array[35], array[65]); + array[65] = std::max(array[35], array[65]); + array[35] = tmp; + tmp = std::min(array[38], array[68]); + array[68] = std::max(array[38], array[68]); + array[38] = tmp; + tmp = std::min(array[39], array[69]); + array[69] = std::max(array[39], array[69]); + array[39] = tmp; + tmp = std::min(array[42], array[72]); + array[72] = std::max(array[42], array[72]); + array[42] = tmp; + tmp = std::min(array[43], array[73]); + array[73] = std::max(array[43], array[73]); + array[43] = tmp; + tmp = std::min(array[46], array[76]); + array[76] = std::max(array[46], array[76]); + array[46] = tmp; + tmp = std::min(array[47], array[77]); + array[77] = std::max(array[47], array[77]); + array[47] = tmp; + tmp = std::min(array[50], array[80]); + array[80] = std::max(array[50], array[80]); + array[50] = tmp; + tmp = std::min(array[2], array[16]); + array[16] = std::max(array[2], array[16]); + array[2] = tmp; + tmp = std::min(array[3], array[17]); + array[17] = std::max(array[3], array[17]); + array[3] = tmp; + tmp = std::min(array[6], array[20]); + array[20] = std::max(array[6], array[20]); + array[6] = tmp; + tmp = std::min(array[7], array[21]); + array[21] = std::max(array[7], array[21]); + array[7] = tmp; + tmp = std::min(array[10], array[24]); + array[24] = std::max(array[10], array[24]); + array[10] = tmp; + tmp = std::min(array[11], array[25]); + array[25] = std::max(array[11], array[25]); + array[11] = tmp; + tmp = std::min(array[14], array[28]); + array[28] = std::max(array[14], array[28]); + array[14] = tmp; + tmp = std::min(array[15], array[29]); + array[29] = std::max(array[15], array[29]); + array[15] = tmp; + tmp = std::min(array[18], array[32]); + array[32] = std::max(array[18], array[32]); + array[18] = tmp; + tmp = std::min(array[19], array[33]); + array[33] = std::max(array[19], array[33]); + array[19] = tmp; + tmp = std::min(array[22], array[36]); + array[36] = std::max(array[22], array[36]); + array[22] = tmp; + tmp = std::min(array[23], array[37]); + array[37] = std::max(array[23], array[37]); + array[23] = tmp; + tmp = std::min(array[26], array[40]); + array[40] = std::max(array[26], array[40]); + array[26] = tmp; + tmp = std::min(array[27], array[41]); + array[41] = std::max(array[27], array[41]); + array[27] = tmp; + tmp = std::min(array[30], array[44]); + array[44] = std::max(array[30], array[44]); + array[30] = tmp; + tmp = std::min(array[31], array[45]); + array[45] = std::max(array[31], array[45]); + array[31] = tmp; + tmp = std::min(array[34], array[48]); + array[48] = std::max(array[34], array[48]); + array[34] = tmp; + tmp = std::min(array[35], array[49]); + array[49] = std::max(array[35], array[49]); + array[35] = tmp; + tmp = std::min(array[38], array[52]); + array[52] = std::max(array[38], array[52]); + array[38] = tmp; + tmp = std::min(array[39], array[53]); + array[53] = std::max(array[39], array[53]); + array[39] = tmp; + tmp = std::min(array[42], array[56]); + array[56] = std::max(array[42], array[56]); + array[42] = tmp; + tmp = std::min(array[43], array[57]); + array[57] = std::max(array[43], array[57]); + array[43] = tmp; + tmp = std::min(array[46], array[60]); + array[60] = std::max(array[46], array[60]); + array[46] = tmp; + tmp = std::min(array[47], array[61]); + array[61] = std::max(array[47], array[61]); + array[47] = tmp; + tmp = std::min(array[50], array[64]); + array[64] = std::max(array[50], array[64]); + array[50] = tmp; + tmp = std::min(array[51], array[65]); + array[65] = std::max(array[51], array[65]); + array[51] = tmp; + tmp = std::min(array[54], array[68]); + array[68] = std::max(array[54], array[68]); + array[54] = tmp; + tmp = std::min(array[55], array[69]); + array[69] = std::max(array[55], array[69]); + array[55] = tmp; + tmp = std::min(array[58], array[72]); + array[72] = std::max(array[58], array[72]); + array[58] = tmp; + tmp = std::min(array[59], array[73]); + array[73] = std::max(array[59], array[73]); + array[59] = tmp; + tmp = std::min(array[62], array[76]); + array[76] = std::max(array[62], array[76]); + array[62] = tmp; + tmp = std::min(array[63], array[77]); + array[77] = std::max(array[63], array[77]); + array[63] = tmp; + tmp = std::min(array[66], array[80]); + array[80] = std::max(array[66], array[80]); + array[66] = tmp; + tmp = std::min(array[2], array[8]); + array[8] = std::max(array[2], array[8]); + array[2] = tmp; + tmp = std::min(array[3], array[9]); + array[9] = std::max(array[3], array[9]); + array[3] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[13]); + array[13] = std::max(array[7], array[13]); + array[7] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = tmp; + tmp = std::min(array[11], array[17]); + array[17] = std::max(array[11], array[17]); + array[11] = tmp; + tmp = std::min(array[14], array[20]); + array[20] = std::max(array[14], array[20]); + array[14] = tmp; + tmp = std::min(array[15], array[21]); + array[21] = std::max(array[15], array[21]); + array[15] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = tmp; + tmp = std::min(array[19], array[25]); + array[25] = std::max(array[19], array[25]); + array[19] = tmp; + tmp = std::min(array[22], array[28]); + array[28] = std::max(array[22], array[28]); + array[22] = tmp; + tmp = std::min(array[23], array[29]); + array[29] = std::max(array[23], array[29]); + array[23] = tmp; + tmp = std::min(array[26], array[32]); + array[32] = std::max(array[26], array[32]); + array[26] = tmp; + tmp = std::min(array[27], array[33]); + array[33] = std::max(array[27], array[33]); + array[27] = tmp; + tmp = std::min(array[30], array[36]); + array[36] = std::max(array[30], array[36]); + array[30] = tmp; + tmp = std::min(array[31], array[37]); + array[37] = std::max(array[31], array[37]); + array[31] = tmp; + tmp = std::min(array[34], array[40]); + array[40] = std::max(array[34], array[40]); + array[34] = tmp; + tmp = std::min(array[35], array[41]); + array[41] = std::max(array[35], array[41]); + array[35] = tmp; + tmp = std::min(array[38], array[44]); + array[44] = std::max(array[38], array[44]); + array[38] = tmp; + tmp = std::min(array[39], array[45]); + array[45] = std::max(array[39], array[45]); + array[39] = tmp; + tmp = std::min(array[42], array[48]); + array[48] = std::max(array[42], array[48]); + array[42] = tmp; + tmp = std::min(array[43], array[49]); + array[49] = std::max(array[43], array[49]); + array[43] = tmp; + tmp = std::min(array[46], array[52]); + array[52] = std::max(array[46], array[52]); + array[46] = tmp; + tmp = std::min(array[47], array[53]); + array[53] = std::max(array[47], array[53]); + array[47] = tmp; + tmp = std::min(array[50], array[56]); + array[56] = std::max(array[50], array[56]); + array[50] = tmp; + tmp = std::min(array[51], array[57]); + array[57] = std::max(array[51], array[57]); + array[51] = tmp; + tmp = std::min(array[54], array[60]); + array[60] = std::max(array[54], array[60]); + array[54] = tmp; + tmp = std::min(array[55], array[61]); + array[61] = std::max(array[55], array[61]); + array[55] = tmp; + tmp = std::min(array[58], array[64]); + array[64] = std::max(array[58], array[64]); + array[58] = tmp; + tmp = std::min(array[59], array[65]); + array[65] = std::max(array[59], array[65]); + array[59] = tmp; + tmp = std::min(array[62], array[68]); + array[68] = std::max(array[62], array[68]); + array[62] = tmp; + tmp = std::min(array[63], array[69]); + array[69] = std::max(array[63], array[69]); + array[63] = tmp; + tmp = std::min(array[66], array[72]); + array[72] = std::max(array[66], array[72]); + array[66] = tmp; + tmp = std::min(array[67], array[73]); + array[73] = std::max(array[67], array[73]); + array[67] = tmp; + tmp = std::min(array[70], array[76]); + array[76] = std::max(array[70], array[76]); + array[70] = tmp; + tmp = std::min(array[71], array[77]); + array[77] = std::max(array[71], array[77]); + array[71] = tmp; + tmp = std::min(array[74], array[80]); + array[80] = std::max(array[74], array[80]); + array[74] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[6] = tmp; + tmp = std::min(array[7], array[9]); + array[9] = std::max(array[7], array[9]); + array[7] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = tmp; + tmp = std::min(array[15], array[17]); + array[17] = std::max(array[15], array[17]); + array[15] = tmp; + tmp = std::min(array[18], array[20]); + array[20] = std::max(array[18], array[20]); + array[18] = tmp; + tmp = std::min(array[19], array[21]); + array[21] = std::max(array[19], array[21]); + array[19] = tmp; + tmp = std::min(array[22], array[24]); + array[24] = std::max(array[22], array[24]); + array[22] = tmp; + tmp = std::min(array[23], array[25]); + array[25] = std::max(array[23], array[25]); + array[23] = tmp; + tmp = std::min(array[26], array[28]); + array[28] = std::max(array[26], array[28]); + array[26] = tmp; + tmp = std::min(array[27], array[29]); + array[29] = std::max(array[27], array[29]); + array[27] = tmp; + tmp = std::min(array[30], array[32]); + array[32] = std::max(array[30], array[32]); + array[30] = tmp; + tmp = std::min(array[31], array[33]); + array[33] = std::max(array[31], array[33]); + array[31] = tmp; + tmp = std::min(array[34], array[36]); + array[36] = std::max(array[34], array[36]); + array[34] = tmp; + tmp = std::min(array[35], array[37]); + array[37] = std::max(array[35], array[37]); + array[35] = tmp; + tmp = std::min(array[38], array[40]); + array[40] = std::max(array[38], array[40]); + array[38] = tmp; + tmp = std::min(array[39], array[41]); + array[41] = std::max(array[39], array[41]); + array[39] = tmp; + tmp = std::min(array[42], array[44]); + array[44] = std::max(array[42], array[44]); + array[42] = tmp; + tmp = std::min(array[43], array[45]); + array[45] = std::max(array[43], array[45]); + array[43] = tmp; + tmp = std::min(array[46], array[48]); + array[48] = std::max(array[46], array[48]); + array[46] = tmp; + tmp = std::min(array[47], array[49]); + array[49] = std::max(array[47], array[49]); + array[47] = tmp; + tmp = std::min(array[50], array[52]); + array[52] = std::max(array[50], array[52]); + array[50] = tmp; + tmp = std::min(array[51], array[53]); + array[53] = std::max(array[51], array[53]); + array[51] = tmp; + tmp = std::min(array[54], array[56]); + array[56] = std::max(array[54], array[56]); + array[54] = tmp; + tmp = std::min(array[55], array[57]); + array[57] = std::max(array[55], array[57]); + array[55] = tmp; + tmp = std::min(array[58], array[60]); + array[60] = std::max(array[58], array[60]); + array[58] = tmp; + tmp = std::min(array[59], array[61]); + array[61] = std::max(array[59], array[61]); + array[59] = tmp; + tmp = std::min(array[62], array[64]); + array[64] = std::max(array[62], array[64]); + array[62] = tmp; + tmp = std::min(array[63], array[65]); + array[65] = std::max(array[63], array[65]); + array[63] = tmp; + tmp = std::min(array[66], array[68]); + array[68] = std::max(array[66], array[68]); + array[66] = tmp; + tmp = std::min(array[67], array[69]); + array[69] = std::max(array[67], array[69]); + array[67] = tmp; + tmp = std::min(array[70], array[72]); + array[72] = std::max(array[70], array[72]); + array[70] = tmp; + tmp = std::min(array[71], array[73]); + array[73] = std::max(array[71], array[73]); + array[71] = tmp; + tmp = std::min(array[74], array[76]); + array[76] = std::max(array[74], array[76]); + array[74] = tmp; + tmp = std::min(array[75], array[77]); + array[77] = std::max(array[75], array[77]); + array[75] = tmp; + tmp = std::min(array[78], array[80]); + array[80] = std::max(array[78], array[80]); + array[78] = tmp; + array[1] = std::max(array[0], array[1]); + array[3] = std::max(array[2], array[3]); + array[5] = std::max(array[4], array[5]); + array[7] = std::max(array[6], array[7]); + array[9] = std::max(array[8], array[9]); + array[11] = std::max(array[10], array[11]); + array[13] = std::max(array[12], array[13]); + array[15] = std::max(array[14], array[15]); + array[17] = std::max(array[16], array[17]); + array[19] = std::max(array[18], array[19]); + array[21] = std::max(array[20], array[21]); + array[23] = std::max(array[22], array[23]); + array[25] = std::max(array[24], array[25]); + array[27] = std::max(array[26], array[27]); + array[29] = std::max(array[28], array[29]); + array[31] = std::max(array[30], array[31]); + array[33] = std::max(array[32], array[33]); + array[35] = std::max(array[34], array[35]); + array[37] = std::max(array[36], array[37]); + array[39] = std::max(array[38], array[39]); + array[40] = std::min(array[40], array[41]); + array[42] = std::min(array[42], array[43]); + array[44] = std::min(array[44], array[45]); + array[46] = std::min(array[46], array[47]); + array[48] = std::min(array[48], array[49]); + array[50] = std::min(array[50], array[51]); + array[52] = std::min(array[52], array[53]); + array[54] = std::min(array[54], array[55]); + array[56] = std::min(array[56], array[57]); + array[58] = std::min(array[58], array[59]); + array[60] = std::min(array[60], array[61]); + array[62] = std::min(array[62], array[63]); + array[64] = std::min(array[64], array[65]); + array[66] = std::min(array[66], array[67]); + array[68] = std::min(array[68], array[69]); + array[70] = std::min(array[70], array[71]); + array[72] = std::min(array[72], array[73]); + array[74] = std::min(array[74], array[75]); + array[76] = std::min(array[76], array[77]); + array[78] = std::min(array[78], array[79]); + array[64] = std::max(array[1], array[64]); + array[66] = std::max(array[3], array[66]); + array[68] = std::max(array[5], array[68]); + array[70] = std::max(array[7], array[70]); + array[9] = std::min(array[9], array[72]); + array[11] = std::min(array[11], array[74]); + array[13] = std::min(array[13], array[76]); + array[15] = std::min(array[15], array[78]); + array[17] = std::min(array[17], array[80]); + array[40] = std::max(array[9], array[40]); + array[42] = std::max(array[11], array[42]); + array[44] = std::max(array[13], array[44]); + array[46] = std::max(array[15], array[46]); + array[48] = std::max(array[17], array[48]); + array[50] = std::max(array[19], array[50]); + array[52] = std::max(array[21], array[52]); + array[54] = std::max(array[23], array[54]); + array[25] = std::min(array[25], array[56]); + array[27] = std::min(array[27], array[58]); + array[29] = std::min(array[29], array[60]); + array[31] = std::min(array[31], array[62]); + array[33] = std::min(array[33], array[64]); + array[35] = std::min(array[35], array[66]); + array[37] = std::min(array[37], array[68]); + array[39] = std::min(array[39], array[70]); + array[40] = std::max(array[25], array[40]); + array[42] = std::max(array[27], array[42]); + array[44] = std::max(array[29], array[44]); + array[46] = std::max(array[31], array[46]); + array[33] = std::min(array[33], array[48]); + array[35] = std::min(array[35], array[50]); + array[37] = std::min(array[37], array[52]); + array[39] = std::min(array[39], array[54]); + array[40] = std::max(array[33], array[40]); + array[42] = std::max(array[35], array[42]); + array[37] = std::min(array[37], array[44]); + array[39] = std::min(array[39], array[46]); + array[40] = std::max(array[37], array[40]); + array[39] = std::min(array[39], array[42]); + return std::max(array[39], array[40]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[64]); + array[64] = vmaxf(array[0], array[64]); + array[0] = tmp; + tmp = vminf(array[1], array[65]); + array[65] = vmaxf(array[1], array[65]); + array[1] = tmp; + tmp = vminf(array[2], array[66]); + array[66] = vmaxf(array[2], array[66]); + array[2] = tmp; + tmp = vminf(array[3], array[67]); + array[67] = vmaxf(array[3], array[67]); + array[3] = tmp; + tmp = vminf(array[4], array[68]); + array[68] = vmaxf(array[4], array[68]); + array[4] = tmp; + tmp = vminf(array[5], array[69]); + array[69] = vmaxf(array[5], array[69]); + array[5] = tmp; + tmp = vminf(array[6], array[70]); + array[70] = vmaxf(array[6], array[70]); + array[6] = tmp; + tmp = vminf(array[7], array[71]); + array[71] = vmaxf(array[7], array[71]); + array[7] = tmp; + tmp = vminf(array[8], array[72]); + array[72] = vmaxf(array[8], array[72]); + array[8] = tmp; + tmp = vminf(array[9], array[73]); + array[73] = vmaxf(array[9], array[73]); + array[9] = tmp; + tmp = vminf(array[10], array[74]); + array[74] = vmaxf(array[10], array[74]); + array[10] = tmp; + tmp = vminf(array[11], array[75]); + array[75] = vmaxf(array[11], array[75]); + array[11] = tmp; + tmp = vminf(array[12], array[76]); + array[76] = vmaxf(array[12], array[76]); + array[12] = tmp; + tmp = vminf(array[13], array[77]); + array[77] = vmaxf(array[13], array[77]); + array[13] = tmp; + tmp = vminf(array[14], array[78]); + array[78] = vmaxf(array[14], array[78]); + array[14] = tmp; + tmp = vminf(array[15], array[79]); + array[79] = vmaxf(array[15], array[79]); + array[15] = tmp; + tmp = vminf(array[16], array[80]); + array[80] = vmaxf(array[16], array[80]); + array[16] = tmp; + tmp = vminf(array[0], array[32]); + array[32] = vmaxf(array[0], array[32]); + array[0] = tmp; + tmp = vminf(array[1], array[33]); + array[33] = vmaxf(array[1], array[33]); + array[1] = tmp; + tmp = vminf(array[2], array[34]); + array[34] = vmaxf(array[2], array[34]); + array[2] = tmp; + tmp = vminf(array[3], array[35]); + array[35] = vmaxf(array[3], array[35]); + array[3] = tmp; + tmp = vminf(array[4], array[36]); + array[36] = vmaxf(array[4], array[36]); + array[4] = tmp; + tmp = vminf(array[5], array[37]); + array[37] = vmaxf(array[5], array[37]); + array[5] = tmp; + tmp = vminf(array[6], array[38]); + array[38] = vmaxf(array[6], array[38]); + array[6] = tmp; + tmp = vminf(array[7], array[39]); + array[39] = vmaxf(array[7], array[39]); + array[7] = tmp; + tmp = vminf(array[8], array[40]); + array[40] = vmaxf(array[8], array[40]); + array[8] = tmp; + tmp = vminf(array[9], array[41]); + array[41] = vmaxf(array[9], array[41]); + array[9] = tmp; + tmp = vminf(array[10], array[42]); + array[42] = vmaxf(array[10], array[42]); + array[10] = tmp; + tmp = vminf(array[11], array[43]); + array[43] = vmaxf(array[11], array[43]); + array[11] = tmp; + tmp = vminf(array[12], array[44]); + array[44] = vmaxf(array[12], array[44]); + array[12] = tmp; + tmp = vminf(array[13], array[45]); + array[45] = vmaxf(array[13], array[45]); + array[13] = tmp; + tmp = vminf(array[14], array[46]); + array[46] = vmaxf(array[14], array[46]); + array[14] = tmp; + tmp = vminf(array[15], array[47]); + array[47] = vmaxf(array[15], array[47]); + array[15] = tmp; + tmp = vminf(array[16], array[48]); + array[48] = vmaxf(array[16], array[48]); + array[16] = tmp; + tmp = vminf(array[17], array[49]); + array[49] = vmaxf(array[17], array[49]); + array[17] = tmp; + tmp = vminf(array[18], array[50]); + array[50] = vmaxf(array[18], array[50]); + array[18] = tmp; + tmp = vminf(array[19], array[51]); + array[51] = vmaxf(array[19], array[51]); + array[19] = tmp; + tmp = vminf(array[20], array[52]); + array[52] = vmaxf(array[20], array[52]); + array[20] = tmp; + tmp = vminf(array[21], array[53]); + array[53] = vmaxf(array[21], array[53]); + array[21] = tmp; + tmp = vminf(array[22], array[54]); + array[54] = vmaxf(array[22], array[54]); + array[22] = tmp; + tmp = vminf(array[23], array[55]); + array[55] = vmaxf(array[23], array[55]); + array[23] = tmp; + tmp = vminf(array[24], array[56]); + array[56] = vmaxf(array[24], array[56]); + array[24] = tmp; + tmp = vminf(array[25], array[57]); + array[57] = vmaxf(array[25], array[57]); + array[25] = tmp; + tmp = vminf(array[26], array[58]); + array[58] = vmaxf(array[26], array[58]); + array[26] = tmp; + tmp = vminf(array[27], array[59]); + array[59] = vmaxf(array[27], array[59]); + array[27] = tmp; + tmp = vminf(array[28], array[60]); + array[60] = vmaxf(array[28], array[60]); + array[28] = tmp; + tmp = vminf(array[29], array[61]); + array[61] = vmaxf(array[29], array[61]); + array[29] = tmp; + tmp = vminf(array[30], array[62]); + array[62] = vmaxf(array[30], array[62]); + array[30] = tmp; + tmp = vminf(array[31], array[63]); + array[63] = vmaxf(array[31], array[63]); + array[31] = tmp; + tmp = vminf(array[32], array[64]); + array[64] = vmaxf(array[32], array[64]); + array[32] = tmp; + tmp = vminf(array[33], array[65]); + array[65] = vmaxf(array[33], array[65]); + array[33] = tmp; + tmp = vminf(array[34], array[66]); + array[66] = vmaxf(array[34], array[66]); + array[34] = tmp; + tmp = vminf(array[35], array[67]); + array[67] = vmaxf(array[35], array[67]); + array[35] = tmp; + tmp = vminf(array[36], array[68]); + array[68] = vmaxf(array[36], array[68]); + array[36] = tmp; + tmp = vminf(array[37], array[69]); + array[69] = vmaxf(array[37], array[69]); + array[37] = tmp; + tmp = vminf(array[38], array[70]); + array[70] = vmaxf(array[38], array[70]); + array[38] = tmp; + tmp = vminf(array[39], array[71]); + array[71] = vmaxf(array[39], array[71]); + array[39] = tmp; + tmp = vminf(array[40], array[72]); + array[72] = vmaxf(array[40], array[72]); + array[40] = tmp; + tmp = vminf(array[41], array[73]); + array[73] = vmaxf(array[41], array[73]); + array[41] = tmp; + tmp = vminf(array[42], array[74]); + array[74] = vmaxf(array[42], array[74]); + array[42] = tmp; + tmp = vminf(array[43], array[75]); + array[75] = vmaxf(array[43], array[75]); + array[43] = tmp; + tmp = vminf(array[44], array[76]); + array[76] = vmaxf(array[44], array[76]); + array[44] = tmp; + tmp = vminf(array[45], array[77]); + array[77] = vmaxf(array[45], array[77]); + array[45] = tmp; + tmp = vminf(array[46], array[78]); + array[78] = vmaxf(array[46], array[78]); + array[46] = tmp; + tmp = vminf(array[47], array[79]); + array[79] = vmaxf(array[47], array[79]); + array[47] = tmp; + tmp = vminf(array[48], array[80]); + array[80] = vmaxf(array[48], array[80]); + array[48] = tmp; + tmp = vminf(array[0], array[16]); + array[16] = vmaxf(array[0], array[16]); + array[0] = tmp; + tmp = vminf(array[1], array[17]); + array[17] = vmaxf(array[1], array[17]); + array[1] = tmp; + tmp = vminf(array[2], array[18]); + array[18] = vmaxf(array[2], array[18]); + array[2] = tmp; + tmp = vminf(array[3], array[19]); + array[19] = vmaxf(array[3], array[19]); + array[3] = tmp; + tmp = vminf(array[4], array[20]); + array[20] = vmaxf(array[4], array[20]); + array[4] = tmp; + tmp = vminf(array[5], array[21]); + array[21] = vmaxf(array[5], array[21]); + array[5] = tmp; + tmp = vminf(array[6], array[22]); + array[22] = vmaxf(array[6], array[22]); + array[6] = tmp; + tmp = vminf(array[7], array[23]); + array[23] = vmaxf(array[7], array[23]); + array[7] = tmp; + tmp = vminf(array[8], array[24]); + array[24] = vmaxf(array[8], array[24]); + array[8] = tmp; + tmp = vminf(array[9], array[25]); + array[25] = vmaxf(array[9], array[25]); + array[9] = tmp; + tmp = vminf(array[10], array[26]); + array[26] = vmaxf(array[10], array[26]); + array[10] = tmp; + tmp = vminf(array[11], array[27]); + array[27] = vmaxf(array[11], array[27]); + array[11] = tmp; + tmp = vminf(array[12], array[28]); + array[28] = vmaxf(array[12], array[28]); + array[12] = tmp; + tmp = vminf(array[13], array[29]); + array[29] = vmaxf(array[13], array[29]); + array[13] = tmp; + tmp = vminf(array[14], array[30]); + array[30] = vmaxf(array[14], array[30]); + array[14] = tmp; + tmp = vminf(array[15], array[31]); + array[31] = vmaxf(array[15], array[31]); + array[15] = tmp; + tmp = vminf(array[32], array[48]); + array[48] = vmaxf(array[32], array[48]); + array[32] = tmp; + tmp = vminf(array[33], array[49]); + array[49] = vmaxf(array[33], array[49]); + array[33] = tmp; + tmp = vminf(array[34], array[50]); + array[50] = vmaxf(array[34], array[50]); + array[34] = tmp; + tmp = vminf(array[35], array[51]); + array[51] = vmaxf(array[35], array[51]); + array[35] = tmp; + tmp = vminf(array[36], array[52]); + array[52] = vmaxf(array[36], array[52]); + array[36] = tmp; + tmp = vminf(array[37], array[53]); + array[53] = vmaxf(array[37], array[53]); + array[37] = tmp; + tmp = vminf(array[38], array[54]); + array[54] = vmaxf(array[38], array[54]); + array[38] = tmp; + tmp = vminf(array[39], array[55]); + array[55] = vmaxf(array[39], array[55]); + array[39] = tmp; + tmp = vminf(array[40], array[56]); + array[56] = vmaxf(array[40], array[56]); + array[40] = tmp; + tmp = vminf(array[41], array[57]); + array[57] = vmaxf(array[41], array[57]); + array[41] = tmp; + tmp = vminf(array[42], array[58]); + array[58] = vmaxf(array[42], array[58]); + array[42] = tmp; + tmp = vminf(array[43], array[59]); + array[59] = vmaxf(array[43], array[59]); + array[43] = tmp; + tmp = vminf(array[44], array[60]); + array[60] = vmaxf(array[44], array[60]); + array[44] = tmp; + tmp = vminf(array[45], array[61]); + array[61] = vmaxf(array[45], array[61]); + array[45] = tmp; + tmp = vminf(array[46], array[62]); + array[62] = vmaxf(array[46], array[62]); + array[46] = tmp; + tmp = vminf(array[47], array[63]); + array[63] = vmaxf(array[47], array[63]); + array[47] = tmp; + tmp = vminf(array[64], array[80]); + array[80] = vmaxf(array[64], array[80]); + array[64] = tmp; + tmp = vminf(array[16], array[64]); + array[64] = vmaxf(array[16], array[64]); + array[16] = tmp; + tmp = vminf(array[17], array[65]); + array[65] = vmaxf(array[17], array[65]); + array[17] = tmp; + tmp = vminf(array[18], array[66]); + array[66] = vmaxf(array[18], array[66]); + array[18] = tmp; + tmp = vminf(array[19], array[67]); + array[67] = vmaxf(array[19], array[67]); + array[19] = tmp; + tmp = vminf(array[20], array[68]); + array[68] = vmaxf(array[20], array[68]); + array[20] = tmp; + tmp = vminf(array[21], array[69]); + array[69] = vmaxf(array[21], array[69]); + array[21] = tmp; + tmp = vminf(array[22], array[70]); + array[70] = vmaxf(array[22], array[70]); + array[22] = tmp; + tmp = vminf(array[23], array[71]); + array[71] = vmaxf(array[23], array[71]); + array[23] = tmp; + tmp = vminf(array[24], array[72]); + array[72] = vmaxf(array[24], array[72]); + array[24] = tmp; + tmp = vminf(array[25], array[73]); + array[73] = vmaxf(array[25], array[73]); + array[25] = tmp; + tmp = vminf(array[26], array[74]); + array[74] = vmaxf(array[26], array[74]); + array[26] = tmp; + tmp = vminf(array[27], array[75]); + array[75] = vmaxf(array[27], array[75]); + array[27] = tmp; + tmp = vminf(array[28], array[76]); + array[76] = vmaxf(array[28], array[76]); + array[28] = tmp; + tmp = vminf(array[29], array[77]); + array[77] = vmaxf(array[29], array[77]); + array[29] = tmp; + tmp = vminf(array[30], array[78]); + array[78] = vmaxf(array[30], array[78]); + array[30] = tmp; + tmp = vminf(array[31], array[79]); + array[79] = vmaxf(array[31], array[79]); + array[31] = tmp; + tmp = vminf(array[16], array[32]); + array[32] = vmaxf(array[16], array[32]); + array[16] = tmp; + tmp = vminf(array[17], array[33]); + array[33] = vmaxf(array[17], array[33]); + array[17] = tmp; + tmp = vminf(array[18], array[34]); + array[34] = vmaxf(array[18], array[34]); + array[18] = tmp; + tmp = vminf(array[19], array[35]); + array[35] = vmaxf(array[19], array[35]); + array[19] = tmp; + tmp = vminf(array[20], array[36]); + array[36] = vmaxf(array[20], array[36]); + array[20] = tmp; + tmp = vminf(array[21], array[37]); + array[37] = vmaxf(array[21], array[37]); + array[21] = tmp; + tmp = vminf(array[22], array[38]); + array[38] = vmaxf(array[22], array[38]); + array[22] = tmp; + tmp = vminf(array[23], array[39]); + array[39] = vmaxf(array[23], array[39]); + array[23] = tmp; + tmp = vminf(array[24], array[40]); + array[40] = vmaxf(array[24], array[40]); + array[24] = tmp; + tmp = vminf(array[25], array[41]); + array[41] = vmaxf(array[25], array[41]); + array[25] = tmp; + tmp = vminf(array[26], array[42]); + array[42] = vmaxf(array[26], array[42]); + array[26] = tmp; + tmp = vminf(array[27], array[43]); + array[43] = vmaxf(array[27], array[43]); + array[27] = tmp; + tmp = vminf(array[28], array[44]); + array[44] = vmaxf(array[28], array[44]); + array[28] = tmp; + tmp = vminf(array[29], array[45]); + array[45] = vmaxf(array[29], array[45]); + array[29] = tmp; + tmp = vminf(array[30], array[46]); + array[46] = vmaxf(array[30], array[46]); + array[30] = tmp; + tmp = vminf(array[31], array[47]); + array[47] = vmaxf(array[31], array[47]); + array[31] = tmp; + tmp = vminf(array[48], array[64]); + array[64] = vmaxf(array[48], array[64]); + array[48] = tmp; + tmp = vminf(array[49], array[65]); + array[65] = vmaxf(array[49], array[65]); + array[49] = tmp; + tmp = vminf(array[50], array[66]); + array[66] = vmaxf(array[50], array[66]); + array[50] = tmp; + tmp = vminf(array[51], array[67]); + array[67] = vmaxf(array[51], array[67]); + array[51] = tmp; + tmp = vminf(array[52], array[68]); + array[68] = vmaxf(array[52], array[68]); + array[52] = tmp; + tmp = vminf(array[53], array[69]); + array[69] = vmaxf(array[53], array[69]); + array[53] = tmp; + tmp = vminf(array[54], array[70]); + array[70] = vmaxf(array[54], array[70]); + array[54] = tmp; + tmp = vminf(array[55], array[71]); + array[71] = vmaxf(array[55], array[71]); + array[55] = tmp; + tmp = vminf(array[56], array[72]); + array[72] = vmaxf(array[56], array[72]); + array[56] = tmp; + tmp = vminf(array[57], array[73]); + array[73] = vmaxf(array[57], array[73]); + array[57] = tmp; + tmp = vminf(array[58], array[74]); + array[74] = vmaxf(array[58], array[74]); + array[58] = tmp; + tmp = vminf(array[59], array[75]); + array[75] = vmaxf(array[59], array[75]); + array[59] = tmp; + tmp = vminf(array[60], array[76]); + array[76] = vmaxf(array[60], array[76]); + array[60] = tmp; + tmp = vminf(array[61], array[77]); + array[77] = vmaxf(array[61], array[77]); + array[61] = tmp; + tmp = vminf(array[62], array[78]); + array[78] = vmaxf(array[62], array[78]); + array[62] = tmp; + tmp = vminf(array[63], array[79]); + array[79] = vmaxf(array[63], array[79]); + array[63] = tmp; + tmp = vminf(array[0], array[8]); + array[8] = vmaxf(array[0], array[8]); + array[0] = tmp; + tmp = vminf(array[1], array[9]); + array[9] = vmaxf(array[1], array[9]); + array[1] = tmp; + tmp = vminf(array[2], array[10]); + array[10] = vmaxf(array[2], array[10]); + array[2] = tmp; + tmp = vminf(array[3], array[11]); + array[11] = vmaxf(array[3], array[11]); + array[3] = tmp; + tmp = vminf(array[4], array[12]); + array[12] = vmaxf(array[4], array[12]); + array[4] = tmp; + tmp = vminf(array[5], array[13]); + array[13] = vmaxf(array[5], array[13]); + array[5] = tmp; + tmp = vminf(array[6], array[14]); + array[14] = vmaxf(array[6], array[14]); + array[6] = tmp; + tmp = vminf(array[7], array[15]); + array[15] = vmaxf(array[7], array[15]); + array[7] = tmp; + tmp = vminf(array[16], array[24]); + array[24] = vmaxf(array[16], array[24]); + array[16] = tmp; + tmp = vminf(array[17], array[25]); + array[25] = vmaxf(array[17], array[25]); + array[17] = tmp; + tmp = vminf(array[18], array[26]); + array[26] = vmaxf(array[18], array[26]); + array[18] = tmp; + tmp = vminf(array[19], array[27]); + array[27] = vmaxf(array[19], array[27]); + array[19] = tmp; + tmp = vminf(array[20], array[28]); + array[28] = vmaxf(array[20], array[28]); + array[20] = tmp; + tmp = vminf(array[21], array[29]); + array[29] = vmaxf(array[21], array[29]); + array[21] = tmp; + tmp = vminf(array[22], array[30]); + array[30] = vmaxf(array[22], array[30]); + array[22] = tmp; + tmp = vminf(array[23], array[31]); + array[31] = vmaxf(array[23], array[31]); + array[23] = tmp; + tmp = vminf(array[32], array[40]); + array[40] = vmaxf(array[32], array[40]); + array[32] = tmp; + tmp = vminf(array[33], array[41]); + array[41] = vmaxf(array[33], array[41]); + array[33] = tmp; + tmp = vminf(array[34], array[42]); + array[42] = vmaxf(array[34], array[42]); + array[34] = tmp; + tmp = vminf(array[35], array[43]); + array[43] = vmaxf(array[35], array[43]); + array[35] = tmp; + tmp = vminf(array[36], array[44]); + array[44] = vmaxf(array[36], array[44]); + array[36] = tmp; + tmp = vminf(array[37], array[45]); + array[45] = vmaxf(array[37], array[45]); + array[37] = tmp; + tmp = vminf(array[38], array[46]); + array[46] = vmaxf(array[38], array[46]); + array[38] = tmp; + tmp = vminf(array[39], array[47]); + array[47] = vmaxf(array[39], array[47]); + array[39] = tmp; + tmp = vminf(array[48], array[56]); + array[56] = vmaxf(array[48], array[56]); + array[48] = tmp; + tmp = vminf(array[49], array[57]); + array[57] = vmaxf(array[49], array[57]); + array[49] = tmp; + tmp = vminf(array[50], array[58]); + array[58] = vmaxf(array[50], array[58]); + array[50] = tmp; + tmp = vminf(array[51], array[59]); + array[59] = vmaxf(array[51], array[59]); + array[51] = tmp; + tmp = vminf(array[52], array[60]); + array[60] = vmaxf(array[52], array[60]); + array[52] = tmp; + tmp = vminf(array[53], array[61]); + array[61] = vmaxf(array[53], array[61]); + array[53] = tmp; + tmp = vminf(array[54], array[62]); + array[62] = vmaxf(array[54], array[62]); + array[54] = tmp; + tmp = vminf(array[55], array[63]); + array[63] = vmaxf(array[55], array[63]); + array[55] = tmp; + tmp = vminf(array[64], array[72]); + array[72] = vmaxf(array[64], array[72]); + array[64] = tmp; + tmp = vminf(array[65], array[73]); + array[73] = vmaxf(array[65], array[73]); + array[65] = tmp; + tmp = vminf(array[66], array[74]); + array[74] = vmaxf(array[66], array[74]); + array[66] = tmp; + tmp = vminf(array[67], array[75]); + array[75] = vmaxf(array[67], array[75]); + array[67] = tmp; + tmp = vminf(array[68], array[76]); + array[76] = vmaxf(array[68], array[76]); + array[68] = tmp; + tmp = vminf(array[69], array[77]); + array[77] = vmaxf(array[69], array[77]); + array[69] = tmp; + tmp = vminf(array[70], array[78]); + array[78] = vmaxf(array[70], array[78]); + array[70] = tmp; + tmp = vminf(array[71], array[79]); + array[79] = vmaxf(array[71], array[79]); + array[71] = tmp; + tmp = vminf(array[8], array[64]); + array[64] = vmaxf(array[8], array[64]); + array[8] = tmp; + tmp = vminf(array[9], array[65]); + array[65] = vmaxf(array[9], array[65]); + array[9] = tmp; + tmp = vminf(array[10], array[66]); + array[66] = vmaxf(array[10], array[66]); + array[10] = tmp; + tmp = vminf(array[11], array[67]); + array[67] = vmaxf(array[11], array[67]); + array[11] = tmp; + tmp = vminf(array[12], array[68]); + array[68] = vmaxf(array[12], array[68]); + array[12] = tmp; + tmp = vminf(array[13], array[69]); + array[69] = vmaxf(array[13], array[69]); + array[13] = tmp; + tmp = vminf(array[14], array[70]); + array[70] = vmaxf(array[14], array[70]); + array[14] = tmp; + tmp = vminf(array[15], array[71]); + array[71] = vmaxf(array[15], array[71]); + array[15] = tmp; + tmp = vminf(array[24], array[80]); + array[80] = vmaxf(array[24], array[80]); + array[24] = tmp; + tmp = vminf(array[8], array[32]); + array[32] = vmaxf(array[8], array[32]); + array[8] = tmp; + tmp = vminf(array[9], array[33]); + array[33] = vmaxf(array[9], array[33]); + array[9] = tmp; + tmp = vminf(array[10], array[34]); + array[34] = vmaxf(array[10], array[34]); + array[10] = tmp; + tmp = vminf(array[11], array[35]); + array[35] = vmaxf(array[11], array[35]); + array[11] = tmp; + tmp = vminf(array[12], array[36]); + array[36] = vmaxf(array[12], array[36]); + array[12] = tmp; + tmp = vminf(array[13], array[37]); + array[37] = vmaxf(array[13], array[37]); + array[13] = tmp; + tmp = vminf(array[14], array[38]); + array[38] = vmaxf(array[14], array[38]); + array[14] = tmp; + tmp = vminf(array[15], array[39]); + array[39] = vmaxf(array[15], array[39]); + array[15] = tmp; + tmp = vminf(array[24], array[48]); + array[48] = vmaxf(array[24], array[48]); + array[24] = tmp; + tmp = vminf(array[25], array[49]); + array[49] = vmaxf(array[25], array[49]); + array[25] = tmp; + tmp = vminf(array[26], array[50]); + array[50] = vmaxf(array[26], array[50]); + array[26] = tmp; + tmp = vminf(array[27], array[51]); + array[51] = vmaxf(array[27], array[51]); + array[27] = tmp; + tmp = vminf(array[28], array[52]); + array[52] = vmaxf(array[28], array[52]); + array[28] = tmp; + tmp = vminf(array[29], array[53]); + array[53] = vmaxf(array[29], array[53]); + array[29] = tmp; + tmp = vminf(array[30], array[54]); + array[54] = vmaxf(array[30], array[54]); + array[30] = tmp; + tmp = vminf(array[31], array[55]); + array[55] = vmaxf(array[31], array[55]); + array[31] = tmp; + tmp = vminf(array[40], array[64]); + array[64] = vmaxf(array[40], array[64]); + array[40] = tmp; + tmp = vminf(array[41], array[65]); + array[65] = vmaxf(array[41], array[65]); + array[41] = tmp; + tmp = vminf(array[42], array[66]); + array[66] = vmaxf(array[42], array[66]); + array[42] = tmp; + tmp = vminf(array[43], array[67]); + array[67] = vmaxf(array[43], array[67]); + array[43] = tmp; + tmp = vminf(array[44], array[68]); + array[68] = vmaxf(array[44], array[68]); + array[44] = tmp; + tmp = vminf(array[45], array[69]); + array[69] = vmaxf(array[45], array[69]); + array[45] = tmp; + tmp = vminf(array[46], array[70]); + array[70] = vmaxf(array[46], array[70]); + array[46] = tmp; + tmp = vminf(array[47], array[71]); + array[71] = vmaxf(array[47], array[71]); + array[47] = tmp; + tmp = vminf(array[56], array[80]); + array[80] = vmaxf(array[56], array[80]); + array[56] = tmp; + tmp = vminf(array[8], array[16]); + array[16] = vmaxf(array[8], array[16]); + array[8] = tmp; + tmp = vminf(array[9], array[17]); + array[17] = vmaxf(array[9], array[17]); + array[9] = tmp; + tmp = vminf(array[10], array[18]); + array[18] = vmaxf(array[10], array[18]); + array[10] = tmp; + tmp = vminf(array[11], array[19]); + array[19] = vmaxf(array[11], array[19]); + array[11] = tmp; + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[13], array[21]); + array[21] = vmaxf(array[13], array[21]); + array[13] = tmp; + tmp = vminf(array[14], array[22]); + array[22] = vmaxf(array[14], array[22]); + array[14] = tmp; + tmp = vminf(array[15], array[23]); + array[23] = vmaxf(array[15], array[23]); + array[15] = tmp; + tmp = vminf(array[24], array[32]); + array[32] = vmaxf(array[24], array[32]); + array[24] = tmp; + tmp = vminf(array[25], array[33]); + array[33] = vmaxf(array[25], array[33]); + array[25] = tmp; + tmp = vminf(array[26], array[34]); + array[34] = vmaxf(array[26], array[34]); + array[26] = tmp; + tmp = vminf(array[27], array[35]); + array[35] = vmaxf(array[27], array[35]); + array[27] = tmp; + tmp = vminf(array[28], array[36]); + array[36] = vmaxf(array[28], array[36]); + array[28] = tmp; + tmp = vminf(array[29], array[37]); + array[37] = vmaxf(array[29], array[37]); + array[29] = tmp; + tmp = vminf(array[30], array[38]); + array[38] = vmaxf(array[30], array[38]); + array[30] = tmp; + tmp = vminf(array[31], array[39]); + array[39] = vmaxf(array[31], array[39]); + array[31] = tmp; + tmp = vminf(array[40], array[48]); + array[48] = vmaxf(array[40], array[48]); + array[40] = tmp; + tmp = vminf(array[41], array[49]); + array[49] = vmaxf(array[41], array[49]); + array[41] = tmp; + tmp = vminf(array[42], array[50]); + array[50] = vmaxf(array[42], array[50]); + array[42] = tmp; + tmp = vminf(array[43], array[51]); + array[51] = vmaxf(array[43], array[51]); + array[43] = tmp; + tmp = vminf(array[44], array[52]); + array[52] = vmaxf(array[44], array[52]); + array[44] = tmp; + tmp = vminf(array[45], array[53]); + array[53] = vmaxf(array[45], array[53]); + array[45] = tmp; + tmp = vminf(array[46], array[54]); + array[54] = vmaxf(array[46], array[54]); + array[46] = tmp; + tmp = vminf(array[47], array[55]); + array[55] = vmaxf(array[47], array[55]); + array[47] = tmp; + tmp = vminf(array[56], array[64]); + array[64] = vmaxf(array[56], array[64]); + array[56] = tmp; + tmp = vminf(array[57], array[65]); + array[65] = vmaxf(array[57], array[65]); + array[57] = tmp; + tmp = vminf(array[58], array[66]); + array[66] = vmaxf(array[58], array[66]); + array[58] = tmp; + tmp = vminf(array[59], array[67]); + array[67] = vmaxf(array[59], array[67]); + array[59] = tmp; + tmp = vminf(array[60], array[68]); + array[68] = vmaxf(array[60], array[68]); + array[60] = tmp; + tmp = vminf(array[61], array[69]); + array[69] = vmaxf(array[61], array[69]); + array[61] = tmp; + tmp = vminf(array[62], array[70]); + array[70] = vmaxf(array[62], array[70]); + array[62] = tmp; + tmp = vminf(array[63], array[71]); + array[71] = vmaxf(array[63], array[71]); + array[63] = tmp; + tmp = vminf(array[72], array[80]); + array[80] = vmaxf(array[72], array[80]); + array[72] = tmp; + tmp = vminf(array[0], array[4]); + array[4] = vmaxf(array[0], array[4]); + array[0] = tmp; + tmp = vminf(array[1], array[5]); + array[5] = vmaxf(array[1], array[5]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[8], array[12]); + array[12] = vmaxf(array[8], array[12]); + array[8] = tmp; + tmp = vminf(array[9], array[13]); + array[13] = vmaxf(array[9], array[13]); + array[9] = tmp; + tmp = vminf(array[10], array[14]); + array[14] = vmaxf(array[10], array[14]); + array[10] = tmp; + tmp = vminf(array[11], array[15]); + array[15] = vmaxf(array[11], array[15]); + array[11] = tmp; + tmp = vminf(array[16], array[20]); + array[20] = vmaxf(array[16], array[20]); + array[16] = tmp; + tmp = vminf(array[17], array[21]); + array[21] = vmaxf(array[17], array[21]); + array[17] = tmp; + tmp = vminf(array[18], array[22]); + array[22] = vmaxf(array[18], array[22]); + array[18] = tmp; + tmp = vminf(array[19], array[23]); + array[23] = vmaxf(array[19], array[23]); + array[19] = tmp; + tmp = vminf(array[24], array[28]); + array[28] = vmaxf(array[24], array[28]); + array[24] = tmp; + tmp = vminf(array[25], array[29]); + array[29] = vmaxf(array[25], array[29]); + array[25] = tmp; + tmp = vminf(array[26], array[30]); + array[30] = vmaxf(array[26], array[30]); + array[26] = tmp; + tmp = vminf(array[27], array[31]); + array[31] = vmaxf(array[27], array[31]); + array[27] = tmp; + tmp = vminf(array[32], array[36]); + array[36] = vmaxf(array[32], array[36]); + array[32] = tmp; + tmp = vminf(array[33], array[37]); + array[37] = vmaxf(array[33], array[37]); + array[33] = tmp; + tmp = vminf(array[34], array[38]); + array[38] = vmaxf(array[34], array[38]); + array[34] = tmp; + tmp = vminf(array[35], array[39]); + array[39] = vmaxf(array[35], array[39]); + array[35] = tmp; + tmp = vminf(array[40], array[44]); + array[44] = vmaxf(array[40], array[44]); + array[40] = tmp; + tmp = vminf(array[41], array[45]); + array[45] = vmaxf(array[41], array[45]); + array[41] = tmp; + tmp = vminf(array[42], array[46]); + array[46] = vmaxf(array[42], array[46]); + array[42] = tmp; + tmp = vminf(array[43], array[47]); + array[47] = vmaxf(array[43], array[47]); + array[43] = tmp; + tmp = vminf(array[48], array[52]); + array[52] = vmaxf(array[48], array[52]); + array[48] = tmp; + tmp = vminf(array[49], array[53]); + array[53] = vmaxf(array[49], array[53]); + array[49] = tmp; + tmp = vminf(array[50], array[54]); + array[54] = vmaxf(array[50], array[54]); + array[50] = tmp; + tmp = vminf(array[51], array[55]); + array[55] = vmaxf(array[51], array[55]); + array[51] = tmp; + tmp = vminf(array[56], array[60]); + array[60] = vmaxf(array[56], array[60]); + array[56] = tmp; + tmp = vminf(array[57], array[61]); + array[61] = vmaxf(array[57], array[61]); + array[57] = tmp; + tmp = vminf(array[58], array[62]); + array[62] = vmaxf(array[58], array[62]); + array[58] = tmp; + tmp = vminf(array[59], array[63]); + array[63] = vmaxf(array[59], array[63]); + array[59] = tmp; + tmp = vminf(array[64], array[68]); + array[68] = vmaxf(array[64], array[68]); + array[64] = tmp; + tmp = vminf(array[65], array[69]); + array[69] = vmaxf(array[65], array[69]); + array[65] = tmp; + tmp = vminf(array[66], array[70]); + array[70] = vmaxf(array[66], array[70]); + array[66] = tmp; + tmp = vminf(array[67], array[71]); + array[71] = vmaxf(array[67], array[71]); + array[67] = tmp; + tmp = vminf(array[72], array[76]); + array[76] = vmaxf(array[72], array[76]); + array[72] = tmp; + tmp = vminf(array[73], array[77]); + array[77] = vmaxf(array[73], array[77]); + array[73] = tmp; + tmp = vminf(array[74], array[78]); + array[78] = vmaxf(array[74], array[78]); + array[74] = tmp; + tmp = vminf(array[75], array[79]); + array[79] = vmaxf(array[75], array[79]); + array[75] = tmp; + tmp = vminf(array[4], array[64]); + array[64] = vmaxf(array[4], array[64]); + array[4] = tmp; + tmp = vminf(array[5], array[65]); + array[65] = vmaxf(array[5], array[65]); + array[5] = tmp; + tmp = vminf(array[6], array[66]); + array[66] = vmaxf(array[6], array[66]); + array[6] = tmp; + tmp = vminf(array[7], array[67]); + array[67] = vmaxf(array[7], array[67]); + array[7] = tmp; + tmp = vminf(array[12], array[72]); + array[72] = vmaxf(array[12], array[72]); + array[12] = tmp; + tmp = vminf(array[13], array[73]); + array[73] = vmaxf(array[13], array[73]); + array[13] = tmp; + tmp = vminf(array[14], array[74]); + array[74] = vmaxf(array[14], array[74]); + array[14] = tmp; + tmp = vminf(array[15], array[75]); + array[75] = vmaxf(array[15], array[75]); + array[15] = tmp; + tmp = vminf(array[20], array[80]); + array[80] = vmaxf(array[20], array[80]); + array[20] = tmp; + tmp = vminf(array[4], array[32]); + array[32] = vmaxf(array[4], array[32]); + array[4] = tmp; + tmp = vminf(array[5], array[33]); + array[33] = vmaxf(array[5], array[33]); + array[5] = tmp; + tmp = vminf(array[6], array[34]); + array[34] = vmaxf(array[6], array[34]); + array[6] = tmp; + tmp = vminf(array[7], array[35]); + array[35] = vmaxf(array[7], array[35]); + array[7] = tmp; + tmp = vminf(array[12], array[40]); + array[40] = vmaxf(array[12], array[40]); + array[12] = tmp; + tmp = vminf(array[13], array[41]); + array[41] = vmaxf(array[13], array[41]); + array[13] = tmp; + tmp = vminf(array[14], array[42]); + array[42] = vmaxf(array[14], array[42]); + array[14] = tmp; + tmp = vminf(array[15], array[43]); + array[43] = vmaxf(array[15], array[43]); + array[15] = tmp; + tmp = vminf(array[20], array[48]); + array[48] = vmaxf(array[20], array[48]); + array[20] = tmp; + tmp = vminf(array[21], array[49]); + array[49] = vmaxf(array[21], array[49]); + array[21] = tmp; + tmp = vminf(array[22], array[50]); + array[50] = vmaxf(array[22], array[50]); + array[22] = tmp; + tmp = vminf(array[23], array[51]); + array[51] = vmaxf(array[23], array[51]); + array[23] = tmp; + tmp = vminf(array[28], array[56]); + array[56] = vmaxf(array[28], array[56]); + array[28] = tmp; + tmp = vminf(array[29], array[57]); + array[57] = vmaxf(array[29], array[57]); + array[29] = tmp; + tmp = vminf(array[30], array[58]); + array[58] = vmaxf(array[30], array[58]); + array[30] = tmp; + tmp = vminf(array[31], array[59]); + array[59] = vmaxf(array[31], array[59]); + array[31] = tmp; + tmp = vminf(array[36], array[64]); + array[64] = vmaxf(array[36], array[64]); + array[36] = tmp; + tmp = vminf(array[37], array[65]); + array[65] = vmaxf(array[37], array[65]); + array[37] = tmp; + tmp = vminf(array[38], array[66]); + array[66] = vmaxf(array[38], array[66]); + array[38] = tmp; + tmp = vminf(array[39], array[67]); + array[67] = vmaxf(array[39], array[67]); + array[39] = tmp; + tmp = vminf(array[44], array[72]); + array[72] = vmaxf(array[44], array[72]); + array[44] = tmp; + tmp = vminf(array[45], array[73]); + array[73] = vmaxf(array[45], array[73]); + array[45] = tmp; + tmp = vminf(array[46], array[74]); + array[74] = vmaxf(array[46], array[74]); + array[46] = tmp; + tmp = vminf(array[47], array[75]); + array[75] = vmaxf(array[47], array[75]); + array[47] = tmp; + tmp = vminf(array[52], array[80]); + array[80] = vmaxf(array[52], array[80]); + array[52] = tmp; + tmp = vminf(array[4], array[16]); + array[16] = vmaxf(array[4], array[16]); + array[4] = tmp; + tmp = vminf(array[5], array[17]); + array[17] = vmaxf(array[5], array[17]); + array[5] = tmp; + tmp = vminf(array[6], array[18]); + array[18] = vmaxf(array[6], array[18]); + array[6] = tmp; + tmp = vminf(array[7], array[19]); + array[19] = vmaxf(array[7], array[19]); + array[7] = tmp; + tmp = vminf(array[12], array[24]); + array[24] = vmaxf(array[12], array[24]); + array[12] = tmp; + tmp = vminf(array[13], array[25]); + array[25] = vmaxf(array[13], array[25]); + array[13] = tmp; + tmp = vminf(array[14], array[26]); + array[26] = vmaxf(array[14], array[26]); + array[14] = tmp; + tmp = vminf(array[15], array[27]); + array[27] = vmaxf(array[15], array[27]); + array[15] = tmp; + tmp = vminf(array[20], array[32]); + array[32] = vmaxf(array[20], array[32]); + array[20] = tmp; + tmp = vminf(array[21], array[33]); + array[33] = vmaxf(array[21], array[33]); + array[21] = tmp; + tmp = vminf(array[22], array[34]); + array[34] = vmaxf(array[22], array[34]); + array[22] = tmp; + tmp = vminf(array[23], array[35]); + array[35] = vmaxf(array[23], array[35]); + array[23] = tmp; + tmp = vminf(array[28], array[40]); + array[40] = vmaxf(array[28], array[40]); + array[28] = tmp; + tmp = vminf(array[29], array[41]); + array[41] = vmaxf(array[29], array[41]); + array[29] = tmp; + tmp = vminf(array[30], array[42]); + array[42] = vmaxf(array[30], array[42]); + array[30] = tmp; + tmp = vminf(array[31], array[43]); + array[43] = vmaxf(array[31], array[43]); + array[31] = tmp; + tmp = vminf(array[36], array[48]); + array[48] = vmaxf(array[36], array[48]); + array[36] = tmp; + tmp = vminf(array[37], array[49]); + array[49] = vmaxf(array[37], array[49]); + array[37] = tmp; + tmp = vminf(array[38], array[50]); + array[50] = vmaxf(array[38], array[50]); + array[38] = tmp; + tmp = vminf(array[39], array[51]); + array[51] = vmaxf(array[39], array[51]); + array[39] = tmp; + tmp = vminf(array[44], array[56]); + array[56] = vmaxf(array[44], array[56]); + array[44] = tmp; + tmp = vminf(array[45], array[57]); + array[57] = vmaxf(array[45], array[57]); + array[45] = tmp; + tmp = vminf(array[46], array[58]); + array[58] = vmaxf(array[46], array[58]); + array[46] = tmp; + tmp = vminf(array[47], array[59]); + array[59] = vmaxf(array[47], array[59]); + array[47] = tmp; + tmp = vminf(array[52], array[64]); + array[64] = vmaxf(array[52], array[64]); + array[52] = tmp; + tmp = vminf(array[53], array[65]); + array[65] = vmaxf(array[53], array[65]); + array[53] = tmp; + tmp = vminf(array[54], array[66]); + array[66] = vmaxf(array[54], array[66]); + array[54] = tmp; + tmp = vminf(array[55], array[67]); + array[67] = vmaxf(array[55], array[67]); + array[55] = tmp; + tmp = vminf(array[60], array[72]); + array[72] = vmaxf(array[60], array[72]); + array[60] = tmp; + tmp = vminf(array[61], array[73]); + array[73] = vmaxf(array[61], array[73]); + array[61] = tmp; + tmp = vminf(array[62], array[74]); + array[74] = vmaxf(array[62], array[74]); + array[62] = tmp; + tmp = vminf(array[63], array[75]); + array[75] = vmaxf(array[63], array[75]); + array[63] = tmp; + tmp = vminf(array[68], array[80]); + array[80] = vmaxf(array[68], array[80]); + array[68] = tmp; + tmp = vminf(array[4], array[8]); + array[8] = vmaxf(array[4], array[8]); + array[4] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[7], array[11]); + array[11] = vmaxf(array[7], array[11]); + array[7] = tmp; + tmp = vminf(array[12], array[16]); + array[16] = vmaxf(array[12], array[16]); + array[12] = tmp; + tmp = vminf(array[13], array[17]); + array[17] = vmaxf(array[13], array[17]); + array[13] = tmp; + tmp = vminf(array[14], array[18]); + array[18] = vmaxf(array[14], array[18]); + array[14] = tmp; + tmp = vminf(array[15], array[19]); + array[19] = vmaxf(array[15], array[19]); + array[15] = tmp; + tmp = vminf(array[20], array[24]); + array[24] = vmaxf(array[20], array[24]); + array[20] = tmp; + tmp = vminf(array[21], array[25]); + array[25] = vmaxf(array[21], array[25]); + array[21] = tmp; + tmp = vminf(array[22], array[26]); + array[26] = vmaxf(array[22], array[26]); + array[22] = tmp; + tmp = vminf(array[23], array[27]); + array[27] = vmaxf(array[23], array[27]); + array[23] = tmp; + tmp = vminf(array[28], array[32]); + array[32] = vmaxf(array[28], array[32]); + array[28] = tmp; + tmp = vminf(array[29], array[33]); + array[33] = vmaxf(array[29], array[33]); + array[29] = tmp; + tmp = vminf(array[30], array[34]); + array[34] = vmaxf(array[30], array[34]); + array[30] = tmp; + tmp = vminf(array[31], array[35]); + array[35] = vmaxf(array[31], array[35]); + array[31] = tmp; + tmp = vminf(array[36], array[40]); + array[40] = vmaxf(array[36], array[40]); + array[36] = tmp; + tmp = vminf(array[37], array[41]); + array[41] = vmaxf(array[37], array[41]); + array[37] = tmp; + tmp = vminf(array[38], array[42]); + array[42] = vmaxf(array[38], array[42]); + array[38] = tmp; + tmp = vminf(array[39], array[43]); + array[43] = vmaxf(array[39], array[43]); + array[39] = tmp; + tmp = vminf(array[44], array[48]); + array[48] = vmaxf(array[44], array[48]); + array[44] = tmp; + tmp = vminf(array[45], array[49]); + array[49] = vmaxf(array[45], array[49]); + array[45] = tmp; + tmp = vminf(array[46], array[50]); + array[50] = vmaxf(array[46], array[50]); + array[46] = tmp; + tmp = vminf(array[47], array[51]); + array[51] = vmaxf(array[47], array[51]); + array[47] = tmp; + tmp = vminf(array[52], array[56]); + array[56] = vmaxf(array[52], array[56]); + array[52] = tmp; + tmp = vminf(array[53], array[57]); + array[57] = vmaxf(array[53], array[57]); + array[53] = tmp; + tmp = vminf(array[54], array[58]); + array[58] = vmaxf(array[54], array[58]); + array[54] = tmp; + tmp = vminf(array[55], array[59]); + array[59] = vmaxf(array[55], array[59]); + array[55] = tmp; + tmp = vminf(array[60], array[64]); + array[64] = vmaxf(array[60], array[64]); + array[60] = tmp; + tmp = vminf(array[61], array[65]); + array[65] = vmaxf(array[61], array[65]); + array[61] = tmp; + tmp = vminf(array[62], array[66]); + array[66] = vmaxf(array[62], array[66]); + array[62] = tmp; + tmp = vminf(array[63], array[67]); + array[67] = vmaxf(array[63], array[67]); + array[63] = tmp; + tmp = vminf(array[68], array[72]); + array[72] = vmaxf(array[68], array[72]); + array[68] = tmp; + tmp = vminf(array[69], array[73]); + array[73] = vmaxf(array[69], array[73]); + array[69] = tmp; + tmp = vminf(array[70], array[74]); + array[74] = vmaxf(array[70], array[74]); + array[70] = tmp; + tmp = vminf(array[71], array[75]); + array[75] = vmaxf(array[71], array[75]); + array[71] = tmp; + tmp = vminf(array[76], array[80]); + array[80] = vmaxf(array[76], array[80]); + array[76] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[1], array[3]); + array[3] = vmaxf(array[1], array[3]); + array[1] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + tmp = vminf(array[13], array[15]); + array[15] = vmaxf(array[13], array[15]); + array[13] = tmp; + tmp = vminf(array[16], array[18]); + array[18] = vmaxf(array[16], array[18]); + array[16] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = tmp; + tmp = vminf(array[21], array[23]); + array[23] = vmaxf(array[21], array[23]); + array[21] = tmp; + tmp = vminf(array[24], array[26]); + array[26] = vmaxf(array[24], array[26]); + array[24] = tmp; + tmp = vminf(array[25], array[27]); + array[27] = vmaxf(array[25], array[27]); + array[25] = tmp; + tmp = vminf(array[28], array[30]); + array[30] = vmaxf(array[28], array[30]); + array[28] = tmp; + tmp = vminf(array[29], array[31]); + array[31] = vmaxf(array[29], array[31]); + array[29] = tmp; + tmp = vminf(array[32], array[34]); + array[34] = vmaxf(array[32], array[34]); + array[32] = tmp; + tmp = vminf(array[33], array[35]); + array[35] = vmaxf(array[33], array[35]); + array[33] = tmp; + tmp = vminf(array[36], array[38]); + array[38] = vmaxf(array[36], array[38]); + array[36] = tmp; + tmp = vminf(array[37], array[39]); + array[39] = vmaxf(array[37], array[39]); + array[37] = tmp; + tmp = vminf(array[40], array[42]); + array[42] = vmaxf(array[40], array[42]); + array[40] = tmp; + tmp = vminf(array[41], array[43]); + array[43] = vmaxf(array[41], array[43]); + array[41] = tmp; + tmp = vminf(array[44], array[46]); + array[46] = vmaxf(array[44], array[46]); + array[44] = tmp; + tmp = vminf(array[45], array[47]); + array[47] = vmaxf(array[45], array[47]); + array[45] = tmp; + tmp = vminf(array[48], array[50]); + array[50] = vmaxf(array[48], array[50]); + array[48] = tmp; + tmp = vminf(array[49], array[51]); + array[51] = vmaxf(array[49], array[51]); + array[49] = tmp; + tmp = vminf(array[52], array[54]); + array[54] = vmaxf(array[52], array[54]); + array[52] = tmp; + tmp = vminf(array[53], array[55]); + array[55] = vmaxf(array[53], array[55]); + array[53] = tmp; + tmp = vminf(array[56], array[58]); + array[58] = vmaxf(array[56], array[58]); + array[56] = tmp; + tmp = vminf(array[57], array[59]); + array[59] = vmaxf(array[57], array[59]); + array[57] = tmp; + tmp = vminf(array[60], array[62]); + array[62] = vmaxf(array[60], array[62]); + array[60] = tmp; + tmp = vminf(array[61], array[63]); + array[63] = vmaxf(array[61], array[63]); + array[61] = tmp; + tmp = vminf(array[64], array[66]); + array[66] = vmaxf(array[64], array[66]); + array[64] = tmp; + tmp = vminf(array[65], array[67]); + array[67] = vmaxf(array[65], array[67]); + array[65] = tmp; + tmp = vminf(array[68], array[70]); + array[70] = vmaxf(array[68], array[70]); + array[68] = tmp; + tmp = vminf(array[69], array[71]); + array[71] = vmaxf(array[69], array[71]); + array[69] = tmp; + tmp = vminf(array[72], array[74]); + array[74] = vmaxf(array[72], array[74]); + array[72] = tmp; + tmp = vminf(array[73], array[75]); + array[75] = vmaxf(array[73], array[75]); + array[73] = tmp; + tmp = vminf(array[76], array[78]); + array[78] = vmaxf(array[76], array[78]); + array[76] = tmp; + tmp = vminf(array[77], array[79]); + array[79] = vmaxf(array[77], array[79]); + array[77] = tmp; + tmp = vminf(array[2], array[64]); + array[64] = vmaxf(array[2], array[64]); + array[2] = tmp; + tmp = vminf(array[3], array[65]); + array[65] = vmaxf(array[3], array[65]); + array[3] = tmp; + tmp = vminf(array[6], array[68]); + array[68] = vmaxf(array[6], array[68]); + array[6] = tmp; + tmp = vminf(array[7], array[69]); + array[69] = vmaxf(array[7], array[69]); + array[7] = tmp; + tmp = vminf(array[10], array[72]); + array[72] = vmaxf(array[10], array[72]); + array[10] = tmp; + tmp = vminf(array[11], array[73]); + array[73] = vmaxf(array[11], array[73]); + array[11] = tmp; + tmp = vminf(array[14], array[76]); + array[76] = vmaxf(array[14], array[76]); + array[14] = tmp; + tmp = vminf(array[15], array[77]); + array[77] = vmaxf(array[15], array[77]); + array[15] = tmp; + tmp = vminf(array[18], array[80]); + array[80] = vmaxf(array[18], array[80]); + array[18] = tmp; + tmp = vminf(array[2], array[32]); + array[32] = vmaxf(array[2], array[32]); + array[2] = tmp; + tmp = vminf(array[3], array[33]); + array[33] = vmaxf(array[3], array[33]); + array[3] = tmp; + tmp = vminf(array[6], array[36]); + array[36] = vmaxf(array[6], array[36]); + array[6] = tmp; + tmp = vminf(array[7], array[37]); + array[37] = vmaxf(array[7], array[37]); + array[7] = tmp; + tmp = vminf(array[10], array[40]); + array[40] = vmaxf(array[10], array[40]); + array[10] = tmp; + tmp = vminf(array[11], array[41]); + array[41] = vmaxf(array[11], array[41]); + array[11] = tmp; + tmp = vminf(array[14], array[44]); + array[44] = vmaxf(array[14], array[44]); + array[14] = tmp; + tmp = vminf(array[15], array[45]); + array[45] = vmaxf(array[15], array[45]); + array[15] = tmp; + tmp = vminf(array[18], array[48]); + array[48] = vmaxf(array[18], array[48]); + array[18] = tmp; + tmp = vminf(array[19], array[49]); + array[49] = vmaxf(array[19], array[49]); + array[19] = tmp; + tmp = vminf(array[22], array[52]); + array[52] = vmaxf(array[22], array[52]); + array[22] = tmp; + tmp = vminf(array[23], array[53]); + array[53] = vmaxf(array[23], array[53]); + array[23] = tmp; + tmp = vminf(array[26], array[56]); + array[56] = vmaxf(array[26], array[56]); + array[26] = tmp; + tmp = vminf(array[27], array[57]); + array[57] = vmaxf(array[27], array[57]); + array[27] = tmp; + tmp = vminf(array[30], array[60]); + array[60] = vmaxf(array[30], array[60]); + array[30] = tmp; + tmp = vminf(array[31], array[61]); + array[61] = vmaxf(array[31], array[61]); + array[31] = tmp; + tmp = vminf(array[34], array[64]); + array[64] = vmaxf(array[34], array[64]); + array[34] = tmp; + tmp = vminf(array[35], array[65]); + array[65] = vmaxf(array[35], array[65]); + array[35] = tmp; + tmp = vminf(array[38], array[68]); + array[68] = vmaxf(array[38], array[68]); + array[38] = tmp; + tmp = vminf(array[39], array[69]); + array[69] = vmaxf(array[39], array[69]); + array[39] = tmp; + tmp = vminf(array[42], array[72]); + array[72] = vmaxf(array[42], array[72]); + array[42] = tmp; + tmp = vminf(array[43], array[73]); + array[73] = vmaxf(array[43], array[73]); + array[43] = tmp; + tmp = vminf(array[46], array[76]); + array[76] = vmaxf(array[46], array[76]); + array[46] = tmp; + tmp = vminf(array[47], array[77]); + array[77] = vmaxf(array[47], array[77]); + array[47] = tmp; + tmp = vminf(array[50], array[80]); + array[80] = vmaxf(array[50], array[80]); + array[50] = tmp; + tmp = vminf(array[2], array[16]); + array[16] = vmaxf(array[2], array[16]); + array[2] = tmp; + tmp = vminf(array[3], array[17]); + array[17] = vmaxf(array[3], array[17]); + array[3] = tmp; + tmp = vminf(array[6], array[20]); + array[20] = vmaxf(array[6], array[20]); + array[6] = tmp; + tmp = vminf(array[7], array[21]); + array[21] = vmaxf(array[7], array[21]); + array[7] = tmp; + tmp = vminf(array[10], array[24]); + array[24] = vmaxf(array[10], array[24]); + array[10] = tmp; + tmp = vminf(array[11], array[25]); + array[25] = vmaxf(array[11], array[25]); + array[11] = tmp; + tmp = vminf(array[14], array[28]); + array[28] = vmaxf(array[14], array[28]); + array[14] = tmp; + tmp = vminf(array[15], array[29]); + array[29] = vmaxf(array[15], array[29]); + array[15] = tmp; + tmp = vminf(array[18], array[32]); + array[32] = vmaxf(array[18], array[32]); + array[18] = tmp; + tmp = vminf(array[19], array[33]); + array[33] = vmaxf(array[19], array[33]); + array[19] = tmp; + tmp = vminf(array[22], array[36]); + array[36] = vmaxf(array[22], array[36]); + array[22] = tmp; + tmp = vminf(array[23], array[37]); + array[37] = vmaxf(array[23], array[37]); + array[23] = tmp; + tmp = vminf(array[26], array[40]); + array[40] = vmaxf(array[26], array[40]); + array[26] = tmp; + tmp = vminf(array[27], array[41]); + array[41] = vmaxf(array[27], array[41]); + array[27] = tmp; + tmp = vminf(array[30], array[44]); + array[44] = vmaxf(array[30], array[44]); + array[30] = tmp; + tmp = vminf(array[31], array[45]); + array[45] = vmaxf(array[31], array[45]); + array[31] = tmp; + tmp = vminf(array[34], array[48]); + array[48] = vmaxf(array[34], array[48]); + array[34] = tmp; + tmp = vminf(array[35], array[49]); + array[49] = vmaxf(array[35], array[49]); + array[35] = tmp; + tmp = vminf(array[38], array[52]); + array[52] = vmaxf(array[38], array[52]); + array[38] = tmp; + tmp = vminf(array[39], array[53]); + array[53] = vmaxf(array[39], array[53]); + array[39] = tmp; + tmp = vminf(array[42], array[56]); + array[56] = vmaxf(array[42], array[56]); + array[42] = tmp; + tmp = vminf(array[43], array[57]); + array[57] = vmaxf(array[43], array[57]); + array[43] = tmp; + tmp = vminf(array[46], array[60]); + array[60] = vmaxf(array[46], array[60]); + array[46] = tmp; + tmp = vminf(array[47], array[61]); + array[61] = vmaxf(array[47], array[61]); + array[47] = tmp; + tmp = vminf(array[50], array[64]); + array[64] = vmaxf(array[50], array[64]); + array[50] = tmp; + tmp = vminf(array[51], array[65]); + array[65] = vmaxf(array[51], array[65]); + array[51] = tmp; + tmp = vminf(array[54], array[68]); + array[68] = vmaxf(array[54], array[68]); + array[54] = tmp; + tmp = vminf(array[55], array[69]); + array[69] = vmaxf(array[55], array[69]); + array[55] = tmp; + tmp = vminf(array[58], array[72]); + array[72] = vmaxf(array[58], array[72]); + array[58] = tmp; + tmp = vminf(array[59], array[73]); + array[73] = vmaxf(array[59], array[73]); + array[59] = tmp; + tmp = vminf(array[62], array[76]); + array[76] = vmaxf(array[62], array[76]); + array[62] = tmp; + tmp = vminf(array[63], array[77]); + array[77] = vmaxf(array[63], array[77]); + array[63] = tmp; + tmp = vminf(array[66], array[80]); + array[80] = vmaxf(array[66], array[80]); + array[66] = tmp; + tmp = vminf(array[2], array[8]); + array[8] = vmaxf(array[2], array[8]); + array[2] = tmp; + tmp = vminf(array[3], array[9]); + array[9] = vmaxf(array[3], array[9]); + array[3] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[13]); + array[13] = vmaxf(array[7], array[13]); + array[7] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = tmp; + tmp = vminf(array[11], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[11] = tmp; + tmp = vminf(array[14], array[20]); + array[20] = vmaxf(array[14], array[20]); + array[14] = tmp; + tmp = vminf(array[15], array[21]); + array[21] = vmaxf(array[15], array[21]); + array[15] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = tmp; + tmp = vminf(array[19], array[25]); + array[25] = vmaxf(array[19], array[25]); + array[19] = tmp; + tmp = vminf(array[22], array[28]); + array[28] = vmaxf(array[22], array[28]); + array[22] = tmp; + tmp = vminf(array[23], array[29]); + array[29] = vmaxf(array[23], array[29]); + array[23] = tmp; + tmp = vminf(array[26], array[32]); + array[32] = vmaxf(array[26], array[32]); + array[26] = tmp; + tmp = vminf(array[27], array[33]); + array[33] = vmaxf(array[27], array[33]); + array[27] = tmp; + tmp = vminf(array[30], array[36]); + array[36] = vmaxf(array[30], array[36]); + array[30] = tmp; + tmp = vminf(array[31], array[37]); + array[37] = vmaxf(array[31], array[37]); + array[31] = tmp; + tmp = vminf(array[34], array[40]); + array[40] = vmaxf(array[34], array[40]); + array[34] = tmp; + tmp = vminf(array[35], array[41]); + array[41] = vmaxf(array[35], array[41]); + array[35] = tmp; + tmp = vminf(array[38], array[44]); + array[44] = vmaxf(array[38], array[44]); + array[38] = tmp; + tmp = vminf(array[39], array[45]); + array[45] = vmaxf(array[39], array[45]); + array[39] = tmp; + tmp = vminf(array[42], array[48]); + array[48] = vmaxf(array[42], array[48]); + array[42] = tmp; + tmp = vminf(array[43], array[49]); + array[49] = vmaxf(array[43], array[49]); + array[43] = tmp; + tmp = vminf(array[46], array[52]); + array[52] = vmaxf(array[46], array[52]); + array[46] = tmp; + tmp = vminf(array[47], array[53]); + array[53] = vmaxf(array[47], array[53]); + array[47] = tmp; + tmp = vminf(array[50], array[56]); + array[56] = vmaxf(array[50], array[56]); + array[50] = tmp; + tmp = vminf(array[51], array[57]); + array[57] = vmaxf(array[51], array[57]); + array[51] = tmp; + tmp = vminf(array[54], array[60]); + array[60] = vmaxf(array[54], array[60]); + array[54] = tmp; + tmp = vminf(array[55], array[61]); + array[61] = vmaxf(array[55], array[61]); + array[55] = tmp; + tmp = vminf(array[58], array[64]); + array[64] = vmaxf(array[58], array[64]); + array[58] = tmp; + tmp = vminf(array[59], array[65]); + array[65] = vmaxf(array[59], array[65]); + array[59] = tmp; + tmp = vminf(array[62], array[68]); + array[68] = vmaxf(array[62], array[68]); + array[62] = tmp; + tmp = vminf(array[63], array[69]); + array[69] = vmaxf(array[63], array[69]); + array[63] = tmp; + tmp = vminf(array[66], array[72]); + array[72] = vmaxf(array[66], array[72]); + array[66] = tmp; + tmp = vminf(array[67], array[73]); + array[73] = vmaxf(array[67], array[73]); + array[67] = tmp; + tmp = vminf(array[70], array[76]); + array[76] = vmaxf(array[70], array[76]); + array[70] = tmp; + tmp = vminf(array[71], array[77]); + array[77] = vmaxf(array[71], array[77]); + array[71] = tmp; + tmp = vminf(array[74], array[80]); + array[80] = vmaxf(array[74], array[80]); + array[74] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[6] = tmp; + tmp = vminf(array[7], array[9]); + array[9] = vmaxf(array[7], array[9]); + array[7] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = tmp; + tmp = vminf(array[15], array[17]); + array[17] = vmaxf(array[15], array[17]); + array[15] = tmp; + tmp = vminf(array[18], array[20]); + array[20] = vmaxf(array[18], array[20]); + array[18] = tmp; + tmp = vminf(array[19], array[21]); + array[21] = vmaxf(array[19], array[21]); + array[19] = tmp; + tmp = vminf(array[22], array[24]); + array[24] = vmaxf(array[22], array[24]); + array[22] = tmp; + tmp = vminf(array[23], array[25]); + array[25] = vmaxf(array[23], array[25]); + array[23] = tmp; + tmp = vminf(array[26], array[28]); + array[28] = vmaxf(array[26], array[28]); + array[26] = tmp; + tmp = vminf(array[27], array[29]); + array[29] = vmaxf(array[27], array[29]); + array[27] = tmp; + tmp = vminf(array[30], array[32]); + array[32] = vmaxf(array[30], array[32]); + array[30] = tmp; + tmp = vminf(array[31], array[33]); + array[33] = vmaxf(array[31], array[33]); + array[31] = tmp; + tmp = vminf(array[34], array[36]); + array[36] = vmaxf(array[34], array[36]); + array[34] = tmp; + tmp = vminf(array[35], array[37]); + array[37] = vmaxf(array[35], array[37]); + array[35] = tmp; + tmp = vminf(array[38], array[40]); + array[40] = vmaxf(array[38], array[40]); + array[38] = tmp; + tmp = vminf(array[39], array[41]); + array[41] = vmaxf(array[39], array[41]); + array[39] = tmp; + tmp = vminf(array[42], array[44]); + array[44] = vmaxf(array[42], array[44]); + array[42] = tmp; + tmp = vminf(array[43], array[45]); + array[45] = vmaxf(array[43], array[45]); + array[43] = tmp; + tmp = vminf(array[46], array[48]); + array[48] = vmaxf(array[46], array[48]); + array[46] = tmp; + tmp = vminf(array[47], array[49]); + array[49] = vmaxf(array[47], array[49]); + array[47] = tmp; + tmp = vminf(array[50], array[52]); + array[52] = vmaxf(array[50], array[52]); + array[50] = tmp; + tmp = vminf(array[51], array[53]); + array[53] = vmaxf(array[51], array[53]); + array[51] = tmp; + tmp = vminf(array[54], array[56]); + array[56] = vmaxf(array[54], array[56]); + array[54] = tmp; + tmp = vminf(array[55], array[57]); + array[57] = vmaxf(array[55], array[57]); + array[55] = tmp; + tmp = vminf(array[58], array[60]); + array[60] = vmaxf(array[58], array[60]); + array[58] = tmp; + tmp = vminf(array[59], array[61]); + array[61] = vmaxf(array[59], array[61]); + array[59] = tmp; + tmp = vminf(array[62], array[64]); + array[64] = vmaxf(array[62], array[64]); + array[62] = tmp; + tmp = vminf(array[63], array[65]); + array[65] = vmaxf(array[63], array[65]); + array[63] = tmp; + tmp = vminf(array[66], array[68]); + array[68] = vmaxf(array[66], array[68]); + array[66] = tmp; + tmp = vminf(array[67], array[69]); + array[69] = vmaxf(array[67], array[69]); + array[67] = tmp; + tmp = vminf(array[70], array[72]); + array[72] = vmaxf(array[70], array[72]); + array[70] = tmp; + tmp = vminf(array[71], array[73]); + array[73] = vmaxf(array[71], array[73]); + array[71] = tmp; + tmp = vminf(array[74], array[76]); + array[76] = vmaxf(array[74], array[76]); + array[74] = tmp; + tmp = vminf(array[75], array[77]); + array[77] = vmaxf(array[75], array[77]); + array[75] = tmp; + tmp = vminf(array[78], array[80]); + array[80] = vmaxf(array[78], array[80]); + array[78] = tmp; + array[1] = vmaxf(array[0], array[1]); + array[3] = vmaxf(array[2], array[3]); + array[5] = vmaxf(array[4], array[5]); + array[7] = vmaxf(array[6], array[7]); + array[9] = vmaxf(array[8], array[9]); + array[11] = vmaxf(array[10], array[11]); + array[13] = vmaxf(array[12], array[13]); + array[15] = vmaxf(array[14], array[15]); + array[17] = vmaxf(array[16], array[17]); + array[19] = vmaxf(array[18], array[19]); + array[21] = vmaxf(array[20], array[21]); + array[23] = vmaxf(array[22], array[23]); + array[25] = vmaxf(array[24], array[25]); + array[27] = vmaxf(array[26], array[27]); + array[29] = vmaxf(array[28], array[29]); + array[31] = vmaxf(array[30], array[31]); + array[33] = vmaxf(array[32], array[33]); + array[35] = vmaxf(array[34], array[35]); + array[37] = vmaxf(array[36], array[37]); + array[39] = vmaxf(array[38], array[39]); + array[40] = vminf(array[40], array[41]); + array[42] = vminf(array[42], array[43]); + array[44] = vminf(array[44], array[45]); + array[46] = vminf(array[46], array[47]); + array[48] = vminf(array[48], array[49]); + array[50] = vminf(array[50], array[51]); + array[52] = vminf(array[52], array[53]); + array[54] = vminf(array[54], array[55]); + array[56] = vminf(array[56], array[57]); + array[58] = vminf(array[58], array[59]); + array[60] = vminf(array[60], array[61]); + array[62] = vminf(array[62], array[63]); + array[64] = vminf(array[64], array[65]); + array[66] = vminf(array[66], array[67]); + array[68] = vminf(array[68], array[69]); + array[70] = vminf(array[70], array[71]); + array[72] = vminf(array[72], array[73]); + array[74] = vminf(array[74], array[75]); + array[76] = vminf(array[76], array[77]); + array[78] = vminf(array[78], array[79]); + array[64] = vmaxf(array[1], array[64]); + array[66] = vmaxf(array[3], array[66]); + array[68] = vmaxf(array[5], array[68]); + array[70] = vmaxf(array[7], array[70]); + array[9] = vminf(array[9], array[72]); + array[11] = vminf(array[11], array[74]); + array[13] = vminf(array[13], array[76]); + array[15] = vminf(array[15], array[78]); + array[17] = vminf(array[17], array[80]); + array[40] = vmaxf(array[9], array[40]); + array[42] = vmaxf(array[11], array[42]); + array[44] = vmaxf(array[13], array[44]); + array[46] = vmaxf(array[15], array[46]); + array[48] = vmaxf(array[17], array[48]); + array[50] = vmaxf(array[19], array[50]); + array[52] = vmaxf(array[21], array[52]); + array[54] = vmaxf(array[23], array[54]); + array[25] = vminf(array[25], array[56]); + array[27] = vminf(array[27], array[58]); + array[29] = vminf(array[29], array[60]); + array[31] = vminf(array[31], array[62]); + array[33] = vminf(array[33], array[64]); + array[35] = vminf(array[35], array[66]); + array[37] = vminf(array[37], array[68]); + array[39] = vminf(array[39], array[70]); + array[40] = vmaxf(array[25], array[40]); + array[42] = vmaxf(array[27], array[42]); + array[44] = vmaxf(array[29], array[44]); + array[46] = vmaxf(array[31], array[46]); + array[33] = vminf(array[33], array[48]); + array[35] = vminf(array[35], array[50]); + array[37] = vminf(array[37], array[52]); + array[39] = vminf(array[39], array[54]); + array[40] = vmaxf(array[33], array[40]); + array[42] = vmaxf(array[35], array[42]); + array[37] = vminf(array[37], array[44]); + array[39] = vminf(array[39], array[46]); + array[40] = vmaxf(array[37], array[40]); + array[39] = vminf(array[39], array[42]); + return vmaxf(array[39], array[40]); +} +#endif + +template +inline T median(T arg, ARGS... args) +{ + return median(std::array{std::move(arg), std::move(args)...}); +} + +template +inline std::array middle4of6(const std::array& array) +{ + std::array res; + + res[0] = std::min(array[1], array[2]); + res[1] = std::max(array[1], array[2]); + T left = std::min(array[0], res[1]); + res[1] = std::max(array[0], res[1]); + T tmp = std::min(left, res[0]); + res[0] = std::max(left, res[0]); + left = tmp; + res[3] = std::min(array[4], array[5]); + T right = std::max(array[4], array[5]); + res[2] = std::min(array[3], right); + right = std::max(array[3], right); + tmp = std::min(res[2], res[3]); + res[3] = std::max(res[2], res[3]); + res[2] = std::max(left, tmp); + res[1] = std::min(res[1], right); + + return res; +} + +#ifdef __SSE2__ +template<> +inline std::array middle4of6(const std::array& array) +{ + std::array res; + + res[0] = vminf(array[1], array[2]); + res[1] = vmaxf(array[1], array[2]); + vfloat left = vminf(array[0], res[1]); + res[1] = vmaxf(array[0], res[1]); + vfloat tmp = vminf(left, res[0]); + res[0] = vmaxf(left, res[0]); + left = tmp; + res[3] = vminf(array[4], array[5]); + vfloat right = vmaxf(array[4], array[5]); + res[2] = vminf(array[3], right); + right = vmaxf(array[3], right); + tmp = vminf(res[2], res[3]); + res[3] = vmaxf(res[2], res[3]); + res[2] = vmaxf(left, tmp); + res[1] = vminf(res[1], right); + + return res; +} +#endif + +template +inline std::array middle4of6(T arg0, T arg1, T arg2, T arg3, T arg4, T arg5) +{ + return middle4of6(std::array{std::move(arg0), std::move(arg1), std::move(arg2), std::move(arg3), std::move(arg4), std::move(arg5)}); } diff --git a/rtengine/minmax.h b/rtengine/minmax.h deleted file mode 100644 index 69e939b72..000000000 --- a/rtengine/minmax.h +++ /dev/null @@ -1,76 +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 . - */ -#define MINMAX3(a,b,c,min,max) \ -{ \ -if ((a)<(b)) { \ - if ((b)<(c)) { \ - (min) = (a); \ - (max) = (c); \ - } \ - else { \ - (max) = (b); \ - if ((a)<(c)) \ - (min) = (a); \ - else \ - (min) = (c); \ - } \ -} else { \ - if ((b)>(c)) { \ - (min) = (c); \ - (max) = (a); \ - } \ - else { \ - (min) = (b); \ - if ((a)>(c)) \ - (max) = (a); \ - else \ - (max) = (c); \ - } \ -} \ -} - -#define MIN3(a,b,c,min) \ -{ \ -if ((a)<(b)) { \ - if ((a)<(c)) \ - (min) = (a); \ - else \ - (min) = (c); \ -} else { \ - if ((b)>(c)) \ - (min) = (c); \ - else \ - (min) = (b); \ -} \ -} - -#define MAX3(a,b,c,min) \ -{ \ -if ((a)>(b)) { \ - if ((a)>(c)) \ - (max) = (a); \ - else \ - (max) = (c); \ -} else { \ - if ((b)<(c)) \ - (max) = (c); \ - else \ - (max) = (b); \ -} \ -} diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc index bcc2a7db7..0414cc1de 100644 --- a/rtengine/myfile.cc +++ b/rtengine/myfile.cc @@ -68,18 +68,17 @@ int munmap(void *start, size_t length) IMFILE* fopen (const char* fname) { - int fd = -1; + int fd; #ifdef WIN32 - { - // First convert UTF8 to UTF16, then use Windows function to open the file and convert back to file descriptor. - std::unique_ptr wfname (reinterpret_cast(g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL)), g_free); + fd = -1; + // First convert UTF8 to UTF16, then use Windows function to open the file and convert back to file descriptor. + std::unique_ptr wfname (reinterpret_cast(g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL)), g_free); - HANDLE hFile = CreateFileW (wfname.get (), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) { - fd = _open_osfhandle((intptr_t)hFile, 0); - } + HANDLE hFile = CreateFileW (wfname.get (), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) { + fd = _open_osfhandle((intptr_t)hFile, 0); } #else diff --git a/rtengine/myfile.h b/rtengine/myfile.h index 9e9039a7a..771dd7b84 100644 --- a/rtengine/myfile.h +++ b/rtengine/myfile.h @@ -79,7 +79,7 @@ inline void fseek (IMFILE* f, int p, int how) inline int fgetc (IMFILE* f) { - if (f->pos < f->size) { + if (LIKELY(f->pos < f->size)) { if (f->plistener && ++f->progress_current >= f->progress_next) { imfile_update_progress(f); } diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index f9f6c12a1..16355a8c0 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -84,26 +84,16 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext unsigned char *dst; #pragma omp for schedule(static,10) - for (unsigned int i = 0; i < (unsigned int)(h); i++) { + for (unsigned int i = 0; i < (unsigned int)(h); ++i) { src = data + i * w * 3; dst = previewImage->get_data() + i * w * 4; - for (unsigned int j = 0; j < (unsigned int)(w); j++) { + for (unsigned int j = 0; j < (unsigned int)(w); ++j) { unsigned char r = *(src++); unsigned char g = *(src++); unsigned char b = *(src++); -#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - *(dst++) = b; - *(dst++) = g; - *(dst++) = r; - *(dst++) = 0; -#else - *(dst++) = 0; - *(dst++) = r; - *(dst++) = g; - *(dst++) = b; -#endif + poke255_uc(dst, r, g, b); } } } @@ -120,15 +110,8 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext rtengine::Image8 *output = NULL; const unsigned char *data = NULL; int fw, fh; - LUTf cdcurve; - bool dehacontlutili = false; procparams::ProcParams params; - /*rtengine::RAWParams raw; - rtengine::LensProfParams lensProf; - rtengine::procparams::ToneCurveParams toneCurve; - rtengine::procparams::ColorManagementParams icm; - rtengine::CoarseTransformParams coarse;*/ ColorTemp wb = rawImage.getWB (); rawImage.getFullSize (fw, fh, TR_NONE); PreviewProps pp (0, 0, fw, fh, 1); @@ -178,17 +161,8 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext unsigned char r = *(src++); unsigned char g = *(src++); unsigned char b = *(src++); -#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - *(dst++) = b; - *(dst++) = g; - *(dst++) = r; - *(dst++) = 0; -#else - *(dst++) = 0; - *(dst++) = r; - *(dst++) = g; - *(dst++) = b; -#endif + + poke255_uc(dst, r, g, b); } } } diff --git a/rtengine/previewimage.h b/rtengine/previewimage.h index 5135ddd9a..26b9a85d2 100644 --- a/rtengine/previewimage.h +++ b/rtengine/previewimage.h @@ -20,7 +20,7 @@ #define _PREVIEWIMAGE_ #include -#include "cairomm/cairomm.h" +#include namespace rtengine { diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h index 3364e6daf..fbf56234f 100644 --- a/rtengine/processingjob.h +++ b/rtengine/processingjob.h @@ -34,15 +34,11 @@ public: procparams::ProcParams pparams; ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp) - : fname(fn), isRaw(iR), initialImage(NULL) - { - pparams = pp; - } + : fname(fn), isRaw(iR), initialImage(NULL), pparams(pp) {} ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp) - : fname(""), initialImage(iImage) + : fname(""), initialImage(iImage), pparams(pp) { - pparams = pp; iImage->increaseRef(); } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 20b099d6d..eddb47b91 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -467,7 +467,9 @@ enum ProcEvent { EvRetinexmapcurve = 437, EvviewMethod = 438, EvcbdlMethod = 439, - EvSpotEnabled = 440, + EvRetinexgaintransmission = 440, + EvLskal = 441, + EvSpotEnabled = 442, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 86d88240f..07a62df72 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -19,7 +19,7 @@ #include #include "procparams.h" #include "rt_math.h" -#include "dcp.h" +#include "curves.h" #include "../rtgui/multilangmgr.h" #include "../rtgui/version.h" #include "../rtgui/ppversion.h" @@ -124,7 +124,7 @@ RetinexParams::RetinexParams () void RetinexParams::getDefaulttransmissionCurve(std::vector &curve) { - double v[12] = { 0.00, 0.34, 0.35, 0.35, + double v[12] = { 0.00, 0.50, 0.35, 0.35, 0.60, 0.75, 0.35, 0.35, 1.00, 0.50, 0.35, 0.35, }; @@ -137,6 +137,23 @@ void RetinexParams::getDefaulttransmissionCurve(std::vector &curve) curve.at(i) = v[i - 1]; } } +void RetinexParams::getDefaultgaintransmissionCurve(std::vector &curve) +{ + double v[16] = { 0.00, 0.1, 0.35, 0.00, + 0.25, 0.25, 0.35, 0.35, + 0.70, 0.25, 0.35, 0.35, + 1.00, 0.1, 0.00, 0.00 + }; + + + curve.resize(17); + curve.at(0 ) = double(FCT_MinMaxCPoints); + + for (size_t i = 1; i < curve.size(); ++i) { + curve.at(i) = v[i - 1]; + } +} + void RetinexParams::setDefaults() { @@ -161,7 +178,7 @@ void RetinexParams::setDefaults() radius = 40; baselog = 2.71828; -// grbl = 50; + skal = 3; retinexMethod = "high"; mapMethod = "none"; viewMethod = "none"; @@ -176,13 +193,16 @@ void RetinexParams::setDefaults() lhcurve.push_back(DCT_Linear); mapcurve.clear(); mapcurve.push_back(DCT_Linear); + getDefaultgaintransmissionCurve(gaintransmissionCurve); getDefaulttransmissionCurve(transmissionCurve); } -void RetinexParams::getCurves(RetinextransmissionCurve &transmissionCurveLUT) const +void RetinexParams::getCurves(RetinextransmissionCurve &transmissionCurveLUT, RetinexgaintransmissionCurve &gaintransmissionCurveLUT) const { transmissionCurveLUT.Set(this->transmissionCurve); + gaintransmissionCurveLUT.Set(this->gaintransmissionCurve); + } @@ -897,7 +917,7 @@ void RAWParams::setDefaults() ff_clipControl = 0; cared = 0; cablue = 0; - caautostrength = 6; + caautostrength = 2; ca_autocorrect = false; hotPixelFilter = false; deadPixelFilter = false; @@ -1027,8 +1047,8 @@ void ProcParams::setDefaults () prsharpening.edges_tolerance = 1800; prsharpening.halocontrol = false; prsharpening.halocontrol_amount = 85; - prsharpening.method = "usm"; - prsharpening.deconvradius = 0.5; + prsharpening.method = "rld"; + prsharpening.deconvradius = 0.45; prsharpening.deconviter = 100; prsharpening.deconvdamping = 0; prsharpening.deconvamount = 100; @@ -1138,10 +1158,10 @@ void ProcParams::setDefaults () crop.y = -1; crop.w = 15000; crop.h = 15000; - crop.fixratio = false; + crop.fixratio = true; crop.ratio = "3:2"; crop.orientation = "As Image"; - crop.guide = "Rule of thirds"; + crop.guide = "Frame"; coarse.setDefaults(); @@ -1260,7 +1280,7 @@ void ProcParams::setDefaults () ppVersion = PPVERSION; } -static Glib::ustring expandRelativePath(Glib::ustring procparams_fname, Glib::ustring prefix, Glib::ustring embedded_fname) +static Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Glib::ustring &prefix, Glib::ustring embedded_fname) { if (embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { return embedded_fname; @@ -1282,7 +1302,7 @@ static Glib::ustring expandRelativePath(Glib::ustring procparams_fname, Glib::us return absPath; } -static Glib::ustring relativePathIfInside(Glib::ustring procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname) +static Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname) { if (fnameAbsolute || embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { return embedded_fname; @@ -1310,7 +1330,7 @@ static Glib::ustring relativePathIfInside(Glib::ustring procparams_fname, bool f return prefix + embedded_fname.substr(dir1.length()); } -int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsolute, ParamsEdited* pedited) +int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, bool fnameAbsolute, ParamsEdited* pedited) { if (fname.empty () && fname2.empty ()) { @@ -1321,1210 +1341,1219 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol try { - Glib::KeyFile keyFile; + Glib::KeyFile keyFile; - keyFile.set_string ("Version", "AppVersion", APPVERSION); - keyFile.set_integer ("Version", "Version", PPVERSION); + keyFile.set_string ("Version", "AppVersion", APPVERSION); + keyFile.set_integer ("Version", "Version", PPVERSION); - if (!pedited || pedited->general.rank) { - keyFile.set_integer ("General", "Rank", rank); - } - - if (!pedited || pedited->general.colorlabel) { - keyFile.set_integer ("General", "ColorLabel", colorlabel); - } - - if (!pedited || pedited->general.intrash) { - keyFile.set_boolean ("General", "InTrash", inTrash); - } - - // save tone curve - if (!pedited || pedited->toneCurve.autoexp) { - keyFile.set_boolean ("Exposure", "Auto", toneCurve.autoexp); - } - - if (!pedited || pedited->toneCurve.clip) { - keyFile.set_double ("Exposure", "Clip", toneCurve.clip); - } - - if (!pedited || pedited->toneCurve.expcomp) { - keyFile.set_double ("Exposure", "Compensation", toneCurve.expcomp); - } - - if (!pedited || pedited->toneCurve.brightness) { - keyFile.set_integer ("Exposure", "Brightness", toneCurve.brightness); - } - - if (!pedited || pedited->toneCurve.contrast) { - keyFile.set_integer ("Exposure", "Contrast", toneCurve.contrast); - } - - if (!pedited || pedited->toneCurve.saturation) { - keyFile.set_integer ("Exposure", "Saturation", toneCurve.saturation); - } - - if (!pedited || pedited->toneCurve.black) { - keyFile.set_integer ("Exposure", "Black", toneCurve.black); - } - - if (!pedited || pedited->toneCurve.hlcompr) { - keyFile.set_integer ("Exposure", "HighlightCompr", toneCurve.hlcompr); - } - - if (!pedited || pedited->toneCurve.hlcomprthresh) { - keyFile.set_integer ("Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh); - } - - if (!pedited || pedited->toneCurve.shcompr) { - keyFile.set_integer ("Exposure", "ShadowCompr", toneCurve.shcompr); - } - - // save highlight recovery settings - if (!pedited || pedited->toneCurve.hrenabled) { - keyFile.set_boolean ("HLRecovery", "Enabled", toneCurve.hrenabled); - } - - if (!pedited || pedited->toneCurve.method) { - keyFile.set_string ("HLRecovery", "Method", toneCurve.method); - } - - if (!pedited || pedited->toneCurve.curveMode) { - Glib::ustring method; - - switch (toneCurve.curveMode) { - case (ToneCurveParams::TC_MODE_STD): - method = "Standard"; - break; - - case (ToneCurveParams::TC_MODE_FILMLIKE): - method = "FilmLike"; - break; - - case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): - method = "SatAndValueBlending"; - break; - - case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): - method = "WeightedStd"; - break; - - case (ToneCurveParams::TC_MODE_LUMINANCE): - method = "Luminance"; - break; - - case (ToneCurveParams::TC_MODE_PERCEPTUAL): - method = "Perceptual"; - break; + if (!pedited || pedited->general.rank) { + keyFile.set_integer ("General", "Rank", rank); } - keyFile.set_string ("Exposure", "CurveMode", method); - } - - if (!pedited || pedited->toneCurve.curveMode2) { - Glib::ustring method; - - switch (toneCurve.curveMode2) { - case (ToneCurveParams::TC_MODE_STD): - method = "Standard"; - break; - - case (ToneCurveParams::TC_MODE_FILMLIKE): - method = "FilmLike"; - break; - - case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): - method = "SatAndValueBlending"; - break; - - case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): - method = "WeightedStd"; - break; - - case (ToneCurveParams::TC_MODE_LUMINANCE): - method = "Luminance"; - break; - - case (ToneCurveParams::TC_MODE_PERCEPTUAL): - method = "Perceptual"; - break; + if (!pedited || pedited->general.colorlabel) { + keyFile.set_integer ("General", "ColorLabel", colorlabel); } - keyFile.set_string ("Exposure", "CurveMode2", method); - } - - if (!pedited || pedited->toneCurve.curve) { - Glib::ArrayHandle tcurve = toneCurve.curve; - keyFile.set_double_list("Exposure", "Curve", tcurve); - } - - if (!pedited || pedited->toneCurve.curve2) { - Glib::ArrayHandle tcurve = toneCurve.curve2; - keyFile.set_double_list("Exposure", "Curve2", tcurve); - } - - //save retinex - - if (!pedited || pedited->retinex.str) { - keyFile.set_integer ("Retinex", "Str", retinex.str); - } - - if (!pedited || pedited->retinex.scal) { - keyFile.set_integer ("Retinex", "Scal", retinex.scal); - } - - if (!pedited || pedited->retinex.iter) { - keyFile.set_integer ("Retinex", "Iter", retinex.iter); - } - - if (!pedited || pedited->retinex.grad) { - keyFile.set_integer ("Retinex", "Grad", retinex.grad); - } - - if (!pedited || pedited->retinex.grads) { - keyFile.set_integer ("Retinex", "Grads", retinex.grads); - } - - if (!pedited || pedited->retinex.gam) { - keyFile.set_double ("Retinex", "Gam", retinex.gam); - } - - if (!pedited || pedited->retinex.slope) { - keyFile.set_double ("Retinex", "Slope", retinex.slope); - } - - if (!pedited || pedited->retinex.enabled) { - keyFile.set_boolean ("Retinex", "Enabled", retinex.enabled); - } - - if (!pedited || pedited->retinex.medianmap) { - keyFile.set_boolean ("Retinex", "Median", retinex.medianmap); - } - - - - if (!pedited || pedited->retinex.neigh) { - keyFile.set_integer ("Retinex", "Neigh", retinex.neigh); - } - - if (!pedited || pedited->retinex.gain) { - keyFile.set_integer ("Retinex", "Gain", retinex.gain); - } - - if (!pedited || pedited->retinex.offs) { - keyFile.set_integer ("Retinex", "Offs", retinex.offs); - } - - if (!pedited || pedited->retinex.vart) { - keyFile.set_integer ("Retinex", "Vart", retinex.vart); - } - - if (!pedited || pedited->retinex.limd) { - keyFile.set_integer ("Retinex", "Limd", retinex.limd); - } - - if (!pedited || pedited->retinex.highl) { - keyFile.set_integer ("Retinex", "highl", retinex.highl); - } - - if (!pedited || pedited->retinex.baselog) { - keyFile.set_double ("Retinex", "baselog", retinex.baselog); - } - -// if (!pedited || pedited->retinex.grbl) { -// keyFile.set_integer ("Retinex", "grbl", retinex.grbl); -// } - - if (!pedited || pedited->retinex.retinexMethod) { - keyFile.set_string ("Retinex", "RetinexMethod", retinex.retinexMethod); - } - - if (!pedited || pedited->retinex.mapMethod) { - keyFile.set_string ("Retinex", "mapMethod", retinex.mapMethod); - } - - if (!pedited || pedited->retinex.viewMethod) { - keyFile.set_string ("Retinex", "viewMethod", retinex.viewMethod); - } - - if (!pedited || pedited->retinex.retinexcolorspace) { - keyFile.set_string ("Retinex", "Retinexcolorspace", retinex.retinexcolorspace); - } - - if (!pedited || pedited->retinex.gammaretinex) { - keyFile.set_string ("Retinex", "Gammaretinex", retinex.gammaretinex); - } - - if (!pedited || pedited->retinex.cdcurve) { - Glib::ArrayHandle cdcurve = retinex.cdcurve; - keyFile.set_double_list("Retinex", "CDCurve", cdcurve); - } - - if (!pedited || pedited->retinex.mapcurve) { - Glib::ArrayHandle mapcurve = retinex.mapcurve; - keyFile.set_double_list("Retinex", "MAPCurve", mapcurve); - } - - if (!pedited || pedited->retinex.cdHcurve) { - Glib::ArrayHandle cdHcurve = retinex.cdHcurve; - keyFile.set_double_list("Retinex", "CDHCurve", cdHcurve); - } - - if (!pedited || pedited->retinex.lhcurve) { - Glib::ArrayHandle lhcurve = retinex.lhcurve; - keyFile.set_double_list("Retinex", "LHCurve", lhcurve); - } - - if (!pedited || pedited->retinex.highlights) { - keyFile.set_integer ("Retinex", "Highlights", retinex.highlights); - } - - if (!pedited || pedited->retinex.htonalwidth) { - keyFile.set_integer ("Retinex", "HighlightTonalWidth", retinex.htonalwidth); - } - - if (!pedited || pedited->retinex.shadows) { - keyFile.set_integer ("Retinex", "Shadows", retinex.shadows); - } - - if (!pedited || pedited->retinex.stonalwidth) { - keyFile.set_integer ("Retinex", "ShadowTonalWidth", retinex.stonalwidth); - } - - if (!pedited || pedited->retinex.radius) { - keyFile.set_integer ("Retinex", "Radius", retinex.radius); - } - - if (!pedited || pedited->retinex.transmissionCurve) { - Glib::ArrayHandle transmissionCurve = retinex.transmissionCurve; - keyFile.set_double_list("Retinex", "TransmissionCurve", transmissionCurve); - } - - // save channel mixer - if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) { - Glib::ArrayHandle rmix (chmixer.red, 3, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Channel Mixer", "Red", rmix); - } - - if (!pedited || pedited->chmixer.green[0] || pedited->chmixer.green[1] || pedited->chmixer.green[2]) { - Glib::ArrayHandle gmix (chmixer.green, 3, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Channel Mixer", "Green", gmix); - } - - if (!pedited || pedited->chmixer.blue[0] || pedited->chmixer.blue[1] || pedited->chmixer.blue[2]) { - Glib::ArrayHandle bmix (chmixer.blue, 3, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Channel Mixer", "Blue", bmix); - } - - //save Black & White - if (!pedited || pedited->blackwhite.enabled) { - keyFile.set_boolean ("Black & White", "Enabled", blackwhite.enabled); - } - - if (!pedited || pedited->blackwhite.method) { - keyFile.set_string ("Black & White", "Method", blackwhite.method ); - } - - if (!pedited || pedited->blackwhite.autoc) { - keyFile.set_boolean ("Black & White", "Auto", blackwhite.autoc); - } - - if (!pedited || pedited->blackwhite.enabledcc) { - keyFile.set_boolean ("Black & White", "ComplementaryColors", blackwhite.enabledcc); - } - - if (!pedited || pedited->blackwhite.setting) { - keyFile.set_string ("Black & White", "Setting", blackwhite.setting ); - } - - if (!pedited || pedited->blackwhite.filter) { - keyFile.set_string ("Black & White", "Filter", blackwhite.filter ); - } - - if (!pedited || pedited->blackwhite.mixerRed) { - keyFile.set_integer ("Black & White", "MixerRed", blackwhite.mixerRed); - } - - if (!pedited || pedited->blackwhite.mixerOrange) { - keyFile.set_integer ("Black & White", "MixerOrange", blackwhite.mixerOrange); - } - - if (!pedited || pedited->blackwhite.mixerYellow) { - keyFile.set_integer ("Black & White", "MixerYellow", blackwhite.mixerYellow); - } - - if (!pedited || pedited->blackwhite.mixerGreen) { - keyFile.set_integer ("Black & White", "MixerGreen", blackwhite.mixerGreen); - } - - if (!pedited || pedited->blackwhite.mixerCyan) { - keyFile.set_integer ("Black & White", "MixerCyan", blackwhite.mixerCyan); - } - - if (!pedited || pedited->blackwhite.mixerBlue) { - keyFile.set_integer ("Black & White", "MixerBlue", blackwhite.mixerBlue); - } - - if (!pedited || pedited->blackwhite.mixerMagenta) { - keyFile.set_integer ("Black & White", "MixerMagenta", blackwhite.mixerMagenta); - } - - if (!pedited || pedited->blackwhite.mixerPurple) { - keyFile.set_integer ("Black & White", "MixerPurple", blackwhite.mixerPurple); - } - - if (!pedited || pedited->blackwhite.gammaRed) { - keyFile.set_integer ("Black & White", "GammaRed", blackwhite.gammaRed); - } - - if (!pedited || pedited->blackwhite.gammaGreen) { - keyFile.set_integer ("Black & White", "GammaGreen", blackwhite.gammaGreen); - } - - if (!pedited || pedited->blackwhite.gammaBlue) { - keyFile.set_integer ("Black & White", "GammaBlue", blackwhite.gammaBlue); - } - - if (!pedited || pedited->blackwhite.algo) { - keyFile.set_string ("Black & White", "Algorithm", blackwhite.algo); - } - - if (!pedited || pedited->blackwhite.luminanceCurve) { - Glib::ArrayHandle luminanceCurve = blackwhite.luminanceCurve; - keyFile.set_double_list("Black & White", "LuminanceCurve", luminanceCurve); - } - - if (!pedited || pedited->blackwhite.beforeCurveMode) { - Glib::ustring mode; - - switch (blackwhite.beforeCurveMode) { - case (BlackWhiteParams::TC_MODE_STD_BW): - mode = "Standard"; - break; - - case (BlackWhiteParams::TC_MODE_FILMLIKE_BW): - mode = "FilmLike"; - break; - - case (BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW): - mode = "SatAndValueBlending"; - break; - - case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): - mode = "WeightedStd"; - break; + if (!pedited || pedited->general.intrash) { + keyFile.set_boolean ("General", "InTrash", inTrash); } - keyFile.set_string ("Black & White", "BeforeCurveMode", mode); - } - - if (!pedited || pedited->blackwhite.afterCurveMode) { - Glib::ustring mode; - - switch (blackwhite.afterCurveMode) { - case (BlackWhiteParams::TC_MODE_STD_BW): - mode = "Standard"; - break; - - case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): - mode = "WeightedStd"; - break; - - default: - break; + // save tone curve + if (!pedited || pedited->toneCurve.autoexp) { + keyFile.set_boolean ("Exposure", "Auto", toneCurve.autoexp); } - keyFile.set_string ("Black & White", "AfterCurveMode", mode); - } + if (!pedited || pedited->toneCurve.clip) { + keyFile.set_double ("Exposure", "Clip", toneCurve.clip); + } - if (!pedited || pedited->blackwhite.beforeCurve) { - Glib::ArrayHandle tcurvebw = blackwhite.beforeCurve; - keyFile.set_double_list("Black & White", "BeforeCurve", tcurvebw); - } + if (!pedited || pedited->toneCurve.expcomp) { + keyFile.set_double ("Exposure", "Compensation", toneCurve.expcomp); + } - if (!pedited || pedited->blackwhite.afterCurve) { - Glib::ArrayHandle tcurvebw = blackwhite.afterCurve; - keyFile.set_double_list("Black & White", "AfterCurve", tcurvebw); - } + if (!pedited || pedited->toneCurve.brightness) { + keyFile.set_integer ("Exposure", "Brightness", toneCurve.brightness); + } - // save luma curve - if (!pedited || pedited->labCurve.brightness) { - keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness); - } + if (!pedited || pedited->toneCurve.contrast) { + keyFile.set_integer ("Exposure", "Contrast", toneCurve.contrast); + } - if (!pedited || pedited->labCurve.contrast) { - keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast); - } + if (!pedited || pedited->toneCurve.saturation) { + keyFile.set_integer ("Exposure", "Saturation", toneCurve.saturation); + } - if (!pedited || pedited->labCurve.chromaticity) { - keyFile.set_integer ("Luminance Curve", "Chromaticity", labCurve.chromaticity); - } + if (!pedited || pedited->toneCurve.black) { + keyFile.set_integer ("Exposure", "Black", toneCurve.black); + } - if (!pedited || pedited->labCurve.avoidcolorshift) { - keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift); - } + if (!pedited || pedited->toneCurve.hlcompr) { + keyFile.set_integer ("Exposure", "HighlightCompr", toneCurve.hlcompr); + } - if (!pedited || pedited->labCurve.rstprotection) { - keyFile.set_double ("Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection); - } + if (!pedited || pedited->toneCurve.hlcomprthresh) { + keyFile.set_integer ("Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh); + } - if (!pedited || pedited->labCurve.lcredsk) { - keyFile.set_boolean ("Luminance Curve", "LCredsk", labCurve.lcredsk); - } + if (!pedited || pedited->toneCurve.shcompr) { + keyFile.set_integer ("Exposure", "ShadowCompr", toneCurve.shcompr); + } - if (!pedited || pedited->labCurve.lcurve) { - Glib::ArrayHandle lcurve = labCurve.lcurve; - keyFile.set_double_list("Luminance Curve", "LCurve", lcurve); - } + // save highlight recovery settings + if (!pedited || pedited->toneCurve.hrenabled) { + keyFile.set_boolean ("HLRecovery", "Enabled", toneCurve.hrenabled); + } - if (!pedited || pedited->labCurve.acurve) { - Glib::ArrayHandle acurve = labCurve.acurve; - keyFile.set_double_list("Luminance Curve", "aCurve", acurve); - } + if (!pedited || pedited->toneCurve.method) { + keyFile.set_string ("HLRecovery", "Method", toneCurve.method); + } - if (!pedited || pedited->labCurve.bcurve) { - Glib::ArrayHandle bcurve = labCurve.bcurve; - keyFile.set_double_list("Luminance Curve", "bCurve", bcurve); - } + if (!pedited || pedited->toneCurve.curveMode) { + Glib::ustring method; - if (!pedited || pedited->labCurve.cccurve) { - Glib::ArrayHandle cccurve = labCurve.cccurve; - keyFile.set_double_list("Luminance Curve", "ccCurve", cccurve); - } + switch (toneCurve.curveMode) { + case (ToneCurveParams::TC_MODE_STD): + method = "Standard"; + break; - if (!pedited || pedited->labCurve.chcurve) { - Glib::ArrayHandle chcurve = labCurve.chcurve; - keyFile.set_double_list("Luminance Curve", "chCurve", chcurve); - } + case (ToneCurveParams::TC_MODE_FILMLIKE): + method = "FilmLike"; + break; - if (!pedited || pedited->labCurve.lhcurve) { - Glib::ArrayHandle lhcurve = labCurve.lhcurve; - keyFile.set_double_list("Luminance Curve", "lhCurve", lhcurve); - } + case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): + method = "SatAndValueBlending"; + break; - if (!pedited || pedited->labCurve.hhcurve) { - Glib::ArrayHandle hhcurve = labCurve.hhcurve; - keyFile.set_double_list("Luminance Curve", "hhCurve", hhcurve); - } + case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): + method = "WeightedStd"; + break; - if (!pedited || pedited->labCurve.lccurve) { - Glib::ArrayHandle lccurve = labCurve.lccurve; - keyFile.set_double_list("Luminance Curve", "LcCurve", lccurve); - } + case (ToneCurveParams::TC_MODE_LUMINANCE): + method = "Luminance"; + break; - if (!pedited || pedited->labCurve.clcurve) { - Glib::ArrayHandle clcurve = labCurve.clcurve; - keyFile.set_double_list("Luminance Curve", "ClCurve", clcurve); - } + case (ToneCurveParams::TC_MODE_PERCEPTUAL): + method = "Perceptual"; + break; + } - // save sharpening - if (!pedited || pedited->sharpening.enabled) { - keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled); - } + keyFile.set_string ("Exposure", "CurveMode", method); + } - if (!pedited || pedited->sharpening.method) { - keyFile.set_string ("Sharpening", "Method", sharpening.method); - } + if (!pedited || pedited->toneCurve.curveMode2) { + Glib::ustring method; - if (!pedited || pedited->sharpening.radius) { - keyFile.set_double ("Sharpening", "Radius", sharpening.radius); - } + switch (toneCurve.curveMode2) { + case (ToneCurveParams::TC_MODE_STD): + method = "Standard"; + break; - if (!pedited || pedited->sharpening.amount) { - keyFile.set_integer ("Sharpening", "Amount", sharpening.amount); - } + case (ToneCurveParams::TC_MODE_FILMLIKE): + method = "FilmLike"; + break; - if (!pedited || pedited->sharpening.threshold) { - Glib::ArrayHandle thresh (sharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Sharpening", "Threshold", thresh); - } + case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): + method = "SatAndValueBlending"; + break; - if (!pedited || pedited->sharpening.edgesonly) { - keyFile.set_boolean ("Sharpening", "OnlyEdges", sharpening.edgesonly); - } + case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): + method = "WeightedStd"; + break; - if (!pedited || pedited->sharpening.edges_radius) { - keyFile.set_double ("Sharpening", "EdgedetectionRadius", sharpening.edges_radius); - } + case (ToneCurveParams::TC_MODE_LUMINANCE): + method = "Luminance"; + break; - if (!pedited || pedited->sharpening.edges_tolerance) { - keyFile.set_integer ("Sharpening", "EdgeTolerance", sharpening.edges_tolerance); - } + case (ToneCurveParams::TC_MODE_PERCEPTUAL): + method = "Perceptual"; + break; + } - if (!pedited || pedited->sharpening.halocontrol) { - keyFile.set_boolean ("Sharpening", "HalocontrolEnabled", sharpening.halocontrol); - } + keyFile.set_string ("Exposure", "CurveMode2", method); + } - if (!pedited || pedited->sharpening.halocontrol_amount) { - keyFile.set_integer ("Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount); - } + if (!pedited || pedited->toneCurve.curve) { + Glib::ArrayHandle tcurve = toneCurve.curve; + keyFile.set_double_list("Exposure", "Curve", tcurve); + } - if (!pedited || pedited->sharpening.deconvradius) { - keyFile.set_double ("Sharpening", "DeconvRadius", sharpening.deconvradius); - } + if (!pedited || pedited->toneCurve.curve2) { + Glib::ArrayHandle tcurve = toneCurve.curve2; + keyFile.set_double_list("Exposure", "Curve2", tcurve); + } - if (!pedited || pedited->sharpening.deconvamount) { - keyFile.set_integer ("Sharpening", "DeconvAmount", sharpening.deconvamount); - } + //save retinex - if (!pedited || pedited->sharpening.deconvdamping) { - keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); - } + if (!pedited || pedited->retinex.str) { + keyFile.set_integer ("Retinex", "Str", retinex.str); + } - if (!pedited || pedited->sharpening.deconviter) { - keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); - } + if (!pedited || pedited->retinex.scal) { + keyFile.set_integer ("Retinex", "Scal", retinex.scal); + } - // save vibrance - if (!pedited || pedited->vibrance.enabled) { - keyFile.set_boolean ("Vibrance", "Enabled", vibrance.enabled); - } + if (!pedited || pedited->retinex.iter) { + keyFile.set_integer ("Retinex", "Iter", retinex.iter); + } - if (!pedited || pedited->vibrance.pastels) { - keyFile.set_integer ("Vibrance", "Pastels", vibrance.pastels); - } + if (!pedited || pedited->retinex.grad) { + keyFile.set_integer ("Retinex", "Grad", retinex.grad); + } - if (!pedited || pedited->vibrance.saturated) { - keyFile.set_integer ("Vibrance", "Saturated", vibrance.saturated); - } + if (!pedited || pedited->retinex.grads) { + keyFile.set_integer ("Retinex", "Grads", retinex.grads); + } - if (!pedited || pedited->vibrance.psthreshold) { - Glib::ArrayHandle thresh (vibrance.psthreshold.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Vibrance", "PSThreshold", thresh); - } + if (!pedited || pedited->retinex.gam) { + keyFile.set_double ("Retinex", "Gam", retinex.gam); + } - if (!pedited || pedited->vibrance.protectskins) { - keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins); - } + if (!pedited || pedited->retinex.slope) { + keyFile.set_double ("Retinex", "Slope", retinex.slope); + } - if (!pedited || pedited->vibrance.avoidcolorshift) { - keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift); - } + if (!pedited || pedited->retinex.enabled) { + keyFile.set_boolean ("Retinex", "Enabled", retinex.enabled); + } - if (!pedited || pedited->vibrance.pastsattog) { - keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog); - } + if (!pedited || pedited->retinex.medianmap) { + keyFile.set_boolean ("Retinex", "Median", retinex.medianmap); + } - if (!pedited || pedited->vibrance.skintonescurve) { - Glib::ArrayHandle skintonescurve = vibrance.skintonescurve; - keyFile.set_double_list("Vibrance", "SkinTonesCurve", skintonescurve); - } - //save edge sharpening - if (!pedited || pedited->sharpenEdge.enabled) { - keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled); - } - if (!pedited || pedited->sharpenEdge.passes) { - keyFile.set_integer ("SharpenEdge", "Passes", sharpenEdge.passes); - } + if (!pedited || pedited->retinex.neigh) { + keyFile.set_integer ("Retinex", "Neigh", retinex.neigh); + } - if (!pedited || pedited->sharpenEdge.amount) { - keyFile.set_double ("SharpenEdge", "Strength", sharpenEdge.amount); - } + if (!pedited || pedited->retinex.gain) { + keyFile.set_integer ("Retinex", "Gain", retinex.gain); + } - if (!pedited || pedited->sharpenEdge.threechannels) { - keyFile.set_boolean ("SharpenEdge", "ThreeChannels", sharpenEdge.threechannels); - } + if (!pedited || pedited->retinex.offs) { + keyFile.set_integer ("Retinex", "Offs", retinex.offs); + } - //save micro-contrast sharpening - if (!pedited || pedited->sharpenMicro.enabled) { - keyFile.set_boolean ("SharpenMicro", "Enabled", sharpenMicro.enabled); - } + if (!pedited || pedited->retinex.vart) { + keyFile.set_integer ("Retinex", "Vart", retinex.vart); + } - if (!pedited || pedited->sharpenMicro.matrix) { - keyFile.set_boolean ("SharpenMicro", "Matrix", sharpenMicro.matrix); - } + if (!pedited || pedited->retinex.limd) { + keyFile.set_integer ("Retinex", "Limd", retinex.limd); + } - if (!pedited || pedited->sharpenMicro.amount) { - keyFile.set_double ("SharpenMicro", "Strength", sharpenMicro.amount); - } + if (!pedited || pedited->retinex.highl) { + keyFile.set_integer ("Retinex", "highl", retinex.highl); + } - if (!pedited || pedited->sharpenMicro.uniformity) { - keyFile.set_double ("SharpenMicro", "Uniformity", sharpenMicro.uniformity); - } + if (!pedited || pedited->retinex.baselog) { + keyFile.set_double ("Retinex", "baselog", retinex.baselog); + } - /* - // save colorBoost - if (!pedited || pedited->colorBoost.amount) keyFile.set_integer ("Color Boost", "Amount", colorBoost.amount); - if (!pedited || pedited->colorBoost.avoidclip) keyFile.set_boolean ("Color Boost", "AvoidColorClipping", colorBoost.avoidclip); - if (!pedited || pedited->colorBoost.enable_saturationlimiter) keyFile.set_boolean ("Color Boost", "SaturationLimiter", colorBoost.enable_saturationlimiter); - if (!pedited || pedited->colorBoost.saturationlimit) keyFile.set_double ("Color Boost", "SaturationLimit", colorBoost.saturationlimit); - */ + if (!pedited || pedited->retinex.skal) { + keyFile.set_integer ("Retinex", "skal", retinex.skal); + } - // save wb - if (!pedited || pedited->wb.method) { - keyFile.set_string ("White Balance", "Setting", wb.method); - } + if (!pedited || pedited->retinex.retinexMethod) { + keyFile.set_string ("Retinex", "RetinexMethod", retinex.retinexMethod); + } - if (!pedited || pedited->wb.temperature) { - keyFile.set_integer ("White Balance", "Temperature", wb.temperature); - } + if (!pedited || pedited->retinex.mapMethod) { + keyFile.set_string ("Retinex", "mapMethod", retinex.mapMethod); + } - if (!pedited || pedited->wb.green) { - keyFile.set_double ("White Balance", "Green", wb.green); - } + if (!pedited || pedited->retinex.viewMethod) { + keyFile.set_string ("Retinex", "viewMethod", retinex.viewMethod); + } - if (!pedited || pedited->wb.equal) { - keyFile.set_double ("White Balance", "Equal", wb.equal); - } + if (!pedited || pedited->retinex.retinexcolorspace) { + keyFile.set_string ("Retinex", "Retinexcolorspace", retinex.retinexcolorspace); + } - /* - // save colorShift - if (!pedited || pedited->colorShift.a) keyFile.set_double ("Color Shift", "ChannelA", colorShift.a); - if (!pedited || pedited->colorShift.b) keyFile.set_double ("Color Shift", "ChannelB", colorShift.b); - */ - // save colorappearance - if (!pedited || pedited->colorappearance.enabled) { - keyFile.set_boolean ("Color appearance", "Enabled", colorappearance.enabled); - } + if (!pedited || pedited->retinex.gammaretinex) { + keyFile.set_string ("Retinex", "Gammaretinex", retinex.gammaretinex); + } - if (!pedited || pedited->colorappearance.degree) { - keyFile.set_integer ("Color appearance", "Degree", colorappearance.degree); - } + if (!pedited || pedited->retinex.cdcurve) { + Glib::ArrayHandle cdcurve = retinex.cdcurve; + keyFile.set_double_list("Retinex", "CDCurve", cdcurve); + } - if (!pedited || pedited->colorappearance.autodegree) { - keyFile.set_boolean ("Color appearance", "AutoDegree", colorappearance.autodegree); - } + if (!pedited || pedited->retinex.mapcurve) { + Glib::ArrayHandle mapcurve = retinex.mapcurve; + keyFile.set_double_list("Retinex", "MAPCurve", mapcurve); + } - if (!pedited || pedited->colorappearance.surround) { - keyFile.set_string ("Color appearance", "Surround", colorappearance.surround); - } + if (!pedited || pedited->retinex.cdHcurve) { + Glib::ArrayHandle cdHcurve = retinex.cdHcurve; + keyFile.set_double_list("Retinex", "CDHCurve", cdHcurve); + } + + if (!pedited || pedited->retinex.lhcurve) { + Glib::ArrayHandle lhcurve = retinex.lhcurve; + keyFile.set_double_list("Retinex", "LHCurve", lhcurve); + } + + if (!pedited || pedited->retinex.highlights) { + keyFile.set_integer ("Retinex", "Highlights", retinex.highlights); + } + + if (!pedited || pedited->retinex.htonalwidth) { + keyFile.set_integer ("Retinex", "HighlightTonalWidth", retinex.htonalwidth); + } + + if (!pedited || pedited->retinex.shadows) { + keyFile.set_integer ("Retinex", "Shadows", retinex.shadows); + } + + if (!pedited || pedited->retinex.stonalwidth) { + keyFile.set_integer ("Retinex", "ShadowTonalWidth", retinex.stonalwidth); + } + + if (!pedited || pedited->retinex.radius) { + keyFile.set_integer ("Retinex", "Radius", retinex.radius); + } + + if (!pedited || pedited->retinex.transmissionCurve) { + Glib::ArrayHandle transmissionCurve = retinex.transmissionCurve; + keyFile.set_double_list("Retinex", "TransmissionCurve", transmissionCurve); + } + + if (!pedited || pedited->retinex.gaintransmissionCurve) { + Glib::ArrayHandle gaintransmissionCurve = retinex.gaintransmissionCurve; + keyFile.set_double_list("Retinex", "GainTransmissionCurve", gaintransmissionCurve); + } + + // save channel mixer + if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) { + Glib::ArrayHandle rmix (chmixer.red, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Red", rmix); + } + + if (!pedited || pedited->chmixer.green[0] || pedited->chmixer.green[1] || pedited->chmixer.green[2]) { + Glib::ArrayHandle gmix (chmixer.green, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Green", gmix); + } + + if (!pedited || pedited->chmixer.blue[0] || pedited->chmixer.blue[1] || pedited->chmixer.blue[2]) { + Glib::ArrayHandle bmix (chmixer.blue, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Blue", bmix); + } + + //save Black & White + if (!pedited || pedited->blackwhite.enabled) { + keyFile.set_boolean ("Black & White", "Enabled", blackwhite.enabled); + } + + if (!pedited || pedited->blackwhite.method) { + keyFile.set_string ("Black & White", "Method", blackwhite.method ); + } + + if (!pedited || pedited->blackwhite.autoc) { + keyFile.set_boolean ("Black & White", "Auto", blackwhite.autoc); + } + + if (!pedited || pedited->blackwhite.enabledcc) { + keyFile.set_boolean ("Black & White", "ComplementaryColors", blackwhite.enabledcc); + } + + if (!pedited || pedited->blackwhite.setting) { + keyFile.set_string ("Black & White", "Setting", blackwhite.setting ); + } + + if (!pedited || pedited->blackwhite.filter) { + keyFile.set_string ("Black & White", "Filter", blackwhite.filter ); + } + + if (!pedited || pedited->blackwhite.mixerRed) { + keyFile.set_integer ("Black & White", "MixerRed", blackwhite.mixerRed); + } + + if (!pedited || pedited->blackwhite.mixerOrange) { + keyFile.set_integer ("Black & White", "MixerOrange", blackwhite.mixerOrange); + } + + if (!pedited || pedited->blackwhite.mixerYellow) { + keyFile.set_integer ("Black & White", "MixerYellow", blackwhite.mixerYellow); + } + + if (!pedited || pedited->blackwhite.mixerGreen) { + keyFile.set_integer ("Black & White", "MixerGreen", blackwhite.mixerGreen); + } + + if (!pedited || pedited->blackwhite.mixerCyan) { + keyFile.set_integer ("Black & White", "MixerCyan", blackwhite.mixerCyan); + } + + if (!pedited || pedited->blackwhite.mixerBlue) { + keyFile.set_integer ("Black & White", "MixerBlue", blackwhite.mixerBlue); + } + + if (!pedited || pedited->blackwhite.mixerMagenta) { + keyFile.set_integer ("Black & White", "MixerMagenta", blackwhite.mixerMagenta); + } + + if (!pedited || pedited->blackwhite.mixerPurple) { + keyFile.set_integer ("Black & White", "MixerPurple", blackwhite.mixerPurple); + } + + if (!pedited || pedited->blackwhite.gammaRed) { + keyFile.set_integer ("Black & White", "GammaRed", blackwhite.gammaRed); + } + + if (!pedited || pedited->blackwhite.gammaGreen) { + keyFile.set_integer ("Black & White", "GammaGreen", blackwhite.gammaGreen); + } + + if (!pedited || pedited->blackwhite.gammaBlue) { + keyFile.set_integer ("Black & White", "GammaBlue", blackwhite.gammaBlue); + } + + if (!pedited || pedited->blackwhite.algo) { + keyFile.set_string ("Black & White", "Algorithm", blackwhite.algo); + } + + if (!pedited || pedited->blackwhite.luminanceCurve) { + Glib::ArrayHandle luminanceCurve = blackwhite.luminanceCurve; + keyFile.set_double_list("Black & White", "LuminanceCurve", luminanceCurve); + } + + if (!pedited || pedited->blackwhite.beforeCurveMode) { + Glib::ustring mode; + + switch (blackwhite.beforeCurveMode) { + case (BlackWhiteParams::TC_MODE_STD_BW): + mode = "Standard"; + break; + + case (BlackWhiteParams::TC_MODE_FILMLIKE_BW): + mode = "FilmLike"; + break; + + case (BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW): + mode = "SatAndValueBlending"; + break; + + case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): + mode = "WeightedStd"; + break; + } + + keyFile.set_string ("Black & White", "BeforeCurveMode", mode); + } + + if (!pedited || pedited->blackwhite.afterCurveMode) { + Glib::ustring mode; + + switch (blackwhite.afterCurveMode) { + case (BlackWhiteParams::TC_MODE_STD_BW): + mode = "Standard"; + break; + + case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): + mode = "WeightedStd"; + break; + + default: + break; + } + + keyFile.set_string ("Black & White", "AfterCurveMode", mode); + } + + if (!pedited || pedited->blackwhite.beforeCurve) { + Glib::ArrayHandle tcurvebw = blackwhite.beforeCurve; + keyFile.set_double_list("Black & White", "BeforeCurve", tcurvebw); + } + + if (!pedited || pedited->blackwhite.afterCurve) { + Glib::ArrayHandle tcurvebw = blackwhite.afterCurve; + keyFile.set_double_list("Black & White", "AfterCurve", tcurvebw); + } + + // save luma curve + if (!pedited || pedited->labCurve.brightness) { + keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness); + } + + if (!pedited || pedited->labCurve.contrast) { + keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast); + } + + if (!pedited || pedited->labCurve.chromaticity) { + keyFile.set_integer ("Luminance Curve", "Chromaticity", labCurve.chromaticity); + } + + if (!pedited || pedited->labCurve.avoidcolorshift) { + keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift); + } + + if (!pedited || pedited->labCurve.rstprotection) { + keyFile.set_double ("Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection); + } + + if (!pedited || pedited->labCurve.lcredsk) { + keyFile.set_boolean ("Luminance Curve", "LCredsk", labCurve.lcredsk); + } + + if (!pedited || pedited->labCurve.lcurve) { + Glib::ArrayHandle lcurve = labCurve.lcurve; + keyFile.set_double_list("Luminance Curve", "LCurve", lcurve); + } + + if (!pedited || pedited->labCurve.acurve) { + Glib::ArrayHandle acurve = labCurve.acurve; + keyFile.set_double_list("Luminance Curve", "aCurve", acurve); + } + + if (!pedited || pedited->labCurve.bcurve) { + Glib::ArrayHandle bcurve = labCurve.bcurve; + keyFile.set_double_list("Luminance Curve", "bCurve", bcurve); + } + + if (!pedited || pedited->labCurve.cccurve) { + Glib::ArrayHandle cccurve = labCurve.cccurve; + keyFile.set_double_list("Luminance Curve", "ccCurve", cccurve); + } + + if (!pedited || pedited->labCurve.chcurve) { + Glib::ArrayHandle chcurve = labCurve.chcurve; + keyFile.set_double_list("Luminance Curve", "chCurve", chcurve); + } + + if (!pedited || pedited->labCurve.lhcurve) { + Glib::ArrayHandle lhcurve = labCurve.lhcurve; + keyFile.set_double_list("Luminance Curve", "lhCurve", lhcurve); + } + + if (!pedited || pedited->labCurve.hhcurve) { + Glib::ArrayHandle hhcurve = labCurve.hhcurve; + keyFile.set_double_list("Luminance Curve", "hhCurve", hhcurve); + } + + if (!pedited || pedited->labCurve.lccurve) { + Glib::ArrayHandle lccurve = labCurve.lccurve; + keyFile.set_double_list("Luminance Curve", "LcCurve", lccurve); + } + + if (!pedited || pedited->labCurve.clcurve) { + Glib::ArrayHandle clcurve = labCurve.clcurve; + keyFile.set_double_list("Luminance Curve", "ClCurve", clcurve); + } + + // save sharpening + if (!pedited || pedited->sharpening.enabled) { + keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled); + } + + if (!pedited || pedited->sharpening.method) { + keyFile.set_string ("Sharpening", "Method", sharpening.method); + } + + if (!pedited || pedited->sharpening.radius) { + keyFile.set_double ("Sharpening", "Radius", sharpening.radius); + } + + if (!pedited || pedited->sharpening.amount) { + keyFile.set_integer ("Sharpening", "Amount", sharpening.amount); + } + + if (!pedited || pedited->sharpening.threshold) { + Glib::ArrayHandle thresh (sharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Sharpening", "Threshold", thresh); + } + + if (!pedited || pedited->sharpening.edgesonly) { + keyFile.set_boolean ("Sharpening", "OnlyEdges", sharpening.edgesonly); + } + + if (!pedited || pedited->sharpening.edges_radius) { + keyFile.set_double ("Sharpening", "EdgedetectionRadius", sharpening.edges_radius); + } + + if (!pedited || pedited->sharpening.edges_tolerance) { + keyFile.set_integer ("Sharpening", "EdgeTolerance", sharpening.edges_tolerance); + } + + if (!pedited || pedited->sharpening.halocontrol) { + keyFile.set_boolean ("Sharpening", "HalocontrolEnabled", sharpening.halocontrol); + } + + if (!pedited || pedited->sharpening.halocontrol_amount) { + keyFile.set_integer ("Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount); + } + + if (!pedited || pedited->sharpening.deconvradius) { + keyFile.set_double ("Sharpening", "DeconvRadius", sharpening.deconvradius); + } + + if (!pedited || pedited->sharpening.deconvamount) { + keyFile.set_integer ("Sharpening", "DeconvAmount", sharpening.deconvamount); + } + + if (!pedited || pedited->sharpening.deconvdamping) { + keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); + } + + if (!pedited || pedited->sharpening.deconviter) { + keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); + } + + // save vibrance + if (!pedited || pedited->vibrance.enabled) { + keyFile.set_boolean ("Vibrance", "Enabled", vibrance.enabled); + } + + if (!pedited || pedited->vibrance.pastels) { + keyFile.set_integer ("Vibrance", "Pastels", vibrance.pastels); + } + + if (!pedited || pedited->vibrance.saturated) { + keyFile.set_integer ("Vibrance", "Saturated", vibrance.saturated); + } + + if (!pedited || pedited->vibrance.psthreshold) { + Glib::ArrayHandle thresh (vibrance.psthreshold.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Vibrance", "PSThreshold", thresh); + } + + if (!pedited || pedited->vibrance.protectskins) { + keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins); + } + + if (!pedited || pedited->vibrance.avoidcolorshift) { + keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift); + } + + if (!pedited || pedited->vibrance.pastsattog) { + keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog); + } + + if (!pedited || pedited->vibrance.skintonescurve) { + Glib::ArrayHandle skintonescurve = vibrance.skintonescurve; + keyFile.set_double_list("Vibrance", "SkinTonesCurve", skintonescurve); + } + + //save edge sharpening + if (!pedited || pedited->sharpenEdge.enabled) { + keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled); + } + + if (!pedited || pedited->sharpenEdge.passes) { + keyFile.set_integer ("SharpenEdge", "Passes", sharpenEdge.passes); + } + + if (!pedited || pedited->sharpenEdge.amount) { + keyFile.set_double ("SharpenEdge", "Strength", sharpenEdge.amount); + } + + if (!pedited || pedited->sharpenEdge.threechannels) { + keyFile.set_boolean ("SharpenEdge", "ThreeChannels", sharpenEdge.threechannels); + } + + //save micro-contrast sharpening + if (!pedited || pedited->sharpenMicro.enabled) { + keyFile.set_boolean ("SharpenMicro", "Enabled", sharpenMicro.enabled); + } + + if (!pedited || pedited->sharpenMicro.matrix) { + keyFile.set_boolean ("SharpenMicro", "Matrix", sharpenMicro.matrix); + } + + if (!pedited || pedited->sharpenMicro.amount) { + keyFile.set_double ("SharpenMicro", "Strength", sharpenMicro.amount); + } + + if (!pedited || pedited->sharpenMicro.uniformity) { + keyFile.set_double ("SharpenMicro", "Uniformity", sharpenMicro.uniformity); + } + + /* + // save colorBoost + if (!pedited || pedited->colorBoost.amount) keyFile.set_integer ("Color Boost", "Amount", colorBoost.amount); + if (!pedited || pedited->colorBoost.avoidclip) keyFile.set_boolean ("Color Boost", "AvoidColorClipping", colorBoost.avoidclip); + if (!pedited || pedited->colorBoost.enable_saturationlimiter) keyFile.set_boolean ("Color Boost", "SaturationLimiter", colorBoost.enable_saturationlimiter); + if (!pedited || pedited->colorBoost.saturationlimit) keyFile.set_double ("Color Boost", "SaturationLimit", colorBoost.saturationlimit); + */ + + // save wb + if (!pedited || pedited->wb.method) { + keyFile.set_string ("White Balance", "Setting", wb.method); + } + + if (!pedited || pedited->wb.temperature) { + keyFile.set_integer ("White Balance", "Temperature", wb.temperature); + } + + if (!pedited || pedited->wb.green) { + keyFile.set_double ("White Balance", "Green", wb.green); + } + + if (!pedited || pedited->wb.equal) { + keyFile.set_double ("White Balance", "Equal", wb.equal); + } + + /* + // save colorShift + if (!pedited || pedited->colorShift.a) keyFile.set_double ("Color Shift", "ChannelA", colorShift.a); + if (!pedited || pedited->colorShift.b) keyFile.set_double ("Color Shift", "ChannelB", colorShift.b); + */ + // save colorappearance + if (!pedited || pedited->colorappearance.enabled) { + keyFile.set_boolean ("Color appearance", "Enabled", colorappearance.enabled); + } + + if (!pedited || pedited->colorappearance.degree) { + keyFile.set_integer ("Color appearance", "Degree", colorappearance.degree); + } + + if (!pedited || pedited->colorappearance.autodegree) { + keyFile.set_boolean ("Color appearance", "AutoDegree", colorappearance.autodegree); + } + + if (!pedited || pedited->colorappearance.surround) { + keyFile.set_string ("Color appearance", "Surround", colorappearance.surround); + } // if (!pedited || pedited->colorappearance.backgrd) keyFile.set_integer ("Color appearance", "Background", colorappearance.backgrd); - if (!pedited || pedited->colorappearance.adaplum) { - keyFile.set_double ("Color appearance", "AdaptLum", colorappearance.adaplum); - } + if (!pedited || pedited->colorappearance.adaplum) { + keyFile.set_double ("Color appearance", "AdaptLum", colorappearance.adaplum); + } - if (!pedited || pedited->colorappearance.badpixsl) { - keyFile.set_integer ("Color appearance", "Badpixsl", colorappearance.badpixsl); - } + if (!pedited || pedited->colorappearance.badpixsl) { + keyFile.set_integer ("Color appearance", "Badpixsl", colorappearance.badpixsl); + } - if (!pedited || pedited->colorappearance.wbmodel) { - keyFile.set_string ("Color appearance", "Model", colorappearance.wbmodel); - } + if (!pedited || pedited->colorappearance.wbmodel) { + keyFile.set_string ("Color appearance", "Model", colorappearance.wbmodel); + } - if (!pedited || pedited->colorappearance.algo) { - keyFile.set_string ("Color appearance", "Algorithm", colorappearance.algo); - } + if (!pedited || pedited->colorappearance.algo) { + keyFile.set_string ("Color appearance", "Algorithm", colorappearance.algo); + } - if (!pedited || pedited->colorappearance.jlight) { - keyFile.set_double ("Color appearance", "J-Light", colorappearance.jlight); - } + if (!pedited || pedited->colorappearance.jlight) { + keyFile.set_double ("Color appearance", "J-Light", colorappearance.jlight); + } - if (!pedited || pedited->colorappearance.qbright) { - keyFile.set_double ("Color appearance", "Q-Bright", colorappearance.qbright); - } + if (!pedited || pedited->colorappearance.qbright) { + keyFile.set_double ("Color appearance", "Q-Bright", colorappearance.qbright); + } - if (!pedited || pedited->colorappearance.chroma) { - keyFile.set_double ("Color appearance", "C-Chroma", colorappearance.chroma); - } + if (!pedited || pedited->colorappearance.chroma) { + keyFile.set_double ("Color appearance", "C-Chroma", colorappearance.chroma); + } - if (!pedited || pedited->colorappearance.schroma) { - keyFile.set_double ("Color appearance", "S-Chroma", colorappearance.schroma); - } + if (!pedited || pedited->colorappearance.schroma) { + keyFile.set_double ("Color appearance", "S-Chroma", colorappearance.schroma); + } - if (!pedited || pedited->colorappearance.mchroma) { - keyFile.set_double ("Color appearance", "M-Chroma", colorappearance.mchroma); - } + if (!pedited || pedited->colorappearance.mchroma) { + keyFile.set_double ("Color appearance", "M-Chroma", colorappearance.mchroma); + } - if (!pedited || pedited->colorappearance.contrast) { - keyFile.set_double ("Color appearance", "J-Contrast", colorappearance.contrast); - } + if (!pedited || pedited->colorappearance.contrast) { + keyFile.set_double ("Color appearance", "J-Contrast", colorappearance.contrast); + } - if (!pedited || pedited->colorappearance.qcontrast) { - keyFile.set_double ("Color appearance", "Q-Contrast", colorappearance.qcontrast); - } + if (!pedited || pedited->colorappearance.qcontrast) { + keyFile.set_double ("Color appearance", "Q-Contrast", colorappearance.qcontrast); + } - if (!pedited || pedited->colorappearance.colorh) { - keyFile.set_double ("Color appearance", "H-Hue", colorappearance.colorh); - } + if (!pedited || pedited->colorappearance.colorh) { + keyFile.set_double ("Color appearance", "H-Hue", colorappearance.colorh); + } - if (!pedited || pedited->colorappearance.rstprotection) { - keyFile.set_double ("Color appearance", "RSTProtection", colorappearance.rstprotection); - } + if (!pedited || pedited->colorappearance.rstprotection) { + keyFile.set_double ("Color appearance", "RSTProtection", colorappearance.rstprotection); + } - if (!pedited || pedited->colorappearance.adapscen) { - keyFile.set_double ("Color appearance", "AdaptScene", colorappearance.adapscen); - } + if (!pedited || pedited->colorappearance.adapscen) { + keyFile.set_double ("Color appearance", "AdaptScene", colorappearance.adapscen); + } - if (!pedited || pedited->colorappearance.autoadapscen) { - keyFile.set_boolean ("Color appearance", "AutoAdapscen", colorappearance.autoadapscen); - } + if (!pedited || pedited->colorappearance.autoadapscen) { + keyFile.set_boolean ("Color appearance", "AutoAdapscen", colorappearance.autoadapscen); + } - if (!pedited || pedited->colorappearance.surrsource) { - keyFile.set_boolean ("Color appearance", "SurrSource", colorappearance.surrsource); - } + if (!pedited || pedited->colorappearance.surrsource) { + keyFile.set_boolean ("Color appearance", "SurrSource", colorappearance.surrsource); + } - if (!pedited || pedited->colorappearance.gamut) { - keyFile.set_boolean ("Color appearance", "Gamut", colorappearance.gamut); - } + if (!pedited || pedited->colorappearance.gamut) { + keyFile.set_boolean ("Color appearance", "Gamut", colorappearance.gamut); + } // if (!pedited || pedited->colorappearance.badpix) keyFile.set_boolean ("Color appearance", "Badpix", colorappearance.badpix); - if (!pedited || pedited->colorappearance.datacie) { - keyFile.set_boolean ("Color appearance", "Datacie", colorappearance.datacie); - } + if (!pedited || pedited->colorappearance.datacie) { + keyFile.set_boolean ("Color appearance", "Datacie", colorappearance.datacie); + } - if (!pedited || pedited->colorappearance.tonecie) { - keyFile.set_boolean ("Color appearance", "Tonecie", colorappearance.tonecie); - } + if (!pedited || pedited->colorappearance.tonecie) { + keyFile.set_boolean ("Color appearance", "Tonecie", colorappearance.tonecie); + } // if (!pedited || pedited->colorappearance.sharpcie) keyFile.set_boolean ("Color appearance", "Sharpcie", colorappearance.sharpcie); - if (!pedited || pedited->colorappearance.curveMode) { - Glib::ustring method; + if (!pedited || pedited->colorappearance.curveMode) { + Glib::ustring method; - switch (colorappearance.curveMode) { - case (ColorAppearanceParams::TC_MODE_LIGHT): - method = "Lightness"; - break; + switch (colorappearance.curveMode) { + case (ColorAppearanceParams::TC_MODE_LIGHT): + method = "Lightness"; + break; - case (ColorAppearanceParams::TC_MODE_BRIGHT): - method = "Brightness"; - break; + case (ColorAppearanceParams::TC_MODE_BRIGHT): + method = "Brightness"; + break; + } + + keyFile.set_string ("Color appearance", "CurveMode", method); } - keyFile.set_string ("Color appearance", "CurveMode", method); - } + if (!pedited || pedited->colorappearance.curveMode2) { + Glib::ustring method; - if (!pedited || pedited->colorappearance.curveMode2) { - Glib::ustring method; + switch (colorappearance.curveMode2) { + case (ColorAppearanceParams::TC_MODE_LIGHT): + method = "Lightness"; + break; - switch (colorappearance.curveMode2) { - case (ColorAppearanceParams::TC_MODE_LIGHT): - method = "Lightness"; - break; + case (ColorAppearanceParams::TC_MODE_BRIGHT): + method = "Brightness"; + break; + } - case (ColorAppearanceParams::TC_MODE_BRIGHT): - method = "Brightness"; - break; + keyFile.set_string ("Color appearance", "CurveMode2", method); } - keyFile.set_string ("Color appearance", "CurveMode2", method); - } + if (!pedited || pedited->colorappearance.curveMode3) { + Glib::ustring method; - if (!pedited || pedited->colorappearance.curveMode3) { - Glib::ustring method; + switch (colorappearance.curveMode3) { + case (ColorAppearanceParams::TC_MODE_CHROMA): + method = "Chroma"; + break; - switch (colorappearance.curveMode3) { - case (ColorAppearanceParams::TC_MODE_CHROMA): - method = "Chroma"; - break; + case (ColorAppearanceParams::TC_MODE_SATUR): + method = "Saturation"; + break; - case (ColorAppearanceParams::TC_MODE_SATUR): - method = "Saturation"; - break; + case (ColorAppearanceParams::TC_MODE_COLORF): + method = "Colorfullness"; + break; - case (ColorAppearanceParams::TC_MODE_COLORF): - method = "Colorfullness"; - break; + } + keyFile.set_string ("Color appearance", "CurveMode3", method); } - keyFile.set_string ("Color appearance", "CurveMode3", method); - } + if (!pedited || pedited->colorappearance.curve) { + Glib::ArrayHandle tcurve = colorappearance.curve; + keyFile.set_double_list("Color appearance", "Curve", tcurve); + } - if (!pedited || pedited->colorappearance.curve) { - Glib::ArrayHandle tcurve = colorappearance.curve; - keyFile.set_double_list("Color appearance", "Curve", tcurve); - } + if (!pedited || pedited->colorappearance.curve2) { + Glib::ArrayHandle tcurve = colorappearance.curve2; + keyFile.set_double_list("Color appearance", "Curve2", tcurve); + } - if (!pedited || pedited->colorappearance.curve2) { - Glib::ArrayHandle tcurve = colorappearance.curve2; - keyFile.set_double_list("Color appearance", "Curve2", tcurve); - } - - if (!pedited || pedited->colorappearance.curve3) { - Glib::ArrayHandle tcurve = colorappearance.curve3; - keyFile.set_double_list("Color appearance", "Curve3", tcurve); - } + if (!pedited || pedited->colorappearance.curve3) { + Glib::ArrayHandle tcurve = colorappearance.curve3; + keyFile.set_double_list("Color appearance", "Curve3", tcurve); + } - // save impulseDenoise - if (!pedited || pedited->impulseDenoise.enabled) { - keyFile.set_boolean ("Impulse Denoising", "Enabled", impulseDenoise.enabled); - } + // save impulseDenoise + if (!pedited || pedited->impulseDenoise.enabled) { + keyFile.set_boolean ("Impulse Denoising", "Enabled", impulseDenoise.enabled); + } - if (!pedited || pedited->impulseDenoise.thresh) { - keyFile.set_integer ("Impulse Denoising", "Threshold", impulseDenoise.thresh); - } + if (!pedited || pedited->impulseDenoise.thresh) { + keyFile.set_integer ("Impulse Denoising", "Threshold", impulseDenoise.thresh); + } - // save defringe - if (!pedited || pedited->defringe.enabled) { - keyFile.set_boolean ("Defringing", "Enabled", defringe.enabled); - } + // save defringe + if (!pedited || pedited->defringe.enabled) { + keyFile.set_boolean ("Defringing", "Enabled", defringe.enabled); + } - if (!pedited || pedited->defringe.radius) { - keyFile.set_double ("Defringing", "Radius", defringe.radius); - } + if (!pedited || pedited->defringe.radius) { + keyFile.set_double ("Defringing", "Radius", defringe.radius); + } - if (!pedited || pedited->defringe.threshold) { - keyFile.set_integer ("Defringing", "Threshold", defringe.threshold); - } + if (!pedited || pedited->defringe.threshold) { + keyFile.set_integer ("Defringing", "Threshold", defringe.threshold); + } - if (!pedited || pedited->defringe.huecurve) { - Glib::ArrayHandle huecurve = defringe.huecurve; - keyFile.set_double_list("Defringing", "HueCurve", huecurve); - } + if (!pedited || pedited->defringe.huecurve) { + Glib::ArrayHandle huecurve = defringe.huecurve; + keyFile.set_double_list("Defringing", "HueCurve", huecurve); + } - // save dirpyrDenoise - if (!pedited || pedited->dirpyrDenoise.enabled) { - keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); - } + // save dirpyrDenoise + if (!pedited || pedited->dirpyrDenoise.enabled) { + keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); + } - if (!pedited || pedited->dirpyrDenoise.enhance) { - keyFile.set_boolean ("Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance); - } + if (!pedited || pedited->dirpyrDenoise.enhance) { + keyFile.set_boolean ("Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance); + } - if (!pedited || pedited->dirpyrDenoise.median) { - keyFile.set_boolean ("Directional Pyramid Denoising", "Median", dirpyrDenoise.median); - } + if (!pedited || pedited->dirpyrDenoise.median) { + keyFile.set_boolean ("Directional Pyramid Denoising", "Median", dirpyrDenoise.median); + } - if (!pedited || pedited->dirpyrDenoise.autochroma) { - keyFile.set_boolean ("Directional Pyramid Denoising", "Auto", dirpyrDenoise.autochroma); - } + if (!pedited || pedited->dirpyrDenoise.autochroma) { + keyFile.set_boolean ("Directional Pyramid Denoising", "Auto", dirpyrDenoise.autochroma); + } // if (!pedited || pedited->dirpyrDenoise.perform) keyFile.set_boolean ("Directional Pyramid Denoising", "Perform", dirpyrDenoise.perform); - if (!pedited || pedited->dirpyrDenoise.luma) { - keyFile.set_double ("Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma); - } - - if (!pedited || pedited->dirpyrDenoise.Ldetail) { - keyFile.set_double ("Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail); - } - - if (!pedited || pedited->dirpyrDenoise.chroma) { - keyFile.set_double ("Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma); - } - - if (!pedited || pedited->dirpyrDenoise.dmethod) { - keyFile.set_string ("Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod); - } - - if (!pedited || pedited->dirpyrDenoise.Lmethod) { - keyFile.set_string ("Directional Pyramid Denoising", "LMethod", dirpyrDenoise.Lmethod); - } - - // never save 'auto chroma preview mode' to pp3 - if (!pedited || pedited->dirpyrDenoise.Cmethod) { - if(dirpyrDenoise.Cmethod == "PRE") { - dirpyrDenoise.Cmethod = "MAN"; + if (!pedited || pedited->dirpyrDenoise.luma) { + keyFile.set_double ("Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma); } - keyFile.set_string ("Directional Pyramid Denoising", "CMethod", dirpyrDenoise.Cmethod); - } - - if (!pedited || pedited->dirpyrDenoise.C2method) { - if(dirpyrDenoise.C2method == "PREV") { - dirpyrDenoise.C2method = "MANU"; + if (!pedited || pedited->dirpyrDenoise.Ldetail) { + keyFile.set_double ("Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail); } - keyFile.set_string ("Directional Pyramid Denoising", "C2Method", dirpyrDenoise.C2method); - } - - if (!pedited || pedited->dirpyrDenoise.smethod) { - keyFile.set_string ("Directional Pyramid Denoising", "SMethod", dirpyrDenoise.smethod); - } - - if (!pedited || pedited->dirpyrDenoise.medmethod) { - keyFile.set_string ("Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod); - } - - if (!pedited || pedited->dirpyrDenoise.rgbmethod) { - keyFile.set_string ("Directional Pyramid Denoising", "RGBMethod", dirpyrDenoise.rgbmethod); - } - - if (!pedited || pedited->dirpyrDenoise.methodmed) { - keyFile.set_string ("Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed); - } - - if (!pedited || pedited->dirpyrDenoise.redchro) { - keyFile.set_double ("Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro); - } - - if (!pedited || pedited->dirpyrDenoise.bluechro) { - keyFile.set_double ("Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro); - } - - if (!pedited || pedited->dirpyrDenoise.gamma) { - keyFile.set_double ("Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma); - } - - if (!pedited || pedited->dirpyrDenoise.passes) { - keyFile.set_integer ("Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes); - } - - if (!pedited || pedited->dirpyrDenoise.lcurve) { - Glib::ArrayHandle lcurve = dirpyrDenoise.lcurve; - keyFile.set_double_list("Directional Pyramid Denoising", "LCurve", lcurve); - } - - if (!pedited || pedited->dirpyrDenoise.cccurve) { - Glib::ArrayHandle cccurve = dirpyrDenoise.cccurve; - keyFile.set_double_list("Directional Pyramid Denoising", "CCCurve", cccurve); - } - - //Save epd. - if (!pedited || pedited->epd.enabled) { - keyFile.set_boolean ("EPD", "Enabled", epd.enabled); - } - - if (!pedited || pedited->epd.strength) { - keyFile.set_double ("EPD", "Strength", epd.strength); - } - - if (!pedited || pedited->epd.gamma) { - keyFile.set_double ("EPD", "Gamma", epd.gamma); - } - - if (!pedited || pedited->epd.edgeStopping) { - keyFile.set_double ("EPD", "EdgeStopping", epd.edgeStopping); - } - - if (!pedited || pedited->epd.scale) { - keyFile.set_double ("EPD", "Scale", epd.scale); - } - - if (!pedited || pedited->epd.reweightingIterates) { - keyFile.set_integer ("EPD", "ReweightingIterates", epd.reweightingIterates); - } - - /* - // save lumaDenoise - if (!pedited || pedited->lumaDenoise.enabled) keyFile.set_boolean ("Luminance Denoising", "Enabled", lumaDenoise.enabled); - if (!pedited || pedited->lumaDenoise.radius) keyFile.set_double ("Luminance Denoising", "Radius", lumaDenoise.radius); - if (!pedited || pedited->lumaDenoise.edgetolerance) keyFile.set_integer ("Luminance Denoising", "EdgeTolerance", lumaDenoise.edgetolerance); - */ - - /* - // save colorDenoise - //if (!pedited || pedited->colorDenoise.enabled) keyFile.set_boolean ("Chrominance Denoising", "Enabled", colorDenoise.enabled); - if (!pedited || pedited->colorDenoise.amount) keyFile.set_integer ("Chrominance Denoising", "Amount", colorDenoise.amount); - */ - - // save sh - if (!pedited || pedited->sh.enabled) { - keyFile.set_boolean ("Shadows & Highlights", "Enabled", sh.enabled); - } - - if (!pedited || pedited->sh.hq) { - keyFile.set_boolean ("Shadows & Highlights", "HighQuality", sh.hq); - } - - if (!pedited || pedited->sh.highlights) { - keyFile.set_integer ("Shadows & Highlights", "Highlights", sh.highlights); - } - - if (!pedited || pedited->sh.htonalwidth) { - keyFile.set_integer ("Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth); - } - - if (!pedited || pedited->sh.shadows) { - keyFile.set_integer ("Shadows & Highlights", "Shadows", sh.shadows); - } - - if (!pedited || pedited->sh.stonalwidth) { - keyFile.set_integer ("Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth); - } - - if (!pedited || pedited->sh.localcontrast) { - keyFile.set_integer ("Shadows & Highlights", "LocalContrast", sh.localcontrast); - } - - if (!pedited || pedited->sh.radius) { - keyFile.set_integer ("Shadows & Highlights", "Radius", sh.radius); - } - - // save crop - if (!pedited || pedited->crop.enabled) { - keyFile.set_boolean ("Crop", "Enabled", crop.enabled); - } - - if (!pedited || pedited->crop.x) { - keyFile.set_integer ("Crop", "X", crop.x); - } - - if (!pedited || pedited->crop.y) { - keyFile.set_integer ("Crop", "Y", crop.y); - } - - if (!pedited || pedited->crop.w) { - keyFile.set_integer ("Crop", "W", crop.w); - } - - if (!pedited || pedited->crop.h) { - keyFile.set_integer ("Crop", "H", crop.h); - } - - if (!pedited || pedited->crop.fixratio) { - keyFile.set_boolean ("Crop", "FixedRatio", crop.fixratio); - } - - if (!pedited || pedited->crop.ratio) { - keyFile.set_string ("Crop", "Ratio", crop.ratio); - } - - if (!pedited || pedited->crop.orientation) { - keyFile.set_string ("Crop", "Orientation", crop.orientation); - } - - if (!pedited || pedited->crop.guide) { - keyFile.set_string ("Crop", "Guide", crop.guide); - } - - // save coarse - if (!pedited || pedited->coarse.rotate) { - keyFile.set_integer ("Coarse Transformation", "Rotate", coarse.rotate); - } - - if (!pedited || pedited->coarse.hflip) { - keyFile.set_boolean ("Coarse Transformation", "HorizontalFlip", coarse.hflip); - } - - if (!pedited || pedited->coarse.vflip) { - keyFile.set_boolean ("Coarse Transformation", "VerticalFlip", coarse.vflip); - } - - // save commonTrans - if (!pedited || pedited->commonTrans.autofill) { - keyFile.set_boolean ("Common Properties for Transformations", "AutoFill", commonTrans.autofill); - } - - // save rotate - if (!pedited || pedited->rotate.degree) { - keyFile.set_double ("Rotation", "Degree", rotate.degree); - } - - // save distortion - if (!pedited || pedited->distortion.amount) { - keyFile.set_double ("Distortion", "Amount", distortion.amount); - } - - // lens profile - if (!pedited || pedited->lensProf.lcpFile) { - keyFile.set_string ("LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile)); - } - - if (!pedited || pedited->lensProf.useDist) { - keyFile.set_boolean ("LensProfile", "UseDistortion", lensProf.useDist); - } - - if (!pedited || pedited->lensProf.useVign) { - keyFile.set_boolean ("LensProfile", "UseVignette", lensProf.useVign); - } - - if (!pedited || pedited->lensProf.useCA) { - keyFile.set_boolean ("LensProfile", "UseCA", lensProf.useCA); - } - - // save perspective correction - if (!pedited || pedited->perspective.horizontal) { - keyFile.set_double ("Perspective", "Horizontal", perspective.horizontal); - } - - if (!pedited || pedited->perspective.vertical) { - keyFile.set_double ("Perspective", "Vertical", perspective.vertical); - } - - // save gradient - if (!pedited || pedited->gradient.enabled) { - keyFile.set_boolean ("Gradient", "Enabled", gradient.enabled); - } - - if (!pedited || pedited->gradient.degree) { - keyFile.set_double ("Gradient", "Degree", gradient.degree); - } - - if (!pedited || pedited->gradient.feather) { - keyFile.set_integer ("Gradient", "Feather", gradient.feather); - } - - if (!pedited || pedited->gradient.strength) { - keyFile.set_double ("Gradient", "Strength", gradient.strength); - } - - if (!pedited || pedited->gradient.centerX) { - keyFile.set_integer ("Gradient", "CenterX", gradient.centerX); - } - - if (!pedited || pedited->gradient.centerY) { - keyFile.set_integer ("Gradient", "CenterY", gradient.centerY); - } - - // save post-crop vignette - if (!pedited || pedited->pcvignette.enabled) { - keyFile.set_boolean ("PCVignette", "Enabled", pcvignette.enabled); - } - - if (!pedited || pedited->pcvignette.strength) { - keyFile.set_double ("PCVignette", "Strength", pcvignette.strength); - } - - if (!pedited || pedited->pcvignette.feather) { - keyFile.set_integer ("PCVignette", "Feather", pcvignette.feather); - } - - if (!pedited || pedited->pcvignette.roundness) { - keyFile.set_integer ("PCVignette", "Roundness", pcvignette.roundness); - } - - // save C/A correction - if (!pedited || pedited->cacorrection.red) { - keyFile.set_double ("CACorrection", "Red", cacorrection.red); - } - - if (!pedited || pedited->cacorrection.blue) { - keyFile.set_double ("CACorrection", "Blue", cacorrection.blue); - } - - // save vignetting correction - if (!pedited || pedited->vignetting.amount) { - keyFile.set_integer ("Vignetting Correction", "Amount", vignetting.amount); - } - - if (!pedited || pedited->vignetting.radius) { - keyFile.set_integer ("Vignetting Correction", "Radius", vignetting.radius); - } - - if (!pedited || pedited->vignetting.strength) { - keyFile.set_integer ("Vignetting Correction", "Strength", vignetting.strength); - } - - if (!pedited || pedited->vignetting.centerX) { - keyFile.set_integer ("Vignetting Correction", "CenterX", vignetting.centerX); - } - - if (!pedited || pedited->vignetting.centerY) { - keyFile.set_integer ("Vignetting Correction", "CenterY", vignetting.centerY); - } - + if (!pedited || pedited->dirpyrDenoise.chroma) { + keyFile.set_double ("Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma); + } + + if (!pedited || pedited->dirpyrDenoise.dmethod) { + keyFile.set_string ("Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod); + } + + if (!pedited || pedited->dirpyrDenoise.Lmethod) { + keyFile.set_string ("Directional Pyramid Denoising", "LMethod", dirpyrDenoise.Lmethod); + } + + // never save 'auto chroma preview mode' to pp3 + if (!pedited || pedited->dirpyrDenoise.Cmethod) { + if(dirpyrDenoise.Cmethod == "PRE") { + dirpyrDenoise.Cmethod = "MAN"; + } + + keyFile.set_string ("Directional Pyramid Denoising", "CMethod", dirpyrDenoise.Cmethod); + } + + if (!pedited || pedited->dirpyrDenoise.C2method) { + if(dirpyrDenoise.C2method == "PREV") { + dirpyrDenoise.C2method = "MANU"; + } + + keyFile.set_string ("Directional Pyramid Denoising", "C2Method", dirpyrDenoise.C2method); + } + + if (!pedited || pedited->dirpyrDenoise.smethod) { + keyFile.set_string ("Directional Pyramid Denoising", "SMethod", dirpyrDenoise.smethod); + } + + if (!pedited || pedited->dirpyrDenoise.medmethod) { + keyFile.set_string ("Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod); + } + + if (!pedited || pedited->dirpyrDenoise.rgbmethod) { + keyFile.set_string ("Directional Pyramid Denoising", "RGBMethod", dirpyrDenoise.rgbmethod); + } + + if (!pedited || pedited->dirpyrDenoise.methodmed) { + keyFile.set_string ("Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed); + } + + if (!pedited || pedited->dirpyrDenoise.redchro) { + keyFile.set_double ("Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro); + } + + if (!pedited || pedited->dirpyrDenoise.bluechro) { + keyFile.set_double ("Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro); + } + + if (!pedited || pedited->dirpyrDenoise.gamma) { + keyFile.set_double ("Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma); + } + + if (!pedited || pedited->dirpyrDenoise.passes) { + keyFile.set_integer ("Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes); + } + + if (!pedited || pedited->dirpyrDenoise.lcurve) { + Glib::ArrayHandle lcurve = dirpyrDenoise.lcurve; + keyFile.set_double_list("Directional Pyramid Denoising", "LCurve", lcurve); + } + + if (!pedited || pedited->dirpyrDenoise.cccurve) { + Glib::ArrayHandle cccurve = dirpyrDenoise.cccurve; + keyFile.set_double_list("Directional Pyramid Denoising", "CCCurve", cccurve); + } + + //Save epd. + if (!pedited || pedited->epd.enabled) { + keyFile.set_boolean ("EPD", "Enabled", epd.enabled); + } + + if (!pedited || pedited->epd.strength) { + keyFile.set_double ("EPD", "Strength", epd.strength); + } + + if (!pedited || pedited->epd.gamma) { + keyFile.set_double ("EPD", "Gamma", epd.gamma); + } + + if (!pedited || pedited->epd.edgeStopping) { + keyFile.set_double ("EPD", "EdgeStopping", epd.edgeStopping); + } + + if (!pedited || pedited->epd.scale) { + keyFile.set_double ("EPD", "Scale", epd.scale); + } + + if (!pedited || pedited->epd.reweightingIterates) { + keyFile.set_integer ("EPD", "ReweightingIterates", epd.reweightingIterates); + } + + /* + // save lumaDenoise + if (!pedited || pedited->lumaDenoise.enabled) keyFile.set_boolean ("Luminance Denoising", "Enabled", lumaDenoise.enabled); + if (!pedited || pedited->lumaDenoise.radius) keyFile.set_double ("Luminance Denoising", "Radius", lumaDenoise.radius); + if (!pedited || pedited->lumaDenoise.edgetolerance) keyFile.set_integer ("Luminance Denoising", "EdgeTolerance", lumaDenoise.edgetolerance); + */ + + /* + // save colorDenoise + //if (!pedited || pedited->colorDenoise.enabled) keyFile.set_boolean ("Chrominance Denoising", "Enabled", colorDenoise.enabled); + if (!pedited || pedited->colorDenoise.amount) keyFile.set_integer ("Chrominance Denoising", "Amount", colorDenoise.amount); + */ + + // save sh + if (!pedited || pedited->sh.enabled) { + keyFile.set_boolean ("Shadows & Highlights", "Enabled", sh.enabled); + } + + if (!pedited || pedited->sh.hq) { + keyFile.set_boolean ("Shadows & Highlights", "HighQuality", sh.hq); + } + + if (!pedited || pedited->sh.highlights) { + keyFile.set_integer ("Shadows & Highlights", "Highlights", sh.highlights); + } + + if (!pedited || pedited->sh.htonalwidth) { + keyFile.set_integer ("Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth); + } + + if (!pedited || pedited->sh.shadows) { + keyFile.set_integer ("Shadows & Highlights", "Shadows", sh.shadows); + } + + if (!pedited || pedited->sh.stonalwidth) { + keyFile.set_integer ("Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth); + } + + if (!pedited || pedited->sh.localcontrast) { + keyFile.set_integer ("Shadows & Highlights", "LocalContrast", sh.localcontrast); + } + + if (!pedited || pedited->sh.radius) { + keyFile.set_integer ("Shadows & Highlights", "Radius", sh.radius); + } + + // save crop + if (!pedited || pedited->crop.enabled) { + keyFile.set_boolean ("Crop", "Enabled", crop.enabled); + } + + if (!pedited || pedited->crop.x) { + keyFile.set_integer ("Crop", "X", crop.x); + } + + if (!pedited || pedited->crop.y) { + keyFile.set_integer ("Crop", "Y", crop.y); + } + + if (!pedited || pedited->crop.w) { + keyFile.set_integer ("Crop", "W", crop.w); + } + + if (!pedited || pedited->crop.h) { + keyFile.set_integer ("Crop", "H", crop.h); + } + + if (!pedited || pedited->crop.fixratio) { + keyFile.set_boolean ("Crop", "FixedRatio", crop.fixratio); + } + + if (!pedited || pedited->crop.ratio) { + keyFile.set_string ("Crop", "Ratio", crop.ratio); + } + + if (!pedited || pedited->crop.orientation) { + keyFile.set_string ("Crop", "Orientation", crop.orientation); + } + + if (!pedited || pedited->crop.guide) { + keyFile.set_string ("Crop", "Guide", crop.guide); + } + + // save coarse + if (!pedited || pedited->coarse.rotate) { + keyFile.set_integer ("Coarse Transformation", "Rotate", coarse.rotate); + } + + if (!pedited || pedited->coarse.hflip) { + keyFile.set_boolean ("Coarse Transformation", "HorizontalFlip", coarse.hflip); + } + + if (!pedited || pedited->coarse.vflip) { + keyFile.set_boolean ("Coarse Transformation", "VerticalFlip", coarse.vflip); + } + + // save commonTrans + if (!pedited || pedited->commonTrans.autofill) { + keyFile.set_boolean ("Common Properties for Transformations", "AutoFill", commonTrans.autofill); + } + + // save rotate + if (!pedited || pedited->rotate.degree) { + keyFile.set_double ("Rotation", "Degree", rotate.degree); + } + + // save distortion + if (!pedited || pedited->distortion.amount) { + keyFile.set_double ("Distortion", "Amount", distortion.amount); + } + + // lens profile + if (!pedited || pedited->lensProf.lcpFile) { + keyFile.set_string ("LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile)); + } + + if (!pedited || pedited->lensProf.useDist) { + keyFile.set_boolean ("LensProfile", "UseDistortion", lensProf.useDist); + } + + if (!pedited || pedited->lensProf.useVign) { + keyFile.set_boolean ("LensProfile", "UseVignette", lensProf.useVign); + } + + if (!pedited || pedited->lensProf.useCA) { + keyFile.set_boolean ("LensProfile", "UseCA", lensProf.useCA); + } + + // save perspective correction + if (!pedited || pedited->perspective.horizontal) { + keyFile.set_double ("Perspective", "Horizontal", perspective.horizontal); + } + + if (!pedited || pedited->perspective.vertical) { + keyFile.set_double ("Perspective", "Vertical", perspective.vertical); + } + + // save gradient + if (!pedited || pedited->gradient.enabled) { + keyFile.set_boolean ("Gradient", "Enabled", gradient.enabled); + } + + if (!pedited || pedited->gradient.degree) { + keyFile.set_double ("Gradient", "Degree", gradient.degree); + } + + if (!pedited || pedited->gradient.feather) { + keyFile.set_integer ("Gradient", "Feather", gradient.feather); + } + + if (!pedited || pedited->gradient.strength) { + keyFile.set_double ("Gradient", "Strength", gradient.strength); + } + + if (!pedited || pedited->gradient.centerX) { + keyFile.set_integer ("Gradient", "CenterX", gradient.centerX); + } + + if (!pedited || pedited->gradient.centerY) { + keyFile.set_integer ("Gradient", "CenterY", gradient.centerY); + } + + // save post-crop vignette + if (!pedited || pedited->pcvignette.enabled) { + keyFile.set_boolean ("PCVignette", "Enabled", pcvignette.enabled); + } + + if (!pedited || pedited->pcvignette.strength) { + keyFile.set_double ("PCVignette", "Strength", pcvignette.strength); + } + + if (!pedited || pedited->pcvignette.feather) { + keyFile.set_integer ("PCVignette", "Feather", pcvignette.feather); + } + + if (!pedited || pedited->pcvignette.roundness) { + keyFile.set_integer ("PCVignette", "Roundness", pcvignette.roundness); + } + + // save C/A correction + if (!pedited || pedited->cacorrection.red) { + keyFile.set_double ("CACorrection", "Red", cacorrection.red); + } + + if (!pedited || pedited->cacorrection.blue) { + keyFile.set_double ("CACorrection", "Blue", cacorrection.blue); + } + + // save vignetting correction + if (!pedited || pedited->vignetting.amount) { + keyFile.set_integer ("Vignetting Correction", "Amount", vignetting.amount); + } + + if (!pedited || pedited->vignetting.radius) { + keyFile.set_integer ("Vignetting Correction", "Radius", vignetting.radius); + } + + if (!pedited || pedited->vignetting.strength) { + keyFile.set_integer ("Vignetting Correction", "Strength", vignetting.strength); + } + + if (!pedited || pedited->vignetting.centerX) { + keyFile.set_integer ("Vignetting Correction", "CenterX", vignetting.centerX); + } + + if (!pedited || pedited->vignetting.centerY) { + keyFile.set_integer ("Vignetting Correction", "CenterY", vignetting.centerY); + } + + + if (!pedited || pedited->resize.enabled) { + keyFile.set_boolean ("Resize", "Enabled", resize.enabled); + } // save resizing settings - if (!pedited || pedited->resize.enabled) { - keyFile.set_boolean ("Resize", "Enabled", resize.enabled); - } + if (!pedited || pedited->resize.scale) { + keyFile.set_double ("Resize", "Scale", resize.scale); + } - if (!pedited || pedited->resize.scale) { - keyFile.set_double ("Resize", "Scale", resize.scale); - } + if (!pedited || pedited->resize.appliesTo) { + keyFile.set_string ("Resize", "AppliesTo", resize.appliesTo); + } - if (!pedited || pedited->resize.appliesTo) { - keyFile.set_string ("Resize", "AppliesTo", resize.appliesTo); - } + if (!pedited || pedited->resize.method) { + keyFile.set_string ("Resize", "Method", resize.method); + } - if (!pedited || pedited->resize.method) { - keyFile.set_string ("Resize", "Method", resize.method); - } + if (!pedited || pedited->resize.dataspec) { + keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec); + } - if (!pedited || pedited->resize.dataspec) { - keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec); - } + if (!pedited || pedited->resize.width) { + keyFile.set_integer ("Resize", "Width", resize.width); + } - if (!pedited || pedited->resize.width) { - keyFile.set_integer ("Resize", "Width", resize.width); - } + if (!pedited || pedited->resize.height) { + keyFile.set_integer ("Resize", "Height", resize.height); + } - if (!pedited || pedited->resize.height) { - keyFile.set_integer ("Resize", "Height", resize.height); - } + if (!pedited || pedited->prsharpening.enabled) { + keyFile.set_boolean ("PostResizeSharpening", "Enabled", prsharpening.enabled); + } // save spot removal settings if (!pedited || pedited->spot.enabled) { @@ -2548,866 +2577,862 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_double_list("Spot removal", "Entries", entries); } - if (!pedited || pedited->prsharpening.enabled) { - keyFile.set_boolean ("PostResizeSharpening", "Enabled", prsharpening.enabled); - } - - if (!pedited || pedited->prsharpening.method) { - keyFile.set_string ("PostResizeSharpening", "Method", prsharpening.method); - } - - if (!pedited || pedited->prsharpening.radius) { - keyFile.set_double ("PostResizeSharpening", "Radius", prsharpening.radius); - } - - if (!pedited || pedited->prsharpening.amount) { - keyFile.set_integer ("PostResizeSharpening", "Amount", prsharpening.amount); - } - - if (!pedited || pedited->prsharpening.threshold) { - Glib::ArrayHandle thresh (prsharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("PostResizeSharpening", "Threshold", thresh); - } - - if (!pedited || pedited->prsharpening.edgesonly) { - keyFile.set_boolean ("PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly); - } - - if (!pedited || pedited->prsharpening.edges_radius) { - keyFile.set_double ("PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius); - } - - if (!pedited || pedited->prsharpening.edges_tolerance) { - keyFile.set_integer ("PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance); - } - - if (!pedited || pedited->prsharpening.halocontrol) { - keyFile.set_boolean ("PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol); - } - - if (!pedited || pedited->prsharpening.halocontrol_amount) { - keyFile.set_integer ("PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount); - } - - if (!pedited || pedited->prsharpening.deconvradius) { - keyFile.set_double ("PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius); - } - - if (!pedited || pedited->prsharpening.deconvamount) { - keyFile.set_integer ("PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount); - } - - if (!pedited || pedited->prsharpening.deconvdamping) { - keyFile.set_integer ("PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping); - } - - if (!pedited || pedited->prsharpening.deconviter) { - keyFile.set_integer ("PostResizeSharpening", "DeconvIterations", prsharpening.deconviter); - } - - - // save color management settings - if (!pedited || pedited->icm.input) { - keyFile.set_string ("Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.input)); - } - - if (!pedited || pedited->icm.toneCurve) { - keyFile.set_boolean ("Color Management", "ToneCurve", icm.toneCurve); - } - - if (!pedited || pedited->icm.applyLookTable) { - keyFile.set_boolean ("Color Management", "ApplyLookTable", icm.applyLookTable); - } - - if (!pedited || pedited->icm.applyBaselineExposureOffset) { - keyFile.set_boolean ("Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset); - } - - if (!pedited || pedited->icm.applyHueSatMap) { - keyFile.set_boolean ("Color Management", "ApplyHueSatMap", icm.applyHueSatMap); - } - - if (!pedited || pedited->icm.blendCMSMatrix) { - keyFile.set_boolean ("Color Management", "BlendCMSMatrix", icm.blendCMSMatrix); - } - - if (!pedited || pedited->icm.dcpIlluminant) { - keyFile.set_integer ("Color Management", "DCPIlluminant", icm.dcpIlluminant); - } - - if (!pedited || pedited->icm.working) { - keyFile.set_string ("Color Management", "WorkingProfile", icm.working); - } - - if (!pedited || pedited->icm.output) { - keyFile.set_string ("Color Management", "OutputProfile", icm.output); - } - - if (!pedited || pedited->icm.outputIntent) { - Glib::ustring intent; - - switch (icm.outputIntent) { - default: - case RI_PERCEPTUAL: - intent = "Perceptual"; - break; - - case RI_RELATIVE: - intent = "Relative"; - break; - - case RI_SATURATION: - intent = "Saturation"; - break; - - case RI_ABSOLUTE: - intent = "Absolute"; - break; + if (!pedited || pedited->prsharpening.method) { + keyFile.set_string ("PostResizeSharpening", "Method", prsharpening.method); } - keyFile.set_string ("Color Management", "OutputProfileIntent", intent); - } - - if (!pedited || pedited->icm.gamma) { - keyFile.set_string ("Color Management", "Gammafree", icm.gamma); - } - - if (!pedited || pedited->icm.freegamma) { - keyFile.set_boolean ("Color Management", "Freegamma", icm.freegamma); - } - - if (!pedited || pedited->icm.gampos) { - keyFile.set_double ("Color Management", "GammaValue", icm.gampos); - } - - if (!pedited || pedited->icm.slpos) { - keyFile.set_double ("Color Management", "GammaSlope", icm.slpos); - } - - - - // save wavelet parameters - if (!pedited || pedited->wavelet.enabled) { - keyFile.set_boolean ("Wavelet", "Enabled", wavelet.enabled); - } - - if (!pedited || pedited->wavelet.strength) { - keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); - } - - if (!pedited || pedited->wavelet.balance) { - keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); - } - - if (!pedited || pedited->wavelet.iter) { - keyFile.set_integer ("Wavelet", "Iter", wavelet.iter); - } - - if (!pedited || pedited->wavelet.thres) { - keyFile.set_integer ("Wavelet", "MaxLev", wavelet.thres); - } - - if (!pedited || pedited->wavelet.Tilesmethod) { - keyFile.set_string ("Wavelet", "TilesMethod", wavelet.Tilesmethod); - } - - if (!pedited || pedited->wavelet.daubcoeffmethod) { - keyFile.set_string ("Wavelet", "DaubMethod", wavelet.daubcoeffmethod); - } - - if (!pedited || pedited->wavelet.CLmethod) { - keyFile.set_string ("Wavelet", "ChoiceLevMethod", wavelet.CLmethod); - } - - if (!pedited || pedited->wavelet.Backmethod) { - keyFile.set_string ("Wavelet", "BackMethod", wavelet.Backmethod); - } - - if (!pedited || pedited->wavelet.Lmethod) { - keyFile.set_string ("Wavelet", "LevMethod", wavelet.Lmethod); - } - - if (!pedited || pedited->wavelet.Dirmethod) { - keyFile.set_string ("Wavelet", "DirMethod", wavelet.Dirmethod); - } - - if (!pedited || pedited->wavelet.greenhigh) { - keyFile.set_integer ("Wavelet", "CBgreenhigh", wavelet.greenhigh); - } - - if (!pedited || pedited->wavelet.greenmed) { - keyFile.set_integer ("Wavelet", "CBgreenmed", wavelet.greenmed); - } - - if (!pedited || pedited->wavelet.greenlow) { - keyFile.set_integer ("Wavelet", "CBgreenlow", wavelet.greenlow); - } - - if (!pedited || pedited->wavelet.bluehigh) { - keyFile.set_integer ("Wavelet", "CBbluehigh", wavelet.bluehigh); - } - - if (!pedited || pedited->wavelet.bluemed) { - keyFile.set_integer ("Wavelet", "CBbluemed", wavelet.bluemed); - } - - if (!pedited || pedited->wavelet.bluelow) { - keyFile.set_integer ("Wavelet", "CBbluelow", wavelet.bluelow); - } - - if (!pedited || pedited->wavelet.expcontrast) { - keyFile.set_boolean ("Wavelet", "Expcontrast", wavelet.expcontrast); - } - - if (!pedited || pedited->wavelet.expchroma) { - keyFile.set_boolean ("Wavelet", "Expchroma", wavelet.expchroma); - } - - if (!pedited || pedited->wavelet.expedge) { - keyFile.set_boolean ("Wavelet", "Expedge", wavelet.expedge); - } - - if (!pedited || pedited->wavelet.expresid) { - keyFile.set_boolean ("Wavelet", "Expresid", wavelet.expresid); - } - - if (!pedited || pedited->wavelet.expfinal) { - keyFile.set_boolean ("Wavelet", "Expfinal", wavelet.expfinal); - } - - if (!pedited || pedited->wavelet.exptoning) { - keyFile.set_boolean ("Wavelet", "Exptoning", wavelet.exptoning); - } - - if (!pedited || pedited->wavelet.expnoise) { - keyFile.set_boolean ("Wavelet", "Expnoise", wavelet.expnoise); - } - - for(int i = 0; i < 9; i++) { - std::stringstream ss; - ss << "Contrast" << (i + 1); - - if (!pedited || pedited->wavelet.c[i]) { - keyFile.set_integer("Wavelet", ss.str(), wavelet.c[i]); + if (!pedited || pedited->prsharpening.radius) { + keyFile.set_double ("PostResizeSharpening", "Radius", prsharpening.radius); } - } - for(int i = 0; i < 9; i++) { - std::stringstream ss; - ss << "Chroma" << (i + 1); - - if (!pedited || pedited->wavelet.ch[i]) { - keyFile.set_integer("Wavelet", ss.str(), wavelet.ch[i]); + if (!pedited || pedited->prsharpening.amount) { + keyFile.set_integer ("PostResizeSharpening", "Amount", prsharpening.amount); } - } - if (!pedited || pedited->wavelet.sup) { - keyFile.set_integer ("Wavelet", "ContExtra", wavelet.sup); - } + if (!pedited || pedited->prsharpening.threshold) { + Glib::ArrayHandle thresh (prsharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("PostResizeSharpening", "Threshold", thresh); + } - if (!pedited || pedited->wavelet.HSmethod) { - keyFile.set_string ("Wavelet", "HSMethod", wavelet.HSmethod); - } + if (!pedited || pedited->prsharpening.edgesonly) { + keyFile.set_boolean ("PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly); + } - if (!pedited || pedited->wavelet.hllev) { - Glib::ArrayHandle thresh (wavelet.hllev.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "HLRange", thresh); - } + if (!pedited || pedited->prsharpening.edges_radius) { + keyFile.set_double ("PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius); + } - if (!pedited || pedited->wavelet.bllev) { - Glib::ArrayHandle thresh (wavelet.bllev.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "SHRange", thresh); - } + if (!pedited || pedited->prsharpening.edges_tolerance) { + keyFile.set_integer ("PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance); + } - if (!pedited || pedited->wavelet.edgcont) { - Glib::ArrayHandle thresh (wavelet.edgcont.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "Edgcont", thresh); - } + if (!pedited || pedited->prsharpening.halocontrol) { + keyFile.set_boolean ("PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol); + } - if (!pedited || pedited->wavelet.level0noise) { - Glib::ArrayHandle thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_double_list("Wavelet", "Level0noise", thresh); - } + if (!pedited || pedited->prsharpening.halocontrol_amount) { + keyFile.set_integer ("PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount); + } - if (!pedited || pedited->wavelet.level1noise) { - Glib::ArrayHandle thresh (wavelet.level1noise.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_double_list("Wavelet", "Level1noise", thresh); - } + if (!pedited || pedited->prsharpening.deconvradius) { + keyFile.set_double ("PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius); + } - if (!pedited || pedited->wavelet.level2noise) { - Glib::ArrayHandle thresh (wavelet.level2noise.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_double_list("Wavelet", "Level2noise", thresh); - } + if (!pedited || pedited->prsharpening.deconvamount) { + keyFile.set_integer ("PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount); + } - if (!pedited || pedited->wavelet.level3noise) { - Glib::ArrayHandle thresh (wavelet.level3noise.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_double_list("Wavelet", "Level3noise", thresh); - } + if (!pedited || pedited->prsharpening.deconvdamping) { + keyFile.set_integer ("PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping); + } + + if (!pedited || pedited->prsharpening.deconviter) { + keyFile.set_integer ("PostResizeSharpening", "DeconvIterations", prsharpening.deconviter); + } - if (!pedited || pedited->wavelet.threshold) { - keyFile.set_integer ("Wavelet", "ThresholdHighlight", wavelet.threshold); - } + // save color management settings + if (!pedited || pedited->icm.input) { + keyFile.set_string ("Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.input)); + } - if (!pedited || pedited->wavelet.threshold2) { - keyFile.set_integer ("Wavelet", "ThresholdShadow", wavelet.threshold2); - } + if (!pedited || pedited->icm.toneCurve) { + keyFile.set_boolean ("Color Management", "ToneCurve", icm.toneCurve); + } - if (!pedited || pedited->wavelet.edgedetect) { - keyFile.set_integer ("Wavelet", "Edgedetect", wavelet.edgedetect); - } + if (!pedited || pedited->icm.applyLookTable) { + keyFile.set_boolean ("Color Management", "ApplyLookTable", icm.applyLookTable); + } - if (!pedited || pedited->wavelet.edgedetectthr) { - keyFile.set_integer ("Wavelet", "Edgedetectthr", wavelet.edgedetectthr); - } + if (!pedited || pedited->icm.applyBaselineExposureOffset) { + keyFile.set_boolean ("Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset); + } - if (!pedited || pedited->wavelet.edgedetectthr2) { - keyFile.set_integer ("Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2); - } + if (!pedited || pedited->icm.applyHueSatMap) { + keyFile.set_boolean ("Color Management", "ApplyHueSatMap", icm.applyHueSatMap); + } - if (!pedited || pedited->wavelet.edgesensi) { - keyFile.set_integer ("Wavelet", "Edgesensi", wavelet.edgesensi); - } + if (!pedited || pedited->icm.blendCMSMatrix) { + keyFile.set_boolean ("Color Management", "BlendCMSMatrix", icm.blendCMSMatrix); + } - if (!pedited || pedited->wavelet.edgeampli) { - keyFile.set_integer ("Wavelet", "Edgeampli", wavelet.edgeampli); - } + if (!pedited || pedited->icm.dcpIlluminant) { + keyFile.set_integer ("Color Management", "DCPIlluminant", icm.dcpIlluminant); + } - if (!pedited || pedited->wavelet.chroma) { - keyFile.set_integer ("Wavelet", "ThresholdChroma", wavelet.chroma); - } + if (!pedited || pedited->icm.working) { + keyFile.set_string ("Color Management", "WorkingProfile", icm.working); + } - if (!pedited || pedited->wavelet.CHmethod) { - keyFile.set_string ("Wavelet", "CHromaMethod", wavelet.CHmethod); - } + if (!pedited || pedited->icm.output) { + keyFile.set_string ("Color Management", "OutputProfile", icm.output); + } - if (!pedited || pedited->wavelet.Medgreinf) { - keyFile.set_string ("Wavelet", "Medgreinf", wavelet.Medgreinf); - } + if (!pedited || pedited->icm.outputIntent) { + Glib::ustring intent; - if (!pedited || pedited->wavelet.CHSLmethod) { - keyFile.set_string ("Wavelet", "CHSLromaMethod", wavelet.CHSLmethod); - } + switch (icm.outputIntent) { + default: + case RI_PERCEPTUAL: + intent = "Perceptual"; + break; - if (!pedited || pedited->wavelet.EDmethod) { - keyFile.set_string ("Wavelet", "EDMethod", wavelet.EDmethod); - } + case RI_RELATIVE: + intent = "Relative"; + break; - if (!pedited || pedited->wavelet.NPmethod) { - keyFile.set_string ("Wavelet", "NPMethod", wavelet.NPmethod); - } + case RI_SATURATION: + intent = "Saturation"; + break; - if (!pedited || pedited->wavelet.BAmethod) { - keyFile.set_string ("Wavelet", "BAMethod", wavelet.BAmethod); - } + case RI_ABSOLUTE: + intent = "Absolute"; + break; + } - if (!pedited || pedited->wavelet.TMmethod) { - keyFile.set_string ("Wavelet", "TMMethod", wavelet.TMmethod); - } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); + } - if (!pedited || pedited->wavelet.chro) { - keyFile.set_integer ("Wavelet", "ChromaLink", wavelet.chro); - } + if (!pedited || pedited->icm.gamma) { + keyFile.set_string ("Color Management", "Gammafree", icm.gamma); + } - if (!pedited || pedited->wavelet.ccwcurve) { - Glib::ArrayHandle ccwcurve = wavelet.ccwcurve; - keyFile.set_double_list("Wavelet", "ContrastCurve", ccwcurve); - } + if (!pedited || pedited->icm.freegamma) { + keyFile.set_boolean ("Color Management", "Freegamma", icm.freegamma); + } - if (!pedited || pedited->wavelet.pastlev) { - Glib::ArrayHandle thresh (wavelet.pastlev.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "Pastlev", thresh); - } + if (!pedited || pedited->icm.gampos) { + keyFile.set_double ("Color Management", "GammaValue", icm.gampos); + } - if (!pedited || pedited->wavelet.satlev) { - Glib::ArrayHandle thresh (wavelet.satlev.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "Satlev", thresh); - } - - if (!pedited || pedited->wavelet.opacityCurveRG) { - Glib::ArrayHandle curve = wavelet.opacityCurveRG; - keyFile.set_double_list("Wavelet", "OpacityCurveRG", curve); - } - - if (!pedited || pedited->wavelet.opacityCurveBY) { - Glib::ArrayHandle curve = wavelet.opacityCurveBY; - keyFile.set_double_list("Wavelet", "OpacityCurveBY", curve); - } - - if (!pedited || pedited->wavelet.opacityCurveW) { - Glib::ArrayHandle curve = wavelet.opacityCurveW; - keyFile.set_double_list("Wavelet", "OpacityCurveW", curve); - } - - if (!pedited || pedited->wavelet.opacityCurveWL) { - Glib::ArrayHandle curve = wavelet.opacityCurveWL; - keyFile.set_double_list("Wavelet", "OpacityCurveWL", curve); - } - - if (!pedited || pedited->wavelet.hhcurve) { - Glib::ArrayHandle curve = wavelet.hhcurve; - keyFile.set_double_list("Wavelet", "HHcurve", curve); - } - - if (!pedited || pedited->wavelet.Chcurve) { - Glib::ArrayHandle curve = wavelet.Chcurve; - keyFile.set_double_list("Wavelet", "CHcurve", curve); - } - - if (!pedited || pedited->wavelet.wavclCurve) { - Glib::ArrayHandle wavclCurve = wavelet.wavclCurve; - keyFile.set_double_list("Wavelet", "WavclCurve", wavclCurve); - } + if (!pedited || pedited->icm.slpos) { + keyFile.set_double ("Color Management", "GammaSlope", icm.slpos); + } - if (!pedited || pedited->wavelet.median) { - keyFile.set_boolean ("Wavelet", "Median", wavelet.median); - } - if (!pedited || pedited->wavelet.medianlev) { - keyFile.set_boolean ("Wavelet", "Medianlev", wavelet.medianlev); - } + // save wavelet parameters + if (!pedited || pedited->wavelet.enabled) { + keyFile.set_boolean ("Wavelet", "Enabled", wavelet.enabled); + } - if (!pedited || pedited->wavelet.linkedg) { - keyFile.set_boolean ("Wavelet", "Linkedg", wavelet.linkedg); - } + if (!pedited || pedited->wavelet.strength) { + keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + } - if (!pedited || pedited->wavelet.cbenab) { - keyFile.set_boolean ("Wavelet", "CBenab", wavelet.cbenab); - } + if (!pedited || pedited->wavelet.balance) { + keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); + } - if (!pedited || pedited->wavelet.lipst) { - keyFile.set_boolean ("Wavelet", "Lipst", wavelet.lipst); - } + if (!pedited || pedited->wavelet.iter) { + keyFile.set_integer ("Wavelet", "Iter", wavelet.iter); + } + + if (!pedited || pedited->wavelet.thres) { + keyFile.set_integer ("Wavelet", "MaxLev", wavelet.thres); + } + + if (!pedited || pedited->wavelet.Tilesmethod) { + keyFile.set_string ("Wavelet", "TilesMethod", wavelet.Tilesmethod); + } + + if (!pedited || pedited->wavelet.daubcoeffmethod) { + keyFile.set_string ("Wavelet", "DaubMethod", wavelet.daubcoeffmethod); + } + + if (!pedited || pedited->wavelet.CLmethod) { + keyFile.set_string ("Wavelet", "ChoiceLevMethod", wavelet.CLmethod); + } + + if (!pedited || pedited->wavelet.Backmethod) { + keyFile.set_string ("Wavelet", "BackMethod", wavelet.Backmethod); + } + + if (!pedited || pedited->wavelet.Lmethod) { + keyFile.set_string ("Wavelet", "LevMethod", wavelet.Lmethod); + } + + if (!pedited || pedited->wavelet.Dirmethod) { + keyFile.set_string ("Wavelet", "DirMethod", wavelet.Dirmethod); + } + + if (!pedited || pedited->wavelet.greenhigh) { + keyFile.set_integer ("Wavelet", "CBgreenhigh", wavelet.greenhigh); + } + + if (!pedited || pedited->wavelet.greenmed) { + keyFile.set_integer ("Wavelet", "CBgreenmed", wavelet.greenmed); + } + + if (!pedited || pedited->wavelet.greenlow) { + keyFile.set_integer ("Wavelet", "CBgreenlow", wavelet.greenlow); + } + + if (!pedited || pedited->wavelet.bluehigh) { + keyFile.set_integer ("Wavelet", "CBbluehigh", wavelet.bluehigh); + } + + if (!pedited || pedited->wavelet.bluemed) { + keyFile.set_integer ("Wavelet", "CBbluemed", wavelet.bluemed); + } + + if (!pedited || pedited->wavelet.bluelow) { + keyFile.set_integer ("Wavelet", "CBbluelow", wavelet.bluelow); + } + + if (!pedited || pedited->wavelet.expcontrast) { + keyFile.set_boolean ("Wavelet", "Expcontrast", wavelet.expcontrast); + } + + if (!pedited || pedited->wavelet.expchroma) { + keyFile.set_boolean ("Wavelet", "Expchroma", wavelet.expchroma); + } + + if (!pedited || pedited->wavelet.expedge) { + keyFile.set_boolean ("Wavelet", "Expedge", wavelet.expedge); + } + + if (!pedited || pedited->wavelet.expresid) { + keyFile.set_boolean ("Wavelet", "Expresid", wavelet.expresid); + } + + if (!pedited || pedited->wavelet.expfinal) { + keyFile.set_boolean ("Wavelet", "Expfinal", wavelet.expfinal); + } + + if (!pedited || pedited->wavelet.exptoning) { + keyFile.set_boolean ("Wavelet", "Exptoning", wavelet.exptoning); + } + + if (!pedited || pedited->wavelet.expnoise) { + keyFile.set_boolean ("Wavelet", "Expnoise", wavelet.expnoise); + } + + for(int i = 0; i < 9; i++) { + std::stringstream ss; + ss << "Contrast" << (i + 1); + + if (!pedited || pedited->wavelet.c[i]) { + keyFile.set_integer("Wavelet", ss.str(), wavelet.c[i]); + } + } + + for(int i = 0; i < 9; i++) { + std::stringstream ss; + ss << "Chroma" << (i + 1); + + if (!pedited || pedited->wavelet.ch[i]) { + keyFile.set_integer("Wavelet", ss.str(), wavelet.ch[i]); + } + } + + if (!pedited || pedited->wavelet.sup) { + keyFile.set_integer ("Wavelet", "ContExtra", wavelet.sup); + } + + if (!pedited || pedited->wavelet.HSmethod) { + keyFile.set_string ("Wavelet", "HSMethod", wavelet.HSmethod); + } + + if (!pedited || pedited->wavelet.hllev) { + Glib::ArrayHandle thresh (wavelet.hllev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "HLRange", thresh); + } + + if (!pedited || pedited->wavelet.bllev) { + Glib::ArrayHandle thresh (wavelet.bllev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "SHRange", thresh); + } + + if (!pedited || pedited->wavelet.edgcont) { + Glib::ArrayHandle thresh (wavelet.edgcont.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Edgcont", thresh); + } + + if (!pedited || pedited->wavelet.level0noise) { + Glib::ArrayHandle thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level0noise", thresh); + } + + if (!pedited || pedited->wavelet.level1noise) { + Glib::ArrayHandle thresh (wavelet.level1noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level1noise", thresh); + } + + if (!pedited || pedited->wavelet.level2noise) { + Glib::ArrayHandle thresh (wavelet.level2noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level2noise", thresh); + } + + if (!pedited || pedited->wavelet.level3noise) { + Glib::ArrayHandle thresh (wavelet.level3noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level3noise", thresh); + } + + + if (!pedited || pedited->wavelet.threshold) { + keyFile.set_integer ("Wavelet", "ThresholdHighlight", wavelet.threshold); + } + + if (!pedited || pedited->wavelet.threshold2) { + keyFile.set_integer ("Wavelet", "ThresholdShadow", wavelet.threshold2); + } + + if (!pedited || pedited->wavelet.edgedetect) { + keyFile.set_integer ("Wavelet", "Edgedetect", wavelet.edgedetect); + } + + if (!pedited || pedited->wavelet.edgedetectthr) { + keyFile.set_integer ("Wavelet", "Edgedetectthr", wavelet.edgedetectthr); + } + + if (!pedited || pedited->wavelet.edgedetectthr2) { + keyFile.set_integer ("Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2); + } + + if (!pedited || pedited->wavelet.edgesensi) { + keyFile.set_integer ("Wavelet", "Edgesensi", wavelet.edgesensi); + } + + if (!pedited || pedited->wavelet.edgeampli) { + keyFile.set_integer ("Wavelet", "Edgeampli", wavelet.edgeampli); + } + + if (!pedited || pedited->wavelet.chroma) { + keyFile.set_integer ("Wavelet", "ThresholdChroma", wavelet.chroma); + } + + if (!pedited || pedited->wavelet.CHmethod) { + keyFile.set_string ("Wavelet", "CHromaMethod", wavelet.CHmethod); + } + + if (!pedited || pedited->wavelet.Medgreinf) { + keyFile.set_string ("Wavelet", "Medgreinf", wavelet.Medgreinf); + } + + if (!pedited || pedited->wavelet.CHSLmethod) { + keyFile.set_string ("Wavelet", "CHSLromaMethod", wavelet.CHSLmethod); + } + + if (!pedited || pedited->wavelet.EDmethod) { + keyFile.set_string ("Wavelet", "EDMethod", wavelet.EDmethod); + } + + if (!pedited || pedited->wavelet.NPmethod) { + keyFile.set_string ("Wavelet", "NPMethod", wavelet.NPmethod); + } + + if (!pedited || pedited->wavelet.BAmethod) { + keyFile.set_string ("Wavelet", "BAMethod", wavelet.BAmethod); + } + + if (!pedited || pedited->wavelet.TMmethod) { + keyFile.set_string ("Wavelet", "TMMethod", wavelet.TMmethod); + } + + if (!pedited || pedited->wavelet.chro) { + keyFile.set_integer ("Wavelet", "ChromaLink", wavelet.chro); + } + + if (!pedited || pedited->wavelet.ccwcurve) { + Glib::ArrayHandle ccwcurve = wavelet.ccwcurve; + keyFile.set_double_list("Wavelet", "ContrastCurve", ccwcurve); + } + + if (!pedited || pedited->wavelet.pastlev) { + Glib::ArrayHandle thresh (wavelet.pastlev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Pastlev", thresh); + } + + if (!pedited || pedited->wavelet.satlev) { + Glib::ArrayHandle thresh (wavelet.satlev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Satlev", thresh); + } + + if (!pedited || pedited->wavelet.opacityCurveRG) { + Glib::ArrayHandle curve = wavelet.opacityCurveRG; + keyFile.set_double_list("Wavelet", "OpacityCurveRG", curve); + } + + if (!pedited || pedited->wavelet.opacityCurveBY) { + Glib::ArrayHandle curve = wavelet.opacityCurveBY; + keyFile.set_double_list("Wavelet", "OpacityCurveBY", curve); + } + + if (!pedited || pedited->wavelet.opacityCurveW) { + Glib::ArrayHandle curve = wavelet.opacityCurveW; + keyFile.set_double_list("Wavelet", "OpacityCurveW", curve); + } + + if (!pedited || pedited->wavelet.opacityCurveWL) { + Glib::ArrayHandle curve = wavelet.opacityCurveWL; + keyFile.set_double_list("Wavelet", "OpacityCurveWL", curve); + } + + if (!pedited || pedited->wavelet.hhcurve) { + Glib::ArrayHandle curve = wavelet.hhcurve; + keyFile.set_double_list("Wavelet", "HHcurve", curve); + } + + if (!pedited || pedited->wavelet.Chcurve) { + Glib::ArrayHandle curve = wavelet.Chcurve; + keyFile.set_double_list("Wavelet", "CHcurve", curve); + } + + if (!pedited || pedited->wavelet.wavclCurve) { + Glib::ArrayHandle wavclCurve = wavelet.wavclCurve; + keyFile.set_double_list("Wavelet", "WavclCurve", wavclCurve); + } + + + if (!pedited || pedited->wavelet.median) { + keyFile.set_boolean ("Wavelet", "Median", wavelet.median); + } + + if (!pedited || pedited->wavelet.medianlev) { + keyFile.set_boolean ("Wavelet", "Medianlev", wavelet.medianlev); + } + + if (!pedited || pedited->wavelet.linkedg) { + keyFile.set_boolean ("Wavelet", "Linkedg", wavelet.linkedg); + } + + if (!pedited || pedited->wavelet.cbenab) { + keyFile.set_boolean ("Wavelet", "CBenab", wavelet.cbenab); + } + + if (!pedited || pedited->wavelet.lipst) { + keyFile.set_boolean ("Wavelet", "Lipst", wavelet.lipst); + } // if (!pedited || pedited->wavelet.edgreinf) keyFile.set_boolean ("Wavelet", "Edgreinf", wavelet.edgreinf); - if (!pedited || pedited->wavelet.skinprotect) { - keyFile.set_double ("Wavelet", "Skinprotect", wavelet.skinprotect); - } + if (!pedited || pedited->wavelet.skinprotect) { + keyFile.set_double ("Wavelet", "Skinprotect", wavelet.skinprotect); + } - if (!pedited || pedited->wavelet.hueskin) { - Glib::ArrayHandle thresh (wavelet.hueskin.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "Hueskin", thresh); - } + if (!pedited || pedited->wavelet.hueskin) { + Glib::ArrayHandle thresh (wavelet.hueskin.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Hueskin", thresh); + } - if (!pedited || pedited->wavelet.edgrad) { - keyFile.set_integer ("Wavelet", "Edgrad", wavelet.edgrad); - } + if (!pedited || pedited->wavelet.edgrad) { + keyFile.set_integer ("Wavelet", "Edgrad", wavelet.edgrad); + } - if (!pedited || pedited->wavelet.edgval) { - keyFile.set_integer ("Wavelet", "Edgval", wavelet.edgval); - } + if (!pedited || pedited->wavelet.edgval) { + keyFile.set_integer ("Wavelet", "Edgval", wavelet.edgval); + } - if (!pedited || pedited->wavelet.edgthresh) { - keyFile.set_integer ("Wavelet", "ThrEdg", wavelet.edgthresh); - } + if (!pedited || pedited->wavelet.edgthresh) { + keyFile.set_integer ("Wavelet", "ThrEdg", wavelet.edgthresh); + } // if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); - // if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); + // if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); - if (!pedited || pedited->wavelet.avoid) { - keyFile.set_boolean ("Wavelet", "AvoidColorShift", wavelet.avoid); - } - - if (!pedited || pedited->wavelet.tmr) { - keyFile.set_boolean ("Wavelet", "TMr", wavelet.tmr); - } - - if (!pedited || pedited->wavelet.rescon) { - keyFile.set_integer ("Wavelet", "ResidualcontShadow", wavelet.rescon); - } - - if (!pedited || pedited->wavelet.resconH) { - keyFile.set_integer ("Wavelet", "ResidualcontHighlight", wavelet.resconH); - } - - if (!pedited || pedited->wavelet.thr) { - keyFile.set_integer ("Wavelet", "ThresholdResidShadow", wavelet.thr); - } - - if (!pedited || pedited->wavelet.thrH) { - keyFile.set_integer ("Wavelet", "ThresholdResidHighLight", wavelet.thrH); - } - - if (!pedited || pedited->wavelet.reschro) { - keyFile.set_integer ("Wavelet", "Residualchroma", wavelet.reschro); - } - - if (!pedited || pedited->wavelet.tmrs) { - keyFile.set_double ("Wavelet", "ResidualTM", wavelet.tmrs); - } - - if (!pedited || pedited->wavelet.gamma) { - keyFile.set_double ("Wavelet", "Residualgamma", wavelet.gamma); - } - - if (!pedited || pedited->wavelet.sky) { - keyFile.set_double ("Wavelet", "HueRangeResidual", wavelet.sky); - } - - if (!pedited || pedited->wavelet.hueskin2) { - Glib::ArrayHandle thresh (wavelet.hueskin2.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Wavelet", "HueRange", thresh); - } - - if (!pedited || pedited->wavelet.contrast) { - keyFile.set_integer ("Wavelet", "Contrast", wavelet.contrast); - } - - - // save directional pyramid wavelet parameters - if (!pedited || pedited->dirpyrequalizer.enabled) { - keyFile.set_boolean ("Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled); - } - - if (!pedited || pedited->dirpyrequalizer.gamutlab) { - keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); - } - - if (!pedited || pedited->dirpyrequalizer.cbdlMethod) { - keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod); - } - - for(int i = 0; i < 6; i++) { - std::stringstream ss; - ss << "Mult" << i; - - if (!pedited || pedited->dirpyrequalizer.mult[i]) { - keyFile.set_double("Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i]); + if (!pedited || pedited->wavelet.avoid) { + keyFile.set_boolean ("Wavelet", "AvoidColorShift", wavelet.avoid); } - } - if (!pedited || pedited->dirpyrequalizer.threshold) { - keyFile.set_double ("Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold); - } - - if (!pedited || pedited->dirpyrequalizer.skinprotect) { - keyFile.set_double ("Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect); - } - - // if (!pedited || pedited->dirpyrequalizer.algo) keyFile.set_string ("Directional Pyramid Equalizer", "Algorithm", dirpyrequalizer.algo); - if (!pedited || pedited->dirpyrequalizer.hueskin) { - Glib::ArrayHandle thresh (dirpyrequalizer.hueskin.value, 4, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("Directional Pyramid Equalizer", "Hueskin", thresh); - } - - // save hsv wavelet parameters - if (!pedited || pedited->hsvequalizer.hcurve) { - Glib::ArrayHandle hcurve = hsvequalizer.hcurve; - keyFile.set_double_list("HSV Equalizer", "HCurve", hcurve); - } - - if (!pedited || pedited->hsvequalizer.scurve) { - Glib::ArrayHandle scurve = hsvequalizer.scurve; - keyFile.set_double_list("HSV Equalizer", "SCurve", scurve); - } - - if (!pedited || pedited->hsvequalizer.vcurve) { - Glib::ArrayHandle vcurve = hsvequalizer.vcurve; - keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); - } - - //save film simulation parameters - if ( !pedited || pedited->filmSimulation.enabled ) { - keyFile.set_boolean( "Film Simulation", "Enabled", filmSimulation.enabled ); - } - - if ( !pedited || pedited->filmSimulation.clutFilename ) { - keyFile.set_string ( "Film Simulation", "ClutFilename", filmSimulation.clutFilename ); - } - - if ( !pedited || pedited->filmSimulation.strength ) { - keyFile.set_integer( "Film Simulation", "Strength", filmSimulation.strength ); - } - - - if (!pedited || pedited->rgbCurves.lumamode) { - keyFile.set_boolean ("RGB Curves", "LumaMode", rgbCurves.lumamode); - } - - if (!pedited || pedited->rgbCurves.rcurve) { - Glib::ArrayHandle RGBrcurve = rgbCurves.rcurve; - keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve); - } - - if (!pedited || pedited->rgbCurves.gcurve) { - Glib::ArrayHandle RGBgcurve = rgbCurves.gcurve; - keyFile.set_double_list("RGB Curves", "gCurve", RGBgcurve); - } - - if (!pedited || pedited->rgbCurves.bcurve) { - Glib::ArrayHandle RGBbcurve = rgbCurves.bcurve; - keyFile.set_double_list("RGB Curves", "bCurve", RGBbcurve); - } - - // save Color Toning - if (!pedited || pedited->colorToning.enabled) { - keyFile.set_boolean ("ColorToning", "Enabled", colorToning.enabled); - } - - if (!pedited || pedited->colorToning.method) { - keyFile.set_string ("ColorToning", "Method", colorToning.method); - } - - if (!pedited || pedited->colorToning.lumamode) { - keyFile.set_boolean ("ColorToning", "Lumamode", colorToning.lumamode); - } - - if (!pedited || pedited->colorToning.twocolor) { - keyFile.set_string ("ColorToning", "Twocolor", colorToning.twocolor); - } - - if (!pedited || pedited->colorToning.redlow) { - keyFile.set_double ("ColorToning", "Redlow", colorToning.redlow); - } - - if (!pedited || pedited->colorToning.greenlow) { - keyFile.set_double ("ColorToning", "Greenlow", colorToning.greenlow); - } - - if (!pedited || pedited->colorToning.bluelow) { - keyFile.set_double ("ColorToning", "Bluelow", colorToning.bluelow); - } - - if (!pedited || pedited->colorToning.satlow) { - keyFile.set_double ("ColorToning", "Satlow", colorToning.satlow); - } - - if (!pedited || pedited->colorToning.balance) { - keyFile.set_integer ("ColorToning", "Balance", colorToning.balance); - } - - if (!pedited || pedited->colorToning.sathigh) { - keyFile.set_double ("ColorToning", "Sathigh", colorToning.sathigh); - } - - if (!pedited || pedited->colorToning.redmed) { - keyFile.set_double ("ColorToning", "Redmed", colorToning.redmed); - } - - if (!pedited || pedited->colorToning.greenmed) { - keyFile.set_double ("ColorToning", "Greenmed", colorToning.greenmed); - } - - if (!pedited || pedited->colorToning.bluemed) { - keyFile.set_double ("ColorToning", "Bluemed", colorToning.bluemed); - } - - if (!pedited || pedited->colorToning.redhigh) { - keyFile.set_double ("ColorToning", "Redhigh", colorToning.redhigh); - } - - if (!pedited || pedited->colorToning.greenhigh) { - keyFile.set_double ("ColorToning", "Greenhigh", colorToning.greenhigh); - } - - if (!pedited || pedited->colorToning.bluehigh) { - keyFile.set_double ("ColorToning", "Bluehigh", colorToning.bluehigh); - } - - if (!pedited || pedited->colorToning.autosat) { - keyFile.set_boolean ("ColorToning", "Autosat", colorToning.autosat); - } - - if (!pedited || pedited->colorToning.opacityCurve) { - Glib::ArrayHandle curve = colorToning.opacityCurve; - keyFile.set_double_list("ColorToning", "OpacityCurve", curve); - } - - if (!pedited || pedited->colorToning.colorCurve) { - Glib::ArrayHandle curve = colorToning.colorCurve; - keyFile.set_double_list("ColorToning", "ColorCurve", curve); - } - - if (!pedited || pedited->colorToning.satprotectionthreshold) { - keyFile.set_integer ("ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold ); - } - - if (!pedited || pedited->colorToning.saturatedopacity) { - keyFile.set_integer ("ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity ); - } - - if (!pedited || pedited->colorToning.strength) { - keyFile.set_integer ("ColorToning", "Strength", colorToning.strength ); - } - - if (!pedited || pedited->colorToning.hlColSat) { - Glib::ArrayHandle thresh (colorToning.hlColSat.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("ColorToning", "HighlightsColorSaturation", thresh); - } - - if (!pedited || pedited->colorToning.shadowsColSat) { - Glib::ArrayHandle thresh (colorToning.shadowsColSat.value, 2, Glib::OWNERSHIP_NONE); - keyFile.set_integer_list("ColorToning", "ShadowsColorSaturation", thresh); - } - - if (!pedited || pedited->colorToning.clcurve) { - Glib::ArrayHandle clcurve = colorToning.clcurve; - keyFile.set_double_list("ColorToning", "ClCurve", clcurve); - } - - if (!pedited || pedited->colorToning.cl2curve) { - Glib::ArrayHandle cl2curve = colorToning.cl2curve; - keyFile.set_double_list("ColorToning", "Cl2Curve", cl2curve); - } - - // save raw parameters - if (!pedited || pedited->raw.darkFrame) { - keyFile.set_string ("RAW", "DarkFrame", relativePathIfInside(fname, fnameAbsolute, raw.dark_frame) ); - } - - if (!pedited || pedited->raw.dfAuto) { - keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); - } - - if (!pedited || pedited->raw.ff_file) { - keyFile.set_string ("RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file) ); - } - - if (!pedited || pedited->raw.ff_AutoSelect) { - keyFile.set_boolean ("RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect ); - } - - if (!pedited || pedited->raw.ff_BlurRadius) { - keyFile.set_integer ("RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius ); - } - - if (!pedited || pedited->raw.ff_BlurType) { - keyFile.set_string ("RAW", "FlatFieldBlurType", raw.ff_BlurType ); - } - - if (!pedited || pedited->raw.ff_AutoClipControl) { - keyFile.set_boolean ("RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl ); - } - - if (!pedited || pedited->raw.ff_clipControl) { - keyFile.set_boolean ("RAW", "FlatFieldClipControl", raw.ff_clipControl ); - } - - if (!pedited || pedited->raw.caCorrection) { - keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); - } - - if (!pedited || pedited->raw.caAutoStrength) { - keyFile.set_double ("RAW", "CAAutoStrength", raw.caautostrength ); - } - - if (!pedited || pedited->raw.caRed) { - keyFile.set_double ("RAW", "CARed", raw.cared ); - } - - if (!pedited || pedited->raw.caBlue) { - keyFile.set_double ("RAW", "CABlue", raw.cablue ); - } - - if (!pedited || pedited->raw.hotPixelFilter) { - keyFile.set_boolean ("RAW", "HotPixelFilter", raw.hotPixelFilter ); - } - - if (!pedited || pedited->raw.deadPixelFilter) { - keyFile.set_boolean ("RAW", "DeadPixelFilter", raw.deadPixelFilter ); - } - - if (!pedited || pedited->raw.hotDeadPixelThresh) { - keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh ); - } - - if (!pedited || pedited->raw.bayersensor.method) { - keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method ); - } - - if (!pedited || pedited->raw.bayersensor.ccSteps) { - keyFile.set_integer ("RAW Bayer", "CcSteps", raw.bayersensor.ccSteps); - } - - if (!pedited || pedited->raw.bayersensor.exBlack0) { - keyFile.set_double ("RAW Bayer", "PreBlack0", raw.bayersensor.black0 ); - } - - if (!pedited || pedited->raw.bayersensor.exBlack1) { - keyFile.set_double ("RAW Bayer", "PreBlack1", raw.bayersensor.black1 ); - } - - if (!pedited || pedited->raw.bayersensor.exBlack2) { - keyFile.set_double ("RAW Bayer", "PreBlack2", raw.bayersensor.black2 ); - } - - if (!pedited || pedited->raw.bayersensor.exBlack3) { - keyFile.set_double ("RAW Bayer", "PreBlack3", raw.bayersensor.black3 ); - } - - if (!pedited || pedited->raw.bayersensor.exTwoGreen) { - keyFile.set_boolean ("RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen ); - } - - if (!pedited || pedited->raw.bayersensor.linenoise) { - keyFile.set_integer ("RAW Bayer", "LineDenoise", raw.bayersensor.linenoise); - } - - if (!pedited || pedited->raw.bayersensor.greenEq) { - keyFile.set_integer ("RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh); - } - - if (!pedited || pedited->raw.bayersensor.dcbIterations) { - keyFile.set_integer ("RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations ); - } - - if (!pedited || pedited->raw.bayersensor.dcbEnhance) { - keyFile.set_boolean ("RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance ); - } - - if (!pedited || pedited->raw.bayersensor.lmmseIterations) { - keyFile.set_integer ("RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations ); - } - - //if (!pedited || pedited->raw.bayersensor.allEnhance) keyFile.set_boolean ("RAW Bayer", "ALLEnhance", raw.bayersensor.all_enhance ); - - if (!pedited || pedited->raw.xtranssensor.method) { - keyFile.set_string ("RAW X-Trans", "Method", raw.xtranssensor.method ); - } - - if (!pedited || pedited->raw.xtranssensor.ccSteps) { - keyFile.set_integer ("RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps); - } - - if (!pedited || pedited->raw.xtranssensor.exBlackRed) { - keyFile.set_double ("RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred ); - } - - if (!pedited || pedited->raw.xtranssensor.exBlackGreen) { - keyFile.set_double ("RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen ); - } - - if (!pedited || pedited->raw.xtranssensor.exBlackBlue) { - keyFile.set_double ("RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue ); - } - - - // save raw exposition - if (!pedited || pedited->raw.exPos) { - keyFile.set_double ("RAW", "PreExposure", raw.expos ); - } - - if (!pedited || pedited->raw.exPreser) { - keyFile.set_double ("RAW", "PrePreserv", raw.preser ); - } - - // save exif change list - if (!pedited || pedited->exif) { - for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); i++) { - keyFile.set_string ("Exif", i->first, i->second); + if (!pedited || pedited->wavelet.tmr) { + keyFile.set_boolean ("Wavelet", "TMr", wavelet.tmr); } - } - // save iptc change list - if (!pedited || pedited->iptc) { - for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); i++) { - Glib::ArrayHandle values = i->second; - keyFile.set_string_list ("IPTC", i->first, values); + if (!pedited || pedited->wavelet.rescon) { + keyFile.set_integer ("Wavelet", "ResidualcontShadow", wavelet.rescon); } - } - sPParams = keyFile.to_data(); + if (!pedited || pedited->wavelet.resconH) { + keyFile.set_integer ("Wavelet", "ResidualcontHighlight", wavelet.resconH); + } + + if (!pedited || pedited->wavelet.thr) { + keyFile.set_integer ("Wavelet", "ThresholdResidShadow", wavelet.thr); + } + + if (!pedited || pedited->wavelet.thrH) { + keyFile.set_integer ("Wavelet", "ThresholdResidHighLight", wavelet.thrH); + } + + if (!pedited || pedited->wavelet.reschro) { + keyFile.set_integer ("Wavelet", "Residualchroma", wavelet.reschro); + } + + if (!pedited || pedited->wavelet.tmrs) { + keyFile.set_double ("Wavelet", "ResidualTM", wavelet.tmrs); + } + + if (!pedited || pedited->wavelet.gamma) { + keyFile.set_double ("Wavelet", "Residualgamma", wavelet.gamma); + } + + if (!pedited || pedited->wavelet.sky) { + keyFile.set_double ("Wavelet", "HueRangeResidual", wavelet.sky); + } + + if (!pedited || pedited->wavelet.hueskin2) { + Glib::ArrayHandle thresh (wavelet.hueskin2.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "HueRange", thresh); + } + + if (!pedited || pedited->wavelet.contrast) { + keyFile.set_integer ("Wavelet", "Contrast", wavelet.contrast); + } + + + // save directional pyramid wavelet parameters + if (!pedited || pedited->dirpyrequalizer.enabled) { + keyFile.set_boolean ("Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled); + } + + if (!pedited || pedited->dirpyrequalizer.gamutlab) { + keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); + } + + if (!pedited || pedited->dirpyrequalizer.cbdlMethod) { + keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod); + } + + for(int i = 0; i < 6; i++) { + std::stringstream ss; + ss << "Mult" << i; + + if (!pedited || pedited->dirpyrequalizer.mult[i]) { + keyFile.set_double("Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i]); + } + } + + if (!pedited || pedited->dirpyrequalizer.threshold) { + keyFile.set_double ("Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold); + } + + if (!pedited || pedited->dirpyrequalizer.skinprotect) { + keyFile.set_double ("Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect); + } + + // if (!pedited || pedited->dirpyrequalizer.algo) keyFile.set_string ("Directional Pyramid Equalizer", "Algorithm", dirpyrequalizer.algo); + if (!pedited || pedited->dirpyrequalizer.hueskin) { + Glib::ArrayHandle thresh (dirpyrequalizer.hueskin.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Directional Pyramid Equalizer", "Hueskin", thresh); + } + + // save hsv wavelet parameters + if (!pedited || pedited->hsvequalizer.hcurve) { + Glib::ArrayHandle hcurve = hsvequalizer.hcurve; + keyFile.set_double_list("HSV Equalizer", "HCurve", hcurve); + } + + if (!pedited || pedited->hsvequalizer.scurve) { + Glib::ArrayHandle scurve = hsvequalizer.scurve; + keyFile.set_double_list("HSV Equalizer", "SCurve", scurve); + } + + if (!pedited || pedited->hsvequalizer.vcurve) { + Glib::ArrayHandle vcurve = hsvequalizer.vcurve; + keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); + } + + //save film simulation parameters + if ( !pedited || pedited->filmSimulation.enabled ) { + keyFile.set_boolean( "Film Simulation", "Enabled", filmSimulation.enabled ); + } + + if ( !pedited || pedited->filmSimulation.clutFilename ) { + keyFile.set_string ( "Film Simulation", "ClutFilename", filmSimulation.clutFilename ); + } + + if ( !pedited || pedited->filmSimulation.strength ) { + keyFile.set_integer( "Film Simulation", "Strength", filmSimulation.strength ); + } + + + if (!pedited || pedited->rgbCurves.lumamode) { + keyFile.set_boolean ("RGB Curves", "LumaMode", rgbCurves.lumamode); + } + + if (!pedited || pedited->rgbCurves.rcurve) { + Glib::ArrayHandle RGBrcurve = rgbCurves.rcurve; + keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve); + } + + if (!pedited || pedited->rgbCurves.gcurve) { + Glib::ArrayHandle RGBgcurve = rgbCurves.gcurve; + keyFile.set_double_list("RGB Curves", "gCurve", RGBgcurve); + } + + if (!pedited || pedited->rgbCurves.bcurve) { + Glib::ArrayHandle RGBbcurve = rgbCurves.bcurve; + keyFile.set_double_list("RGB Curves", "bCurve", RGBbcurve); + } + + // save Color Toning + if (!pedited || pedited->colorToning.enabled) { + keyFile.set_boolean ("ColorToning", "Enabled", colorToning.enabled); + } + + if (!pedited || pedited->colorToning.method) { + keyFile.set_string ("ColorToning", "Method", colorToning.method); + } + + if (!pedited || pedited->colorToning.lumamode) { + keyFile.set_boolean ("ColorToning", "Lumamode", colorToning.lumamode); + } + + if (!pedited || pedited->colorToning.twocolor) { + keyFile.set_string ("ColorToning", "Twocolor", colorToning.twocolor); + } + + if (!pedited || pedited->colorToning.redlow) { + keyFile.set_double ("ColorToning", "Redlow", colorToning.redlow); + } + + if (!pedited || pedited->colorToning.greenlow) { + keyFile.set_double ("ColorToning", "Greenlow", colorToning.greenlow); + } + + if (!pedited || pedited->colorToning.bluelow) { + keyFile.set_double ("ColorToning", "Bluelow", colorToning.bluelow); + } + + if (!pedited || pedited->colorToning.satlow) { + keyFile.set_double ("ColorToning", "Satlow", colorToning.satlow); + } + + if (!pedited || pedited->colorToning.balance) { + keyFile.set_integer ("ColorToning", "Balance", colorToning.balance); + } + + if (!pedited || pedited->colorToning.sathigh) { + keyFile.set_double ("ColorToning", "Sathigh", colorToning.sathigh); + } + + if (!pedited || pedited->colorToning.redmed) { + keyFile.set_double ("ColorToning", "Redmed", colorToning.redmed); + } + + if (!pedited || pedited->colorToning.greenmed) { + keyFile.set_double ("ColorToning", "Greenmed", colorToning.greenmed); + } + + if (!pedited || pedited->colorToning.bluemed) { + keyFile.set_double ("ColorToning", "Bluemed", colorToning.bluemed); + } + + if (!pedited || pedited->colorToning.redhigh) { + keyFile.set_double ("ColorToning", "Redhigh", colorToning.redhigh); + } + + if (!pedited || pedited->colorToning.greenhigh) { + keyFile.set_double ("ColorToning", "Greenhigh", colorToning.greenhigh); + } + + if (!pedited || pedited->colorToning.bluehigh) { + keyFile.set_double ("ColorToning", "Bluehigh", colorToning.bluehigh); + } + + if (!pedited || pedited->colorToning.autosat) { + keyFile.set_boolean ("ColorToning", "Autosat", colorToning.autosat); + } + + if (!pedited || pedited->colorToning.opacityCurve) { + Glib::ArrayHandle curve = colorToning.opacityCurve; + keyFile.set_double_list("ColorToning", "OpacityCurve", curve); + } + + if (!pedited || pedited->colorToning.colorCurve) { + Glib::ArrayHandle curve = colorToning.colorCurve; + keyFile.set_double_list("ColorToning", "ColorCurve", curve); + } + + if (!pedited || pedited->colorToning.satprotectionthreshold) { + keyFile.set_integer ("ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold ); + } + + if (!pedited || pedited->colorToning.saturatedopacity) { + keyFile.set_integer ("ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity ); + } + + if (!pedited || pedited->colorToning.strength) { + keyFile.set_integer ("ColorToning", "Strength", colorToning.strength ); + } + + if (!pedited || pedited->colorToning.hlColSat) { + Glib::ArrayHandle thresh (colorToning.hlColSat.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("ColorToning", "HighlightsColorSaturation", thresh); + } + + if (!pedited || pedited->colorToning.shadowsColSat) { + Glib::ArrayHandle thresh (colorToning.shadowsColSat.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("ColorToning", "ShadowsColorSaturation", thresh); + } + + if (!pedited || pedited->colorToning.clcurve) { + Glib::ArrayHandle clcurve = colorToning.clcurve; + keyFile.set_double_list("ColorToning", "ClCurve", clcurve); + } + + if (!pedited || pedited->colorToning.cl2curve) { + Glib::ArrayHandle cl2curve = colorToning.cl2curve; + keyFile.set_double_list("ColorToning", "Cl2Curve", cl2curve); + } + + // save raw parameters + if (!pedited || pedited->raw.darkFrame) { + keyFile.set_string ("RAW", "DarkFrame", relativePathIfInside(fname, fnameAbsolute, raw.dark_frame) ); + } + + if (!pedited || pedited->raw.dfAuto) { + keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); + } + + if (!pedited || pedited->raw.ff_file) { + keyFile.set_string ("RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file) ); + } + + if (!pedited || pedited->raw.ff_AutoSelect) { + keyFile.set_boolean ("RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect ); + } + + if (!pedited || pedited->raw.ff_BlurRadius) { + keyFile.set_integer ("RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius ); + } + + if (!pedited || pedited->raw.ff_BlurType) { + keyFile.set_string ("RAW", "FlatFieldBlurType", raw.ff_BlurType ); + } + + if (!pedited || pedited->raw.ff_AutoClipControl) { + keyFile.set_boolean ("RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl ); + } + + if (!pedited || pedited->raw.ff_clipControl) { + keyFile.set_boolean ("RAW", "FlatFieldClipControl", raw.ff_clipControl ); + } + + if (!pedited || pedited->raw.caCorrection) { + keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); + } + + if (!pedited || pedited->raw.caAutoStrength) { + keyFile.set_double ("RAW", "CAAutoStrength", raw.caautostrength ); + } + + if (!pedited || pedited->raw.caRed) { + keyFile.set_double ("RAW", "CARed", raw.cared ); + } + + if (!pedited || pedited->raw.caBlue) { + keyFile.set_double ("RAW", "CABlue", raw.cablue ); + } + + if (!pedited || pedited->raw.hotPixelFilter) { + keyFile.set_boolean ("RAW", "HotPixelFilter", raw.hotPixelFilter ); + } + + if (!pedited || pedited->raw.deadPixelFilter) { + keyFile.set_boolean ("RAW", "DeadPixelFilter", raw.deadPixelFilter ); + } + + if (!pedited || pedited->raw.hotDeadPixelThresh) { + keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh ); + } + + if (!pedited || pedited->raw.bayersensor.method) { + keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method ); + } + + if (!pedited || pedited->raw.bayersensor.ccSteps) { + keyFile.set_integer ("RAW Bayer", "CcSteps", raw.bayersensor.ccSteps); + } + + if (!pedited || pedited->raw.bayersensor.exBlack0) { + keyFile.set_double ("RAW Bayer", "PreBlack0", raw.bayersensor.black0 ); + } + + if (!pedited || pedited->raw.bayersensor.exBlack1) { + keyFile.set_double ("RAW Bayer", "PreBlack1", raw.bayersensor.black1 ); + } + + if (!pedited || pedited->raw.bayersensor.exBlack2) { + keyFile.set_double ("RAW Bayer", "PreBlack2", raw.bayersensor.black2 ); + } + + if (!pedited || pedited->raw.bayersensor.exBlack3) { + keyFile.set_double ("RAW Bayer", "PreBlack3", raw.bayersensor.black3 ); + } + + if (!pedited || pedited->raw.bayersensor.exTwoGreen) { + keyFile.set_boolean ("RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen ); + } + + if (!pedited || pedited->raw.bayersensor.linenoise) { + keyFile.set_integer ("RAW Bayer", "LineDenoise", raw.bayersensor.linenoise); + } + + if (!pedited || pedited->raw.bayersensor.greenEq) { + keyFile.set_integer ("RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh); + } + + if (!pedited || pedited->raw.bayersensor.dcbIterations) { + keyFile.set_integer ("RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations ); + } + + if (!pedited || pedited->raw.bayersensor.dcbEnhance) { + keyFile.set_boolean ("RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance ); + } + + if (!pedited || pedited->raw.bayersensor.lmmseIterations) { + keyFile.set_integer ("RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations ); + } + + //if (!pedited || pedited->raw.bayersensor.allEnhance) keyFile.set_boolean ("RAW Bayer", "ALLEnhance", raw.bayersensor.all_enhance ); + + if (!pedited || pedited->raw.xtranssensor.method) { + keyFile.set_string ("RAW X-Trans", "Method", raw.xtranssensor.method ); + } + + if (!pedited || pedited->raw.xtranssensor.ccSteps) { + keyFile.set_integer ("RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps); + } + + if (!pedited || pedited->raw.xtranssensor.exBlackRed) { + keyFile.set_double ("RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred ); + } + + if (!pedited || pedited->raw.xtranssensor.exBlackGreen) { + keyFile.set_double ("RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen ); + } + + if (!pedited || pedited->raw.xtranssensor.exBlackBlue) { + keyFile.set_double ("RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue ); + } + + + // save raw exposition + if (!pedited || pedited->raw.exPos) { + keyFile.set_double ("RAW", "PreExposure", raw.expos ); + } + + if (!pedited || pedited->raw.exPreser) { + keyFile.set_double ("RAW", "PrePreserv", raw.preser ); + } + + // save exif change list + if (!pedited || pedited->exif) { + for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { + keyFile.set_string ("Exif", i->first, i->second); + } + } + + // save iptc change list + if (!pedited || pedited->iptc) { + for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); ++i) { + Glib::ArrayHandle values = i->second; + keyFile.set_string_list ("IPTC", i->first, values); + } + } + + sPParams = keyFile.to_data(); } catch(Glib::KeyFileError&) {} @@ -3428,7 +3453,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol } } -int ProcParams::write (Glib::ustring &fname, Glib::ustring &content) const +int ProcParams::write (const Glib::ustring &fname, const Glib::ustring &content) const { int error = 0; @@ -3448,7 +3473,7 @@ int ProcParams::write (Glib::ustring &fname, Glib::ustring &content) const return error; } -int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) +int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) { setlocale(LC_NUMERIC, "C"); // to set decimal point to "." @@ -4088,14 +4113,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } - /* if (keyFile.has_key ("Retinex", "grbl")) { - retinex.grbl = keyFile.get_integer ("Retinex", "grbl"); + if (keyFile.has_key ("Retinex", "skal")) { + retinex.skal = keyFile.get_integer ("Retinex", "skal"); + + if (pedited) { + pedited->retinex.skal = true; + } + } - if (pedited) { - pedited->retinex.grbl = true; - } - } - */ if (keyFile.has_key ("Retinex", "CDCurve")) { retinex.cdcurve = keyFile.get_double_list ("Retinex", "CDCurve"); @@ -4177,6 +4202,16 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) pedited->retinex.transmissionCurve = true; } } + + + if (keyFile.has_key ("Retinex", "GainTransmissionCurve")) { + retinex.gaintransmissionCurve = keyFile.get_double_list ("Retinex", "GainTransmissionCurve"); + + if (pedited) { + pedited->retinex.gaintransmissionCurve = true; + } + } + } @@ -4221,6 +4256,10 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Chromaticity"); + if (ppVersion >= 303 && ppVersion < 314 && labCurve.chromaticity == -100) { + blackwhite.enabled = true; + } + if (pedited) { pedited->labCurve.chromaticity = true; } @@ -7509,7 +7548,7 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) for ( std::vector::iterator currLoadedTagValue = currIptc.begin(); currLoadedTagValue != currIptc.end(); - currLoadedTagValue++) { + ++currLoadedTagValue) { iptc[keys[i]].push_back(currLoadedTagValue->data()); } @@ -7612,6 +7651,7 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.cdHcurve == other.retinex.cdHcurve && retinex.lhcurve == other.retinex.lhcurve && retinex.transmissionCurve == other.retinex.transmissionCurve + && retinex.gaintransmissionCurve == other.retinex.gaintransmissionCurve && retinex.str == other.retinex.str && retinex.scal == other.retinex.scal && retinex.iter == other.retinex.iter @@ -7630,7 +7670,7 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.radius == other.retinex.radius && retinex.baselog == other.retinex.baselog -// && retinex.grbl == other.retinex.grbl + && retinex.skal == other.retinex.skal && retinex.offs == other.retinex.offs && retinex.retinexMethod == other.retinex.retinexMethod && retinex.mapMethod == other.retinex.mapMethod @@ -8068,7 +8108,7 @@ PartialProfile::PartialProfile(const ProcParams* pp, const ParamsEdited* pe) } } -int PartialProfile::load (Glib::ustring fName) +int PartialProfile::load (const Glib::ustring &fName) { if (!pparams) { pparams = new ProcParams(); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 772cffd77..1aa54ebee 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -41,6 +41,7 @@ class WavOpacityCurveBY; class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; +class RetinexgaintransmissionCurve; enum RenderingIntent { RI_PERCEPTUAL = INTENT_PERCEPTUAL, @@ -282,6 +283,7 @@ public: std::vector cdHcurve; std::vector lhcurve; std::vector transmissionCurve; + std::vector gaintransmissionCurve; std::vector mapcurve; int str; int scal; @@ -308,11 +310,13 @@ public: int limd; int highl; double baselog; -// int grbl; + int skal; bool medianmap; RetinexParams (); void setDefaults(); - void getCurves(RetinextransmissionCurve &transmissionCurveLUT) const; + void getCurves(RetinextransmissionCurve &transmissionCurveLUT, RetinexgaintransmissionCurve &gaintransmissionCurveLUT) const; + + static void getDefaultgaintransmissionCurve(std::vector &curve); static void getDefaulttransmissionCurve(std::vector &curve); }; @@ -524,7 +528,7 @@ public: double green; double equal; - WBEntry(Glib::ustring p, enum WBTypes t, Glib::ustring l, int temp, double green, double equal) : ppLabel(p), type(t), GUILabel(l), temperature(temp), green(green), equal(equal) {}; + WBEntry(const Glib::ustring &p, enum WBTypes t, const Glib::ustring &l, int temp, double green, double equal) : ppLabel(p), type(t), GUILabel(l), temperature(temp), green(green), equal(equal) {}; }; class WBParams @@ -1362,14 +1366,14 @@ public: * @param pedited pointer to a ParamsEdited object (optional) to store which values has to be saved * @return Error code (=0 if all supplied filenames where created correctly) */ - int save (Glib::ustring fname, Glib::ustring fname2 = "", bool fnameAbsolute = true, ParamsEdited* pedited = NULL); + int save (const Glib::ustring &fname, const Glib::ustring &fname2 = "", bool fnameAbsolute = true, ParamsEdited* pedited = NULL); /** * Loads the parameters from a file. * @param fname the name of the file * @params pedited pointer to a ParamsEdited object (optional) to store which values has been loaded * @return Error code (=0 if no error) */ - int load (Glib::ustring fname, ParamsEdited* pedited = NULL); + int load (const Glib::ustring &fname, ParamsEdited* pedited = NULL); /** Creates a new instance of ProcParams. * @return a pointer to the new ProcParams instance. */ @@ -1391,7 +1395,7 @@ private: * @param content the text to write * @return Error code (=0 if no error) * */ - int write (Glib::ustring &fname, Glib::ustring &content) const; + int write (const Glib::ustring &fname, const Glib::ustring &content) const; }; @@ -1421,7 +1425,7 @@ public: PartialProfile (const ProcParams* pp, const ParamsEdited* pe = NULL); void deleteInstance (); void clearGeneral (); - int load (Glib::ustring fName); + int load (const Glib::ustring &fName); void set (bool v); const void applyTo (ProcParams *destParams) const ; }; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 3f4b2ac3f..8f91f8f4b 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -19,7 +19,7 @@ namespace rtengine extern const Settings* settings; -RawImage::RawImage( const Glib::ustring name ) +RawImage::RawImage( const Glib::ustring &name ) : data(NULL) , prefilters(0) , filename(name) @@ -580,7 +580,9 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene if (cc) { for (int i = 0; i < 4; i++) { if (RT_blacklevel_from_constant) { - black_c4[i] = cblack[i] + cc->get_BlackLevel(i, iso_speed); + int blackFromCc = cc->get_BlackLevel(i, iso_speed); + // if black level from camconst > 0xffff it is an absolute value. + black_c4[i] = blackFromCc > 0xffff ? (blackFromCc & 0xffff) : blackFromCc + cblack[i]; } // load 4 channel white level here, will be used if available diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index de2baed32..86965a612 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -44,7 +44,7 @@ public: PixelsMap(int width, int height ) : h(height) { - w = (width + base_t_size - 1) / base_t_size; + w = (width / (base_t_size * 8)) + 1; pm = new base_t [h * w ]; memset(pm, 0, h * w * base_t_size ); } @@ -99,7 +99,7 @@ class RawImage: public DCraw { public: - RawImage( const Glib::ustring name ); + RawImage( const Glib::ustring &name ); ~RawImage(); int loadRaw (bool loadData = true, bool closeFile = true, ProgressListener *plistener = 0, double progressRange = 1.0); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 758a37b29..d2bdf9763 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -49,32 +49,32 @@ namespace void rotateLine (const float* const line, rtengine::PlanarPtr &channel, const int tran, const int i, const int w, const int h) { switch(tran & TR_ROT) { - case TR_R180: - for (int j = 0; j < w; j++) { - channel(h - 1 - i, w - 1 - j) = line[j]; - } + case TR_R180: + for (int j = 0; j < w; j++) { + channel(h - 1 - i, w - 1 - j) = line[j]; + } - break; + break; - case TR_R90: - for (int j = 0; j < w; j++) { - channel(j, h - 1 - i) = line[j]; - } + case TR_R90: + for (int j = 0; j < w; j++) { + channel(j, h - 1 - i) = line[j]; + } - break; + break; - case TR_R270: - for (int j = 0; j < w; j++) { - channel(w - 1 - j, i) = line[j]; - } + case TR_R270: + for (int j = 0; j < w; j++) { + channel(w - 1 - j, i) = line[j]; + } - break; + break; - case TR_NONE: - default: - for (int j = 0; j < w; j++) { - channel(i, j) = line[j]; - } + case TR_NONE: + default: + for (int j = 0; j < w; j++) { + channel(i, j) = line[j]; + } } } @@ -96,60 +96,60 @@ void transLineFuji (const float* const red, const float* const green, const floa int end = min(h + fw - i, w - fw + i); switch(tran & TR_ROT) { - case TR_R180: - for (int j = start; j < end; j++) { - int y = i + j - fw; - int x = fw - i + j; + case TR_R180: + for (int j = start; j < end; j++) { + int y = i + j - fw; + int x = fw - i + j; - if (x >= 0 && y < image->height && y >= 0 && x < image->width) { - image->r(image->height - 1 - y, image->width - 1 - x) = red[j]; - image->g(image->height - 1 - y, image->width - 1 - x) = green[j]; - image->b(image->height - 1 - y, image->width - 1 - x) = blue[j]; + if (x >= 0 && y < image->height && y >= 0 && x < image->width) { + image->r(image->height - 1 - y, image->width - 1 - x) = red[j]; + image->g(image->height - 1 - y, image->width - 1 - x) = green[j]; + image->b(image->height - 1 - y, image->width - 1 - x) = blue[j]; + } } - } - break; + break; - case TR_R270: - for (int j = start; j < end; j++) { - int y = i + j - fw; - int x = fw - i + j; + case TR_R270: + for (int j = start; j < end; j++) { + int y = i + j - fw; + int x = fw - i + j; - if (x >= 0 && x < image->height && y >= 0 && y < image->width) { - image->r(image->height - 1 - x, y) = red[j]; - image->g(image->height - 1 - x, y) = green[j]; - image->b(image->height - 1 - x, y) = blue[j]; + if (x >= 0 && x < image->height && y >= 0 && y < image->width) { + image->r(image->height - 1 - x, y) = red[j]; + image->g(image->height - 1 - x, y) = green[j]; + image->b(image->height - 1 - x, y) = blue[j]; + } } - } - break; + break; - case TR_R90: - for (int j = start; j < end; j++) { - int y = i + j - fw; - int x = fw - i + j; + case TR_R90: + for (int j = start; j < end; j++) { + int y = i + j - fw; + int x = fw - i + j; - if (x >= 0 && y < image->width && y >= 0 && x < image->height) { - image->r(x, image->width - 1 - y) = red[j]; - image->g(x, image->width - 1 - y) = green[j]; - image->b(x, image->width - 1 - y) = blue[j]; + if (x >= 0 && y < image->width && y >= 0 && x < image->height) { + image->r(x, image->width - 1 - y) = red[j]; + image->g(x, image->width - 1 - y) = green[j]; + image->b(x, image->width - 1 - y) = blue[j]; + } } - } - break; + break; - case TR_NONE: - default: - for (int j = start; j < end; j++) { - int y = i + j - fw; - int x = fw - i + j; + case TR_NONE: + default: + for (int j = start; j < end; j++) { + int y = i + j - fw; + int x = fw - i + j; - if (x >= 0 && y < image->height && y >= 0 && x < image->width) { - image->r(y, x) = red[j]; - image->g(y, x) = green[j]; - image->b(y, x) = blue[j]; + if (x >= 0 && y < image->height && y >= 0 && x < image->width) { + image->r(y, x) = red[j]; + image->g(y, x) = green[j]; + image->b(y, x) = blue[j]; + } } - } } } @@ -161,250 +161,250 @@ void transLineD1x (const float* const red, const float* const green, const float // We do that in combination with coarse rotation switch(tran & TR_ROT) { - case TR_R180: // rotate 180 degree - for (int j = 0; j < imwidth; j++) { - image->r(2 * (imheight - 1 - i), imwidth - 1 - j) = red[j]; - image->g(2 * (imheight - 1 - i), imwidth - 1 - j) = green[j]; - image->b(2 * (imheight - 1 - i), imwidth - 1 - j) = blue[j]; - } - - if (i == 0) { + case TR_R180: // rotate 180 degree for (int j = 0; j < imwidth; j++) { - image->r(2 * imheight - 1, imwidth - 1 - j) = red[j]; - image->g(2 * imheight - 1, imwidth - 1 - j) = green[j]; - image->b(2 * imheight - 1, imwidth - 1 - j) = blue[j]; - } - } - - if (i == 1 || i == 2) { // linear interpolation - int row = 2 * imheight - 1 - 2 * i; - - for (int j = 0; j < imwidth; j++) { - int col = imwidth - 1 - j; - image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; - image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; - image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; + image->r(2 * (imheight - 1 - i), imwidth - 1 - j) = red[j]; + image->g(2 * (imheight - 1 - i), imwidth - 1 - j) = green[j]; + image->b(2 * (imheight - 1 - i), imwidth - 1 - j) = blue[j]; } - if(i == 2 && oddHeight) { - int row = 2 * imheight; + if (i == 0) { + for (int j = 0; j < imwidth; j++) { + image->r(2 * imheight - 1, imwidth - 1 - j) = red[j]; + image->g(2 * imheight - 1, imwidth - 1 - j) = green[j]; + image->b(2 * imheight - 1, imwidth - 1 - j) = blue[j]; + } + } + + if (i == 1 || i == 2) { // linear interpolation + int row = 2 * imheight - 1 - 2 * i; for (int j = 0; j < imwidth; j++) { int col = imwidth - 1 - j; - image->r(row, col) = (red[j] + image->r(row - 2, col)) / 2; - image->g(row, col) = (green[j] + image->g(row - 2, col)) / 2; - image->b(row, col) = (blue[j] + image->b(row - 2, col)) / 2; - } - } - } else if (i == imheight - 1 || i == imheight - 2) { - int row = 2 * imheight - 1 - 2 * i; - - for (int j = 0; j < imwidth; j++) { - int col = imwidth - 1 - j; - image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; - image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; - image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; - } - - row = 2 * imheight - 1 - 2 * i + 2; - - for (int j = 0; j < imwidth; j++) { - int col = imwidth - 1 - j; - image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; - image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; - image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; - } - } else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation - int row = 2 * imheight - 1 - 2 * i + 2; - - for (int j = 0; j < imwidth; j++) { - int col = imwidth - 1 - j; - image->r(row, col) = MAX(0.f, -0.0625f * (red[j] + image->r(row + 3, col)) + 0.5625f * (image->r(row - 1, col) + image->r(row + 1, col))); - image->g(row, col) = MAX(0.f, -0.0625f * (green[j] + image->g(row + 3, col)) + 0.5625f * (image->g(row - 1, col) + image->g(row + 1, col))); - image->b(row, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(row + 3, col)) + 0.5625f * (image->b(row - 1, col) + image->b(row + 1, col))); - - if(clip) { - image->r(row, col) = MIN(image->r(row, col), rtengine::MAXVALF); - image->g(row, col) = MIN(image->g(row, col), rtengine::MAXVALF); - image->b(row, col) = MIN(image->b(row, col), rtengine::MAXVALF); - } - } - } - - break; - - case TR_R90: // rotate right - if( i == 0) { - for (int j = 0; j < imwidth; j++) { - image->r(j, 2 * imheight - 1) = red[j]; - image->g(j, 2 * imheight - 1) = green[j]; - image->b(j, 2 * imheight - 1) = blue[j]; - } - } - - for (int j = 0; j < imwidth; j++) { - image->r(j, 2 * (imheight - 1 - i)) = red[j]; - image->g(j, 2 * (imheight - 1 - i)) = green[j]; - image->b(j, 2 * (imheight - 1 - i)) = blue[j]; - } - - if (i == 1 || i == 2) { // linear interpolation - int col = 2 * imheight - 1 - 2 * i; - - for (int j = 0; j < imwidth; j++) { - image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; - image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; - image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; - - if(oddHeight && i == 2) { - image->r(j, 2 * imheight) = (red[j] + image->r(j, 2 * imheight - 2)) / 2; - image->g(j, 2 * imheight) = (green[j] + image->g(j, 2 * imheight - 2)) / 2; - image->b(j, 2 * imheight) = (blue[j] + image->b(j, 2 * imheight - 2)) / 2; - } - } - } else if (i == imheight - 1) { - int col = 2 * imheight - 1 - 2 * i; - - for (int j = 0; j < imwidth; j++) { - image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; - image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; - image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; - } - - col = 2 * imheight - 1 - 2 * i + 2; - - for (int j = 0; j < imwidth; j++) { - image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; - image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; - image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; - } - } else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation - int col = 2 * imheight - 1 - 2 * i + 2; - - for (int j = 0; j < imwidth; j++) { - image->r(j, col) = MAX(0.f, -0.0625f * (red[j] + image->r(j, col + 3)) + 0.5625f * (image->r(j, col - 1) + image->r(j, col + 1))); - image->g(j, col) = MAX(0.f, -0.0625f * (green[j] + image->g(j, col + 3)) + 0.5625f * (image->g(j, col - 1) + image->g(j, col + 1))); - image->b(j, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(j, col + 3)) + 0.5625f * (image->b(j, col - 1) + image->b(j, col + 1))); - - if(clip) { - image->r(j, col) = MIN(image->r(j, col), rtengine::MAXVALF); - image->g(j, col) = MIN(image->g(j, col), rtengine::MAXVALF); - image->b(j, col) = MIN(image->b(j, col), rtengine::MAXVALF); - } - } - } - - break; - - case TR_R270: // rotate left - if (i == 0) { - for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { - image->r(row, 2 * i) = red[j]; - image->g(row, 2 * i) = green[j]; - image->b(row, 2 * i) = blue[j]; - } - } else if (i == 1 || i == 2) { // linear interpolation - for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { - image->r(row, 2 * i) = red[j]; - image->g(row, 2 * i) = green[j]; - image->b(row, 2 * i) = blue[j]; - image->r(row, 2 * i - 1) = (red[j] + image->r(row, 2 * i - 2)) * 0.5f; - image->g(row, 2 * i - 1) = (green[j] + image->g(row, 2 * i - 2)) * 0.5f; - image->b(row, 2 * i - 1) = (blue[j] + image->b(row, 2 * i - 2)) * 0.5f; - } - } else if (i > 0 && i < imheight) { // vertical bicubic interpolation - for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { - image->r(row, 2 * i - 3) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 6)) + 0.5625f * (image->r(row, 2 * i - 2) + image->r(row, 2 * i - 4))); - image->g(row, 2 * i - 3) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 6)) + 0.5625f * (image->g(row, 2 * i - 2) + image->g(row, 2 * i - 4))); - image->b(row, 2 * i - 3) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 6)) + 0.5625f * (image->b(row, 2 * i - 2) + image->b(row, 2 * i - 4))); - - if(clip) { - image->r(row, 2 * i - 3) = MIN(image->r(row, 2 * i - 3), rtengine::MAXVALF); - image->g(row, 2 * i - 3) = MIN(image->g(row, 2 * i - 3), rtengine::MAXVALF); - image->b(row, 2 * i - 3) = MIN(image->b(row, 2 * i - 3), rtengine::MAXVALF); + image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; + image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; + image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; } - image->r(row, 2 * i) = red[j]; - image->g(row, 2 * i) = green[j]; - image->b(row, 2 * i) = blue[j]; - } - } + if(i == 2 && oddHeight) { + int row = 2 * imheight; - if (i == imheight - 1) { - for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { - image->r(row, 2 * i - 1) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 4)) + 0.5625f * (image->r(row, 2 * i) + image->r(row, 2 * i - 2))); - image->g(row, 2 * i - 1) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 4)) + 0.5625f * (image->g(row, 2 * i) + image->g(row, 2 * i - 2))); - image->b(row, 2 * i - 1) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 4)) + 0.5625f * (image->b(row, 2 * i) + image->b(row, 2 * i - 2))); + for (int j = 0; j < imwidth; j++) { + int col = imwidth - 1 - j; + image->r(row, col) = (red[j] + image->r(row - 2, col)) / 2; + image->g(row, col) = (green[j] + image->g(row - 2, col)) / 2; + image->b(row, col) = (blue[j] + image->b(row - 2, col)) / 2; + } + } + } else if (i == imheight - 1 || i == imheight - 2) { + int row = 2 * imheight - 1 - 2 * i; - if(clip) { - image->r(j, 2 * i - 1) = MIN(image->r(j, 2 * i - 1), rtengine::MAXVALF); - image->g(j, 2 * i - 1) = MIN(image->g(j, 2 * i - 1), rtengine::MAXVALF); - image->b(j, 2 * i - 1) = MIN(image->b(j, 2 * i - 1), rtengine::MAXVALF); + for (int j = 0; j < imwidth; j++) { + int col = imwidth - 1 - j; + image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; + image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; + image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; } - image->r(row, 2 * i + 1) = (red[j] + image->r(row, 2 * i - 1)) / 2; - image->g(row, 2 * i + 1) = (green[j] + image->g(row, 2 * i - 1)) / 2; - image->b(row, 2 * i + 1) = (blue[j] + image->b(row, 2 * i - 1)) / 2; + row = 2 * imheight - 1 - 2 * i + 2; - if (oddHeight) { - image->r(row, 2 * i + 2) = (red[j] + image->r(row, 2 * i - 2)) / 2; - image->g(row, 2 * i + 2) = (green[j] + image->g(row, 2 * i - 2)) / 2; - image->b(row, 2 * i + 2) = (blue[j] + image->b(row, 2 * i - 2)) / 2; + for (int j = 0; j < imwidth; j++) { + int col = imwidth - 1 - j; + image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2; + image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2; + image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2; + } + } else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation + int row = 2 * imheight - 1 - 2 * i + 2; + + for (int j = 0; j < imwidth; j++) { + int col = imwidth - 1 - j; + image->r(row, col) = MAX(0.f, -0.0625f * (red[j] + image->r(row + 3, col)) + 0.5625f * (image->r(row - 1, col) + image->r(row + 1, col))); + image->g(row, col) = MAX(0.f, -0.0625f * (green[j] + image->g(row + 3, col)) + 0.5625f * (image->g(row - 1, col) + image->g(row + 1, col))); + image->b(row, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(row + 3, col)) + 0.5625f * (image->b(row - 1, col) + image->b(row + 1, col))); + + if(clip) { + image->r(row, col) = MIN(image->r(row, col), rtengine::MAXVALF); + image->g(row, col) = MIN(image->g(row, col), rtengine::MAXVALF); + image->b(row, col) = MIN(image->b(row, col), rtengine::MAXVALF); + } } } - } - break; + break; - case TR_NONE: // no coarse rotation - default: - rotateLine (red, image->r, tran, 2 * i, imwidth, imheight); - rotateLine (green, image->g, tran, 2 * i, imwidth, imheight); - rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight); + case TR_R90: // rotate right + if( i == 0) { + for (int j = 0; j < imwidth; j++) { + image->r(j, 2 * imheight - 1) = red[j]; + image->g(j, 2 * imheight - 1) = green[j]; + image->b(j, 2 * imheight - 1) = blue[j]; + } + } - if (i == 1 || i == 2) { // linear interpolation for (int j = 0; j < imwidth; j++) { - image->r(2 * i - 1, j) = (red[j] + image->r(2 * i - 2, j)) / 2; - image->g(2 * i - 1, j) = (green[j] + image->g(2 * i - 2, j)) / 2; - image->b(2 * i - 1, j) = (blue[j] + image->b(2 * i - 2, j)) / 2; + image->r(j, 2 * (imheight - 1 - i)) = red[j]; + image->g(j, 2 * (imheight - 1 - i)) = green[j]; + image->b(j, 2 * (imheight - 1 - i)) = blue[j]; } - } else if (i > 2 && i < imheight) { // vertical bicubic interpolation - for (int j = 0; j < imwidth; j++) { - image->r(2 * i - 3, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 6, j)) + 0.5625f * (image->r(2 * i - 2, j) + image->r(2 * i - 4, j))); - image->g(2 * i - 3, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 6, j)) + 0.5625f * (image->g(2 * i - 2, j) + image->g(2 * i - 4, j))); - image->b(2 * i - 3, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 6, j)) + 0.5625f * (image->b(2 * i - 2, j) + image->b(2 * i - 4, j))); - if(clip) { - image->r(2 * i - 3, j) = MIN(image->r(2 * i - 3, j), rtengine::MAXVALF); - image->g(2 * i - 3, j) = MIN(image->g(2 * i - 3, j), rtengine::MAXVALF); - image->b(2 * i - 3, j) = MIN(image->b(2 * i - 3, j), rtengine::MAXVALF); + if (i == 1 || i == 2) { // linear interpolation + int col = 2 * imheight - 1 - 2 * i; + + for (int j = 0; j < imwidth; j++) { + image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; + image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; + image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; + + if(oddHeight && i == 2) { + image->r(j, 2 * imheight) = (red[j] + image->r(j, 2 * imheight - 2)) / 2; + image->g(j, 2 * imheight) = (green[j] + image->g(j, 2 * imheight - 2)) / 2; + image->b(j, 2 * imheight) = (blue[j] + image->b(j, 2 * imheight - 2)) / 2; + } } - } - } + } else if (i == imheight - 1) { + int col = 2 * imheight - 1 - 2 * i; - if (i == imheight - 1) { - for (int j = 0; j < imwidth; j++) { - image->r(2 * i - 1, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 4, j)) + 0.5625f * (image->r(2 * i, j) + image->r(2 * i - 2, j))); - image->g(2 * i - 1, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 4, j)) + 0.5625f * (image->g(2 * i, j) + image->g(2 * i - 2, j))); - image->b(2 * i - 1, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 4, j)) + 0.5625f * (image->b(2 * i, j) + image->b(2 * i - 2, j))); - - if(clip) { - image->r(2 * i - 1, j) = MIN(image->r(2 * i - 1, j), rtengine::MAXVALF); - image->g(2 * i - 1, j) = MIN(image->g(2 * i - 1, j), rtengine::MAXVALF); - image->b(2 * i - 1, j) = MIN(image->b(2 * i - 1, j), rtengine::MAXVALF); + for (int j = 0; j < imwidth; j++) { + image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; + image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; + image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; } - image->r(2 * i + 1, j) = (red[j] + image->r(2 * i - 1, j)) / 2; - image->g(2 * i + 1, j) = (green[j] + image->g(2 * i - 1, j)) / 2; - image->b(2 * i + 1, j) = (blue[j] + image->b(2 * i - 1, j)) / 2; + col = 2 * imheight - 1 - 2 * i + 2; - if (oddHeight) { - image->r(2 * i + 2, j) = (red[j] + image->r(2 * i - 2, j)) / 2; - image->g(2 * i + 2, j) = (green[j] + image->g(2 * i - 2, j)) / 2; - image->b(2 * i + 2, j) = (blue[j] + image->b(2 * i - 2, j)) / 2; + for (int j = 0; j < imwidth; j++) { + image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2; + image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2; + image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2; + } + } else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation + int col = 2 * imheight - 1 - 2 * i + 2; + + for (int j = 0; j < imwidth; j++) { + image->r(j, col) = MAX(0.f, -0.0625f * (red[j] + image->r(j, col + 3)) + 0.5625f * (image->r(j, col - 1) + image->r(j, col + 1))); + image->g(j, col) = MAX(0.f, -0.0625f * (green[j] + image->g(j, col + 3)) + 0.5625f * (image->g(j, col - 1) + image->g(j, col + 1))); + image->b(j, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(j, col + 3)) + 0.5625f * (image->b(j, col - 1) + image->b(j, col + 1))); + + if(clip) { + image->r(j, col) = MIN(image->r(j, col), rtengine::MAXVALF); + image->g(j, col) = MIN(image->g(j, col), rtengine::MAXVALF); + image->b(j, col) = MIN(image->b(j, col), rtengine::MAXVALF); + } + } + } + + break; + + case TR_R270: // rotate left + if (i == 0) { + for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { + image->r(row, 2 * i) = red[j]; + image->g(row, 2 * i) = green[j]; + image->b(row, 2 * i) = blue[j]; + } + } else if (i == 1 || i == 2) { // linear interpolation + for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { + image->r(row, 2 * i) = red[j]; + image->g(row, 2 * i) = green[j]; + image->b(row, 2 * i) = blue[j]; + image->r(row, 2 * i - 1) = (red[j] + image->r(row, 2 * i - 2)) * 0.5f; + image->g(row, 2 * i - 1) = (green[j] + image->g(row, 2 * i - 2)) * 0.5f; + image->b(row, 2 * i - 1) = (blue[j] + image->b(row, 2 * i - 2)) * 0.5f; + } + } else if (i > 0 && i < imheight) { // vertical bicubic interpolation + for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { + image->r(row, 2 * i - 3) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 6)) + 0.5625f * (image->r(row, 2 * i - 2) + image->r(row, 2 * i - 4))); + image->g(row, 2 * i - 3) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 6)) + 0.5625f * (image->g(row, 2 * i - 2) + image->g(row, 2 * i - 4))); + image->b(row, 2 * i - 3) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 6)) + 0.5625f * (image->b(row, 2 * i - 2) + image->b(row, 2 * i - 4))); + + if(clip) { + image->r(row, 2 * i - 3) = MIN(image->r(row, 2 * i - 3), rtengine::MAXVALF); + image->g(row, 2 * i - 3) = MIN(image->g(row, 2 * i - 3), rtengine::MAXVALF); + image->b(row, 2 * i - 3) = MIN(image->b(row, 2 * i - 3), rtengine::MAXVALF); + } + + image->r(row, 2 * i) = red[j]; + image->g(row, 2 * i) = green[j]; + image->b(row, 2 * i) = blue[j]; + } + } + + if (i == imheight - 1) { + for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) { + image->r(row, 2 * i - 1) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 4)) + 0.5625f * (image->r(row, 2 * i) + image->r(row, 2 * i - 2))); + image->g(row, 2 * i - 1) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 4)) + 0.5625f * (image->g(row, 2 * i) + image->g(row, 2 * i - 2))); + image->b(row, 2 * i - 1) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 4)) + 0.5625f * (image->b(row, 2 * i) + image->b(row, 2 * i - 2))); + + if(clip) { + image->r(j, 2 * i - 1) = MIN(image->r(j, 2 * i - 1), rtengine::MAXVALF); + image->g(j, 2 * i - 1) = MIN(image->g(j, 2 * i - 1), rtengine::MAXVALF); + image->b(j, 2 * i - 1) = MIN(image->b(j, 2 * i - 1), rtengine::MAXVALF); + } + + image->r(row, 2 * i + 1) = (red[j] + image->r(row, 2 * i - 1)) / 2; + image->g(row, 2 * i + 1) = (green[j] + image->g(row, 2 * i - 1)) / 2; + image->b(row, 2 * i + 1) = (blue[j] + image->b(row, 2 * i - 1)) / 2; + + if (oddHeight) { + image->r(row, 2 * i + 2) = (red[j] + image->r(row, 2 * i - 2)) / 2; + image->g(row, 2 * i + 2) = (green[j] + image->g(row, 2 * i - 2)) / 2; + image->b(row, 2 * i + 2) = (blue[j] + image->b(row, 2 * i - 2)) / 2; + } + } + } + + break; + + case TR_NONE: // no coarse rotation + default: + rotateLine (red, image->r, tran, 2 * i, imwidth, imheight); + rotateLine (green, image->g, tran, 2 * i, imwidth, imheight); + rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight); + + if (i == 1 || i == 2) { // linear interpolation + for (int j = 0; j < imwidth; j++) { + image->r(2 * i - 1, j) = (red[j] + image->r(2 * i - 2, j)) / 2; + image->g(2 * i - 1, j) = (green[j] + image->g(2 * i - 2, j)) / 2; + image->b(2 * i - 1, j) = (blue[j] + image->b(2 * i - 2, j)) / 2; + } + } else if (i > 2 && i < imheight) { // vertical bicubic interpolation + for (int j = 0; j < imwidth; j++) { + image->r(2 * i - 3, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 6, j)) + 0.5625f * (image->r(2 * i - 2, j) + image->r(2 * i - 4, j))); + image->g(2 * i - 3, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 6, j)) + 0.5625f * (image->g(2 * i - 2, j) + image->g(2 * i - 4, j))); + image->b(2 * i - 3, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 6, j)) + 0.5625f * (image->b(2 * i - 2, j) + image->b(2 * i - 4, j))); + + if(clip) { + image->r(2 * i - 3, j) = MIN(image->r(2 * i - 3, j), rtengine::MAXVALF); + image->g(2 * i - 3, j) = MIN(image->g(2 * i - 3, j), rtengine::MAXVALF); + image->b(2 * i - 3, j) = MIN(image->b(2 * i - 3, j), rtengine::MAXVALF); + } + } + } + + if (i == imheight - 1) { + for (int j = 0; j < imwidth; j++) { + image->r(2 * i - 1, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 4, j)) + 0.5625f * (image->r(2 * i, j) + image->r(2 * i - 2, j))); + image->g(2 * i - 1, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 4, j)) + 0.5625f * (image->g(2 * i, j) + image->g(2 * i - 2, j))); + image->b(2 * i - 1, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 4, j)) + 0.5625f * (image->b(2 * i, j) + image->b(2 * i - 2, j))); + + if(clip) { + image->r(2 * i - 1, j) = MIN(image->r(2 * i - 1, j), rtengine::MAXVALF); + image->g(2 * i - 1, j) = MIN(image->g(2 * i - 1, j), rtengine::MAXVALF); + image->b(2 * i - 1, j) = MIN(image->b(2 * i - 1, j), rtengine::MAXVALF); + } + + image->r(2 * i + 1, j) = (red[j] + image->r(2 * i - 1, j)) / 2; + image->g(2 * i + 1, j) = (green[j] + image->g(2 * i - 1, j)) / 2; + image->b(2 * i + 1, j) = (blue[j] + image->b(2 * i - 1, j)) / 2; + + if (oddHeight) { + image->r(2 * i + 2, j) = (red[j] + image->r(2 * i - 2, j)) / 2; + image->g(2 * i + 2, j) = (green[j] + image->g(2 * i - 2, j)) / 2; + image->b(2 * i + 2, j) = (blue[j] + image->b(2 * i - 2, j)) / 2; + } } } - } } } @@ -421,25 +421,6 @@ extern const Settings* settings; #define ABS(a) ((a)<0?-(a):(a)) #define DIST(a,b) (ABS(a-b)) -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ -PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ -PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ -PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median - -#define med5(a0,a1,a2,a3,a4,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \ -PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \ -PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \ -PIX_SORT(p[1],p[2]) ; median=p[2] ;} - - RawImageSource::RawImageSource () : ImageSource() , plistener(NULL) @@ -587,9 +568,7 @@ void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &s } } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -static float -calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const float c_white[4], const float c_black[4], bool isMono, int colors) +float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const float c_white[4], const float c_black[4], bool isMono, int colors) { if (isMono || colors == 1) { for (int c = 0; c < 4; c++) { @@ -617,7 +596,7 @@ calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const float c_w return gain; } -void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, const PreviewProps & pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw ) +void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw ) { MyMutex::MyLock lock(getImageMutex); @@ -716,7 +695,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, con rm /= area; gm /= area; bm /= area; - + bool doHr = (hrp.hrenabled && hrp.method != "Color"); #ifdef _OPENMP #pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) { @@ -727,7 +706,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, con float line_blue[imwidth] ALIGNED16; #ifdef _OPENMP - #pragma omp for + #pragma omp for schedule(dynamic,16) #endif for (int ix = 0; ix < imheight; ix++) { @@ -803,8 +782,8 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, con } //process all highlight recovery other than "Color" - if (hrp.hrenabled && hrp.method != "Color") { - hlRecovery (hrp.method, line_red, line_grn, line_blue, i, sx1, imwidth, skip, raw, hlmax); + if (doHr) { + hlRecovery (hrp.method, line_red, line_grn, line_blue, imwidth, hlmax); } if(d1x) { @@ -881,17 +860,17 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, con // Colour correction (only when running on full resolution) if(pp.skip == 1) { switch(ri->getSensorType()) { - case ST_BAYER: - processFalseColorCorrection (image, raw.bayersensor.ccSteps); - break; + case ST_BAYER: + processFalseColorCorrection (image, raw.bayersensor.ccSteps); + break; - case ST_FUJI_XTRANS: - processFalseColorCorrection (image, raw.xtranssensor.ccSteps); + case ST_FUJI_XTRANS: + processFalseColorCorrection (image, raw.xtranssensor.ccSteps); } } } -DCPProfile *RawImageSource::getDCP(ColorManagementParams cmp, ColorTemp &wb) +DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as) { DCPProfile *dcpProf = NULL; cmsHPROFILE dummy; @@ -901,11 +880,11 @@ DCPProfile *RawImageSource::getDCP(ColorManagementParams cmp, ColorTemp &wb) return NULL; } - dcpProf->setStep2ApplyState(cmp.working, cmp.toneCurve, cmp.applyLookTable, cmp.applyBaselineExposureOffset); + dcpProf->setStep2ApplyState(cmp.working, cmp.toneCurve, cmp.applyLookTable, cmp.applyBaselineExposureOffset, as); return dcpProf; } -void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb) +void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) { double pre_mul[3] = { ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2) }; colorSpaceConversion (image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); @@ -1341,12 +1320,10 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres #endif for (int i = 2; i < H - 2; i++) { - float p[9], temp; // we need this for med3x3 macro - for (int j = 2; j < W - 2; j++) { - med3x3(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], temp); + 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; } } @@ -1501,7 +1478,7 @@ void RawImageSource::vflip (Imagefloat* image) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::load (Glib::ustring fname, bool batch) +int RawImageSource::load (const Glib::ustring &fname, bool batch) { MyTime t1, t2; @@ -1664,8 +1641,9 @@ int RawImageSource::load (Glib::ustring fname, bool batch) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) +void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise) { +// BENCHFUN MyTime t1, t2; t1.set(); @@ -1677,25 +1655,27 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le rid = dfm.searchDarkFrame( raw.dark_frame ); } } else { - rid = dfm.searchDarkFrame( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp()); + rid = dfm.searchDarkFrame(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS()); } if( rid && settings->verbose) { printf( "Subtracting Darkframe:%s\n", rid->get_filename().c_str()); } - PixelsMap bitmapBads(W, H); + PixelsMap *bitmapBads = nullptr; + int totBP = 0; // Hold count of bad pixels to correct if(ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica) + bitmapBads = new PixelsMap(W, H); #ifdef _OPENMP - #pragma omp parallel for reduction(+:totBP) + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) #endif for(int i = 0; i < H; i++) for(int j = 0; j < W; j++) { if(ri->data[i][j] == 0.f) { - bitmapBads.set(j, i); + bitmapBads->set(j, i); totBP++; } } @@ -1706,7 +1686,6 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } //FLATFIELD start - Glib::ustring newFF = raw.ff_file; RawImage *rif = NULL; if (!raw.ff_AutoSelect) { @@ -1732,7 +1711,11 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le std::vector *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), idata->getSerialNumber() ); if( bp ) { - totBP += bitmapBads.set( *bp ); + if(!bitmapBads) { + bitmapBads = new PixelsMap(W, H); + } + + totBP += bitmapBads->set( *bp ); if( settings->verbose ) { std::cout << "Correcting " << bp->size() << " pixels from .badpixels" << std::endl; @@ -1743,13 +1726,17 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le bp = 0; if( raw.df_autoselect ) { - bp = dfm.getHotPixels( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp()); + bp = dfm.getHotPixels(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS()); } else if( !raw.dark_frame.empty() ) { bp = dfm.getHotPixels( raw.dark_frame ); } if(bp) { - totBP += bitmapBads.set( *bp ); + if(!bitmapBads) { + bitmapBads = new PixelsMap(W, H); + } + + totBP += bitmapBads->set( *bp ); if( settings->verbose && !bp->empty()) { std::cout << "Correcting " << bp->size() << " hotpixels from darkframe" << std::endl; @@ -1764,7 +1751,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le LCPProfile *pLCPProf = lcpStore->getProfile(lensProf.lcpFile); if (pLCPProf) { // don't check focal length to allow distortion correction for lenses without chip, also pass dummy focal length 1 in case of 0 - LCPMapper map(pLCPProf, max(idata->getFocalLen(),1.0), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1); + LCPMapper map(pLCPProf, max(idata->getFocalLen(), 1.0), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1); #ifdef _OPENMP #pragma omp parallel for @@ -1788,7 +1775,11 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le plistener->setProgress (0.0); } - int nFound = findHotDeadPixels( bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter ); + if(!bitmapBads) { + bitmapBads = new PixelsMap(W, H); + } + + int nFound = findHotDeadPixels( *bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter ); totBP += nFound; if( settings->verbose && nFound > 0) { @@ -1846,11 +1837,11 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if( totBP ) if ( ri->getSensorType() == ST_BAYER ) { - interpolateBadPixelsBayer( bitmapBads ); + interpolateBadPixelsBayer( *bitmapBads ); } else if ( ri->getSensorType() == ST_FUJI_XTRANS ) { - interpolateBadPixelsXtrans( bitmapBads ); + interpolateBadPixelsXtrans( *bitmapBads ); } else { - interpolateBadPixelsNColours( bitmapBads, ri->get_colors() ); + interpolateBadPixelsNColours( *bitmapBads, ri->get_colors() ); } if ( ri->getSensorType() == ST_BAYER && raw.bayersensor.linenoise > 0 ) { @@ -1875,7 +1866,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le processRawWhitepoint(raw.expos, raw.preser); } - if(dirpyrdenoiseExpComp == INFINITY) { + if(prepareDenoise && dirpyrdenoiseExpComp == INFINITY) { LUTu aehist; int aehistcompr; double clip = 0; @@ -1890,6 +1881,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le printf("Preprocessing: %d usec\n", t2.etime(t1)); } + if(bitmapBads) { + delete bitmapBads; + } + return; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1970,7 +1965,6 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar LUTf *retinexgamtab;//gamma before and after Retinex to restore tones LUTf lutTonereti; - lutTonereti(65536); if(retinexParams.gammaretinex == "low") { retinexgamtab = &(Color::gammatab_115_2); @@ -1986,24 +1980,33 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar double gamm2 = retinexParams.gam; if(gamm2 < 1.) { - pwr = 1. / pwr; - gamm = 1. / gamm; + std::swap(pwr, gamm); } int mode = 0, imax = 0; Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope // printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); + double start; + double add; + + if(gamm2 < 1.) { + start = g_a2; + add = g_a4; + } else { + start = g_a3; + add = g_a4; + } + + double mul = 1. + g_a4; + + lutTonereti(65536); + for (int i = 0; i < 65536; i++) { double val = (i) / 65535.; - double start = g_a3; - double add = g_a4; - double mul = 1. + g_a4; double x; if(gamm2 < 1.) { - start = g_a2; - add = g_a4; x = Color::igammareti (val, gamm, start, ts, mul , add); } else { x = Color::gammareti (val, gamm, start, ts, mul , add); @@ -2055,6 +2058,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } */ if(retinexParams.gammaretinex != "none" && retinexParams.str != 0) {//gamma + #ifdef _OPENMP #pragma omp parallel for #endif @@ -2083,7 +2087,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar if(lhist16RETI) { - lhist16RETIThr(32769, 0); + lhist16RETIThr(lhist16RETI.getSize()); lhist16RETIThr.clear(); } @@ -2101,7 +2105,6 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar for (; j < W - border - 3; j += 4) { vfloat H, S, L; - int pos; Color::rgb2hsl(LVFU(red[i][j]), LVFU(green[i][j]), LVFU(blue[i][j]), H, S, L); STVFU(conversionBuffer[0][i - border][j - border], H); STVFU(conversionBuffer[1][i - border][j - border], S); @@ -2111,7 +2114,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar if(lhist16RETI) { for(int p = 0; p < 4; p++) { - pos = (int) clipretinex( conversionBuffer[2][i - border][j - border + p], 0.f, 32768.f);//histogram in curve HSL + int pos = ( conversionBuffer[2][i - border][j - border + p]);//histogram in curve HSL lhist16RETIThr[pos]++; } } @@ -2121,14 +2124,13 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar for (; j < W - border; j++) { float H, S, L; - int pos; //rgb=>lab Color::rgb2hslfloat(red[i][j], green[i][j], blue[i][j], conversionBuffer[0][i - border][j - border], conversionBuffer[1][i - border][j - border], L); L *= 32768.f; conversionBuffer[2][i - border][j - border] = L; if(lhist16RETI) { - pos = (int) clipretinex(L, 0, 32768); + int pos = L; lhist16RETIThr[pos]++; } } @@ -2139,10 +2141,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar { if(lhist16RETI) { - // Add per Thread LUT to global LUT - for(int i = 0; i < 32769; i++) { - lhist16RETI[i] += lhist16RETIThr[i]; - } + lhist16RETI += lhist16RETIThr; // Add per Thread LUT to global LUT } } #endif @@ -2150,10 +2149,10 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } } else { TMatrix wprof = iccStore->workingSpaceMatrix (cmp.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} + 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])} }; // Conversion rgb -> lab is hard to vectorize because it uses a lut (that's not the main problem) @@ -2166,25 +2165,19 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar LUTu lhist16RETIThr; if(lhist16RETI) { - lhist16RETIThr(32769, 0); + lhist16RETIThr(lhist16RETI.getSize()); lhist16RETIThr.clear(); } #ifdef _OPENMP - #pragma omp for + #pragma omp for schedule(dynamic,16) #endif for (int i = border; i < H - border; i++ ) for (int j = border; j < W - border; j++) { float X, Y, Z, L, aa, bb; - int pos; - float R_, G_, B_; - R_ = red[i][j]; - G_ = green[i][j]; - B_ = blue[i][j]; - float k; //rgb=>lab - Color::rgbxyz(R_, G_, B_, X, Y, Z, wp); + Color::rgbxyz(red[i][j], green[i][j], blue[i][j], X, Y, Z, wp); //convert Lab Color::XYZ2Lab(X, Y, Z, L, aa, bb); conversionBuffer[0][i - border][j - border] = aa; @@ -2195,7 +2188,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar // if(R_>40000.f && G_ > 30000.f && B_ > 30000.f) conversionBuffer[3][i - border][j - border] = R_; // else conversionBuffer[3][i - border][j - border] = 0.f; if(lhist16RETI) { - pos = (int) clipretinex(L, 0, 32768); + int pos = L; lhist16RETIThr[pos]++;//histogram in Curve Lab } } @@ -2204,10 +2197,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar #pragma omp critical { if(lhist16RETI) { - // Add per Thread LUT to global LUT - for(int i = 0; i < 32769; i++) { - lhist16RETI[i] += lhist16RETIThr[i]; - } + lhist16RETI += lhist16RETIThr; // Add per Thread LUT to global LUT } } #endif @@ -2219,7 +2209,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } -void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) +void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) { useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN"); @@ -2231,13 +2221,11 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); - retinexParams.getCurves(retinextransmissionCurve); + retinexParams.getCurves(retinextransmissionCurve, retinexgaintransmissionCurve); } -//void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) -void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, 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) +void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, 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) { - MyTime t4, t5; t4.set(); @@ -2265,23 +2253,29 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC int mode = 0, imax = 0; if(gamm2 < 1.) { - pwr = 1. / pwr; - gamm = 1. / gamm; + std::swap(pwr, gamm); } Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope + double mul = 1. + g_a4; + double add; + double start; + + if(gamm2 < 1.) { + start = g_a3; + add = g_a3; + } else { + add = g_a4; + start = g_a2; + } + // printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); for (int i = 0; i < 65536; i++) { double val = (i) / 65535.; double x; - double mul = 1. + g_a4; - double add = g_a4; - double start = g_a2; if(gamm2 < 1.) { - start = g_a3; - add = g_a3; x = Color::gammareti (val, gamm, start, ts, mul , add); } else { x = Color::igammareti (val, gamm, start, ts, mul , add); @@ -2305,11 +2299,10 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC float val; if(dehacontlutili && histLRETI) { - hist16RET(32769, 0); + hist16RET(32768); hist16RET.clear(); histLRETI.clear(); - dLcurve(32769, 0); - dLcurve.clear(); + dLcurve(32768); } FlatCurve* chcurve = NULL;//curve c=f(H) @@ -2337,8 +2330,8 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC // one LUT per thread LUTu hist16RETThr; - if(dehacontlutili && histLRETI) { - hist16RETThr(32769, 0); + if(hist16RET) { + hist16RETThr(hist16RET.getSize()); hist16RETThr.clear(); } @@ -2352,7 +2345,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC LBuffer[i][j] = cdcurve[2.f * temp[i][j]] / 2.f; if(histLRETI) { - int pos = (int) clipretinex(LBuffer[i][j], 0.f, 32768.f); + int pos = LBuffer[i][j]; hist16RETThr[pos]++; //histogram in Curve } } @@ -2365,29 +2358,29 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC #pragma omp critical #endif { - if(dehacontlutili && histLRETI) { - // Add per Thread LUT to global LUT - for(int i = 0; i < 32769; i++) { - hist16RET[i] += hist16RETThr[i]; - } + if(hist16RET) { + hist16RET += hist16RETThr; // Add per Thread LUT to global LUT } } } - if(dehacontlutili && histLRETI) {//update histogram + if(hist16RET) {//update histogram + // TODO : When rgbcurvesspeedup branch is merged into master, replace this by the following 1-liner + // hist16RET.compressTo(histLRETI); + // also remove declaration and init of dLcurve some lines above then and finally remove this comment :) for (int i = 0; i < 32768; i++) { val = (double)i / 32767.0; - dLcurve[i] = CLIPD(val); + dLcurve[i] = val; } for (int i = 0; i < 32768; i++) { float hval = dLcurve[i]; - int hi = (int)(255.0f * CLIPD(hval)); + int hi = (int)(255.0f * hval); histLRETI[hi] += hist16RET[i]; } } - MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], mapcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], mapcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, dehagaintransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); if(useHsl) { if(chutili) { @@ -2401,7 +2394,6 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC for (; j < W - border; j++) { float valp; - float chr; // if(chutili) { // c=f(H) { valp = float((chcurve->getVal(conversionBuffer[3][i - border][j - border]) - 0.5f)); @@ -2450,46 +2442,113 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC // gamut control only in Lab mode const bool highlight = Tc.hrenabled; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel +#endif + { +#ifdef __SSE2__ + // we need some line buffers to precalculate some expensive stuff using SSE + float atan2Buffer[W] ALIGNED16; + float sqrtBuffer[W] ALIGNED16; + float sincosxBuffer[W] ALIGNED16; + float sincosyBuffer[W] ALIGNED16; + const vfloat c327d68v = F2V(327.68); + const vfloat onev = F2V(1.f); +#endif // __SSE2__ +#ifdef _OPENMP + #pragma omp for #endif - for (int i = border; i < H - border; i++ ) { - for (int j = border; j < W - border; j++) { + for (int i = border; i < H - border; i++ ) { +#ifdef __SSE2__ + // vectorized precalculation + { + int j = border; - float Lprov1 = (LBuffer[i - border][j - border]) / 327.68f; - float Chprov1 = sqrt(SQR(conversionBuffer[0][i - border][j - border]) + SQR(conversionBuffer[1][i - border][j - border])) / 327.68f; - float HH = xatan2f(conversionBuffer[1][i - border][j - border], conversionBuffer[0][i - border][j - border]); - float2 sincosval; - float valp; - float chr; - - if(chutili) { // c=f(H) + for (; j < W - border - 3; j += 4) { - valp = float((chcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); - Chprov1 *= (1.f + 2.f * valp); + vfloat av = LVFU(conversionBuffer[0][i - border][j - border]); + vfloat bv = LVFU(conversionBuffer[1][i - border][j - border]); + vfloat chprovv = vsqrtf(SQRV(av) + SQRV(bv)); + STVF(sqrtBuffer[j - border], chprovv / c327d68v); + vfloat HHv = xatan2f(bv, av); + STVF(atan2Buffer[j - border], HHv); + av /= chprovv; + bv /= chprovv; + vmask selMask = vmaskf_eq(chprovv, ZEROV); + STVF(sincosyBuffer[j - border], vself(selMask, onev, av)); + STVF(sincosxBuffer[j - border], vselfnotzero(selMask, bv)); + } + + for (; j < W - border; j++) + { + float aa = conversionBuffer[0][i - border][j - border]; + float bb = conversionBuffer[1][i - border][j - border]; + float Chprov1 = sqrt(SQR(aa) + SQR(bb)) / 327.68f; + sqrtBuffer[j - border] = Chprov1; + float HH = xatan2f(bb, aa); + atan2Buffer[j - border] = HH; + + if(Chprov1 == 0.0f) { + sincosyBuffer[j - border] = 1.f; + sincosxBuffer[j - border] = 0.0f; + } else { + sincosyBuffer[j - border] = aa / (Chprov1 * 327.68f); + sincosxBuffer[j - border] = bb / (Chprov1 * 327.68f); + } } } +#endif // __SSE2__ + + for (int j = border; j < W - border; j++) { + float Lprov1 = (LBuffer[i - border][j - border]) / 327.68f; +#ifdef __SSE2__ + float Chprov1 = sqrtBuffer[j - border]; + float HH = atan2Buffer[j - border]; + float2 sincosval; + sincosval.x = sincosxBuffer[j - border]; + sincosval.y = sincosyBuffer[j - border]; - sincosval = xsincosf(HH); - float R, G, B; -#ifdef _DEBUG - bool neg = false; - bool more_rgb = false; - //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else - //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); + float aa = conversionBuffer[0][i - border][j - border]; + float bb = conversionBuffer[1][i - border][j - border]; + float Chprov1 = sqrt(SQR(aa) + SQR(bb)) / 327.68f; + float HH = xatan2f(bb, aa); + float2 sincosval;// = xsincosf(HH); + + if(Chprov1 == 0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa / (Chprov1 * 327.68f); + sincosval.x = bb / (Chprov1 * 327.68f); + } + +#endif + + if(chutili) { // c=f(H) + float valp = float((chcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); + Chprov1 *= (1.f + 2.f * valp); + } + + float R, G, B; +#ifdef _DEBUG + bool neg = false; + bool more_rgb = false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); #endif - conversionBuffer[0][i - border][j - border] = 327.68f * Chprov1 * sincosval.y; - conversionBuffer[1][i - border][j - border] = 327.68f * Chprov1 * sincosval.x; - LBuffer[i - border][j - border] = Lprov1 * 327.68f; + conversionBuffer[0][i - border][j - border] = 327.68f * Chprov1 * sincosval.y; + conversionBuffer[1][i - border][j - border] = 327.68f * Chprov1 * sincosval.x; + LBuffer[i - border][j - border] = Lprov1 * 327.68f; + } } } - //end gamut control #ifdef __SSE2__ vfloat wipv[3][3]; @@ -2611,8 +2670,8 @@ void RawImageSource::HLRecovery_Global(ToneCurveParams hrp) void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]) { - float (*cfablur); - cfablur = (float (*)) calloc (H * W, sizeof * cfablur); +// BENCHFUN + float *cfablur = (float (*)) malloc (H * W * sizeof * cfablur); int BS = raw.ff_BlurRadius; BS += BS & 1; @@ -2621,9 +2680,8 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile cfaboxblur(riFlatFile, cfablur, 2 * BS, 0); } else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::h_ff]) { cfaboxblur(riFlatFile, cfablur, 0, 2 * BS); - } else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) + } else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) { //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::ff_BlurTypestring[RAWParams::area_ff]) cfaboxblur(riFlatFile, cfablur, BS, BS); @@ -2632,7 +2690,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile if(ri->getSensorType() == ST_BAYER) { float refcolor[2][2]; - //find center ave values by channel + //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; @@ -2701,27 +2759,47 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile } - for (int m = 0; m < 2; m++) - for (int n = 0; n < 2; n++) { -#ifdef _OPENMP - #pragma omp parallel + unsigned int c[2][2] = {{FC(0, 0), FC(0, 1)}, {FC(1, 0), FC(1, 1)}}; + unsigned int c4[2][2]; + 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 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 epsv = F2V(1e-5f); #endif - { - int c = FC(m, n); - int c4 = ( c == 1 && !(m & 1) ) ? 3 : c; #ifdef _OPENMP - #pragma omp for + #pragma omp parallel for schedule(dynamic,16) #endif - for (int row = 0; row < H - m; row += 2) - { - for (int col = 0; col < W - n; col += 2) { - float vignettecorr = ( refcolor[m][n] / max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]) ); - rawData[row + m][col + n] = (rawData[row + m][col + n] - black[c4]) * vignettecorr + black[c4]; - } - } - } + 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 vignettecorrv = rowRefcolorv / vmaxf(epsv, LVFU(cfablur[(row) * W + col]) - rowBlackv); + vfloat valv = LVFU(rawData[row][col]); + valv -= rowBlackv; + STVFU(rawData[row][col], valv * vignettecorrv + rowBlackv); } + +#endif + + for (; col < W; col ++) { + float vignettecorr = refcolor[row & 1][col & 1] / max(1e-5f, cfablur[(row) * W + col] - black[c4[row & 1][col & 1]]); + rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * vignettecorr + black[c4[row & 1][col & 1]]; + } + } } else if(ri->getSensorType() == ST_FUJI_XTRANS) { float refcolor[3] = {0.f}; int cCount[3] = {0}; @@ -2804,32 +2882,52 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile } if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) { - float (*cfablur1); - cfablur1 = (float (*)) calloc (H * W, sizeof * cfablur1); - float (*cfablur2); - cfablur2 = (float (*)) calloc (H * W, sizeof * cfablur2); + 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) { - for (int m = 0; m < 2; m++) - for (int n = 0; n < 2; n++) { + unsigned int c[2][2] = {{FC(0, 0), FC(0, 1)}, {FC(1, 0), FC(1, 1)}}; + unsigned int c4[2][2]; + 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 + #pragma omp parallel for schedule(dynamic,16) #endif - for (int row = 0; row < H - m; row += 2) { - int c = FC(row, 0); - int c4 = ( c == 1 && !(row & 1) ) ? 3 : c; + for (int row = 0; row < H; row ++) { + int col = 0; +#ifdef __SSE2__ + vfloat rowBlackv = blackv[row & 1]; - for (int col = 0; col < W - n; col += 2) { - float hlinecorr = (max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]) / max(1e-5f, cfablur1[(row + m) * W + col + n] - black[c4]) ); - float vlinecorr = (max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4]) / max(1e-5f, cfablur2[(row + m) * W + col + n] - black[c4]) ); - rawData[row + m][col + n] = ((rawData[row + m][col + n] - black[c4]) * hlinecorr * vlinecorr + black[c4]); - } - } + for (; col < W - 3; col += 4) { + vfloat linecorrv = SQRV(vmaxf(epsv, LVFU(cfablur[row * W + col]) - rowBlackv)) / + (vmaxf(epsv, LVFU(cfablur1[row * W + col]) - rowBlackv) * vmaxf(epsv, LVFU(cfablur2[row * W + col]) - rowBlackv)); + 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 @@ -2876,13 +2974,17 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw for (int col = 0; col < W; col++) { int c = FC(row, col); int c4 = ( c == 1 && !(row & 1) ) ? 3 : c; - rawData[row][col] = max(src->data[row][col] + black[c4] - riDark->data[row][col], 0.0f); + rawData[row][col] = max(src->data[row][col] + black[c4] - riDark->data[row][col], 0.0f); } } } else { +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int row = 0; row < H; row++) { for (int col = 0; col < W; col++) { - rawData[row][col] = src->data[row][col]; + rawData[row][col] = src->data[row][col]; } } } @@ -2939,238 +3041,248 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw } } -SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, const int boxH, const int boxW ) +SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, const int boxH, const int boxW) { - float (*cfatmp); - cfatmp = (float (*)) calloc (H * W, sizeof * cfatmp); -// const float hotdeadthresh = 0.5; + if(boxW == 0 && boxH == 0) { // nothing to blur + 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 + #pragma omp for #endif - for (int i = 0; i < H; i++) { - int iprev, inext, jprev, jnext; - int p[5], temp, median; + 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; - if (i < 2) { - iprev = i + 2; - } else { - iprev = i - 2; - } - - if (i > H - 3) { - inext = i - 2; - } else { - inext = i + 2; - } - - for (int j = 0; j < W; j++) { - if (j < 2) { - jprev = j + 2; - } else { - jprev = j - 2; + 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; } - if (j > W - 3) { - jnext = j - 2; - } else { - jnext = j + 2; + 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 ++; } - //med3x3(riFlatFile->data[iprev][jprev], riFlatFile->data[iprev][j], riFlatFile->data[iprev][jnext], - // riFlatFile->data[i][jprev], riFlatFile->data[i][j], riFlatFile->data[i][jnext], - // riFlatFile->data[inext][jprev], riFlatFile->data[inext][j], riFlatFile->data[inext][jnext], cfatmp[i*W+j]); - med5(riFlatFile->data[iprev][j], riFlatFile->data[i][jprev], riFlatFile->data[i][j], - riFlatFile->data[i][jnext], riFlatFile->data[inext][j], median); - -// if (riFlatFile->data[i][j]>hotdeadthresh*median || median>hotdeadthresh*riFlatFile->data[i][j]) { - if (((int)riFlatFile->data[i][j] << 1) > median || (median << 1) > riFlatFile->data[i][j]) { - cfatmp[i * W + j] = median; - } else { - cfatmp[i * W + j] = riFlatFile->data[i][j]; + 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 --; + } } } - //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] = cfatmp[row * W + 0] / len; - cfatmp[row * W + 1] = cfatmp[row * W + 1] / len; - - for (int j = 2; j <= boxW; j += 2) { - cfatmp[row * W + 0] += cfatmp[row * W + j] / len; - cfatmp[row * W + 1] += cfatmp[row * W + j + 1] / len; - } - - for (int col = 2; col <= boxW; col += 2) { - cfatmp[row * W + col] = (cfatmp[row * W + col - 2] * len + cfatmp[row * W + boxW + col]) / (len + 1); - cfatmp[row * W + col + 1] = (cfatmp[row * W + col - 1] * len + cfatmp[row * W + boxW + col + 1]) / (len + 1); - len ++; - } - - for (int col = boxW + 2; col < W - boxW; col++) { - cfatmp[row * W + col] = cfatmp[row * W + col - 2] + (cfatmp[row * W + 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 --; - } - } - - //vertical blur + if(boxH > 0) { + //vertical blur #ifdef __SSE2__ - vfloat leninitv = F2V(boxH / 2 + 1); - vfloat onev = F2V( 1.0f ); - vfloat temp1v, temp2v, lenv, lenp1v, lenm1v; - int row; + 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 + #pragma omp for nowait #endif - for (int col = 0; col < W - 3; col += 4) { - lenv = leninitv; - temp1v = LVFU(cfatmp[0 * W + col]) / lenv; - temp2v = LVFU(cfatmp[1 * W + col]) / lenv; + 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(cfatmp[i * W + col]) / lenv; - temp2v += LVFU(cfatmp[(i + 1) * W + col]) / lenv; - } - - STVFU(cfablur[0 * W + col], temp1v); - STVFU(cfablur[1 * W + col], temp2v); - - for (row = 2; row < boxH + 2; row += 2) { - lenp1v = lenv + onev; - temp1v = (temp1v * lenv + LVFU(cfatmp[(row + boxH) * W + col])) / lenp1v; - temp2v = (temp2v * lenv + LVFU(cfatmp[(row + boxH + 1) * W + col])) / lenp1v; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - lenv = lenp1v; - } - - for (; row < H - boxH - 1; row += 2) { - temp1v = temp1v + (LVFU(cfatmp[(row + boxH) * W + col]) - LVFU(cfatmp[(row - boxH - 2) * W + col])) / lenv; - temp2v = temp2v + (LVFU(cfatmp[(row + 1 + boxH) * W + col]) - LVFU(cfatmp[(row + 1 - boxH - 2) * W + col])) / lenv; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - } - - for(; row < H - boxH; row++) { - temp1v = temp1v + (LVFU(cfatmp[(row + boxH) * W + col]) - LVFU(cfatmp[(row - boxH - 2) * W + col])) / lenv; - STVFU(cfablur[row * W + col], temp1v); - vfloat swapv = temp1v; - temp1v = temp2v; - temp2v = swapv; - - } - - for (; row < H - 1; row += 2) { - lenm1v = lenv - onev; - temp1v = (temp1v * lenv - LVFU(cfatmp[(row - boxH - 2) * W + col])) / lenm1v; - temp2v = (temp2v * lenv - LVFU(cfatmp[(row - boxH - 1) * W + col])) / lenm1v; - STVFU(cfablur[row * W + col], temp1v); - STVFU(cfablur[(row + 1)*W + col], temp2v); - lenv = lenm1v; - } - - for(; row < H; row++) { - lenm1v = lenv - onev; - temp1v = (temp1v * lenv - LVFU(cfatmp[(row - boxH - 2) * W + col])) / lenm1v; - STVFU(cfablur[(row)*W + col], temp1v); - } - - } - - for (int col = W - (W % 4); col < W; col++) { - int len = boxH / 2 + 1; - cfablur[0 * W + col] = cfatmp[0 * W + col] / len; - cfablur[1 * W + col] = cfatmp[1 * W + col] / len; - - for (int i = 2; i < boxH + 2; i += 2) { - cfablur[0 * W + col] += cfatmp[i * W + col] / len; - cfablur[1 * W + col] += cfatmp[(i + 1) * W + col] / len; - } - - for (int row = 2; row < boxH + 2; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + cfatmp[(row + boxH) * W + col]) / (len + 1); - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len + cfatmp[(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] + (cfatmp[(row + boxH) * W + col] - cfatmp[(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 - cfatmp[(row - boxH - 2) * W + col]) / (len - 1); - - if (row + 1 < H) { - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len - cfatmp[(row - boxH - 1) * W + col]) / (len - 1); + 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); } - len --; } - } + + #pragma omp single + + 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 + #pragma omp for #endif - for (int col = 0; col < W; col++) { - int len = boxH / 2 + 1; - cfablur[0 * W + col] = cfatmp[0 * W + col] / len; - cfablur[1 * W + col] = cfatmp[1 * W + col] / len; + 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] += cfatmp[i * W + col] / len; - cfablur[1 * W + col] += cfatmp[(i + 1) * W + col] / len; - } - - for (int row = 2; row < boxH + 2; row += 2) { - cfablur[row * W + col] = (cfablur[(row - 2) * W + col] * len + cfatmp[(row + boxH) * W + col]) / (len + 1); - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len + cfatmp[(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] + (cfatmp[(row + boxH) * W + col] - cfatmp[(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 - cfatmp[(row - boxH - 2) * W + col]) / (len - 1); - - if (row + 1 < H) { - cfablur[(row + 1)*W + col] = (cfablur[(row - 1) * W + col] * len - cfatmp[(row - boxH - 1) * W + col]) / (len - 1); + 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; } - 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); } - free (cfatmp); } @@ -3401,17 +3513,12 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D vfloat* pre2 = &buffer[3]; vfloat* post1 = &buffer[6]; vfloat* post2 = &buffer[9]; - - vfloat middle[6]; - #else float buffer[12]; float* pre1 = &buffer[0]; float* pre2 = &buffer[3]; float* post1 = &buffer[6]; float* post2 = &buffer[9]; - - float middle[6]; #endif int px = (row_from - 1) % 3, cx = row_from % 3, nx = 0; @@ -3435,7 +3542,6 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D #ifdef __SSE2__ pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0) , pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0) , pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); - vfloat temp[7]; // fill first element in rbout_I and rbout_Q rbout_I[cx][0] = rbconv_I[cx][0]; @@ -3444,13 +3550,12 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median I channel for (int j = 1; j < W - 2; j += 2) { post1[0] = _mm_setr_ps(rbconv_I[px][j + 1], rbconv_Q[px][j + 1], 0, 0), post1[1] = _mm_setr_ps(rbconv_I[cx][j + 1], rbconv_Q[cx][j + 1], 0, 0), post1[2] = _mm_setr_ps(rbconv_I[nx][j + 1], rbconv_Q[nx][j + 1], 0, 0); - VMIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - vfloat medianval; - VMEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + vfloat medianval = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); rbout_I[cx][j] = medianval[0]; rbout_Q[cx][j] = medianval[1]; post2[0] = _mm_setr_ps(rbconv_I[px][j + 2], rbconv_Q[px][j + 2], 0, 0), post2[1] = _mm_setr_ps(rbconv_I[cx][j + 2], rbconv_Q[cx][j + 2], 0, 0), post2[2] = _mm_setr_ps(rbconv_I[nx][j + 2], rbconv_Q[nx][j + 2], 0, 0); - VMEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval); + medianval = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); rbout_I[cx][j + 1] = medianval[0]; rbout_Q[cx][j + 1] = medianval[1]; std::swap(pre1, post1); @@ -3466,7 +3571,6 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D #else pre1[0] = rbconv_I[px][0], pre1[1] = rbconv_I[cx][0], pre1[2] = rbconv_I[nx][0]; pre2[0] = rbconv_I[px][1], pre2[1] = rbconv_I[cx][1], pre2[2] = rbconv_I[nx][1]; - float temp[7]; // fill first element in rbout_I rbout_I[cx][0] = rbconv_I[cx][0]; @@ -3474,10 +3578,10 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median I channel for (int j = 1; j < W - 2; j += 2) { post1[0] = rbconv_I[px][j + 1], post1[1] = rbconv_I[cx][j + 1], post1[2] = rbconv_I[nx][j + 1]; - MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j]); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + rbout_I[cx][j] = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); post2[0] = rbconv_I[px][j + 2], post2[1] = rbconv_I[cx][j + 2], post2[2] = rbconv_I[nx][j + 2]; - MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j + 1]); + rbout_I[cx][j + 1] = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); std::swap(pre1, post1); std::swap(pre2, post2); } @@ -3495,10 +3599,10 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median Q channel for (int j = 1; j < W - 2; j += 2) { post1[0] = rbconv_Q[px][j + 1], post1[1] = rbconv_Q[cx][j + 1], post1[2] = rbconv_Q[nx][j + 1]; - MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j]); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + rbout_Q[cx][j] = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); post2[0] = rbconv_Q[px][j + 2], post2[1] = rbconv_Q[cx][j + 2], post2[2] = rbconv_Q[nx][j + 2]; - MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j + 1]); + rbout_Q[cx][j + 1] = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); std::swap(pre1, post1); std::swap(pre2, post2); } @@ -3651,7 +3755,7 @@ lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b) } // Converts raw image including ICC input profile to working space - floating point version -void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParams &cmp, ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) +void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParams &cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) { // MyTime t1, t2, t3; @@ -3665,7 +3769,18 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam if (dcpProf != NULL) { // DCP processing - dcpProf->Apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul, camMatrix, false, cmp.applyHueSatMap, false); + const DCPProfile::Triple pre_mul_row = { + pre_mul[0], + pre_mul[1], + pre_mul[2] + }; + const DCPProfile::Matrix cam_matrix = {{ + {camMatrix[0][0], camMatrix[0][1], camMatrix[0][2]}, + {camMatrix[1][0], camMatrix[1][1], camMatrix[1][2]}, + {camMatrix[2][0], camMatrix[2][1], camMatrix[2][2]} + } + }; + dcpProf->apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul_row, cam_matrix, cmp.applyHueSatMap); return; } @@ -3772,32 +3887,32 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam lcmsMutex->lock (); switch (camera_icc_type) { - case CAMERA_ICC_TYPE_PHASE_ONE: - case CAMERA_ICC_TYPE_LEAF: { - // These profiles have a RGB to Lab cLUT, gives gamma 1.8 output, and expects a "film-like" curve on input - transform_via_pcs_lab = true; - separate_pcs_lab_highlights = true; - // We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert. - hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, NULL, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + case CAMERA_ICC_TYPE_PHASE_ONE: + case CAMERA_ICC_TYPE_LEAF: { + // These profiles have a RGB to Lab cLUT, gives gamma 1.8 output, and expects a "film-like" curve on input + transform_via_pcs_lab = true; + separate_pcs_lab_highlights = true; + // We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert. + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, NULL, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - leaf_prophoto_mat[i][j] = 0; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + leaf_prophoto_mat[i][j] = 0; - for (int k = 0; k < 3; k++) { - leaf_prophoto_mat[i][j] += prophoto_xyz[i][k] * camMatrix[k][j]; + for (int k = 0; k < 3; k++) { + leaf_prophoto_mat[i][j] += prophoto_xyz[i][k] * camMatrix[k][j]; + } } } + + break; } - break; - } - - case CAMERA_ICC_TYPE_NIKON: - case CAMERA_ICC_TYPE_GENERIC: - default: - hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety - break; + case CAMERA_ICC_TYPE_NIKON: + case CAMERA_ICC_TYPE_GENERIC: + default: + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + break; } lcmsMutex->unlock (); @@ -3855,45 +3970,45 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam } switch (camera_icc_type) { - case CAMERA_ICC_TYPE_PHASE_ONE: - // Here we apply a curve similar to Capture One's "Film Standard" + gamma, the reason is that the LUTs embedded in the - // ICCs are designed to work on such input, and if you provide it with a different curve you don't get as good result. - // We will revert this curve after we've made the color transform. However when we revert the curve, we'll notice that - // highlight rendering suffers due to that the LUT transform don't expand well, therefore we do a less compressed - // conversion too and mix them, this gives us the highest quality and most flexible result. - hl_buffer.data[3 * w + 0] = pow_F(r, 1.0 / 1.8); - hl_buffer.data[3 * w + 1] = pow_F(g, 1.0 / 1.8); - hl_buffer.data[3 * w + 2] = pow_F(b, 1.0 / 1.8); - r = phaseOneIccCurveInv->getVal(r); - g = phaseOneIccCurveInv->getVal(g); - b = phaseOneIccCurveInv->getVal(b); - break; + case CAMERA_ICC_TYPE_PHASE_ONE: + // Here we apply a curve similar to Capture One's "Film Standard" + gamma, the reason is that the LUTs embedded in the + // ICCs are designed to work on such input, and if you provide it with a different curve you don't get as good result. + // We will revert this curve after we've made the color transform. However when we revert the curve, we'll notice that + // highlight rendering suffers due to that the LUT transform don't expand well, therefore we do a less compressed + // conversion too and mix them, this gives us the highest quality and most flexible result. + hl_buffer.data[3 * w + 0] = pow_F(r, 1.0 / 1.8); + hl_buffer.data[3 * w + 1] = pow_F(g, 1.0 / 1.8); + hl_buffer.data[3 * w + 2] = pow_F(b, 1.0 / 1.8); + r = phaseOneIccCurveInv->getVal(r); + g = phaseOneIccCurveInv->getVal(g); + b = phaseOneIccCurveInv->getVal(b); + break; - case CAMERA_ICC_TYPE_LEAF: { - // Leaf profiles expect that the camera native RGB has been converted to Prophoto RGB - float newr = leaf_prophoto_mat[0][0] * r + leaf_prophoto_mat[0][1] * g + leaf_prophoto_mat[0][2] * b; - float newg = leaf_prophoto_mat[1][0] * r + leaf_prophoto_mat[1][1] * g + leaf_prophoto_mat[1][2] * b; - float newb = leaf_prophoto_mat[2][0] * r + leaf_prophoto_mat[2][1] * g + leaf_prophoto_mat[2][2] * b; - hl_buffer.data[3 * w + 0] = pow_F(newr, 1.0 / 1.8); - hl_buffer.data[3 * w + 1] = pow_F(newg, 1.0 / 1.8); - hl_buffer.data[3 * w + 2] = pow_F(newb, 1.0 / 1.8); - r = phaseOneIccCurveInv->getVal(newr); - g = phaseOneIccCurveInv->getVal(newg); - b = phaseOneIccCurveInv->getVal(newb); - break; - } + case CAMERA_ICC_TYPE_LEAF: { + // Leaf profiles expect that the camera native RGB has been converted to Prophoto RGB + float newr = leaf_prophoto_mat[0][0] * r + leaf_prophoto_mat[0][1] * g + leaf_prophoto_mat[0][2] * b; + float newg = leaf_prophoto_mat[1][0] * r + leaf_prophoto_mat[1][1] * g + leaf_prophoto_mat[1][2] * b; + float newb = leaf_prophoto_mat[2][0] * r + leaf_prophoto_mat[2][1] * g + leaf_prophoto_mat[2][2] * b; + hl_buffer.data[3 * w + 0] = pow_F(newr, 1.0 / 1.8); + hl_buffer.data[3 * w + 1] = pow_F(newg, 1.0 / 1.8); + hl_buffer.data[3 * w + 2] = pow_F(newb, 1.0 / 1.8); + r = phaseOneIccCurveInv->getVal(newr); + g = phaseOneIccCurveInv->getVal(newg); + b = phaseOneIccCurveInv->getVal(newb); + break; + } - case CAMERA_ICC_TYPE_NIKON: - // gamma 0.5 - r = sqrtf(r); - g = sqrtf(g); - b = sqrtf(b); - break; + case CAMERA_ICC_TYPE_NIKON: + // gamma 0.5 + r = sqrtf(r); + g = sqrtf(g); + b = sqrtf(b); + break; - case CAMERA_ICC_TYPE_GENERIC: - default: - // do nothing - break; + case CAMERA_ICC_TYPE_GENERIC: + default: + // do nothing + break; } *(p++) = r; @@ -3936,37 +4051,37 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam // restore pre-processing and/or add post-processing for the various ICC types switch (camera_icc_type) { - default: - break; + default: + break; - case CAMERA_ICC_TYPE_PHASE_ONE: - case CAMERA_ICC_TYPE_LEAF: { - // note the 1/1.8 gamma, it's the gamma that the profile has applied, which we must revert before we can revert the curve - r = phaseOneIccCurve->getVal(pow_F(r, 1.0 / 1.8)); - g = phaseOneIccCurve->getVal(pow_F(g, 1.0 / 1.8)); - b = phaseOneIccCurve->getVal(pow_F(b, 1.0 / 1.8)); - const float mix = 0.25; // may seem a low number, but remember this is linear space, mixing starts 2 stops from clipping - const float maxc = max(r, g, b); + case CAMERA_ICC_TYPE_PHASE_ONE: + case CAMERA_ICC_TYPE_LEAF: { + // note the 1/1.8 gamma, it's the gamma that the profile has applied, which we must revert before we can revert the curve + r = phaseOneIccCurve->getVal(pow_F(r, 1.0 / 1.8)); + g = phaseOneIccCurve->getVal(pow_F(g, 1.0 / 1.8)); + b = phaseOneIccCurve->getVal(pow_F(b, 1.0 / 1.8)); + const float mix = 0.25; // may seem a low number, but remember this is linear space, mixing starts 2 stops from clipping + const float maxc = max(r, g, b); - if (maxc > mix) { - float fac = (maxc - mix) / (1.0 - mix); - fac = sqrtf(sqrtf(fac)); // gamma 0.25 to mix in highlight render relatively quick - r = (1.0 - fac) * r + fac * hr; - g = (1.0 - fac) * g + fac * hg; - b = (1.0 - fac) * b + fac * hb; + if (maxc > mix) { + float fac = (maxc - mix) / (1.0 - mix); + fac = sqrtf(sqrtf(fac)); // gamma 0.25 to mix in highlight render relatively quick + r = (1.0 - fac) * r + fac * hr; + g = (1.0 - fac) * g + fac * hg; + b = (1.0 - fac) * b + fac * hb; + } + + break; } - break; - } - - case CAMERA_ICC_TYPE_NIKON: { - const float lineFac = -0.4; - const float lineSum = 1.35; - r *= r * lineFac + lineSum; - g *= g * lineFac + lineSum; - b *= b * lineFac + lineSum; - break; - } + case CAMERA_ICC_TYPE_NIKON: { + const float lineFac = -0.4; + const float lineSum = 1.35; + r *= r * lineFac + lineSum; + g *= g * lineFac + lineSum; + b *= b * lineFac + lineSum; + break; + } } // restore highlight scaling if any @@ -4023,7 +4138,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed in = embedded; } else if (inProfile == "(cameraICC)") { // DCPs have higher quality, so use them first - *dcpProf = dcpStore->getStdProfile(camName); + *dcpProf = DCPStore::getInstance()->getStdProfile(camName); if (*dcpProf == NULL) { in = iccStore->getStdProfile(camName); @@ -4035,8 +4150,8 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed normalName = inProfile.substr(5); } - if (dcpStore->isValidDCPFileName(normalName)) { - *dcpProf = dcpStore->getProfile(normalName); + if (DCPStore::getInstance()->isValidDCPFileName(normalName)) { + *dcpProf = DCPStore::getInstance()->getProfile(normalName); } if (*dcpProf == NULL) { @@ -4280,7 +4395,7 @@ void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, floa //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::hlRecovery (std::string method, float* red, float* green, float* blue, int i, int sx1, int width, int skip, const RAWParams &raw, float* hlmax ) +void RawImageSource::hlRecovery (std::string method, float* red, float* green, float* blue, int width, float* hlmax ) { if (method == "Luminance") { @@ -4300,21 +4415,21 @@ void RawImageSource::hlRecovery (std::string method, float* red, float* green, f void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { -BENCHFUN +// BENCHFUN histcompr = 3; histogram(65536 >> histcompr); histogram.clear(); - const float refwb[3] = {static_cast(refwb_red),static_cast(refwb_green),static_cast(refwb_blue)}; + const float refwb[3] = {static_cast(refwb_red / (1 << histcompr)), static_cast(refwb_green / (1 << histcompr)), static_cast(refwb_blue / (1 << histcompr))}; #ifdef _OPENMP #pragma omp parallel #endif { - LUTu tmphistogram(65536 >> histcompr); + LUTu tmphistogram(histogram.getSize()); tmphistogram.clear(); #ifdef _OPENMP - #pragma omp for nowait + #pragma omp for schedule(dynamic,16) nowait #endif for (int i = border; i < H - border; i++) { @@ -4322,22 +4437,50 @@ BENCHFUN getRowStartEnd (i, start, end); if (ri->getSensorType() == ST_BAYER) { - for (int j = start; j < end; j++) { - tmphistogram[(int)(refwb[ri->FC(i,j)] * rawData[i][j]) >> histcompr] += 4; + // precalculate factors to avoid expensive per pixel calculations + float refwb0 = refwb[ri->FC(i, start)]; + float refwb1 = refwb[ri->FC(i, start + 1)]; + int j; + + for (j = start; j < end - 1; j += 2) { + tmphistogram[(int)(refwb0 * rawData[i][j])] += 4; + tmphistogram[(int)(refwb1 * rawData[i][j + 1])] += 4; + } + + if(j < end) { + tmphistogram[(int)(refwb0 * rawData[i][j])] += 4; } } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int j = start; j < end; j++) { - tmphistogram[(int)(refwb[ri->XTRANSFC(i,j)] * rawData[i][j]) >> histcompr] += 4; + // precalculate factors to avoid expensive per pixel calculations + float refwb0 = refwb[ri->XTRANSFC(i, start)]; + float refwb1 = refwb[ri->XTRANSFC(i, start + 1)]; + float refwb2 = refwb[ri->XTRANSFC(i, start + 2)]; + float refwb3 = refwb[ri->XTRANSFC(i, start + 3)]; + float refwb4 = refwb[ri->XTRANSFC(i, start + 4)]; + float refwb5 = refwb[ri->XTRANSFC(i, start + 5)]; + int j; + + for (j = start; j < end - 5; j += 6) { + tmphistogram[(int)(refwb0 * rawData[i][j])] += 4; + tmphistogram[(int)(refwb1 * rawData[i][j + 1])] += 4; + tmphistogram[(int)(refwb2 * rawData[i][j + 2])] += 4; + tmphistogram[(int)(refwb3 * rawData[i][j + 3])] += 4; + tmphistogram[(int)(refwb4 * rawData[i][j + 4])] += 4; + tmphistogram[(int)(refwb5 * rawData[i][j + 5])] += 4; + } + + for (; j < end; j++) { + tmphistogram[(int)(refwb[ri->XTRANSFC(i, j)] * rawData[i][j])] += 4; } } else if (ri->get_colors() == 1) { for (int j = start; j < end; j++) { - tmphistogram[(int)(refwb_red * rawData[i][j]) >> histcompr]++; + tmphistogram[(int)(refwb_red * rawData[i][j])]++; } } else { for (int j = start; j < end; j++) { - tmphistogram[CLIP((int)(refwb_red * rawData[i][3 * j + 0])) >> histcompr]++; - tmphistogram[CLIP((int)(refwb_green * rawData[i][3 * j + 1])) >> histcompr] += 2; - tmphistogram[CLIP((int)(refwb_blue * rawData[i][3 * j + 2])) >> histcompr]++; + tmphistogram[CLIP((int)(refwb_red * rawData[i][3 * j + 0]))]++; + tmphistogram[CLIP((int)(refwb_green * rawData[i][3 * j + 1]))] += 2; + tmphistogram[CLIP((int)(refwb_blue * rawData[i][3 * j + 2]))]++; } } } @@ -4354,7 +4497,7 @@ BENCHFUN // Histogram MUST be 256 in size; gamma is applied, blackpoint and gain also void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { -BENCHFUN +// BENCHFUN histRedRaw.clear(); histGreenRaw.clear(); histBlueRaw.clear(); @@ -4364,25 +4507,28 @@ BENCHFUN 65535.0f / ri->get_white(3) }; - const bool fourColours = ri->getSensorType() == ST_BAYER && ((mult[1] != mult[3] || cblacksom[1] != cblacksom[3]) || FC(0,0) == 3 || FC(0,1) == 3 || FC(1,0) == 3 || FC(1,1) == 3); + const bool fourColours = ri->getSensorType() == ST_BAYER && ((mult[1] != mult[3] || cblacksom[1] != cblacksom[3]) || FC(0, 0) == 3 || FC(0, 1) == 3 || FC(1, 0) == 3 || FC(1, 1) == 3); + constexpr int histoSize = 65536; LUTu hist[4]; - hist[0](65536); + hist[0](histoSize); hist[0].clear(); + if (ri->get_colors() > 1) { - hist[1](65536); + hist[1](histoSize); hist[1].clear(); - hist[2](65536); + hist[2](histoSize); hist[2].clear(); } + if (fourColours) { - hist[3](65536); + hist[3](histoSize); hist[3].clear(); } #ifdef _OPENMP int numThreads; - // reduce the number of threads under certain conditions to avoid overhaed of too many critical regions + // reduce the number of threads under certain conditions to avoid overhead of too many critical regions numThreads = sqrt((((H - 2 * border) * (W - 2 * border)) / 262144.f)); numThreads = std::min(std::max(numThreads, 1), omp_get_max_threads()); @@ -4391,18 +4537,21 @@ BENCHFUN { // we need one LUT per color and thread, which corresponds to 1 MB per thread LUTu tmphist[4]; - tmphist[0](65536); + tmphist[0](histoSize); tmphist[0].clear(); + if (ri->get_colors() > 1) { - tmphist[1](65536); + tmphist[1](histoSize); tmphist[1].clear(); - tmphist[2](65536); + tmphist[2](histoSize); tmphist[2].clear(); + if (fourColours) { - tmphist[3](65536); + tmphist[3](histoSize); tmphist[3].clear(); } } + #ifdef _OPENMP #pragma omp for nowait #endif @@ -4449,9 +4598,11 @@ BENCHFUN #endif { hist[0] += tmphist[0]; + if (ri->get_colors() > 1) { hist[1] += tmphist[1]; hist[2] += tmphist[2]; + if (fourColours) { hist[3] += tmphist[3]; } @@ -4463,13 +4614,16 @@ BENCHFUN int idx; idx = CLIP((int)Color::gamma(mult[0] * (i - (cblacksom[0]/*+black_lev[0]*/)))); histRedRaw[idx >> 8] += hist[0][i]; + if (ri->get_colors() > 1) { idx = CLIP((int)Color::gamma(mult[1] * (i - (cblacksom[1]/*+black_lev[1]*/)))); histGreenRaw[idx >> 8] += hist[1][i]; + if (fourColours) { idx = CLIP((int)Color::gamma(mult[3] * (i - (cblacksom[3]/*+black_lev[3]*/)))); histGreenRaw[idx >> 8] += hist[3][i]; } + idx = CLIP((int)Color::gamma(mult[2] * (i - (cblacksom[2]/*+black_lev[2]*/)))); histBlueRaw[idx >> 8] += hist[2][i]; } @@ -4507,8 +4661,9 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) { - BENCHFUN +// BENCHFUN constexpr double clipHigh = 64000.0; + if (ri->get_colors() == 1) { rm = gm = bm = 1; return; @@ -4588,6 +4743,7 @@ void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) #ifdef _OPENMP #pragma omp for schedule(dynamic,16) nowait #endif + for (int i = 32; i < H - 32; i++) { for (int j = 32; j < W - 32; j++) { // each loop read 1 rgb triplet value @@ -5070,11 +5226,4 @@ void RawImageSource::cleanup () delete phaseOneIccCurveInv; } -#undef PIX_SORT -#undef med3x3 - } /* namespace */ - -#undef PIX_SORT -#undef med3x3 - diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 241f8300b..e682f0e79 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -39,7 +39,8 @@ private: static DiagonalCurve *phaseOneIccCurveInv; static LUTf invGrad; // for fast_demosaic static LUTf initInvGrad (); - static void colorSpaceConversion_ (Imagefloat* im, ColorManagementParams &cmp, ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName); + static void colorSpaceConversion_ (Imagefloat* im, ColorManagementParams &cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName); + int defTransform (int tran); protected: MyMutex getImageMutex; // locks getImage @@ -96,8 +97,7 @@ protected: void hphd_horizontal (float** hpmap, int row_from, int row_to); void hphd_green (float** hpmap); void processFalseColorCorrectionThread (Imagefloat* im, array2D &rbconv_Y, array2D &rbconv_I, array2D &rbconv_Q, array2D &rbout_I, array2D &rbout_Q, const int row_from, const int row_to); - void hlRecovery (std::string method, float* red, float* green, float* blue, int i, int sx1, int width, int skip, const RAWParams &raw, float* hlmax); - int defTransform (int tran); + void hlRecovery (std::string method, float* red, float* green, float* blue, int width, float* hlmax); void transformRect (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); @@ -115,11 +115,11 @@ public: RawImageSource (); ~RawImageSource (); - int load (Glib::ustring fname, bool batch = false); - void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); + int load (const Glib::ustring &fname, bool batch = false); + void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true); void demosaic (const RAWParams &raw); - void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, 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); - void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); + void retinex (ColorManagementParams cmp, RetinexParams deh, 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); + void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI); void flushRawData (); void flushRGB (); @@ -127,22 +127,22 @@ public: void refinement_lassus (int PassCount); void refinement(int PassCount); - bool IsrgbSourceModified() + bool IsrgbSourceModified() const { 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 ); - void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW ); + void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW); void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw); // raw for cblack - void getImage (ColorTemp ctemp, int tran, Imagefloat* image, const PreviewProps & pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw); - eSensorType getSensorType () + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw); + eSensorType getSensorType () const { return ri != NULL ? ri->getSensorType() : ST_NONE; } - ColorTemp getWB () + ColorTemp getWB () const { return camera_wb; } @@ -153,7 +153,7 @@ public: return rawData; } - double getDefGain () + double getDefGain () const { return defGain; } @@ -184,11 +184,11 @@ public: } void getAutoExpHistogram (LUTu & histogram, int& histcompr); void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); - DCPProfile *getDCP(ColorManagementParams cmp, ColorTemp &wb); + DCPProfile *getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as); - void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb); + void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb); static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in); - static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) { colorSpaceConversion_ (im, cmp, wb, pre_mul, embedded, camprofile, cam, camName); } @@ -196,7 +196,7 @@ public: void boxblur2(float** src, float** dst, float** temp, int H, int W, int box ); void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp ); - void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); + void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, 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); 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]); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 52dae275e..7fb198816 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -467,6 +467,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DEMOSAIC, // EvRetinexmapcurve DEMOSAIC, // EvviewMethod ALLNORAW, // EvcbdlMethod + RETINEX, // EvRetinexgaintransmission + RETINEX, // EvLskal SPOT // EvSpotEnabled }; diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 898f1397c..67d883080 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -1,20 +1,21 @@ -#ifndef _MYMATH_ -#define _MYMATH_ -#include -#include +#pragma once +#include +#include +#include namespace rtengine { -static const int MAXVAL = 0xffff; -static const float MAXVALF = float(MAXVAL); // float version of MAXVAL -static const double MAXVALD = double(MAXVAL); // double version of MAXVAL + +constexpr int MAXVAL = 0xffff; +constexpr float MAXVALF = static_cast(MAXVAL); // float version of MAXVAL +constexpr double MAXVALD = static_cast(MAXVAL); // double version of MAXVAL template -inline const _Tp SQR (_Tp x) +inline _Tp SQR (_Tp x) { // return std::pow(x,2); Slower than: - return (x * x); + return x * x; } template @@ -31,25 +32,19 @@ inline const _Tp& max(const _Tp& a, const _Tp& b) template -inline const _Tp LIM(const _Tp& a, const _Tp& b, const _Tp& c) +inline const _Tp& LIM(const _Tp& a, const _Tp& b, const _Tp& c) { return std::max(b, std::min(a, c)); } template -inline const _Tp LIM01(const _Tp& a) +inline _Tp LIM01(const _Tp& a) { return std::max(_Tp(0), std::min(a, _Tp(1))); } template -inline const _Tp ULIM(const _Tp& a, const _Tp& b, const _Tp& c) -{ - return ((b < c) ? LIM(a, b, c) : LIM(a, c, b)); -} - -template -inline const _Tp CLIP(const _Tp& a) +inline _Tp CLIP(const _Tp& a) { return LIM(a, static_cast<_Tp>(0), static_cast<_Tp>(MAXVAL)); } @@ -80,32 +75,42 @@ inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) } template -inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) +inline _Tp intp(_Tp a, _Tp b, _Tp c) { // calculate a * b + (1 - a) * c // following is valid: // intp(a, b+x, c+x) = intp(a, b, c) + x // intp(a, b*x, c*x) = intp(a, b, c) * x - return a * (b-c) + c; + return a * (b - c) + c; } template -T norm1(const T& x, const T& y) +inline T norm1(const T& x, const T& y) { return std::abs(x) + std::abs(y); } template -T norm2(const T& x, const T& y) +inline T norm2(const T& x, const T& y) { return std::sqrt(x * x + y * y); } template< typename T > -T norminf(const T& x, const T& y) +inline T norminf(const T& x, const T& y) { return std::max(std::abs(x), std::abs(y)); } +inline int float2uint16range(float d) // clips input to [0;65535] and rounds +{ + d = CLIP(d); // clip to [0;65535] + return d + 0.5f; +} + +constexpr std::uint8_t uint16ToUint8Rounded(std::uint16_t i) +{ + return ((i + 128) - ((i + 128) >> 8)) >> 8; +} + } -#endif diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index e20efdbdd..7c6aa5b5b 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -32,12 +32,13 @@ #include "rawimagesource.h" #include "stdimagesource.h" #include -#include #include "rawimage.h" #include "jpeg.h" #include "../rtgui/ppversion.h" #include "improccoordinator.h" #include +//#define BENCHMARK +#include "StopWatch.h" extern Options options; @@ -52,7 +53,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, StdImageSource imgSrc; if (imgSrc.load(fname)) { - return NULL; + return nullptr; } ImageIO* img = imgSrc.getImageIO(); @@ -94,7 +95,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, // bilinear interpolation if (tpp->thumbImg) { delete tpp->thumbImg; - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; } if (inspectorMode) { @@ -159,7 +160,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL if( r ) { delete ri; - return NULL; + return nullptr; } rml.exifBase = ri->get_exifBase(); @@ -175,7 +176,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL int err = 1; // see if it is something we support - if ( ri->is_supportedThumb() ) { + if ( ri->is_supportedThumb() && ri->get_thumbOffset() < ri->get_file()->size ) { const char* data((const char*)fdata(ri->get_thumbOffset(), ri->get_file())); if ( (unsigned char)data[1] == 0xd8 ) { @@ -190,7 +191,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL printf("Could not extract thumb from %s\n", fname.data()); delete img; delete ri; - return NULL; + return nullptr; } Thumbnail* tpp = new Thumbnail (); @@ -218,7 +219,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL if (tpp->thumbImg) { delete tpp->thumbImg; - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; } if (inspectorMode) { @@ -287,7 +288,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati if( r ) { delete ri; - return NULL; + return nullptr; } int width = ri->get_width(); @@ -295,8 +296,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati rtengine::Thumbnail* tpp = new rtengine::Thumbnail; tpp->isRaw = true; - tpp->embProfile = NULL; - tpp->embProfileData = NULL; + tpp->embProfile = nullptr; + tpp->embProfileData = nullptr; tpp->embProfileLength = ri->get_profileLen(); if (ri->get_profileLen()) @@ -420,23 +421,23 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati c = ri->XTRANSFC(row, col); switch (c) { - case 0: - tmpImg->r(y, x) = image[ofs][0]; - tmpImg->g(y, x) = sum[1] / 5.f; - tmpImg->b(y, x) = sum[2] / 3.f; - break; + case 0: + tmpImg->r(y, x) = image[ofs][0]; + tmpImg->g(y, x) = sum[1] / 5.f; + tmpImg->b(y, x) = sum[2] / 3.f; + break; - case 1: - tmpImg->r(y, x) = sum[0] / 2.f; - tmpImg->g(y, x) = image[ofs][1]; - tmpImg->b(y, x) = sum[2] / 2.f; - break; + case 1: + tmpImg->r(y, x) = sum[0] / 2.f; + tmpImg->g(y, x) = image[ofs][1]; + tmpImg->b(y, x) = sum[2] / 2.f; + break; - case 2: - tmpImg->r(y, x) = sum[0] / 3.f; - tmpImg->g(y, x) = sum[1] / 5.f; - tmpImg->b(y, x) = image[ofs][2]; - break; + case 2: + tmpImg->r(y, x) = sum[0] / 3.f; + tmpImg->g(y, x) = sum[1] / 5.f; + tmpImg->b(y, x) = image[ofs][2]; + break; } } } @@ -500,7 +501,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati delete tpp->thumbImg; } - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; tpp->thumbImg = resizeTo(w, h, TI_Bilinear, tmpImg); delete tmpImg; @@ -720,7 +721,6 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati void Thumbnail::init () { - RawImageSource::inverse33 (colorMatrix, iColorMatrix); //colorMatrix is rgb_cam memset (cam2xyz, 0, sizeof(cam2xyz)); @@ -735,11 +735,11 @@ void Thumbnail::init () } Thumbnail::Thumbnail () : - camProfile(NULL), thumbImg(NULL), + camProfile(nullptr), thumbImg(nullptr), camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0), - embProfileLength(0), embProfileData(NULL), embProfile(NULL), + embProfileLength(0), embProfileData(nullptr), embProfile(nullptr), redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0), defGain(1.0), scaleForSave(8192), @@ -798,6 +798,8 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName, double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso, std::string expcomp_, double& myscale) { + BENCHFUN + // check if the WB's equalizer value has changed if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4)) { wbEqual = params.wb.equal; @@ -829,24 +831,16 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei gm = camwbGreen / gm; bm = camwbBlue / bm; double mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm; - double logDefGain = log(defGain) / log(2.0); - int rmi, gmi, bmi; - // Since HL recovery is not rendered in thumbs -// if (!isRaw || !params.toneCurve.hrenabled) { - logDefGain = 0.0; - rmi = 1024.0 * rm * defGain / mul_lum; - gmi = 1024.0 * gm * defGain / mul_lum; - bmi = 1024.0 * bm * defGain / mul_lum; - /* } - else { - rmi = 1024.0 * rm / mul_lum; - gmi = 1024.0 * gm / mul_lum; - bmi = 1024.0 * bm / mul_lum; - }*/ + double logDefGain = 0.0; + float rmi, gmi, bmi; + + rmi = rm * defGain / mul_lum; + gmi = gm * defGain / mul_lum; + bmi = bm * defGain / mul_lum; // The RAW exposure is not reflected since it's done in preprocessing. If we only have e.g. the chached thumb, // that is already preprocessed. So we simulate the effect here roughly my modifying the exposure accordingly - if (isRaw && fabs(1.0 - params.raw.expos) > 0.001) { + if (isRaw) { rmi *= params.raw.expos; gmi *= params.raw.expos; bmi *= params.raw.expos; @@ -862,6 +856,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei rwidth = int(size_t(thumbImg->width) * size_t(rheight) / size_t(thumbImg->height)); } + Imagefloat* baseImg = resizeTo(rwidth, rheight, interp, thumbImg); if (params.coarse.rotate) { @@ -878,45 +873,28 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei baseImg->vflip (); } + // apply white balance and raw white point (simulated) - int val; - unsigned short val_; + for (int i = 0; i < rheight; i++) { +#ifdef _OPENMP + #pragma omp simd +#endif - for (int i = 0; i < rheight; i++) for (int j = 0; j < rwidth; j++) { + float red = baseImg->r(i, j) * rmi; + baseImg->r(i, j) = CLIP(red); + float green = baseImg->g(i, j) * gmi; + baseImg->g(i, j) = CLIP(green); + float blue = baseImg->b(i, j) * bmi; + baseImg->b(i, j) = CLIP(blue); - baseImg->convertTo(baseImg->r(i, j), val_); - val = static_cast(val_) * rmi >> 10; - baseImg->r(i, j) = CLIP(val); - - baseImg->convertTo(baseImg->g(i, j), val_); - val = static_cast(val_) * gmi >> 10; - baseImg->g(i, j) = CLIP(val); - - baseImg->convertTo(baseImg->b(i, j), val_); - val = static_cast(val_) * bmi >> 10; - baseImg->b(i, j) = CLIP(val); } - - /* - // apply highlight recovery, if needed -- CURRENTLY BROKEN DUE TO INCOMPATIBLE DATA TYPES, BUT HL RECOVERY AREN'T COMPUTED FOR THUMBNAILS ANYWAY... - if (isRaw && params.toneCurve.hrenabled) { - int maxval = 65535 / defGain; - if (params.toneCurve.method=="Luminance" || params.toneCurve.method=="Color") - for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval); - else if (params.toneCurve.method=="CIELab blending") { - double icamToD50[3][3]; - RawImageSource::inverse33 (cam2xyz, icamToD50); - for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval, cam2xyz, icamToD50); - } - } - */ + } // if luma denoise has to be done for thumbnails, it should be right here // perform color space transformation + if (isRaw) { double pre_mul[3] = { redMultiplier, greenMultiplier, blueMultiplier }; RawImageSource::colorSpaceConversion (baseImg, params.icm, currWB, pre_mul, embProfile, camProfile, cam2xyz, camName ); @@ -933,10 +911,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent); LUTu hist16 (65536); - LUTu hist16C (65536); double gamma = isRaw ? Color::sRGBGamma : 0; // usually in ImageSource, but we don't have that here - ipf.firstAnalysis (baseImg, ¶ms, hist16); + ipf.firstAnalysis (baseImg, params, hist16); // perform transform if (ipf.needsTransform()) { @@ -951,7 +928,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } // update blurmap - SHMap* shmap = NULL; + SHMap* shmap = nullptr; if (params.sh.enabled) { shmap = new SHMap (fw, fh, false); @@ -975,67 +952,69 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei if (params.toneCurve.autoexp && aeHistogram) { ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); - //ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr); } LUTf curve1 (65536); LUTf curve2 (65536); LUTf curve (65536); + LUTf satcurve (65536); LUTf lhskcurve (65536); + LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation LUTf clcurve (65536); - LUTf clToningcurve (65536); - LUTf cl2Toningcurve (65536); - - LUTf rCurve (65536); - LUTf gCurve (65536); - LUTf bCurve (65536); - + LUTf clToningcurve; + LUTf cl2Toningcurve; LUTu dummy; ToneCurve customToneCurve1, customToneCurve2; ColorGradientCurve ctColorCurve; OpacityCurve ctOpacityCurve; - // NoisCurve dnNoisCurve; ColorAppearance customColCurve1; ColorAppearance customColCurve2; ColorAppearance customColCurve3; ToneCurve customToneCurvebw1; ToneCurve customToneCurvebw2; - CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, - hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); + hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; bool opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - //params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili); - bool clctoningutili = false; - bool llctoningutili = false; - CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); - CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); + if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + clToningcurve (65536); + CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); + + cl2Toningcurve (65536); + CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); + } + + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + } double rrm, ggm, bbm; float autor, autog, autob; @@ -1065,25 +1044,25 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool LabImage* labView = new LabImage (fw, fh); - DCPProfile *dcpProf = NULL; + DCPProfile *dcpProf = nullptr; + DCPProfile::ApplyState as; if (isRaw) { cmsHPROFILE dummy; - RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, dummy); + RawImageSource::findInputProfile(params.icm.input, nullptr, camName, &dcpProf, dummy); - if (dcpProf != NULL) { - dcpProf->setStep2ApplyState(params.icm.working, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset); + if (dcpProf) { + dcpProf->setStep2ApplyState(params.icm.working, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset, as); } } - ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf); + ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as); // freeing up some memory customToneCurve1.Reset(); customToneCurve2.Reset(); ctColorCurve.Reset(); ctOpacityCurve.Reset(); -// dnNoisCurve.Reset(); customToneCurvebw1.Reset(); customToneCurvebw2.Reset(); @@ -1092,38 +1071,30 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } // luminance histogram update - hist16.clear(); - hist16C.clear(); + if(params.labCurve.contrast != 0) { + hist16.clear(); - for (int i = 0; i < fh; i++) - for (int j = 0; j < fw; j++) { - hist16[CLIP((int)((labView->L[i][j])))]++; - hist16C[CLIP((int)sqrt(labView->a[i][j]*labView->a[i][j] + labView->b[i][j]*labView->b[i][j]))]++; - } + for (int i = 0; i < fh; i++) + for (int j = 0; j < fw; j++) { + hist16[(int)((labView->L[i][j]))]++; + } + } // luminance processing // ipf.EPDToneMap(labView,0,6); - bool utili = false; - bool autili = false; - bool butili = false; - bool ccutili = false; - bool cclutili = false; - bool clcutili = false; - + bool utili; CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, - hist16, hist16, curve, dummy, 16, utili); + hist16, lumacurve, dummy, 16, utili); - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 16); + bool clcutili; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 16); - CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, - params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, - hist16C, hist16C, dummy, dummy, - 16); - //ipf.luminanceCurve (labView, labView, curve); + bool autili, butili, ccutili, cclutili; + CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, + params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 16); - - ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, curve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); ipf.vibrance(labView); @@ -1131,20 +1102,17 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ipf.EPDToneMap(labView, 5, 6); } - //if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);} - - CurveFactory::curveLightBrightColor ( - params.colorappearance.curveMode, params.colorappearance.curve, - params.colorappearance.curveMode2, params.colorappearance.curve2, - params.colorappearance.curveMode3, params.colorappearance.curve3, - hist16, hist16, dummy, - hist16C, dummy, - customColCurve1, - customColCurve2, - customColCurve3, - 16); - if(params.colorappearance.enabled) { + CurveFactory::curveLightBrightColor ( + params.colorappearance.curve, + params.colorappearance.curve2, + params.colorappearance.curve3, + hist16, dummy, + dummy, dummy, + customColCurve1, + customColCurve2, + customColCurve3, + 16); int begh = 0, endh = labView->H; bool execsharp = false; float d; @@ -1181,6 +1149,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei sk = 16; int rtt = 0; CieImage* cieView = new CieImage (fw, fh); + CAMMean = NAN; + CAMBrightCurveJ.dirty = true; + CAMBrightCurveQ.dirty = true; ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, execsharp, d, sk, rtt); delete cieView; } @@ -1221,7 +1192,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio) { - if (thumbImg == NULL) { + if (!thumbImg) { return 0; // Can happen if thumb is just building and GUI comes in with resize wishes } @@ -1373,11 +1344,11 @@ void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty) unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) { if (!thumbImg) { - return NULL; + return nullptr; } if (thumbImg->width < trim_width) { - return NULL; + return nullptr; } // to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction @@ -1661,7 +1632,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname) if (thumbImg) { delete thumbImg; - thumbImg = NULL; + thumbImg = nullptr; } Glib::ustring fullFName = fname + ".rtti"; @@ -1874,8 +1845,8 @@ bool Thumbnail::readEmbProfile (const Glib::ustring& fname) FILE* f = g_fopen (fname.c_str (), "rb"); if (!f) { - embProfileData = NULL; - embProfile = NULL; + embProfileData = nullptr; + embProfile = nullptr; embProfileLength = 0; } else { fseek (f, 0, SEEK_END); @@ -1947,7 +1918,7 @@ unsigned char* Thumbnail::getImage8Data() return img8->data; } - return NULL; + return nullptr; } diff --git a/rtengine/settings.h b/rtengine/settings.h index 3e9c9d38a..8810322be 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -56,6 +56,7 @@ public: Glib::ustring bruce; // default name of Bruce Glib::ustring srgb; // default name of SRGB space profile Glib::ustring srgb10; // default name of SRGB space profile + Glib::ustring rec2020; // default name of rec2020 bool gamutICC; // no longer used bool gamutLch; @@ -70,7 +71,7 @@ public: int nrwavlevel; bool daubech; bool ciebadpixgauss; - int CRI_color; // N� for display Lab value ; 0 disabled + int CRI_color; // Number for display Lab value; 0 = disabled int denoiselabgamma; // 0=gamma 26 11 1=gamma 40 5 2 =gamma 55 10 // double colortoningab; // // double decaction; diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index ac77da25d..bb8e96c11 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -227,7 +227,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //experimental dirpyr shmap float thresh = (100.f * radius); //1000; - int levrad = 16; + int levrad; // = 16; levrad = 2; //for retinex - otherwise levrad = 16 // set up range function // calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 15ebe5a5a..d649e3c81 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -102,7 +102,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p ImProcFunctions ipf (¶ms, true); PreviewProps pp (0, 0, fw, fh, 1); - imgsrc->preprocess( params.raw, params.lensProf, params.coarse); + imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); if (params.toneCurve.autoexp) {// this enabled HLRecovery LUTu histRedRaw(256), histGreenRaw(256), histBlueRaw(256); @@ -129,15 +129,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf mapcurve (65536, 0); LUTu dummy; RetinextransmissionCurve dehatransmissionCurve; + RetinexgaintransmissionCurve dehagaintransmissionCurve; 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, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); + imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); } if (pl) { @@ -293,6 +294,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p adjustr = 1.f / 1.3f; } else if (params.icm.working == "WideGamut") { adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Rec2020") { + adjustr = 1.f / 1.1f; } else if (params.icm.working == "Beta RGB") { adjustr = 1.f / 1.2f; } else if (params.icm.working == "BestRGB") { @@ -532,6 +535,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p adjustr = 1.f / 1.3f; } else if (params.icm.working == "WideGamut") { adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Rec2020") { + adjustr = 1.f / 1.1f; } else if (params.icm.working == "Beta RGB") { adjustr = 1.f / 1.2f; } else if (params.icm.working == "BestRGB") { @@ -726,9 +731,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // perform first analysis LUTu hist16 (65536); - LUTu hist16C (65536); - ipf.firstAnalysis (baseImg, ¶ms, hist16); + ipf.firstAnalysis (baseImg, params, hist16); // perform transform (excepted resizing) if (ipf.needsTransform()) { @@ -775,15 +779,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf curve (65536, 0); LUTf satcurve (65536, 0); LUTf lhskcurve (65536, 0); - LUTf lumacurve(65536, 0); + LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation LUTf clcurve (65536, 0); - LUTf clToningcurve (65536, 0); - LUTf cl2Toningcurve (65536, 0); + LUTf clToningcurve; + LUTf cl2Toningcurve; LUTf wavclCurve (65536, 0); - LUTf rCurve (65536, 0); - LUTf gCurve (65536, 0); - LUTf bCurve (65536, 0); + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; LUTu dummy; ToneCurve customToneCurve1, customToneCurve2; @@ -796,37 +800,40 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, - hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); + hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; bool opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - bool clctoningutili = false; - CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, 1); - bool llctoningutili = false; - CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, 1); + if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + clToningcurve (65536, 0); + CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1); + cl2Toningcurve (65536, 0); + CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1); + } LabImage* labView = new LabImage (fw, fh); + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); + } - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); double rrm, ggm, bbm; float autor, autog, autob; float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; @@ -852,8 +859,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB); - ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf); + DCPProfile::ApplyState as; + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as); + + ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as); if (settings->verbose) { printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); @@ -861,7 +870,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS) if ( params.filmSimulation.enabled && !params.filmSimulation.clutFilename.empty() && options.clutCacheSize == 1) { - clutStore.clearCache(); + CLUTStore::getInstance().clearCache(); } // freeing up some memory @@ -892,56 +901,43 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // start tile processing...??? - hist16.clear(); - hist16C.clear(); if(params.labCurve.contrast != 0) { //only use hist16 for contrast + hist16.clear(); #ifdef _OPENMP - #pragma omp parallel shared(hist16,labView, fh, fw) + #pragma omp parallel #endif { - LUTu hist16thr (65536); // one temporary lookup table per thread + LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread hist16thr.clear(); #ifdef _OPENMP #pragma omp for schedule(static) nowait #endif for (int i = 0; i < fh; i++) - for (int j = 0; j < fw; j++) - { - hist16thr[CLIP((int)((labView->L[i][j])))]++; + for (int j = 0; j < fw; j++) { + hist16thr[(int)((labView->L[i][j]))]++; } #pragma omp critical { - for(int i = 0; i < 65536; i++) - { - hist16[i] += hist16thr[i]; - } + hist16 += hist16thr; } } - - } - bool utili = false; - bool autili = false; - bool butili = false; - bool ccutili = false; - bool cclutili = false; - bool clcutili = false; + bool utili; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, lumacurve, dummy, 1, utili); - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, lumacurve, dummy, 1, utili); - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 1); + bool clcutili; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1); - CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, - params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, - hist16C, hist16C, dummy, dummy, - 1); -// ipf.MSR(labView, labView->W, labView->H, 1); + bool autili, butili, ccutili, cclutili; + CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, + params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1); - ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { ipf.EPDToneMap(labView, 5, 1); @@ -1029,11 +1025,11 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p begh = 0; endh = fh; CurveFactory::curveLightBrightColor ( - params.colorappearance.curveMode, params.colorappearance.curve, - params.colorappearance.curveMode2, params.colorappearance.curve2, - params.colorappearance.curveMode3, params.colorappearance.curve3, - hist16, hist16, dummy, - hist16C, dummy, + params.colorappearance.curve, + params.colorappearance.curve2, + params.colorappearance.curve3, + hist16, dummy, + dummy, dummy, customColCurve1, customColCurve2, customColCurve3, @@ -1058,7 +1054,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf CAMBrightCurveJ; LUTf CAMBrightCurveQ; - float CAMMean; + float CAMMean = NAN; if (params.sharpening.enabled) { float d; @@ -1181,11 +1177,11 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p useLCMS = false; bool pro = false; Glib::ustring chpro, outProfile; - bool present_space[9] = {false, false, false, false, false, false, false, false, false}; + bool present_space[10] = {false, false, false, false, false, false, false, false, false, false}; std::vector opnames = iccStore->getProfiles (); //test if files are in system - for (int j = 0; j < 9; j++) { + for (int j = 0; j < 10; j++) { // one can modify "option" [Color Management] to adapt the profile's name if they are different for windows, MacOS, Linux ?? // some of them are actually provided by RT, thanks to Jacques Desmis if (j == 0) { @@ -1206,6 +1202,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p chpro = options.rtSettings.srgb10; //gamma 1.0 } else if(j == 8) { chpro = options.rtSettings.prophoto10; //gamma 1.0 + } else if(j == 9) { + chpro = options.rtSettings.rec2020; } for (unsigned int i = 0; i < opnames.size(); i++) { @@ -1245,6 +1243,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p outProfile = options.rtSettings.srgb10; } else if (params.icm.working == "ProPhoto" && present_space[8] && pro) { outProfile = options.rtSettings.prophoto10; + } else if (params.icm.working == "Rec2020" && present_space[9]) { + outProfile = options.rtSettings.rec2020; } else { // Should not occurs if (settings->verbose) { diff --git a/rtengine/sleef.c b/rtengine/sleef.c index c7b3fb486..bc38a3cfb 100644 --- a/rtengine/sleef.c +++ b/rtengine/sleef.c @@ -1,3 +1,12 @@ +//////////////////////////////////////////////////////////////// +// +// 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_ @@ -58,7 +67,9 @@ __inline double ldexpk(double x, int q) { m = (((m + q) >> 9) - m) << 7; q = q - (m << 2); u = longBitsToDouble(((int64_t)(m + 0x3ff)) << 52); - x = x * u * u * u * u; + double u2 = u*u; + u2 = u2 * u2; + x = x * u2; u = longBitsToDouble(((int64_t)(q + 0x3ff)) << 52); return x * u; } @@ -1197,7 +1208,7 @@ __inline float xexpf(float d) { int q = (int)xrintf(d * R_LN2f); float s, u; - + s = mlaf(q, -L2Uf, d); s = mlaf(q, -L2Lf, s); @@ -1246,7 +1257,7 @@ __inline float xdivf( float d, int n){ uflint.intval -= n << 23; // add n to the exponent } return uflint.floatval; -} +} diff --git a/rtengine/sleef.h b/rtengine/sleef.h deleted file mode 100644 index 101a4faff..000000000 --- a/rtengine/sleef.h +++ /dev/null @@ -1,51 +0,0 @@ -typedef struct { - double x, y; -} double2; - -typedef struct { - float x, y; -} float2; - -double xsin(double d); -double xcos(double d); -double2 xsincos(double d); -double xtan(double d); -double xasin(double s); -double xacos(double s); -double xatan(double s); -double xatan2(double y, double x); -double xlog(double d); -double xexp(double d); -double xpow(double x, double y); - -double xsinh(double x); -double xcosh(double x); -double xtanh(double x); -double xasinh(double x); -double xacosh(double x); -double xatanh(double x); -double xldexp(double x, int q); -int xilogb(double d); - -double xfma(double x, double y, double z); -double xsqrt(double d); -double xcbrt(double d); - -double xexp2(double a); -double xexp10(double a); -double xexpm1(double a); -double xlog10(double a); -double xlog1p(double a); - -float xsinf(float d); -float xcosf(float d); -float2 xsincosf(float d); -float xtanf(float d); -float xasinf(float s); -float xacosf(float s); -float xatanf(float s); -float xatan2f(float y, float x); -float xlogf(float d); -float xexpf(float d); -float xpowf(float x, float y); -float xcbrtf(float d); diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c index 1d15e1e41..a55fcf897 100644 --- a/rtengine/sleefsseavx.c +++ b/rtengine/sleefsseavx.c @@ -1,3 +1,13 @@ +//////////////////////////////////////////////////////////////// +// +// 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 SLEEFSSEAVX #define SLEEFSSEAVX @@ -1275,6 +1285,25 @@ static INLINE vfloat xlogf0(vfloat d) { 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; + + e = vilogbp1f(vmulf(d, vcast_vf_f(0.7071f))); + m = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); + + x = vdivf(vaddf(vcast_vf_f(-1.0f), m), vaddf(vcast_vf_f(1.0f), m)); + x2 = vmulf(x, x); + + t = vcast_vf_f(0.2371599674224853515625f); + t = vmlaf(t, x2, vcast_vf_f(0.285279005765914916992188f)); + t = vmlaf(t, x2, vcast_vf_f(0.400005519390106201171875f)); + t = vmlaf(t, x2, vcast_vf_f(0.666666567325592041015625f)); + t = vmlaf(t, x2, vcast_vf_f(2.0f)); + + 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))); @@ -1299,6 +1328,24 @@ static INLINE vfloat xexpf(vfloat d) { return 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; + + 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 = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); + + return vldexpf(u, q); +} + static INLINE vfloat xcbrtf(vfloat d) { vfloat x, y, q = vcast_vf_f(1.0), t; vint2 e, qu, re; @@ -1334,12 +1381,6 @@ static INLINE vfloat LIMV( vfloat a, vfloat b, vfloat c ) { return vmaxf( b, vminf(a,c)); } -static INLINE vfloat ULIMV( vfloat a, vfloat b, vfloat c ){ - // made to clamp a in range [b,c] but in fact it's also the median of a,b,c, which means that the result is independent on order of arguments - // ULIMV(a,b,c) = ULIMV(a,c,b) = ULIMV(b,a,c) = ULIMV(b,c,a) = ULIMV(c,a,b) = ULIMV(c,b,a) - return vmaxf(vminf(a,b), vminf(vmaxf(a,b),c)); -} - static INLINE vfloat SQRV(vfloat a){ return a * a; } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 8c85c287f..e422d23b2 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -83,7 +83,7 @@ StdImageSource::~StdImageSource () } } -void StdImageSource::getSampleFormat (Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) +void StdImageSource::getSampleFormat (const Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) { sFormat = IIOSF_UNKNOWN; @@ -125,7 +125,7 @@ void StdImageSource::getSampleFormat (Glib::ustring &fname, IIOSampleFormat &sFo * and RT's image data type (Image8, Image16 and Imagefloat), then it will * load the image into it */ -int StdImageSource::load (Glib::ustring fname, bool batch) +int StdImageSource::load (const Glib::ustring &fname, bool batch) { fileName = fname; @@ -213,7 +213,7 @@ int StdImageSource::load (Glib::ustring fname, bool batch) return 0; } -void StdImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps & pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw) +void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw) { // the code will use OpenMP as of now. @@ -234,12 +234,12 @@ void StdImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre } } -void StdImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb) +void StdImageSource::convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) { colorSpaceConversion (image, cmp, embProfile, img->getSampleFormat()); } -void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat) +void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagementParams &cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat) { bool skipTransform = false; diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 51bbfab1d..048f3b3c0 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -38,15 +38,15 @@ protected: bool rgbSourceModified; //void transformPixel (int x, int y, int tran, int& tx, int& ty); - void getSampleFormat (Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement); + void getSampleFormat (const Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement); public: StdImageSource (); ~StdImageSource (); - int load (Glib::ustring fname, bool batch = false); - void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps & pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw); - ColorTemp getWB () + int load (const Glib::ustring &fname, bool batch = false); + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw); + ColorTemp getWB () const { return wb; } @@ -60,7 +60,7 @@ public: void getAutoExpHistogram (LUTu &histogram, int& histcompr); - double getDefGain () + double getDefGain () const { return 0.0; } @@ -90,20 +90,10 @@ public: plistener = pl; } - void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb);// RAWParams raw will not be used for non-raw files (see imagesource.h) - static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat); + void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb);// 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); - static inline double intpow (double a, int b) - { - double r = 1.0; - - for (int i = 0; i < b; i++) { - r *= a; - } - - return r; - } - bool IsrgbSourceModified() + bool IsrgbSourceModified() const { return rgbSourceModified; } diff --git a/rtengine/utils.cc b/rtengine/utils.cc index b45e4b436..2366f3a0c 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -29,6 +29,51 @@ using namespace std; namespace rtengine { +void poke255_uc(unsigned char* &dest, unsigned char r, unsigned char g, unsigned char b) +{ +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + *(dest++) = b; + *(dest++) = g; + *(dest++) = r; + *(dest++) = 0; +#else + *(dest++) = 0; + *(dest++) = r; + *(dest++) = g; + *(dest++) = b; +#endif +} + +void poke01_d(unsigned char* &dest, double r, double g, double b) +{ +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + *(dest++) = (unsigned char)(b * 255.); + *(dest++) = (unsigned char)(g * 255.); + *(dest++) = (unsigned char)(r * 255.); + *(dest++) = 0; +#else + *(dest++) = 0; + *(dest++) = (unsigned char)(r * 255.); + *(dest++) = (unsigned char)(g * 255.); + *(dest++) = (unsigned char)(b * 255.); +#endif +} + +void poke01_f(unsigned char* &dest, float r, float g, float b) +{ +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + *(dest++) = (unsigned char)(b * 255.f); + *(dest++) = (unsigned char)(g * 255.f); + *(dest++) = (unsigned char)(r * 255.f); + *(dest++) = 0; +#else + *(dest++) = 0; + *(dest++) = (unsigned char)(r * 255.f); + *(dest++) = (unsigned char)(g * 255.f); + *(dest++) = (unsigned char)(b * 255.f); +#endif +} + void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { diff --git a/rtengine/utils.h b/rtengine/utils.h index 3040e39b9..c46999219 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -16,17 +16,30 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _SIMPLEUTILS_ -#define _SIMPLEUTILS_ +#pragma once + +#include namespace rtengine { +// update a point of a Cairo::Surface by accessing the raw data +void poke255_uc(unsigned char* &dest, unsigned char r, unsigned char g, unsigned char b); +// update a point of a Cairo::Surface by accessing the raw data +void poke01_d(unsigned char* &dest, double r, double g, double b); +// update a point of a Cairo::Surface by accessing the raw data +void poke01_f(unsigned char* &dest, float r, float g, float b); + void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); void nearestInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); void rotate (unsigned char* img, int& w, int& h, int deg); void hflip (unsigned char* img, int w, int h); void vflip (unsigned char* img, int w, int h); +template +typename std::underlying_type::type toUnderlying(ENUM value) +{ + return static_cast::type>(value); +} + } -#endif diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc index 981798732..bd14c6514 100644 --- a/rtexif/canonattribs.cc +++ b/rtexif/canonattribs.cc @@ -149,6 +149,9 @@ public: choices[3] = "Continuous, Speed Priority"; choices[4] = "Continuous, Low"; choices[5] = "Continuous, High"; + choices[6] = "Silent Single"; + choices[9] = "Single, Silent"; + choices[10] = "Continuous, Silent"; } }; CAContinuousDriveInterpreter caContinuousDriveInterpreter; @@ -161,11 +164,13 @@ public: choices[0] = "One-shot AF"; choices[1] = "AI Servo AF"; choices[2] = "AI Focus AF"; - choices[3] = "Manual Focus"; + choices[3] = "Manual Focus (3)"; choices[4] = "Single"; choices[5] = "Continuous"; - choices[6] = "Manual Focus"; + choices[6] = "Manual Focus (6)"; choices[16] = "Pan Focus"; + choices[256] = "AF + MF"; + choices[512] = "Movie Snap Focus"; } }; CAFocusModeInterpreter caFocusModeInterpreter; @@ -182,7 +187,8 @@ public: choices[5] = "TIF+JPEG"; choices[6] = "CR2"; choices[7] = "CR2+JPEG"; - choices[9] = "Video"; + choices[9] = "MOV"; + choices[10] = "MP4"; } }; CARecordModeInterpreter caRecordModeInterpreter; @@ -201,6 +207,9 @@ public: choices[8] = "Postcard"; choices[9] = "Widescreen"; choices[10] = "Medium Widescreen"; + choices[14] = "Small 1"; + choices[15] = "Small 2"; + choices[16] = "Small 3"; choices[128] = "640x480 Movie"; choices[129] = "Medium Movie"; choices[130] = "Small Movie"; @@ -215,17 +224,17 @@ class CAEasyModeInterpreter : public ChoiceInterpreter public: CAEasyModeInterpreter () { - choices[0] = "Full auto "; - choices[1] = "Manual "; - choices[2] = "Landscape "; - choices[3] = "Fast shutter "; - choices[4] = "Slow shutter "; - choices[5] = "Night "; - choices[6] = "Gray Scale "; - choices[7] = "Sepia "; - choices[8] = "Portrait "; - choices[9] = "Sports "; - choices[10] = "Macro "; + choices[0] = "Full auto"; + choices[1] = "Manual"; + choices[2] = "Landscape"; + choices[3] = "Fast shutter"; + choices[4] = "Slow shutter"; + choices[5] = "Night"; + choices[6] = "Gray Scale"; + choices[7] = "Sepia"; + choices[8] = "Portrait"; + choices[9] = "Sports"; + choices[10] = "Macro"; choices[11] = "Black & White"; choices[12] = "Pan focus"; choices[13] = "Vivid"; @@ -243,17 +252,49 @@ public: choices[25] = "Night Snapshot"; choices[26] = "Digital Macro"; choices[27] = "My Colors"; - choices[28] = "Still Image"; + choices[28] = "Movie Snap"; + choices[29] = "Super Macro 2"; choices[30] = "Color Accent"; choices[31] = "Color Swap"; choices[32] = "Aquarium"; choices[33] = "ISO 3200"; + choices[34] = "ISO 6400"; + choices[35] = "Creative Light Effect"; + choices[36] = "Easy"; + choices[37] = "Quick Shot"; choices[38] = "Creative Auto"; + choices[39] = "Zoom Blur"; + choices[40] = "Low Light"; + choices[41] = "Nostalgic"; choices[42] = "Super Vivid"; - choices[43] = "Poster"; - choices[47] = "Fisheye"; - choices[48] = "Miniature"; + choices[43] = "Poster Effect"; + choices[44] = "Face Self-timer"; + choices[45] = "Smile"; + choices[46] = "Wink Self-timer"; + choices[47] = "Fisheye Effect"; + choices[48] = "Miniature Effect"; + choices[49] = "High-speed Burst"; + choices[50] = "Best Image Selection"; + choices[51] = "High Dynamic Range"; + choices[52] = "Handheld Night Scene"; + choices[53] = "Movie Digest"; + choices[54] = "Live View Control"; + choices[55] = "Discreet"; + choices[56] = "Blur Reduction"; + choices[57] = "Monochrome"; + choices[58] = "Toy Camera Effect"; + choices[59] = "Scene Intelligent Auto"; + choices[60] = "High-speed Burst HQ"; + choices[61] = "Smooth Skin"; + choices[62] = "Soft Focus"; + choices[257] = "Spotlight"; + choices[258] = "Night 2"; + choices[259] = "Night+"; + choices[260] = "Super Night"; choices[261] = "Sunset"; + choices[263] = "Night Scene"; + choices[264] = "Surface"; + choices[265] = "Low Light 2"; } }; CAEasyModeInterpreter caEasyModeInterpreter; @@ -281,7 +322,7 @@ public: choices[2] = "Average"; choices[3] = "Evaluative"; choices[4] = "Partial"; - choices[5] = "Center-weighted averaging"; + choices[5] = "Center-weighted average"; } }; CAMeteringModeInterpreter caMeteringModeInterpreter; @@ -422,9 +463,14 @@ public: { choices[0] = "Off"; choices[1] = "On"; - choices[2] = "On, Shot Only"; - choices[3] = "On, Panning"; - choices[4] = "On, Video"; + choices[2] = "Shoot Only"; + choices[3] = "Panning"; + choices[4] = "Dynamic"; + choices[256] = "Off (2)"; + choices[257] = "On (2)"; + choices[258] = "Shoot Only (2)"; + choices[259] = "Panning (2)"; + choices[260] = "Dynamic (2)"; } }; CAStabilizationInterpreter caStabilizationInterpreter; @@ -593,6 +639,8 @@ public: choices.insert(p_t(44, "Canon EF 90-300mm f/4.5-5.6")); choices.insert(p_t(45, "Canon EF-S 18-55mm f/3.5-5.6 [II]")); choices.insert(p_t(46, "Canon EF 28-90mm f/4-5.6")); + choices.insert(p_t(47, "Zeiss Milvus 35mm f/2 or 50mm f/2")); + choices.insert(p_t(47, "Zeiss Milvus 50mm f/2 Makro")); choices.insert(p_t(48, "Canon EF-S 18-55mm f/3.5-5.6 IS")); choices.insert(p_t(49, "Canon EF-S 55-250mm f/4-5.6 IS")); choices.insert(p_t(50, "Canon EF-S 18-200mm f/3.5-5.6 IS")); @@ -626,9 +674,9 @@ public: choices.insert(p_t(137, "Sigma 18-250mm f/3.5-6.3 DC OS HSM")); choices.insert(p_t(137, "Sigma 24-70mm f/2.8 IF EX DG HSM")); choices.insert(p_t(137, "Sigma 18-125mm f/3.8-5.6 DC OS HSM")); - choices.insert(p_t(137, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM")); + choices.insert(p_t(137, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C")); choices.insert(p_t(137, "Sigma 17-50mm f/2.8 OS HSM")); - choices.insert(p_t(137, "Sigma 18-200mm f/3.5-6.3 II DC OS HSM")); + choices.insert(p_t(137, "Sigma 18-200mm f/3.5-6.3 DC OS HSM [II]")); choices.insert(p_t(137, "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD")); choices.insert(p_t(137, "Sigma 8-16mm f/4.5-5.6 DC HSM")); choices.insert(p_t(137, "Tamron SP 17-50mm f/2.8 XR Di II VC")); @@ -642,7 +690,8 @@ public: choices.insert(p_t(140, "Canon EF 500mm f/4.5L")); choices.insert(p_t(141, "Canon EF 500mm f/4.5L")); choices.insert(p_t(142, "Canon EF 300mm f/2.8L IS")); - choices.insert(p_t(143, "Canon EF 500mm f/4L IS")); + choices.insert(p_t(143, "Canon EF 500mm f/4L IS or Sigma Lens")); + choices.insert(p_t(143, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM")); choices.insert(p_t(144, "Canon EF 35-135mm f/4-5.6 USM")); choices.insert(p_t(145, "Canon EF 100-300mm f/4.5-5.6 USM")); choices.insert(p_t(146, "Canon EF 70-210mm f/3.5-4.5 USM")); @@ -665,15 +714,18 @@ public: choices.insert(p_t(153, "Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical [IF] Macro")); choices.insert(p_t(153, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro Model A14")); choices.insert(p_t(153, "Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro")); - choices.insert(p_t(154, "Canon EF 20mm f/2.8 USM")); + choices.insert(p_t(154, "Canon EF 20mm f/2.8 USM or Zeiss Lens")); + choices.insert(p_t(154, "Zeiss Milvus 21mm f/2.8")); choices.insert(p_t(155, "Canon EF 85mm f/1.8 USM")); choices.insert(p_t(156, "Canon EF 28-105mm f/3.5-4.5 USM or Tamron Lens")); choices.insert(p_t(156, "Tamron SP 70-300mm f/4.0-5.6 Di VC USD")); + choices.insert(p_t(156, "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF")); choices.insert(p_t(160, "Canon EF 20-35mm f/3.5-4.5 USM or Tamron or Tokina Lens")); choices.insert(p_t(160, "Tamron AF 19-35mm f/3.5-4.5")); choices.insert(p_t(160, "Tokina AT-X 124 AF Pro DX 12-24mm f/4")); choices.insert(p_t(160, "Tokina AT-X 107 AF DX 10-17mm f/3.5-4.5 Fisheye")); choices.insert(p_t(160, "Tokina AT-X 116 AF Pro DX 11-16mm f/2.8")); + choices.insert(p_t(160, "Tokina AT-X 11-20 F2.8 PRO DX Aspherical 11-20mm f/2.8")); choices.insert(p_t(161, "Canon EF 28-70mm f/2.8L or Sigma or Tamron Lens")); choices.insert(p_t(161, "Sigma 24-70mm f/2.8 EX")); choices.insert(p_t(161, "Sigma 28-70mm f/2.8 EX")); @@ -688,7 +740,8 @@ public: choices.insert(p_t(165, "Canon EF 70-200mm f/2.8 L")); choices.insert(p_t(166, "Canon EF 70-200mm f/2.8 L + 1.4x")); choices.insert(p_t(167, "Canon EF 70-200mm f/2.8 L + 2x")); - choices.insert(p_t(168, "Canon EF 28mm f/1.8 USM")); + choices.insert(p_t(168, "Canon EF 28mm f/1.8 USM or Sigma Lens")); + choices.insert(p_t(168, "Sigma 50-100mm f/1.8 DC HSM | A")); choices.insert(p_t(169, "Canon EF 17-35mm f/2.8L or Sigma Lens")); choices.insert(p_t(169, "Sigma 18-200mm f/3.5-6.3 DC OS")); choices.insert(p_t(169, "Sigma 15-30mm f/3.5-4.5 EX DG Aspherical")); @@ -704,25 +757,32 @@ public: choices.insert(p_t(173, "Canon EF 180mm Macro f/3.5L or Sigma Lens")); choices.insert(p_t(173, "Sigma 180mm EX HSM Macro f/3.5")); choices.insert(p_t(173, "Sigma APO Macro 150mm f/2.8 EX DG HSM")); - choices.insert(p_t(174, "Canon EF 135mm f/2L or Sigma Lens")); + choices.insert(p_t(174, "Canon EF 135mm f/2L or Other Lens")); choices.insert(p_t(174, "Sigma 70-200mm f/2.8 EX DG APO OS HSM")); choices.insert(p_t(174, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM")); choices.insert(p_t(174, "Sigma 150-500mm f/5-6.3 APO DG OS HSM")); + choices.insert(p_t(174, "Zeiss Milvus 100mm f/2 Makro")); choices.insert(p_t(175, "Canon EF 400mm f/2.8L")); choices.insert(p_t(176, "Canon EF 24-85mm f/3.5-4.5 USM")); choices.insert(p_t(177, "Canon EF 300mm f/4L IS")); choices.insert(p_t(178, "Canon EF 28-135mm f/3.5-5.6 IS")); choices.insert(p_t(179, "Canon EF 24mm f/1.4L")); - choices.insert(p_t(180, "Canon EF 35mm f/1.4L or Sigma Lens")); + choices.insert(p_t(180, "Canon EF 35mm f/1.4L or Other Lens")); choices.insert(p_t(180, "Sigma 50mm f/1.4 DG HSM | A")); choices.insert(p_t(180, "Sigma 24mm f/1.4 DG HSM | A")); - choices.insert(p_t(181, "Canon EF 100-400mm f/4.5-5.6L IS + 1.4x")); - choices.insert(p_t(182, "Canon EF 100-400mm f/4.5-5.6L IS + 2x")); + choices.insert(p_t(180, "Zeiss Milvus 50mm f/1.4")); + choices.insert(p_t(180, "Zeiss Milvus 85mm f/1.4")); + choices.insert(p_t(180, "Zeiss Otus 28mm f/1.4 ZE")); + choices.insert(p_t(181, "Canon EF 100-400mm f/4.5-5.6L IS + 1.4x or Sigma Lens")); + choices.insert(p_t(181, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + 1.4x")); + choices.insert(p_t(182, "Canon EF 100-400mm f/4.5-5.6L IS + 2x or Sigma Lens")); + choices.insert(p_t(182, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + 2x")); choices.insert(p_t(183, "Canon EF 100-400mm f/4.5-5.6L IS or Sigma Lens")); choices.insert(p_t(183, "Sigma 150mm f/2.8 EX DG OS HSM APO Macro")); choices.insert(p_t(183, "Sigma 105mm f/2.8 EX DG OS HSM Macro")); choices.insert(p_t(183, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro")); choices.insert(p_t(183, "Sigma 150-600mm f/5-6.3 DG OS HSM | C")); + choices.insert(p_t(183, "Sigma 150-600mm f/5-6.3 DG OS HSM | S")); choices.insert(p_t(184, "Canon EF 400mm f/2.8L + 2x")); choices.insert(p_t(185, "Canon EF 600mm f/4L IS")); choices.insert(p_t(186, "Canon EF 70-200mm f/4L")); @@ -751,6 +811,8 @@ public: choices.insert(p_t(213, "Canon EF 90-300mm f/4.5-5.6 USM or Tamron Lens")); choices.insert(p_t(213, "Tamron SP 150-600mm f/5-6.3 Di VC USD")); choices.insert(p_t(213, "Tamron 16-300mm f/3.5-6.3 Di II VC PZD Macro")); + choices.insert(p_t(213, "Tamron SP 35mm f/1.8 Di VC USD")); + choices.insert(p_t(213, "Tamron SP 45mm f/1.8 Di VC USD")); choices.insert(p_t(214, "Canon EF-S 18-55mm f/3.5-5.6 USM")); choices.insert(p_t(215, "Canon EF 55-200mm f/4.5-5.6 II USM")); choices.insert(p_t(217, "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD")); @@ -765,7 +827,7 @@ public: choices.insert(p_t(232, "Canon EF 70-300mm f/4.5-5.6 DO IS USM")); choices.insert(p_t(233, "Canon EF 28-300mm f/3.5-5.6L IS")); choices.insert(p_t(234, "Canon EF-S 17-85mm f/4-5.6 IS USM or Tokina Lens")); - choices.insert(p_t(234, "Tokina AT-X 12-28mm f/4 PRO DX")); + choices.insert(p_t(234, "Tokina AT-X 12-28 PRO DX 12-28mm f/4")); choices.insert(p_t(235, "Canon EF-S 10-22mm f/3.5-4.5 USM")); choices.insert(p_t(236, "Canon EF-S 60mm f/2.8 Macro USM")); choices.insert(p_t(237, "Canon EF 24-105mm f/4L IS")); @@ -779,9 +841,11 @@ public: choices.insert(p_t(245, "Canon EF 70-200mm f/4L IS + 2.8x")); choices.insert(p_t(246, "Canon EF 16-35mm f/2.8L II")); choices.insert(p_t(247, "Canon EF 14mm f/2.8L II USM")); - choices.insert(p_t(248, "Canon EF 200mm f/2L IS")); + choices.insert(p_t(248, "Canon EF 200mm f/2L IS or Sigma Lens")); + choices.insert(p_t(248, "Sigma 24-35mm f/2 DG HSM | A")); choices.insert(p_t(249, "Canon EF 800mm f/5.6L IS")); - choices.insert(p_t(250, "Canon EF 24 f/1.4L II")); + choices.insert(p_t(250, "Canon EF 24mm f/1.4L II or Sigma Lens")); + choices.insert(p_t(250, "Sigma 20mm f/1.4 DG HSM | A")); choices.insert(p_t(251, "Canon EF 70-200mm f/2.8L IS II USM")); choices.insert(p_t(252, "Canon EF 70-200mm f/2.8L IS II USM + 1.4x")); choices.insert(p_t(253, "Canon EF 70-200mm f/2.8L IS II USM + 2x")); @@ -807,6 +871,8 @@ public: choices.insert(p_t(507, "Canon EF 16-35mm f/4L IS USM")); choices.insert(p_t(508, "Canon EF 11-24mm f/4L USM")); choices.insert(p_t(747, "Canon EF 100-400mm f/4.5-5.6L IS II USM")); + choices.insert(p_t(748, "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x")); + choices.insert(p_t(750, "Canon EF 35mm f/1.4L II USM")); choices.insert(p_t(4142, "Canon EF-S 18-135mm f/3.5-5.6 IS STM")); choices.insert(p_t(4143, "Canon EF-M 18-55mm f/3.5-5.6 IS STM or Tamron Lens")); choices.insert(p_t(4143, "Tamron 18-200mm f/3.5-6.3 Di III VC")); @@ -818,8 +884,12 @@ public: choices.insert(p_t(4149, "Canon EF-M 55-200mm f/4.5-6.3 IS STM")); choices.insert(p_t(4150, "Canon EF-S 10-18mm f/4.5-5.6 IS STM")); choices.insert(p_t(4152, "Canon EF 24-105mm f/3.5-5.6 IS STM")); + choices.insert(p_t(4153, "Canon EF-M 15-45mm f/3.5-6.3 IS STM")); choices.insert(p_t(4154, "Canon EF-S 24mm f/2.8 STM")); + choices.insert(p_t(4155, "Canon EF-M 28mm f/3.5 Macro IS STM ")); choices.insert(p_t(4156, "Canon EF 50mm f/1.8 STM")); + choices.insert(p_t(36912, "Canon EF-S 18-135mm f/3.5-5.6 IS USM")); + choices.insert(p_t(65535, "n/a")); } virtual std::string toString (Tag* t) @@ -962,7 +1032,7 @@ class CAFocalTypeInterpreter : public ChoiceInterpreter public: CAFocalTypeInterpreter() { - choices[0] = "undef"; + choices[0] = "Fixed"; choices[1] = "Fixed"; choices[2] = "Zoom"; } @@ -980,7 +1050,7 @@ public: return "undef"; } - char buffer[1024]; + char buffer[32]; sprintf (buffer, "%.2fmm", val * 25.4 / 1000); return buffer; } @@ -992,7 +1062,7 @@ class CAExposureTimeInterpreter : public Interpreter public: virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; double d = pow (2, - t->toInt() / 32.0); sprintf (buffer, "%.3f", d); return buffer; @@ -1004,7 +1074,7 @@ class CAEVInterpreter : public Interpreter { virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; sprintf (buffer, "%.1f", t->toDouble() / 32.0 ); return buffer; } @@ -1095,6 +1165,11 @@ public: choices[15] = "Custom 1"; choices[16] = "Custom 2"; choices[17] = "Underwater"; + choices[18] = "Custom 3"; + choices[19] = "Custom 4"; + choices[20] = "PC Set4"; + choices[21] = "PC Set5"; + choices[23] = "Auto (ambience priority)"; } }; CAWhiteBalanceInterpreter caWhiteBalanceInterpreter; @@ -1112,15 +1187,17 @@ public: choices[0x21] = "User Def. 1"; choices[0x22] = "User Def. 2"; choices[0x23] = "User Def. 3"; - choices[0x41] = "External 1"; - choices[0x42] = "External 2"; - choices[0x43] = "External 3"; + choices[0x41] = "PC 1"; + choices[0x42] = "PC 2"; + choices[0x43] = "PC 3"; choices[0x81] = "Standard"; choices[0x82] = "Portrait"; choices[0x83] = "Landscape"; choices[0x84] = "Neutral"; choices[0x85] = "Faithful"; choices[0x86] = "Monochrome"; + choices[0x87] = "Auto"; + choices[0x88] = "Fine Detail"; } }; CAPictureStyleInterpreter caPictureStyleInterpreter; @@ -1204,7 +1281,7 @@ class CAFocusDistanceInterpreter : public Interpreter public: virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; sprintf (buffer, "%.2f", t->toDouble() / 100 ); return buffer; } @@ -1216,7 +1293,7 @@ class CAMeasuredEVInterpreter : public Interpreter public: virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; sprintf (buffer, "%.1f", t->toDouble() / 8 - 6 ); return buffer; } @@ -1274,6 +1351,8 @@ public: choices[3] = "Fine"; choices[4] = "RAW"; choices[5] = "Superfine"; + choices[130] = "Normal Movie"; + choices[131] = "Movie (2)"; } }; CARAWJpegQualityInterpreter caRAWJpegQualityInterpreter; @@ -1291,6 +1370,15 @@ public: choices[7] = "Medium 3"; choices[8] = "Postcard"; choices[9] = "Widescreen"; + choices[10] = "Medium Widescreen"; + choices[14] = "Small 1"; + choices[15] = "Small 2"; + choices[16] = "Small 3"; + choices[128] = "640x480 Movie"; + choices[129] = "Medium Movie"; + choices[130] = "Small Movie"; + choices[137] = "1280x720 Movie"; + choices[142] = "1920x1080 Movie"; } }; CAJpegSizeInterpreter caJpegSizeInterpreter; @@ -1301,8 +1389,8 @@ public: CAWBBracketModeInterpreter() { choices[0] = "Off"; - choices[1] = "Shift AB"; - choices[2] = "shift GM"; + choices[1] = "On (shift AB)"; + choices[2] = "On (shift GM)"; } }; CAWBBracketModeInterpreter caWBBracketModeInterpreter; @@ -1398,10 +1486,10 @@ public: choices[0x1570000] = "PowerShot A510"; choices[0x1590000] = "PowerShot SD20 / Digital IXUS i5 / IXY Digital L2"; choices[0x1640000] = "PowerShot S2 IS"; - choices[0x1650000] = "PowerShot SD430 / IXUS Wireless / IXY Wireless"; + choices[0x1650000] = "PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless"; choices[0x1660000] = "PowerShot SD500 / Digital IXUS 700 / IXY Digital 600"; choices[0x1668000] = "EOS D60"; - choices[0x1700000] = "PowerShot SD30 / Digital IXUS i zoom / IXY Digital L3"; + choices[0x1700000] = "PowerShot SD30 / Digital IXUS i Zoom / IXY Digital L3"; choices[0x1740000] = "PowerShot A430"; choices[0x1750000] = "PowerShot A410"; choices[0x1760000] = "PowerShot S80"; @@ -1474,7 +1562,7 @@ public: choices[0x2770000] = "PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS"; choices[0x2800000] = "PowerShot A495"; choices[0x2810000] = "PowerShot A490"; - choices[0x2820000] = "PowerShot A3100 IS"; + choices[0x2820000] = "PowerShot A3100 IS / A3150 IS"; choices[0x2830000] = "PowerShot A3000 IS"; choices[0x2840000] = "PowerShot SD1400 IS / IXUS 130 / IXY 400F"; choices[0x2850000] = "PowerShot SD1300 IS / IXUS 105 / IXY 200F"; @@ -1486,36 +1574,125 @@ public: choices[0x2930000] = "PowerShot SX30 IS"; choices[0x2940000] = "PowerShot SX130 IS"; choices[0x2950000] = "PowerShot S95"; + choices[0x2980000] = "PowerShot A3300 IS"; + choices[0x2990000] = "PowerShot A3200 IS"; + choices[0x3000000] = "PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31S"; choices[0x3010000] = "PowerShot Pro90 IS"; - choices[0x3340000] = "PowerShot SX50 HS"; - choices[0x3360000] = "PowerShot S110"; + choices[0x3010001] = "PowerShot A800"; + choices[0x3020000] = "PowerShot ELPH 100 HS / IXUS 115 HS / IXY 210F"; + choices[0x3030000] = "PowerShot SX230 HS"; + choices[0x3040000] = "PowerShot ELPH 300 HS / IXUS 220 HS / IXY 410F"; + choices[0x3050000] = "PowerShot A2200"; + choices[0x3060000] = "PowerShot A1200"; + choices[0x3070000] = "PowerShot SX220 HS"; + choices[0x3080000] = "PowerShot G1 X"; + choices[0x3090000] = "PowerShot SX150 IS"; + choices[0x3100000] = "PowerShot ELPH 510 HS / IXUS 1100 HS / IXY 51S"; + choices[0x3110000] = "PowerShot S100 (new)"; + choices[0x3120000] = "PowerShot ELPH 310 HS / IXUS 230 HS / IXY 600F"; + choices[0x3130000] = "PowerShot SX40 HS"; + choices[0x3140000] = "IXY 32S"; + choices[0x3160000] = "PowerShot A1300"; + choices[0x3170000] = "PowerShot A810"; + choices[0x3180000] = "PowerShot ELPH 320 HS / IXUS 240 HS / IXY 420F"; + choices[0x3190000] = "PowerShot ELPH 110 HS / IXUS 125 HS / IXY 220F"; + choices[0x3200000] = "PowerShot D20"; + choices[0x3210000] = "PowerShot A4000 IS"; + choices[0x3220000] = "PowerShot SX260 HS"; + choices[0x3230000] = "PowerShot SX240 HS"; + choices[0x3240000] = "PowerShot ELPH 530 HS / IXUS 510 HS / IXY 1"; + choices[0x3250000] = "PowerShot ELPH 520 HS / IXUS 500 HS / IXY 3"; + choices[0x3260000] = "PowerShot A3400 IS"; + choices[0x3270000] = "PowerShot A2400 IS"; + choices[0x3280000] = "PowerShot A2300"; + choices[0x3330000] = "PowerShot G15"; + choices[0x3340000] = "PowerShot SX50"; + choices[0x3350000] = "PowerShot SX160 IS"; + choices[0x3360000] = "PowerShot S110 (new)"; + choices[0x3370000] = "PowerShot SX500 IS"; + choices[0x3380000] = "PowerShot N"; + choices[0x3390000] = "IXUS 245 HS / IXY 430F"; + choices[0x3400000] = "PowerShot SX280 HS"; + choices[0x3410000] = "PowerShot SX270 HS"; + choices[0x3420000] = "PowerShot A3500 IS"; + choices[0x3430000] = "PowerShot A2600"; + choices[0x3450000] = "PowerShot A1400"; + choices[0x3460000] = "PowerShot ELPH 130 IS / IXUS 140 / IXY 110F"; + choices[0x3470000] = "PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F"; + choices[0x3490000] = "PowerShot ELPH 330 HS / IXUS 255 HS / IXY 610F"; + choices[0x3510000] = "PowerShot A2500"; choices[0x3540000] = "PowerShot G16"; choices[0x3550000] = "PowerShot S120"; + choices[0x3560000] = "PowerShot SX170 IS"; + choices[0x3580000] = "PowerShot SX510 HS"; + choices[0x3590000] = "PowerShot S200 (new)"; + choices[0x3600000] = "IXY 620F"; + choices[0x3610000] = "PowerShot N100"; + choices[0x3640000] = "PowerShot G1 X Mark II"; + choices[0x3650000] = "PowerShot D30"; + choices[0x3660000] = "PowerShot SX700 HS"; + choices[0x3670000] = "PowerShot SX600 HS"; + choices[0x3680000] = "PowerShot ELPH 140 IS / IXUS 150 / IXY 130"; + choices[0x3690000] = "PowerShot ELPH 135 / IXUS 145 / IXY 120"; + choices[0x3700000] = "PowerShot ELPH 340 HS / IXUS 265 HS / IXY 630"; + choices[0x3710000] = "PowerShot ELPH 150 IS / IXUS 155 / IXY 140"; + choices[0x3740000] = "EOS M3"; + choices[0x3750000] = "PowerShot SX60 HS"; + choices[0x3760000] = "PowerShot SX520 HS"; + choices[0x3770000] = "PowerShot SX400 IS"; + choices[0x3780000] = "PowerShot G7 X"; + choices[0x3790000] = "PowerShot N2"; + choices[0x3800000] = "PowerShot SX530 HS"; + choices[0x3820000] = "PowerShot SX710 HS"; + choices[0x3830000] = "PowerShot SX610 HS"; + choices[0x3840000] = "EOS M10"; + choices[0x3850000] = "PowerShot G3 X"; + choices[0x3860000] = "PowerShot ELPH 165 HS / IXUS 165 / IXY 160"; + choices[0x3870000] = "PowerShot ELPH 160 / IXUS 160"; + choices[0x3880000] = "PowerShot ELPH 350 HS / IXUS 275 HS / IXY 640"; + choices[0x3890000] = "PowerShot ELPH 170 IS / IXUS 170"; + choices[0x3910000] = "PowerShot SX410 IS"; + choices[0x3930000] = "PowerShot G9 X"; + choices[0x3950000] = "PowerShot G5 X"; + choices[0x3970000] = "PowerShot G7 X Mark II"; + choices[0x3990000] = "PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650"; + choices[0x4010000] = "PowerShot SX540 HS"; + choices[0x4020000] = "PowerShot SX420 IS"; + choices[0x4030000] = "PowerShot ELPH 190 IS / IXUS 180 / IXY 190"; choices[0x4040000] = "PowerShot G1"; + choices[0x4040001] = "IXY 180"; + choices[0x4050000] = "PowerShot SX720 HS"; choices[0x6040000] = "PowerShot S100 / Digital IXUS / IXY Digital"; - choices[0x4007d673] = "DC19 / DC21 / DC22"; + choices[0x4007d673] = "DC19/DC21/DC22"; choices[0x4007d674] = "XH A1"; choices[0x4007d675] = "HV10"; - choices[0x4007d676] = "MD130 / MD140 / MD150 / MD160"; - choices[0x4007d777] = "iVIS DC50"; - choices[0x4007d778] = "iVIS HV20"; + choices[0x4007d676] = "MD130/MD140/MD150/MD160/ZR850"; + choices[0x4007d777] = "DC50"; + choices[0x4007d778] = "HV20"; choices[0x4007d779] = "DC211"; choices[0x4007d77a] = "HG10"; - choices[0x4007d77b] = "iVIS HR10"; + choices[0x4007d77b] = "HR10"; + choices[0x4007d77d] = "MD255/ZR950"; + choices[0x4007d81c] = "HF11"; choices[0x4007d878] = "HV30"; - choices[0x4007d87e] = "DC301 / DC310 / DC311 / DC320 / DC330"; + choices[0x4007d87c] = "XH A1S"; + choices[0x4007d87e] = "DC301/DC310/DC311/DC320/DC330"; choices[0x4007d87f] = "FS100"; - choices[0x4007d880] = "iVIS HF10"; - choices[0x4007d882] = "HG20 / HG21 / VIXIA HG21"; - choices[0x4007d925] = "LEGRIA HF21"; - choices[0x4007d978] = "LEGRIA HV40"; - choices[0x4007d987] = "DC410 / DC420"; - choices[0x4007d988] = "LEGRIA FS19 / FS20 / FS21 / FS22 / FS200"; - choices[0x4007d989] = "LEGRIA HF20 / HF200"; - choices[0x4007d98a] = "VIXIA HF S10 / S100"; - choices[0x4007da8e] = "LEGRIA HF R16 / R17 / R106"; - choices[0x4007da90] = "LEGRIA HF S21 / VIXIA HF S200"; - choices[0x4007da92] = "LEGRIA FS36 / FS305 / FS306 / FS307"; + choices[0x4007d880] = "HF10"; + choices[0x4007d882] = "HG20/HG21"; + choices[0x4007d925] = "HF21"; + choices[0x4007d926] = "HF S11"; + choices[0x4007d978] = "HV40"; + choices[0x4007d987] = "DC410/DC411/DC420"; + choices[0x4007d988] = "FS19/FS20/FS21/FS22/FS200"; + choices[0x4007d989] = "HF20/HF200"; + choices[0x4007d98a] = "HF S10/S100"; + choices[0x4007da8e] = "HF R10/R16/R17/R18/R100/R106"; + choices[0x4007da8f] = "HF M30/M31/M36/M300/M306"; + choices[0x4007da90] = "HF S20/S21/S200"; + choices[0x4007da92] = "FS31/FS36/FS37/FS300/FS305/FS306/FS307"; + choices[0x4007dda9] = "HF G25"; + choices[0x4007dfb4] = "XC10"; choices[0x80000001] = "EOS-1D"; choices[0x80000167] = "EOS-1DS"; choices[0x80000168] = "EOS 10D"; @@ -1530,19 +1707,44 @@ public: choices[0x80000213] = "EOS 5D"; choices[0x80000215] = "EOS-1Ds Mark III"; choices[0x80000218] = "EOS 5D Mark II"; + choices[0x80000219] = "WFT-E1"; choices[0x80000232] = "EOS-1D Mark II N"; choices[0x80000234] = "EOS 30D"; choices[0x80000236] = "EOS Digital Rebel XTi / 400D / Kiss Digital X"; + choices[0x80000241] = "WFT-E2"; + choices[0x80000246] = "WFT-E3"; choices[0x80000250] = "EOS 7D"; choices[0x80000252] = "EOS Rebel T1i / 500D / Kiss X3"; choices[0x80000254] = "EOS Rebel XS / 1000D / Kiss F"; choices[0x80000261] = "EOS 50D"; + choices[0x80000269] = "EOS-1D X"; choices[0x80000270] = "EOS Rebel T2i / 550D / Kiss X4"; + choices[0x80000271] = "WFT-E4"; + choices[0x80000273] = "WFT-E5"; choices[0x80000281] = "EOS-1D Mark IV"; choices[0x80000285] = "EOS 5D Mark III"; - choices[0x80000286] = "EOS 600D"; + choices[0x80000286] = "EOS Rebel T3i / 600D / Kiss X5"; choices[0x80000287] = "EOS 60D"; + choices[0x80000288] = "EOS Rebel T3 / 1100D / Kiss X50"; + choices[0x80000289] = "EOS 7D Mark II"; + choices[0x80000297] = "WFT-E2 II"; + choices[0x80000298] = "WFT-E4 II"; + choices[0x80000301] = "EOS Rebel T4i / 650D / Kiss X6i"; + choices[0x80000302] = "EOS 6D"; + choices[0x80000324] = "EOS-1D C"; choices[0x80000325] = "EOS 70D"; + choices[0x80000326] = "EOS Rebel T5i / 700D / Kiss X7i"; + choices[0x80000327] = "EOS Rebel T5 / 1200D / Kiss X70"; + choices[0x80000328] = "EOS-1D X MARK II"; + choices[0x80000331] = "EOS M"; + choices[0x80000346] = "EOS Rebel SL1 / 100D / Kiss X7"; + choices[0x80000347] = "EOS Rebel T6s / 760D / 8000D"; + choices[0x80000350] = "EOS 80D"; + choices[0x80000355] = "EOS M2"; + choices[0x80000382] = "EOS 5DS"; + choices[0x80000393] = "EOS Rebel T6i / 750D / Kiss X8i"; + choices[0x80000401] = "EOS 5DS R"; + choices[0x80000404] = "EOS Rebel T6 / 1300D / Kiss X80"; } }; CAModelIDInterpreter caModelIDInterpreter; @@ -1570,6 +1772,7 @@ public: choices[1] = "1:1"; choices[2] = "4:3"; choices[7] = "16:9"; + choices[8] = "4:5"; } }; @@ -1641,12 +1844,10 @@ const TagAttrib canonShotInfoAttribs[] = { {0, AC_WRITE, 0, 0, 16, AUTO, "AutoExposureBracketing", &caAutoExposureBracketingInterpreter}, {0, AC_WRITE, 0, 0, 17, AUTO, "AEBBracketValue", &stdInterpreter}, {0, AC_WRITE, 0, 0, 18, AUTO, "ControlMode", &caControModeInterpreter}, - {0, AC_WRITE, 0, 0, 19, AUTO, "FocusDistanceUpper", &caFocusDistanceInterpreter}, - {0, AC_WRITE, 0, 0, 20, AUTO, "FocusDistanceLower", &caFocusDistanceInterpreter}, {0, AC_WRITE, 0, 0, 21, AUTO, "FNumber" , &caApertureInterpreter}, {0, AC_WRITE, 0, 0, 22, AUTO, "ExposureTime", &caExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 23, AUTO, "MeasuredEV2", &caMeasuredEVInterpreter}, {0, AC_WRITE, 0, 0, 24, AUTO, "BulbDuration", &stdInterpreter}, - {0, AC_WRITE, 0, 0, 24, AUTO, "MeasuredEV2", &caMeasuredEVInterpreter}, {0, AC_WRITE, 0, 0, 26, AUTO, "CameraType", &caCameraTypeInterpreter}, {0, AC_WRITE, 0, 0, 27, AUTO, "AutoRotate", &caAutoRotateInterpreter}, {0, AC_WRITE, 0, 0, 28, AUTO, "NDFilter", &caOnOffInterpreter}, @@ -1669,6 +1870,8 @@ const TagAttrib canonFileInfoAttribs[] = { {0, AC_WRITE, 0, 0, 14, AUTO, "FilterEffect" , &caFilterEffectInterpreter}, {0, AC_WRITE, 0, 0, 15, AUTO, "ToningEffect" , &caToningEffectInterpreter}, {0, AC_WRITE, 0, 0, 19, AUTO, "LiveViewShooting" , &caOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 20, AUTO, "FocusDistanceUpper", &caFocusDistanceInterpreter}, + {0, AC_WRITE, 0, 0, 21, AUTO, "FocusDistanceLower", &caFocusDistanceInterpreter}, {0, AC_WRITE, 0, 0, 25, AUTO, "FlashExposureLock" , &caOnOffInterpreter}, { -1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, }; diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc index 456559175..311e47ad6 100644 --- a/rtexif/fujiattribs.cc +++ b/rtexif/fujiattribs.cc @@ -68,6 +68,7 @@ public: choices[0x304] = "Living Room Warm White Fluorescent"; choices[0x400] = "Incandescent"; choices[0x500] = "Flash"; + choices[0x600] = "Underwater"; choices[0xf00] = "Custom"; choices[0xf01] = "Custom2"; choices[0xf02] = "Custom3"; @@ -89,6 +90,11 @@ public: choices[0x180] = "Medium Low"; choices[0x200] = "Low"; choices[0x300] = "None (B&W)"; + choices[0x301] = "B&W Red Filter"; + choices[0x302] = "B&W Yellow Filter"; + choices[0x303] = "B&W Green Filter"; + choices[0x310] = "B&W Sepia"; + choices[0x400] = "Low 2"; choices[0x8000] = "Film Simulation"; } }; @@ -126,8 +132,9 @@ class FANoiseReductionInterpreter : public ChoiceInterpreter public: FANoiseReductionInterpreter () { - choices[0x40] = "Low"; - choices[0x80] = "Normal"; + choices[0x40] = "Low"; + choices[0x80] = "Normal"; + choices[0x100] = "n/a"; } }; FANoiseReductionInterpreter faNoiseReductionInterpreter; @@ -135,6 +142,7 @@ FANoiseReductionInterpreter faNoiseReductionInterpreter; class FAFlashInterpreter : public ChoiceInterpreter { public: + // FujiFlashMode FAFlashInterpreter () { choices[0] = "Auto"; @@ -185,14 +193,17 @@ class FAFilmModeInterpreter : public ChoiceInterpreter public: FAFilmModeInterpreter () { - choices[0] = "F0/Standard"; - choices[0x100] = "F1/Studio Portrait"; - choices[0x110] = "F1a/Studio Portrait Enhanced Saturation"; - choices[0x120] = "F1b/Studio Portrait Smooth Skin Tone"; - choices[0x130] = "F1c/Studio Portrait Increased Sharpness "; - choices[0x200] = "F2/Fujichrome"; - choices[0x300] = "F3/Studio Portrait Ex"; - choices[0x400] = "F4/Velvia"; + choices[0x0] = "F0/Standard (Provia)"; + choices[0x100] = "F1/Studio Portrait"; + choices[0x110] = "F1a/Studio Portrait Enhanced Saturation"; + choices[0x120] = "F1b/Studio Portrait Smooth Skin Tone (Astia)"; + choices[0x130] = "F1c/Studio Portrait Increased Sharpness"; + choices[0x200] = "F2/Fujichrome (Velvia)"; + choices[0x300] = "F3/Studio Portrait Ex"; + choices[0x400] = "F4/Velvia"; + choices[0x500] = "Pro Neg. Std"; + choices[0x501] = "Pro Neg. Hi"; + choices[0x600] = "Classic Chrome"; } }; FAFilmModeInterpreter faFilmModeInterpreter; @@ -200,10 +211,11 @@ FAFilmModeInterpreter faFilmModeInterpreter; class FADRSettingInterpreter : public ChoiceInterpreter { public: + // DynamicRangeSetting FADRSettingInterpreter () { - choices[0] = "Auto (100-400%)"; - choices[0x1] = "RAW"; + choices[0x0] = "Auto (100-400%)"; + choices[0x1] = "Manual"; choices[0x100] = "Standard (100%)"; choices[0x200] = "Wide1 (230%)"; choices[0x201] = "Wide2 (400%)"; @@ -217,25 +229,35 @@ class FAPictureModeInterpreter : public ChoiceInterpreter public: FAPictureModeInterpreter () { - choices[0] = "Auto"; - choices[1] = "Portrait"; - choices[2] = "Landscape"; - choices[3] = "Macro"; - choices[4] = "Sports"; - choices[5] = "Night Scene"; - choices[6] = "Program AE"; - choices[7] = "Natural Light"; - choices[8] = "Anti-blur"; - choices[9] = "Beach & Snow"; - choices[10] = "Sunset"; - choices[11] = "Museum"; - choices[12] = "Party"; - choices[13] = "Flower"; - choices[14] = "Text"; - choices[15] = "Natural Light & Flash"; - choices[16] = "Beach"; - choices[17] = "Fireworks"; - choices[18] = "Underwater"; + choices[0x0] = "Auto"; + choices[0x1] = "Portrait"; + choices[0x2] = "Landscape"; + choices[0x3] = "Macro"; + choices[0x4] = "Sports"; + choices[0x5] = "Night Scene"; + choices[0x6] = "Program AE"; + choices[0x7] = "Natural Light"; + choices[0x8] = "Anti-blur"; + choices[0x9] = "Beach & Snow"; + choices[0xa] = "Sunset"; + choices[0xb] = "Museum"; + choices[0xc] = "Party"; + choices[0xd] = "Flower"; + choices[0xe] = "Text"; + choices[0xf] = "Natural Light & Flash"; + choices[0x10] = "Beach"; + choices[0x11] = "Snow"; + choices[0x12] = "Fireworks"; + choices[0x13] = "Underwater"; + choices[0x14] = "Portrait with Skin Correction"; + choices[0x16] = "Panorama"; + choices[0x17] = "Night (tripod)"; + choices[0x18] = "Pro Low-light"; + choices[0x19] = "Pro Focus"; + choices[0x1a] = "Portrait 2"; + choices[0x1b] = "Dog Face Detection"; + choices[0x1c] = "Cat Face Detection"; + choices[0x40] = "Advanced Filter"; choices[0x100] = "Aperture-priority AE"; choices[0x200] = "Shutter speed priority AE"; choices[0x300] = "Manual"; diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index facb13a36..38f4ce1f0 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -161,11 +161,12 @@ class NAFlashModeInterpreter : public ChoiceInterpreter public: NAFlashModeInterpreter () { - choices[0] = "Did Not Fire"; - choices[1] = "Fired, Manual"; - choices[7] = "Fired, External"; - choices[8] = "Fired, Commander Mode"; - choices[9] = "Fired, TTL Mode"; + choices[0x0] = "Did Not Fire"; + choices[0x1] = "Fired, Manual"; + choices[0x3] = "Not Ready"; + choices[0x7] = "Fired, External"; + choices[0x8] = "Fired, Commander Mode"; + choices[0x9] = "Fired, TTL Mode"; } }; NAFlashModeInterpreter naFlashModeInterpreter; @@ -173,13 +174,16 @@ NAFlashModeInterpreter naFlashModeInterpreter; class NAHiISONRInterpreter : public ChoiceInterpreter { public: + // HighISONoiseReduction NAHiISONRInterpreter () { - choices[0] = "Off"; - choices[1] = "Minimal"; - choices[2] = "Low"; - choices[4] = "Normal"; - choices[6] = "High"; + choices[0x0] = "Off"; + choices[0x1] = "Minimal"; + choices[0x2] = "Low"; + choices[0x3] = "Medium Low"; + choices[0x4] = "Normal"; + choices[0x5] = "Medium High"; + choices[0x6] = "High"; } }; NAHiISONRInterpreter naHiISONRInterpreter; @@ -209,25 +213,27 @@ class NAAFInfoInterpreter : public Interpreter std::map amchoices; std::map afpchoices; public: + // AFAreaMode NAAFInfoInterpreter () { - amchoices[0] = "Single Area"; - amchoices[1] = "Dynamic Area"; - amchoices[2] = "Dynamic Area, Closest Subject"; - amchoices[3] = "Group Dynamic"; - amchoices[4] = "Single Area (wide)"; - amchoices[5] = "Dynamic Area (wide)"; - afpchoices[0] = "Center"; - afpchoices[1] = "Top"; - afpchoices[2] = "Bottom"; - afpchoices[3] = "Left"; - afpchoices[4] = "Right"; - afpchoices[5] = "Upper-left"; - afpchoices[6] = "Upper-right"; - afpchoices[7] = "Lower-left"; - afpchoices[8] = "Lower-right"; - afpchoices[9] = "Far Left"; - afpchoices[10] = "Far Right"; + amchoices[0x0] = "Single Area"; + amchoices[0x1] = "Dynamic Area"; + amchoices[0x2] = "Dynamic Area (closest subject)"; + amchoices[0x3] = "Group Dynamic"; + amchoices[0x4] = "Single Area (wide)"; + amchoices[0x5] = "Dynamic Area (wide)"; + // AFPoint + afpchoices[0x0] = "Center"; + afpchoices[0x1] = "Top"; + afpchoices[0x2] = "Bottom"; + afpchoices[0x3] = "Mid-left"; + afpchoices[0x4] = "Mid-right"; + afpchoices[0x5] = "Upper-left"; + afpchoices[0x6] = "Upper-right"; + afpchoices[0x7] = "Lower-left"; + afpchoices[0x8] = "Lower-right"; + afpchoices[0x9] = "Far Left"; + afpchoices[0xa] = "Far Right"; } virtual std::string toString (Tag* t) { @@ -329,6 +335,8 @@ public: lenses["00 00 48 48 53 53 00 01"] = "Loreo 40mm f/11-22 3D Lens in a Cap 9005"; lenses["00 36 1C 2D 34 3C 00 06"] = "Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical (IF) (A13)"; lenses["00 3C 1F 37 30 30 00 06"] = "Tokina AT-X 124 AF PRO DX (AF 12-24mm f/4)"; + lenses["00 3C 2B 44 30 30 00 06"] = "Tokina AT-X 17-35 f/4 PRO FX (AF 17-35mm f/4)"; + lenses["00 3C 5C 80 30 30 00 0E"] = "Tokina AT-X 70-200 f/4 FX VCM-S (AF 70-200mm f/4)"; lenses["00 3E 80 A0 38 3F 00 02"] = "Tamron SP AF 200-500mm f/5-6.3 Di LD (IF) (A08)"; lenses["00 3F 2D 80 2B 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) (A14)"; lenses["00 3F 2D 80 2C 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14)"; @@ -354,10 +362,13 @@ public: lenses["00 48 29 3C 24 24 00 06"] = "Tokina AT-X 16-28 AF PRO FX (AF 16-28mm f/2.8)"; lenses["00 48 29 50 24 24 00 06"] = "Tokina AT-X 165 PRO DX (AF 16-50mm f/2.8)"; lenses["00 48 32 32 24 24 00 00"] = "Carl Zeiss Distagon T* 2.8/21 ZF.2"; + lenses["00 48 37 5C 24 24 00 06"] = "Tokina AT-X 24-70 f/2.8 PRO FX (AF 24-70mm f/2.8)"; + lenses["00 48 3C 3C 24 24 00 00"] = "Voigtlander Color Skopar 28mm f/2.8 SL II"; lenses["00 48 3C 60 24 24 00 02"] = "Tokina AT-X 280 AF PRO (AF 28-80mm f/2.8)"; lenses["00 48 3C 6A 24 24 00 02"] = "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)"; lenses["00 48 50 50 18 18 00 00"] = "Nikkor H 50mm f/2"; lenses["00 48 50 72 24 24 00 06"] = "Tokina AT-X 535 PRO DX (AF 50-135mm f/2.8)"; + lenses["00 48 5C 80 30 30 00 0E"] = "Tokina AT-X 70-200 f/4 FX VCM-S (AF 70-200mm f/4)"; lenses["00 48 5C 8E 30 3C 00 06"] = "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17NII)"; lenses["00 48 68 68 24 24 00 00"] = "Series E 100mm f/2.8"; lenses["00 48 80 80 30 30 00 00"] = "Nikkor 200mm f/4 AiS"; @@ -367,7 +378,7 @@ public: lenses["00 53 2B 50 24 24 00 06"] = "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16)"; lenses["00 54 2B 50 24 24 00 06"] = "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"; lenses["00 54 3C 3C 18 18 00 00"] = "Carl Zeiss Distagon T* 2/28 ZF.2"; - lenses["00 54 44 44 0C 0C 00 00"] = "Nikkor 35mm f/1.4 AiS"; + lenses["00 54 44 44 0C 0C 00 00"] = "Carl Zeiss Distagon T* 1.4/35 ZF.2"; lenses["00 54 44 44 18 18 00 00"] = "Carl Zeiss Distagon T* 2/35 ZF.2"; lenses["00 54 48 48 18 18 00 00"] = "Voigtlander Ultron 40mm f/2 SLII Aspherical"; lenses["00 54 50 50 0C 0C 00 00"] = "Carl Zeiss Planar T* 1.4/50 ZF.2"; @@ -378,11 +389,13 @@ public: lenses["00 54 62 62 0C 0C 00 00"] = "Carl Zeiss Planar T* 1.4/85 ZF.2"; lenses["00 54 68 68 18 18 00 00"] = "Carl Zeiss Makro-Planar T* 2/100 ZF.2"; lenses["00 54 68 68 24 24 00 02"] = "Tokina AT-X M100 AF PRO D (AF 100mm f/2.8 Macro)"; + lenses["00 54 72 72 18 18 00 00"] = "Carl Zeiss Apo Sonnar T* 2/135 ZF.2"; lenses["00 54 8E 8E 24 24 00 02"] = "Tokina AT-X 300 AF PRO (AF 300mm f/2.8)"; lenses["00 57 50 50 14 14 00 00"] = "Nikkor 50mm f/1.8 AI"; lenses["00 58 64 64 20 20 00 00"] = "Soligor C/D Macro MC 90mm f/2.5"; lenses["01 00 00 00 00 00 02 00"] = "TC-16A"; lenses["01 00 00 00 00 00 08 00"] = "TC-16A"; + lenses["01 54 62 62 0C 0C 00 00"] = "Zeiss Otus 1.4/85"; lenses["01 58 50 50 14 14 02 00"] = "AF Nikkor 50mm f/1.8"; lenses["01 58 50 50 14 14 05 00"] = "AF Nikkor 50mm f/1.8"; lenses["02 2F 98 98 3D 3D 02 00"] = "Sigma APO 400mm f/5.6"; @@ -611,12 +624,17 @@ public: lenses["4E 48 72 72 18 18 51 02"] = "AF DC-Nikkor 135mm f/2D"; lenses["4F 40 37 5C 2C 3C 53 06"] = "IX-Nikkor 24-70mm f/3.5-5.6"; lenses["50 48 56 7C 30 3C 54 06"] = "IX-Nikkor 60-180mm f/4-5.6"; + lenses["52 54 44 44 18 18 00 00"] = "Zeiss Milvus 35mm f/2"; lenses["53 48 60 80 24 24 57 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; lenses["53 48 60 80 24 24 60 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["53 54 50 50 0C 0C 00 00"] = "Zeiss Milvus 50mm f/1.4"; lenses["54 44 5C 7C 34 3C 58 02"] = "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"; lenses["54 44 5C 7C 34 3C 61 02"] = "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"; + lenses["54 54 50 50 18 18 00 00"] = "Zeiss Milvus 50mm f/2 Macro"; + lenses["55 54 62 62 0C 0C 00 00"] = "Zeiss Milvus 85mm f/1.4"; lenses["56 3C 5C 8E 30 3C 1C 02"] = "Sigma 70-300mm f/4-5.6 APO Macro Super II"; lenses["56 48 5C 8E 30 3C 5A 02"] = "AF Zoom-Nikkor 70-300mm f/4-5.6D ED"; + lenses["56 54 68 68 18 18 00 00"] = "Zeiss Milvus 100mm f/2 Macro"; lenses["59 48 98 98 24 24 5D 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED"; lenses["59 48 98 98 24 24 E1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-17E"; lenses["59 48 98 98 24 24 F1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-14E"; @@ -664,6 +682,7 @@ public: lenses["7A 47 2B 5C 24 34 4B 06"] = "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"; lenses["7A 47 50 76 24 24 4B 06"] = "Sigma 50-150mm f/2.8 EX APO DC HSM"; lenses["7A 48 1C 29 24 24 7E 06"] = "Tokina AT-X 116 PRO DX II (AF 11-16mm f/2.8)"; + lenses["7A 48 1C 30 24 24 7E 06"] = "Tokina AT-X 11-20 f/2.8 PRO DX (AF 11-20mm f/2.8)"; lenses["7A 48 2B 5C 24 34 4B 06"] = "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"; lenses["7A 48 2D 50 24 24 4B 06"] = "Sigma 18-50mm f/2.8 EX DC Macro"; lenses["7A 48 5C 80 24 24 4B 06"] = "Sigma 70-200mm f/2.8 EX APO DG Macro HSM II"; @@ -676,6 +695,7 @@ public: lenses["80 48 1A 1A 24 24 85 06"] = "AF DX Fisheye-Nikkor 10.5mm f/2.8G ED"; lenses["81 34 76 A6 38 40 4B 0E"] = "Sigma 150-600mm f/5-6.3 DG OS HSM | S"; lenses["81 54 80 80 18 18 86 0E"] = "AF-S VR Nikkor 200mm f/2G IF-ED"; + lenses["82 34 76 A6 38 40 4B 0E"] = "Sigma 150-600mm f/5-6.3 DG OS HSM | C"; lenses["82 48 8E 8E 24 24 87 0E"] = "AF-S VR Nikkor 300mm f/2.8G IF-ED"; lenses["83 00 B0 B0 5A 5A 88 04"] = "FSA-L2, EDG 65, 800mm f/13 G"; lenses["88 54 50 50 0C 0C 4B 06"] = "Sigma 50mm f/1.4 DG HSM | A"; @@ -687,7 +707,7 @@ public: lenses["8B 4C 2D 44 14 14 4B 06"] = "Sigma 18-35mm f/1.8 DC HSM"; lenses["8C 40 2D 53 2C 3C 8E 06"] = "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED"; lenses["8D 44 5C 8E 34 3C 8F 0E"] = "AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED"; - lenses["8E 3C 2B 5C 24 30 4B 0E"] = "Sigma 17-70mm f/2.8-4 DC Macro OS HSM Contemporary"; + lenses["8E 3C 2B 5C 24 30 4B 0E"] = "Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C"; lenses["8F 40 2D 72 2C 3C 91 06"] = "AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED"; lenses["8F 48 2B 50 24 24 4B 0E"] = "Sigma 17-50mm f/2.8 EX DC OS HSM"; lenses["90 3B 53 80 30 3C 92 0E"] = "AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED"; @@ -726,7 +746,7 @@ public: lenses["A1 40 18 37 2C 34 A3 06"] = "AF-S DX Nikkor 10-24mm f/3.5-4.5G ED"; lenses["A1 41 19 31 2C 2C 4B 06"] = "Sigma 10-20mm f/3.5 EX DC HSM"; lenses["A1 54 55 55 0C 0C BC 06"] = "AF-S Nikkor 58mm f/1.4G"; - lenses["A2 40 2D 53 2C 3C BD 0E"] = "AF-S DX VR Nikkor 18-55mm f/3.5-5.6G II"; + lenses["A2 40 2D 53 2C 3C BD 0E"] = "AF-S DX Nikkor 18-55mm f/3.5-5.6G VR II"; lenses["A2 48 5C 80 24 24 A4 0E"] = "AF-S Nikkor 70-200mm f/2.8G ED VR II"; lenses["A3 3C 29 44 30 30 A5 0E"] = "AF-S Nikkor 16-35mm f/4G ED VR"; lenses["A3 3C 5C 8E 30 3C 4B 0E"] = "Sigma 70-300mm f/4-5.6 DG OS"; @@ -735,9 +755,10 @@ public: lenses["A4 54 37 37 0C 0C A6 06"] = "AF-S Nikkor 24mm f/1.4G ED"; lenses["A5 40 2D 88 2C 40 4B 0E"] = "Sigma 18-250mm f/3.5-6.3 DC OS HSM"; lenses["A5 40 3C 8E 2C 3C A7 0E"] = "AF-S Nikkor 28-300mm f/3.5-5.6G ED VR"; - lenses["A5 4C 44 44 14 14 C0 06"] = "AF-S Nikkor 35mm f/1.8G"; + lenses["A5 4C 44 44 14 14 C0 06"] = "AF-S Nikkor 35mm f/1.8G ED"; lenses["A6 48 37 5C 24 24 4B 06"] = "Sigma 24-70mm f/2.8 IF EX DG HSM"; lenses["A6 48 8E 8E 24 24 A8 0E"] = "AF-S VR Nikkor 300mm f/2.8G IF-ED II"; + lenses["A6 48 98 98 24 24 C1 0E"] = "AF-S Nikkor 400mm f/2.8E FL ED VR"; lenses["A7 3C 53 80 30 3C C2 0E"] = "AF-S DX Nikkor 55-200mm f/4-5.6G ED VR II"; lenses["A7 49 80 A0 24 24 4B 06"] = "Sigma APO 200-500mm f/2.8 EX DG"; lenses["A7 4B 62 62 2C 2C A9 0E"] = "AF-S DX Micro Nikkor 85mm f/3.5G ED VR"; @@ -748,9 +769,16 @@ public: lenses["A9 54 80 80 18 18 AB 0E"] = "AF-S Nikkor 200mm f/2G ED VR II"; lenses["AA 3C 37 6E 30 30 AC 0E"] = "AF-S Nikkor 24-120mm f/4G ED VR"; lenses["AA 48 37 5C 24 24 C5 4E"] = "AF-S Nikkor 24-70mm f/2.8E ED VR"; + lenses["AB 3C A0 A0 30 30 C6 4E"] = "AF-S Nikkor 500mm f/4E FL ED VR"; lenses["AC 38 53 8E 34 3C AE 0E"] = "AF-S DX VR Nikkor 55-300mm f/4.5-5.6G ED"; + lenses["AC 3C A6 A6 30 30 C7 4E"] = "AF-S Nikkor 600mm f/4E FL ED VR"; lenses["AD 3C 2D 8E 2C 3C AF 0E"] = "AF-S DX Nikkor 18-300mm f/3.5-5.6G ED VR"; + lenses["AD 48 28 60 24 30 C8 0E"] = "AF-S DX Nikkor 16-80mm f/2.8-4E ED VR"; + lenses["AD 48 28 60 24 30 C8 4E"] = "AF-S DX Nikkor 16-80mm f/2.8-4E ED VR"; + lenses["AE 3C 80 A0 3C 3C C9 0E"] = "AF-S Nikkor 200-500mm f/5.6E ED VR"; + lenses["AE 3C 80 A0 3C 3C C9 4E"] = "AF-S Nikkor 200-500mm f/5.6E ED VR"; lenses["AE 54 62 62 0C 0C B0 06"] = "AF-S Nikkor 85mm f/1.4G"; + lenses["AF 4C 37 37 14 14 CC 06"] = "AF-S Nikkor 24mm f/1.8G ED"; lenses["AF 54 44 44 0C 0C B1 06"] = "AF-S Nikkor 35mm f/1.4G"; lenses["B0 4C 50 50 14 14 B2 06"] = "AF-S Nikkor 50mm f/1.8G"; lenses["B1 48 48 48 24 24 B3 06"] = "AF-S DX Micro Nikkor 40mm f/2.8G"; @@ -758,9 +786,11 @@ public: lenses["B3 4C 62 62 14 14 B5 06"] = "AF-S Nikkor 85mm f/1.8G"; lenses["B4 40 37 62 2C 34 B6 0E"] = "AF-S VR Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"; lenses["B5 4C 3C 3C 14 14 B7 06"] = "AF-S Nikkor 28mm f/1.8G"; + lenses["B6 3C B0 B0 3C 3C B8 0E"] = "AF-S VR Nikkor 800mm f/5.6E FL ED"; lenses["B6 48 37 56 24 24 1C 02"] = "Sigma 24-60mm f/2.8 EX DG"; lenses["B7 44 60 98 34 3C B9 0E"] = "AF-S Nikkor 80-400mm f/4.5-5.6G ED VR"; lenses["B8 40 2D 44 2C 34 BA 06"] = "AF-S Nikkor 18-35mm f/3.5-4.5G ED"; + lenses["CC 4C 50 68 14 14 4B 06"] = "Sigma 50-100mm f/1.8 DC HSM | A"; lenses["CD 3D 2D 70 2E 3C 4B 0E"] = "Sigma 18-125mm f/3.8-5.6 DC OS HSM"; lenses["CE 34 76 A0 38 40 4B 0E"] = "Sigma 150-500mm f/5-6.3 DG OS APO HSM"; lenses["CF 38 6E 98 34 3C 4B 0E"] = "Sigma APO 120-400mm f/4.5-5.6 DG OS HSM"; @@ -771,6 +801,7 @@ public: lenses["E3 54 50 50 24 24 35 02"] = "Sigma Macro 50mm f/2.8 EX DG"; lenses["E5 54 6A 6A 24 24 35 02"] = "Sigma Macro 105mm f/2.8 EX DG"; lenses["E6 41 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm f/3.5-6.3 DG Macro"; + lenses["E8 4C 44 44 14 14 DF 0E"] = "Tamron SP 35mm f/1.8 VC"; lenses["E9 48 27 3E 24 24 DF 0E"] = "Tamron SP 15-30mm f/2.8 Di VC USD (A012)"; lenses["E9 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm f/2.8 EX DG Macro"; lenses["EA 40 29 8E 2C 40 DF 0E"] = "Tamron AF 16-300mm f/3.5-6.3 Di II VC PZD (B016)"; diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc index 8ec17b90a..35e390b88 100644 --- a/rtexif/olympusattribs.cc +++ b/rtexif/olympusattribs.cc @@ -120,6 +120,7 @@ public: lenses["00 23 00"] = "Olympus Zuiko Digital ED 14-42mm f/3.5-5.6"; lenses["00 23 10"] = "Olympus M.Zuiko Digital ED 7-14mm f/2.8 Pro"; lenses["00 24 00"] = "Olympus Zuiko Digital ED 40-150mm f/4.0-5.6"; + lenses["00 24 10"] = "Olympus M.Zuiko Digital ED 300mm f/4.0 IS Pro"; lenses["00 25 10"] = "Olympus M.Zuiko Digital ED 8mm f/1.8 Fisheye Pro"; lenses["00 30 00"] = "Olympus Zuiko Digital ED 50-200mm f/2.8-3.5 SWD"; lenses["00 31 00"] = "Olympus Zuiko Digital ED 12-60mm f/2.8-4.0 SWD"; @@ -138,6 +139,7 @@ public: lenses["01 05 00"] = "Sigma 30mm f/1.4 EX DC HSM"; lenses["01 05 10"] = "Sigma 60mm f/2.8 DN | A"; lenses["01 06 00"] = "Sigma APO 50-500mm f/4.0-6.3 EX DG HSM"; + lenses["01 06 10"] = "Sigma 30mm f/1.4 DC DN | C"; lenses["01 07 00"] = "Sigma Macro 105mm f/2.8 EX DG"; lenses["01 08 00"] = "Sigma APO Macro 150mm f/2.8 EX DG HSM"; lenses["01 09 00"] = "Sigma 18-50mm f/2.8 EX DC Macro"; @@ -176,8 +178,12 @@ public: lenses["02 20 10"] = "Lumix G Vario 12-32mm f/3.5-5.6 Asph. Mega OIS"; lenses["02 21 10"] = "Leica DG Nocticron 42.5mm f/1.2 Asph. Power OIS"; lenses["02 22 10"] = "Leica DG Summilux 15mm f/1.7 Asph."; + lenses["02 23 10"] = "Lumix G Vario 35-100mm f/4.0-5.6 Asph. Mega OIS"; lenses["02 24 10"] = "Lumix G Macro 30mm f/2.8 Asph. Mega OIS"; lenses["02 25 10"] = "Lumix G 42.5mm f/1.7 Asph. Power OIS"; + lenses["02 26 10"] = "Lumix G 25mm f/1.7 Asph."; + lenses["02 27 10"] = "Leica DG Vario-Elmar 100-400mm f/4.0-6.3 Asph. Power OIS"; + lenses["02 28 10"] = "Lumix G Vario 12-60mm f/3.5-5.6 Asph. Power OIS"; lenses["03 01 00"] = "Leica D Vario Elmarit 14-50mm f/2.8-3.5 Asph."; lenses["03 02 00"] = "Leica D Summilux 25mm f/1.4 Asph."; lenses["05 01 10"] = "Tamron 14-150mm f/3.5-5.8 Di III"; @@ -263,22 +269,28 @@ public: OLWhitebalance2Interpreter () { choices[0] = "Auto"; + choices[1] = "Auto (Keep Warm Color Off)"; choices[16] = "7500K (Fine Weather with Shade)"; choices[17] = "6000K (Cloudy)"; choices[18] = "5300K (Fine Weather)"; choices[20] = "3000K (Tungsten light)"; choices[21] = "3600K (Tungsten light-like)"; + choices[22] = "Auto Setup"; + choices[23] = "5500K (Flash)"; choices[33] = "6600K (Daylight fluorescent)"; choices[34] = "4500K (Neutral white fluorescent)"; choices[35] = "4000K (Cool white fluorescent)"; + choices[36] = "White Fluorescent"; choices[48] = "3600K (Tungsten light-like)"; - choices[256] = "Custom WB 1"; - choices[257] = "Custom WB 2"; - choices[258] = "Custom WB 3"; - choices[259] = "Custom WB 4"; - choices[512] = "Custom WB 5400K"; - choices[513] = "Custom WB 2900K"; - choices[514] = "Custom WB 8000K"; + choices[67] = "Underwater"; + choices[256] = "One Touch WB 1"; + choices[257] = "One Touch WB 2"; + choices[258] = "One Touch WB 3"; + choices[259] = "One Touch WB 4"; + choices[512] = "Custom WB 1"; + choices[513] = "Custom WB 2"; + choices[514] = "Custom WB 3"; + choices[515] = "Custom WB 4"; } }; OLWhitebalance2Interpreter olWhitebalance2Interpreter; @@ -304,6 +316,7 @@ public: choices[18] = "Indoor"; choices[19] = "Fireworks"; choices[20] = "Sunset"; + choices[21] = "Beauty Skin"; choices[22] = "Macro"; choices[23] = "Super Macro"; choices[24] = "Food"; @@ -333,6 +346,17 @@ public: choices[48] = "Nature Macro"; choices[49] = "Underwater Snapshot"; choices[50] = "Shooting Guide"; + choices[54] = "Face Portrait"; + choices[57] = "Bulb"; + choices[59] = "Smile Shot"; + choices[60] = "Quick Shutter"; + choices[63] = "Slow Shutter"; + choices[64] = "Bird Watching"; + choices[65] = "Multiple Exposure"; + choices[66] = "e-Portrait"; + choices[67] = "Soft Background Shot"; + choices[142] = "Hand-held Starlight"; + choices[154] = "HDR"; } }; OLSceneModeInterpreter olSceneModeInterpreter; @@ -376,6 +400,7 @@ public: choices[2] = "HQ"; choices[3] = "SHQ"; choices[4] = "RAW"; + choices[5] = "SQ (5)"; } }; OLImageQuality2Interpreter olImageQuality2Interpreter; @@ -383,6 +408,7 @@ OLImageQuality2Interpreter olImageQuality2Interpreter; class OLDevEngineInterpreter : public ChoiceInterpreter { public: + // RawDevEngine OLDevEngineInterpreter () { choices[0] = "High Speed"; @@ -402,6 +428,14 @@ public: choices[2] = "Natural"; choices[3] = "Muted"; choices[4] = "Portrait"; + choices[5] = "i-Enhance"; + choices[7] = "Color Creator"; + choices[9] = "Color Profile 1"; + choices[10] = "Color Profile 2"; + choices[11] = "Color Profile 3"; + choices[12] = "Monochrome Profile 1"; + choices[13] = "Monochrome Profile 2"; + choices[14] = "Monochrome Profile 3"; choices[256] = "Monotone"; choices[512] = "Sepia"; } @@ -474,7 +508,8 @@ public: int a = t->toInt (); str << "Noise Reduction = " << ((a & 1) ? "On" : "Off") << std::endl; str << "Noise Filter = " << ((a & 2) ? "On" : "Off") << std::endl; - str << "Noise Filter (ISO Boost) = " << ((a & 4) ? "On" : "Off"); + str << "Noise Filter (ISO Boost) = " << ((a & 4) ? "On" : "Off") << std::endl; + str << "Auto = " << ((a & 8) ? "On" : "Off"); return str.str(); } }; @@ -485,14 +520,16 @@ class OLFlashModelInterpreter : public ChoiceInterpreter public: OLFlashModelInterpreter () { - choices[0] = "None"; - choices[1] = "FL-20"; - choices[2] = "FL-50"; - choices[3] = "RF-11"; - choices[4] = "TF-22"; - choices[5] = "FL-36"; - choices[6] = "FL-50R"; - choices[7] = "FL-36R"; + choices[0] = "None"; + choices[1] = "FL-20"; + choices[2] = "FL-50"; + choices[3] = "RF-11"; + choices[4] = "TF-22"; + choices[5] = "FL-36"; + choices[6] = "FL-50R"; + choices[7] = "FL-36R"; + choices[9] = "FL-14"; + choices[11] = "FL-600R"; } }; OLFlashModelInterpreter olFlashModelInterpreter; diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index 8f183cd09..f88e650ec 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -36,12 +36,14 @@ class PAQualityInterpreter : public ChoiceInterpreter public: PAQualityInterpreter () { - choices[0] = "Good"; - choices[1] = "Better"; - choices[2] = "Best"; - choices[3] = "TIFF"; - choices[4] = "RAW"; - choices[5] = "Premium"; + choices[0] = "Good"; + choices[1] = "Better"; + choices[2] = "Best"; + choices[3] = "TIFF"; + choices[4] = "RAW"; + choices[5] = "Premium"; + choices[7] = "RAW (pixel shift enabled)"; + choices[65535] = "n/a"; } }; PAQualityInterpreter paQualityInterpreter; @@ -79,6 +81,7 @@ PAShakeReductionInterpreter paShakeReductionInterpreter; class PAShakeReduction2Interpreter : public ChoiceInterpreter { public: + // ShakeReduction PAShakeReduction2Interpreter () { choices[ 0] = "Off"; @@ -144,7 +147,15 @@ public: choices[59] = "Report"; choices[60] = "Kids"; choices[61] = "Blur Reduction"; + choices[63] = "Panorama 2"; choices[65] = "Half-length Portrait"; + choices[66] = "Portrait 2"; + choices[74] = "Digital Microscope"; + choices[75] = "Blue Sky"; + choices[80] = "Miniature"; + choices[81] = "HDR"; + choices[83] = "Fisheye"; + choices[85] = "Digital Filter 4"; choices[221] = "P"; choices[255] = "PICT"; } @@ -156,14 +167,14 @@ class PASceneModeInterpreter : public ChoiceInterpreter public: PASceneModeInterpreter () { - choices[ 0] = "Off"; - choices[ 1] = "HDR"; - choices[ 4] = "Auto PICT"; - choices[ 5] = "Portrait"; - choices[ 6] = "Landscape"; - choices[ 7] = "Macro"; - choices[ 8] = "Sport"; - choices[ 9] = "Night Scene Portrait"; + choices[0] = "Off"; + choices[1] = "HDR"; + choices[4] = "Auto PICT"; + choices[5] = "Portrait"; + choices[6] = "Landscape"; + choices[7] = "Macro"; + choices[8] = "Sport"; + choices[9] = "Night Scene Portrait"; choices[10] = "No Flash"; choices[11] = "Night Scene"; choices[12] = "Surf & Snow"; @@ -188,25 +199,25 @@ class PAAEProgramModeInterpreter : public ChoiceInterpreter public: PAAEProgramModeInterpreter () { - choices[ 0] = "M, P or TAv"; - choices[ 1] = "Av, B or X"; - choices[ 2] = "Tv"; - choices[ 3] = "Sv or Green Mode"; - choices[ 8] = "Hi-speed Program"; - choices[ 11] = "Hi-speed Program (P-Shift)"; - choices[ 16] = "DOF Program"; - choices[ 19] = "DOF Program (P-Shift)"; - choices[ 24] = "MTF Program"; - choices[ 27] = "MTF Program (P-Shift)"; - choices[ 35] = "Standard"; - choices[ 43] = "Portrait"; - choices[ 51] = "Landscape"; - choices[ 59] = "Macro"; - choices[ 67] = "Sport"; - choices[ 75] = "Night Scene Portrait"; - choices[ 83] = "No Flash"; - choices[ 91] = "Night Scene"; - choices[ 99] = "Surf & Snow"; + choices[0] = "M, P or TAv"; + choices[1] = "Av, B or X"; + choices[2] = "Tv"; + choices[3] = "Sv or Green Mode"; + choices[8] = "Hi-speed Program"; + choices[11] = "Hi-speed Program (P-Shift)"; + choices[16] = "DOF Program"; + choices[19] = "DOF Program (P-Shift)"; + choices[24] = "MTF Program"; + choices[27] = "MTF Program (P-Shift)"; + choices[35] = "Standard"; + choices[43] = "Portrait"; + choices[51] = "Landscape"; + choices[59] = "Macro"; + choices[67] = "Sport"; + choices[75] = "Night Scene Portrait"; + choices[83] = "No Flash"; + choices[91] = "Night Scene"; + choices[99] = "Surf & Snow"; choices[104] = "Night Snap"; choices[107] = "Text"; choices[115] = "Sunset"; @@ -227,20 +238,21 @@ class PAFlashModeInterpreter : public ChoiceInterpreter public: PAFlashModeInterpreter () { - choices[0x0] = "Auto, Did not fire"; - choices[0x1] = "Off"; - choices[0x2] = "On, Did not fire"; - choices[0x3] = "Auto, Did not fire, Red-eye reduction"; - choices[0x100] = "Auto, Fired"; - choices[0x102] = "On"; - choices[0x103] = "Auto, Fired, Red-eye reduction"; - choices[0x104] = "On, Red-eye reduction"; - choices[0x105] = "On, Wireless (Master)"; - choices[0x106] = "On, Wireless (Control)"; - choices[0x108] = "On, Soft"; - choices[0x109] = "On, Slow-sync"; - choices[0x10a] = "On, Slow-sync, Red-eye reduction"; - choices[0x10b] = "On, Trailing-curtain Sync"; + choices[0] = "Auto, Did not fire"; + choices[1] = "Off, Did not fire"; + choices[2] = "On, Did not fire"; + choices[3] = "Auto, Did not fire, Red-eye reduction"; + choices[5] = "On, Did not fire, Wireless (Master)"; + choices[256] = "Auto, Fired"; + choices[258] = "On, Fired"; + choices[259] = "Auto, Fired, Red-eye reduction"; + choices[260] = "On, Red-eye reduction"; + choices[261] = "On, Wireless (Master)"; + choices[262] = "On, Wireless (Control)"; + choices[264] = "On, Soft"; + choices[265] = "On, Slow-sync"; + choices[266] = "On, Slow-sync, Red-eye reduction"; + choices[267] = "On, Trailing-curtain Sync"; } }; PAFlashModeInterpreter paFlashModeInterpreter; @@ -256,9 +268,15 @@ public: choices[3] = "Manual"; choices[4] = "Super Macro"; choices[5] = "Pan Focus"; - choices[16] = "AF-S"; - choices[17] = "AF-C"; - choices[18] = "AF-A"; + choices[16] = "AF-S (Focus-priority)"; + choices[17] = "AF-C (Focus-priority)"; + choices[18] = "AF-A (Focus-priority)"; + choices[32] = "Contrast-detect (Focus-priority)"; + choices[33] = "Tracking Contrast-detect (Focus-priority)"; + choices[272] = "AF-S (Release-priority)"; + choices[273] = "AF-C (Release-priority)"; + choices[274] = "AF-A (Release-priority)"; + choices[288] = "Contrast-detect (Release-priority)"; } }; PAFocusModeInterpreter paFocusModeInterpreter; @@ -266,8 +284,10 @@ PAFocusModeInterpreter paFocusModeInterpreter; class PAAFPointInterpreter : public ChoiceInterpreter { public: + // AFPointSelected PAAFPointInterpreter () { + choices[0] = "None"; choices[1] = "Upper-left"; choices[2] = "Top"; choices[3] = "Upper-right"; @@ -279,7 +299,8 @@ public: choices[9] = "Lower-left"; choices[10] = "Bottom"; choices[11] = "Lower-right"; - choices[65532] = "Face Recognition AF"; + choices[65531] = "AF Select"; + choices[65532] = "Face Detect AF"; choices[65533] = "Automatic Tracking AF"; choices[65534] = "Fixed Center"; choices[65535] = "Auto"; @@ -290,19 +311,20 @@ PAAFPointInterpreter paAFPointInterpreter; class PAAFFocusInterpreter : public ChoiceInterpreter { public: + // AFPointsInFocus PAAFFocusInterpreter () { - choices[0x0] = "Fixed Center or Multiple"; - choices[0x1] = "Top-left"; - choices[0x2] = "Top-center"; - choices[0x3] = "Top-right"; - choices[0x4] = "Left"; - choices[0x5] = "Center"; - choices[0x6] = "Right"; - choices[0x7] = "Bottom-left"; - choices[0x8] = "Bottom-center"; - choices[0x9] = "Bottom-right"; - choices[0xffff] = "None"; + choices[0] = "Fixed Center or Multiple"; + choices[1] = "Top-left"; + choices[2] = "Top-center"; + choices[3] = "Top-right"; + choices[4] = "Left"; + choices[5] = "Center"; + choices[6] = "Right"; + choices[7] = "Bottom-left"; + choices[8] = "Bottom-center"; + choices[9] = "Bottom-right"; + choices[65535] = "None"; } }; PAAFFocusInterpreter paAFFocusInterpreter; @@ -343,15 +365,15 @@ public: choices[31] = "32000"; choices[32] = "40000"; choices[33] = "51200"; - + choices[34] = "64000"; + choices[35] = "80000"; + choices[36] = "102400"; + choices[37] = "128000"; + choices[38] = "160000"; + choices[39] = "204800"; choices[50] = "50"; choices[100] = "100"; choices[200] = "200"; - /*choices[400] = "400"; - choices[800] = "800"; - choices[1600] = "1600"; - choices[3200] = "3200"; Moved to tail for sorting reasons */ - choices[258] = "50"; choices[259] = "70"; choices[260] = "100"; @@ -373,14 +395,10 @@ public: choices[276] = "25600"; choices[277] = "36000"; choices[278] = "51200"; - choices[400] = "400"; choices[800] = "800"; choices[1600] = "1600"; choices[3200] = "3200"; - - //choices[65534] = "Auto"; ?? - //choices[65535] = "Auto"; ?? } }; PAISOInterpreter paISOInterpreter; @@ -437,7 +455,7 @@ public: choices[15] = "Color Temperature Enhancement"; choices[17] = "Kelvin"; choices[65534] = "Unknown"; - choices[65535] = "User Selected"; + choices[65535] = "User-Selected"; } }; PAWhiteBalanceInterpreter paWhiteBalanceInterpreter; @@ -451,11 +469,11 @@ public: choices[2] = "Auto (Shade)"; choices[3] = "Auto (Flash)"; choices[4] = "Auto (Tungsten)"; - choices[6] = "Auto (DaylightFluorescent)"; - choices[7] = "Auto (DaywhiteFluorescent)"; - choices[8] = "Auto (WhiteFluorescent)"; + choices[6] = "Auto (Daylight Fluorescent)"; + choices[7] = "Auto (Day White Fluorescent)"; + choices[8] = "Auto (White Fluorescent)"; choices[10] = "Auto (Cloudy)"; - choices[65534] = "Preset (Fireworks?)"; + choices[65534] = "Unknown"; choices[65535] = "User-Selected"; } }; @@ -466,13 +484,16 @@ class PASaturationInterpreter : public ChoiceInterpreter public: PASaturationInterpreter () { - choices[0] = "Low"; - choices[1] = "Normal"; - choices[2] = "High"; - choices[3] = "Med Low"; - choices[4] = "Med High"; - choices[5] = "Very Low"; - choices[6] = "Very High"; + choices[0] = "-2 (low)"; + choices[1] = "0 (normal)"; + choices[2] = "+2 (high)"; + choices[3] = "-1 (med low)"; + choices[4] = "+1 (med high)"; + choices[5] = "-3 (very low)"; + choices[6] = "+3 (very high)"; + choices[7] = "-4 (minimum)"; + choices[8] = "+4 (maximum)"; + choices[65535] = "None"; } }; PASaturationInterpreter paSaturationInterpreter; @@ -482,13 +503,16 @@ class PAContrastInterpreter : public ChoiceInterpreter public: PAContrastInterpreter () { - choices[0] = "Low"; - choices[1] = "Normal"; - choices[2] = "High"; - choices[3] = "Med Low"; - choices[4] = "Med High"; - choices[5] = "Very Low"; - choices[6] = "Very High"; + choices[0] = "-2 (low)"; + choices[1] = "0 (normal)"; + choices[2] = "+2 (high)"; + choices[3] = "-1 (med low)"; + choices[4] = "+1 (med high)"; + choices[5] = "-3 (very low)"; + choices[6] = "+3 (very high)"; + choices[7] = "-4 (minimum)"; + choices[8] = "+4 (maximum)"; + choices[65535] = "n/a"; } }; PAContrastInterpreter paContrastInterpreter; @@ -498,13 +522,15 @@ class PASharpnessInterpreter : public ChoiceInterpreter public: PASharpnessInterpreter () { - choices[0] = "Soft"; - choices[1] = "Normal"; - choices[2] = "Hard"; - choices[3] = "Med Soft"; - choices[4] = "Med Hard"; - choices[5] = "Very Soft"; - choices[6] = "Very Hard"; + choices[0] = "-2 (soft)"; + choices[1] = "0 (normal)"; + choices[2] = "+2 (hard)"; + choices[3] = "-1 (med soft)"; + choices[4] = "+1 (med hard)"; + choices[5] = "-3 (very soft)"; + choices[6] = "+3 (very hard)"; + choices[7] = "-4 (minimum)"; + choices[8] = "+4 (maximum)"; } }; PASharpnessInterpreter paSharpnessInterpreter; @@ -514,51 +540,67 @@ class PAPictureModeInterpreter2: public ChoiceInterpreter public: PAPictureModeInterpreter2() { - choices[ 0] = "Program"; - choices[ 1] = "Hi-speed Program"; - choices[ 2] = "DOF Program"; - choices[ 3] = "MTF Program"; - choices[ 4] = "Standard"; - choices[ 5] = "Portrait"; - choices[ 6] = "Landscape"; - choices[ 7] = "Macro"; - choices[ 8] = "Sport "; - choices[ 9] = "Night Scene Portrait "; - choices[10] = "No Flash"; - choices[11] = "Night Scene"; - choices[12] = "Surf & Snow"; - choices[13] = "Text"; - choices[14] = "Sunset"; - choices[15] = "Kids"; - choices[16] = "Pet"; - choices[17] = "Candlelight"; - choices[18] = "Museum"; - choices[19] = "Food "; - choices[20] = "Stage Lighting"; - choices[21] = "Night Snap"; - choices[256 + 4] = "Auto PICT"; - choices[256 + 5] = "Auto PICT (Portrait)"; - choices[256 + 6] = "Auto PICT (Landscape)"; - choices[256 + 7] = "Auto PICT (Macro)"; - choices[256 + 8] = "Auto PICT (Sport)"; - choices[256 + 8] = "Auto PICT (Sport)"; - choices[512 + 0] = "Program (HyP)"; - choices[512 + 1] = "Hi-speed Program (HyP)"; - choices[512 + 2] = "DOF Program (HyP)"; - choices[512 + 3] = "MTF Program (HyP)"; - choices[3 * 256] = "Green Mode"; - choices[4 * 256] = "Shutter Speed Priority"; - choices[5 * 256] = "Aperture Priority"; - choices[6 * 256] = "Program Tv Shift"; - choices[7 * 256] = "Program Av Shift"; - choices[8 * 256] = "Manual"; - choices[9 * 256] = "Bulb"; - choices[10 * 256] = "Aperture Priority, Off-Auto-Aperture"; - choices[11 * 256] = "Manual, Off-Auto-Aperture"; - choices[12 * 256] = "Bulb, Off-Auto-Aperture"; - choices[13 * 256] = "Shutter & Aperture Priority AE"; - choices[15 * 256] = "Sensitivity Priority AE"; - choices[16 * 256] = "Flash X-Sync Speed AE"; + choices[256 * 0 + 0] = "Program"; + choices[256 * 0 + 1] = "Hi-speed Program"; + choices[256 * 0 + 2] = "DOF Program"; + choices[256 * 0 + 3] = "MTF Program"; + choices[256 * 0 + 4] = "Standard"; + choices[256 * 0 + 5] = "Portrait"; + choices[256 * 0 + 6] = "Landscape"; + choices[256 * 0 + 7] = "Macro"; + choices[256 * 0 + 8] = "Sport"; + choices[256 * 0 + 9] = "Night Scene Portrait"; + choices[256 * 0 + 10] = "No Flash"; + choices[256 * 0 + 11] = "Night Scene"; + choices[256 * 0 + 12] = "Surf & Snow"; + choices[256 * 0 + 13] = "Text"; + choices[256 * 0 + 14] = "Sunset"; + choices[256 * 0 + 15] = "Kids"; + choices[256 * 0 + 16] = "Pet"; + choices[256 * 0 + 17] = "Candlelight"; + choices[256 * 0 + 18] = "Museum"; + choices[256 * 0 + 19] = "Food"; + choices[256 * 0 + 20] = "Stage Lighting"; + choices[256 * 0 + 21] = "Night Snap"; + choices[256 * 0 + 23] = "Blue Sky"; + choices[256 * 0 + 24] = "Sunset"; + choices[256 * 0 + 26] = "Night Scene HDR"; + choices[256 * 0 + 27] = "HDR"; + choices[256 * 0 + 28] = "Quick Macro"; + choices[256 * 0 + 29] = "Forest"; + choices[256 * 0 + 30] = "Backlight Silhouette"; + choices[256 * 1 + 4] = "Auto PICT (Standard)"; + choices[256 * 1 + 5] = "Auto PICT (Portrait)"; + choices[256 * 1 + 6] = "Auto PICT (Landscape)"; + choices[256 * 1 + 7] = "Auto PICT (Macro)"; + choices[256 * 1 + 8] = "Auto PICT (Sport)"; + choices[256 * 2 + 0] = "Program (HyP)"; + choices[256 * 2 + 1] = "Hi-speed Program (HyP)"; + choices[256 * 2 + 2] = "DOF Program (HyP)"; + choices[256 * 2 + 3] = "MTF Program (HyP)"; + choices[256 * 2 + 22] = "Shallow DOF (HyP)"; + choices[256 * 3 + 0] = "Green Mode"; + choices[256 * 4 + 0] = "Shutter Speed Priority"; + choices[256 * 5 + 0] = "Aperture Priority"; + choices[256 * 6 + 0] = "Program Tv Shift"; + choices[256 * 7 + 0] = "Program Av Shift"; + choices[256 * 8 + 0] = "Manual"; + choices[256 * 9 + 0] = "Bulb"; + choices[256 * 10 + 0] = "Aperture Priority, Off-Auto-Aperture"; + choices[256 * 11 + 0] = "Manual, Off-Auto-Aperture"; + choices[256 * 12 + 0] = "Bulb, Off-Auto-Aperture"; + choices[256 * 13 + 0] = "Shutter & Aperture Priority AE"; + choices[256 * 15 + 0] = "Sensitivity Priority AE"; + choices[256 * 16 + 0] = "Flash X-Sync Speed AE"; + choices[256 * 18 + 0] = "Auto Program (Normal)"; + choices[256 * 18 + 1] = "Auto Program (Hi-speed)"; + choices[256 * 18 + 2] = "Auto Program (DOF)"; + choices[256 * 18 + 3] = "Auto Program (MTF)"; + choices[256 * 18 + 22] = "Auto Program (Shallow DOF)"; + choices[256 * 20 + 22] = "Blur Control"; + choices[256 * 254 + 0] = "Video"; + choices[256 * 255 + 0] = "Video (Auto Aperture)"; + choices[256 * 255 + 4] = "Video (4)"; } virtual std::string toString (Tag* t) { @@ -701,6 +743,7 @@ public: choices.insert(p_t(256 * 3 + 44, "Sigma 12-24mm f/4.5-5.6 EX DG")); choices.insert(p_t(256 * 3 + 44, "Sigma 17-70mm f/2.8-4.5 DC Macro")); choices.insert(p_t(256 * 3 + 44, "Sigma 18-50mm f/3.5-5.6 DC")); + choices.insert(p_t(256 * 3 + 44, "Sigma 17-35mm f/2.8-4 EX DG")); choices.insert(p_t(256 * 3 + 44, "Tamron 35-90mm f/4 AF")); choices.insert(p_t(256 * 3 + 46, "Sigma or Samsung Lens (3 46)")); choices.insert(p_t(256 * 3 + 46, "Sigma APO 70-200mm f/2.8 EX")); @@ -873,11 +916,16 @@ public: choices.insert(p_t(256 * 8 + 27, "Sigma 18-200mm f/3.5-6.3 II DC HSM")); choices.insert(p_t(256 * 8 + 28, "Sigma 18-250mm f/3.5-6.3 DC Macro HSM")); choices.insert(p_t(256 * 8 + 29, "Sigma 35mm f/1.4 DG HSM")); - choices.insert(p_t(256 * 8 + 30, "Sigma 17-70mm f/2.8-4 DC Macro HSM Contemporary")); + choices.insert(p_t(256 * 8 + 30, "Sigma 17-70mm f/2.8-4 DC Macro HSM | C")); choices.insert(p_t(256 * 8 + 31, "Sigma 18-35mm f/1.8 DC HSM")); choices.insert(p_t(256 * 8 + 32, "Sigma 30mm f/1.4 DC HSM | A")); + choices.insert(p_t(256 * 8 + 34, "Sigma 18-300mm f/3.5-6.3 DC Macro HSM")); choices.insert(p_t(256 * 8 + 59, "HD PENTAX-D FA 150-450mm f/4.5-5.6 ED DC AW")); choices.insert(p_t(256 * 8 + 60, "HD PENTAX-D FA* 70-200mm f/2.8 ED DC AW")); + choices.insert(p_t(256 * 8 + 61, "HD PENTAX-D FA 28-105mm f/3.5-5.6 ED DC WR")); + choices.insert(p_t(256 * 8 + 62, "HD PENTAX-D FA 24-70mm f/2.8 ED SDM WR")); + choices.insert(p_t(256 * 8 + 63, "HD PENTAX-D FA 15-30mm f/2.8 ED SDM WR")); + choices.insert(p_t(256 * 8 + 197, "HD PENTAX-DA 55-300mm f/4.5-6.3 ED PLM WR RE")); choices.insert(p_t(256 * 8 + 198, "smc PENTAX-DA L 18-50mm f/4-5.6 DC WR RE")); choices.insert(p_t(256 * 8 + 199, "HD PENTAX-DA 18-50mm f/4-5.6 DC WR RE")); choices.insert(p_t(256 * 8 + 200, "HD PENTAX-DA 16-85mm f/3.5-5.6 ED DC WR")); @@ -915,6 +963,7 @@ public: choices.insert(p_t(256 * 11 + 14, "smc PENTAX-FA 645 55-110mm f/5.6")); choices.insert(p_t(256 * 11 + 16, "smc PENTAX-FA 645 33-55mm f/4.5 AL")); choices.insert(p_t(256 * 11 + 17, "smc PENTAX-FA 645 150-300mm f/5.6 ED [IF]")); + choices.insert(p_t(256 * 11 + 21, "HD PENTAX-D FA 645 35mm f/3.5 AL [IF]")); choices.insert(p_t(256 * 13 + 18, "smc PENTAX-D FA 645 55mm f/2.8 AL [IF] SDM AW")); choices.insert(p_t(256 * 13 + 19, "smc PENTAX-D FA 645 25mm f/4 AL [IF] SDM AW")); choices.insert(p_t(256 * 13 + 20, "HD PENTAX-D FA 645 90mm f/2.8 ED AW SR")); @@ -1018,12 +1067,15 @@ PASRResultInterpreter paSRResultInterpreter; class PAHighISONoiseInterpreter: public ChoiceInterpreter { public: + // HighISONoiseReduction PAHighISONoiseInterpreter() { choices[0] = "Off"; choices[1] = "Weakest"; choices[2] = "Weak"; choices[3] = "Strong"; + choices[4] = "Medium"; + choices[255] = "Auto"; } }; PAHighISONoiseInterpreter paHighISONoiseInterpreter; @@ -1171,9 +1223,9 @@ public: choices1[1] = "Auto-align On"; choices2[0] = "n/a"; - choices2[1] = "1 EV"; - choices2[2] = "2 EV"; - choices2[4] = "3 EV"; + choices2[4] = "1 EV"; + choices2[8] = "2 EV"; + choices2[12] = "3 EV"; } virtual std::string toString (Tag* t) { @@ -1268,7 +1320,7 @@ public: a = t->toInt(0, SBYTE) / 6; // int8u[2] } - char buffer[10]; + char buffer[32]; sprintf (buffer, "%d", a ); return buffer; } @@ -1296,7 +1348,7 @@ public: double a = double(t->toInt(0, LONG)); if(a > 1.) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%.2f", a / 100. ); return buffer; } else { @@ -1326,7 +1378,7 @@ public: float b = float(10 * int(a >> 2)) * pow(4.f, float(int(a & 0x03) - 2)); if(b > 1.f) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%.2f", b ); return buffer; } else { @@ -1529,11 +1581,13 @@ class PAFlashStatusInterpreter: public ChoiceInterpreter public: PAFlashStatusInterpreter() { - choices[0x0] = "Off"; - choices[0x2] = "External, Did not fire"; - choices[0x6] = "External, Fired"; - choices[0x9] = "Internal, Did not fire"; - choices[0xd] = "Internal, Fired"; + choices[0] = "Off"; + choices[1] = "Off (1)"; + choices[2] = "External, Did not fire"; + choices[6] = "External, Fired"; + choices[8] = "Internal, Did not fire (0x08)"; + choices[9] = "Internal, Did not fire"; + choices[13] = "Internal, Fired"; } }; PAFlashStatusInterpreter paFlashStatusInterpreter; @@ -1543,26 +1597,27 @@ class PAInternalFlashModeInterpreter: public ChoiceInterpreter public: PAInternalFlashModeInterpreter() { - choices[0x0] = "n/a - Off-Auto-Aperture"; - choices[0x86] = "On, Wireless (Control)"; - choices[0x95] = "On, Wireless (Master)"; - choices[0xc0] = "On"; - choices[0xc1] = "On, Red-eye reduction"; - choices[0xc2] = "On, Auto"; - choices[0xc3] = "On, Auto, Red-eye reduction"; - choices[0xc8] = "On, Slow-sync"; - choices[0xc9] = "On, Slow-sync, Red-eye reduction"; - choices[0xca] = "On, Trailing-curtain Sync"; - choices[0xf0] = "Off, Normal"; - choices[0xf1] = "Off, Red-eye reduction"; - choices[0xf2] = "Off, Auto"; - choices[0xf3] = "Off, Auto, Red-eye reduction"; - choices[0xf4] = "Off, (Unknown 0xf4)"; - choices[0xf5] = "Off, Wireless (Master)"; - choices[0xf6] = "Off, Wireless (Control)"; - choices[0xf8] = "Off, Slow-sync"; - choices[0xf9] = "Off, Slow-sync, Red-eye reduction"; - choices[0xfa] = "Off, Trailing-curtain Sync"; + choices[0] = "n/a - Off-Auto-Aperture"; + choices[134] = "Fired, Wireless (Control)"; + choices[149] = "Fired, Wireless (Master)"; + choices[192] = "Fired"; + choices[193] = "Fired, Red-eye reduction"; + choices[194] = "Fired, Auto"; + choices[195] = "Fired, Auto, Red-eye reduction"; + choices[198] = "Fired, Wireless (Control), Fired normally not as control"; + choices[200] = "Fired, Slow-sync"; + choices[201] = "Fired, Slow-sync, Red-eye reduction"; + choices[202] = "Fired, Trailing-curtain Sync"; + choices[240] = "Did not fire, Normal"; + choices[241] = "Did not fire, Red-eye reduction"; + choices[242] = "Did not fire, Auto"; + choices[243] = "Did not fire, Auto, Red-eye reduction"; + choices[244] = "Did not fire, (Unknown 0xf4)"; + choices[245] = "Did not fire, Wireless (Master)"; + choices[246] = "Did not fire, Wireless (Control)"; + choices[248] = "Did not fire, Slow-sync"; + choices[249] = "Did not fire, Slow-sync, Red-eye reduction"; + choices[250] = "Did not fire, Trailing-curtain Sync"; } }; PAInternalFlashModeInterpreter paInternalFlashModeInterpreter; @@ -1572,16 +1627,17 @@ class PAExternalFlashModeInterpreter: public ChoiceInterpreter public: PAExternalFlashModeInterpreter() { - choices[0x0 ] = "n/a - Off-Auto-Aperture"; - choices[0x3f] = "Off"; - choices[0x40] = "On, Auto"; - choices[0xbf] = "On, Flash Problem"; - choices[0xc0] = "On, Manual"; - choices[0xc4] = "On, P-TTL Auto"; - choices[0xc5] = "On, Contrast-control Sync"; - choices[0xc6] = "On, High-speed Sync"; - choices[0xcc] = "On, Wireless"; - choices[0xcd] = "On, Wireless, High-speed Sync"; + choices[0] = "n/a - Off-Auto-Aperture"; + choices[63] = "Off"; + choices[64] = "On, Auto"; + choices[191] = "On, Flash Problem"; + choices[192] = "On, Manual"; + choices[196] = "On, P-TTL Auto"; + choices[197] = "On, Contrast-control Sync"; + choices[198] = "On, High-speed Sync"; + choices[204] = "On, Wireless"; + choices[205] = "On, Wireless, High-speed Sync"; + choices[240] = "Not Connected"; } }; PAExternalFlashModeInterpreter paExternalFlashModeInterpreter; @@ -1599,9 +1655,9 @@ public: choices[171] = "-1.5"; choices[172] = "-1.0"; choices[175] = "-0.5"; - choices[176] = "0"; - choices[179] = "+0.5"; - choices[180] = "+1.0"; + choices[176] = "0.0"; + choices[179] = "0.5"; + choices[180] = "1.0"; } }; PAExternalFlashExposureCompInterpreter paExternalFlashExposureCompInterpreter; @@ -1624,7 +1680,7 @@ public: PAExternalFlashGNInterpreter() {} virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; int b = t->toInt(0, BYTE) & 0x1F; sprintf (buffer, "%.0f", pow(2., b / 16. + 4) ); return buffer; @@ -1694,15 +1750,15 @@ class PAFlashOptionInterpreter: public ChoiceInterpreter public: PAFlashOptionInterpreter() { - choices[0x0] = "Normal"; - choices[0x1] = "Red-eye reduction"; - choices[0x2] = "Auto"; - choices[0x3] = "Auto, Red-eye reduction"; - choices[0x5] = "Wireless (Master)"; - choices[0x6] = "Wireless (Control)"; - choices[0x8] = "Slow-sync"; - choices[0x9] = "Slow-sync, Red-eye reduction"; - choices[0xa] = "Trailing-curtain Sync"; + choices[0] = "Normal"; + choices[1] = "Red-eye reduction"; + choices[2] = "Auto"; + choices[3] = "Auto, Red-eye reduction"; + choices[5] = "Wireless (Master)"; + choices[6] = "Wireless (Control)"; + choices[8] = "Slow-sync"; + choices[9] = "Slow-sync, Red-eye reduction"; + choices[10] = "Trailing-curtain Sync"; } virtual std::string toString (Tag* t) { @@ -1884,6 +1940,8 @@ public: return "Single-frame"; } else if( c & 0x01) { return "Continuous"; + } else if( c & 0x02) { + return "Continuous (Lo)"; } else if( c & 0x04) { return "Self-timer (12 s)"; } else if( c & 0x08) { diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index f61d90c08..91f52ce55 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -336,7 +336,7 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring return true; } -Glib::ustring TagDirectory::getDumpKey (int tagID, const Glib::ustring tagName) +Glib::ustring TagDirectory::getDumpKey (int tagID, const Glib::ustring &tagName) { Glib::ustring key; @@ -1553,11 +1553,11 @@ void Tag::toString (char* buffer, int ofs) break; case SLONG: - sprintf (b, "%ld", (long)toInt(4 * i + ofs)); + sprintf (b, "%d", toInt(4 * i + ofs)); break; case LONG: - sprintf (b, "%lu", (unsigned long)toInt(4 * i + ofs)); + sprintf (b, "%u", toInt(4 * i + ofs)); break; case SRATIONAL: @@ -2792,6 +2792,7 @@ TagDirectory* ExifManager::parseTIFF (FILE* f, bool skipIgnored) std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) { + std::vector defTags; defTags.reserve (12); @@ -2800,7 +2801,7 @@ std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "XResolution"), 300, RATIONAL)); defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "YResolution"), 300, RATIONAL)); defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "ResolutionUnit"), 2, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "Software"), "RawTherapee")); + defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "Software"), "RawTherapee " VERSION)); defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "Orientation"), 1, SHORT)); defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "SamplesPerPixel"), 3, SHORT)); defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs, "BitsPerSample"), 8, SHORT)); @@ -2840,7 +2841,7 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro cl = new TagDirectory (NULL, ifdAttribs, INTEL); } - for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); i++) { + for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); ++i) { cl->applyChange (i->first, i->second); } @@ -2864,7 +2865,7 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro return size + 6; } -int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer) +int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize) { // write tiff header @@ -2875,17 +2876,17 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro order = root->getOrder (); } - sset2 ((unsigned short)order, buffer + offs, order); - offs += 2; - sset2 (42, buffer + offs, order); - offs += 2; - sset4 (8, buffer + offs, order); - offs += 4; - TagDirectory* cl; if (root) { cl = (const_cast(root))->clone (NULL); + // remove some unknown top level tags which produce warnings when opening a tiff + Tag *removeTag = cl->getTag(0x9003); + if(removeTag) + removeTag->setKeep(false); + removeTag = cl->getTag(0x9211); + if(removeTag) + removeTag->setKeep(false); } else { cl = new TagDirectory (NULL, ifdAttribs, HOSTORDER); } @@ -2926,7 +2927,7 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro } // apply list of changes - for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); i++) { + for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); ++i) { cl->applyChange (i->first, i->second); } @@ -2956,6 +2957,15 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro } cl->sort (); + bufferSize = cl->calculateSize() + 8; + buffer = new unsigned char[bufferSize]; // this has to be deleted in caller + sset2 ((unsigned short)order, buffer + offs, order); + offs += 2; + sset2 (42, buffer + offs, order); + offs += 2; + sset4 (8, buffer + offs, order); + offs += 4; + int endOffs = cl->write (8, buffer); // cl->printAll(); diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 2d6c800fc..7777331e9 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -101,7 +101,7 @@ protected: const TagAttrib* attribs; // descriptor table to decode the tags ByteOrder order; // byte order TagDirectory* parent; // parent directory (NULL if root) - static Glib::ustring getDumpKey (int tagID, const Glib::ustring tagName); + static Glib::ustring getDumpKey (int tagID, const Glib::ustring &tagName); public: TagDirectory (); @@ -318,7 +318,7 @@ public: /// @return The ownership of the return tags is passed to the caller. static std::vector getDefaultTIFFTags (TagDirectory* forthis); static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer); - static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer); + static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); }; class Interpreter @@ -495,7 +495,7 @@ protected: * Get the lens info (min/man focal, min/max aperture) and compare them to the possible choice */ if (lensInfoArray) { - for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); r++ ) { + for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); ++r ) { if( !extractLensInfo( r->second , f1, f2, a1, a2) ) { continue; } @@ -532,7 +532,7 @@ protected: std::ostringstream candidates; double deltaMin = 1000.; - for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); r++ ) { + for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); ++r ) { double lensAperture, dif; if( !extractLensInfo( r->second , f1, f2, a1, a2) ) { @@ -558,7 +558,7 @@ protected: lensAperture = exp( log(a1) + (log(a2) - log(a1)) / (log(f2) - log(f1)) * (log(focalLength) - log(f1)) ); } - dif = abs(lensAperture - maxApertureAtFocal); + dif = std::abs(lensAperture - maxApertureAtFocal); } else { dif = 0; } diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc index ea8fc0b49..7f4e1bb53 100644 --- a/rtexif/sonyminoltaattribs.cc +++ b/rtexif/sonyminoltaattribs.cc @@ -314,6 +314,7 @@ public: choices[0x50] = "Flash"; choices[0x60] = "Fluorescent"; choices[0x70] = "Custom"; + choices[0x80] = "Underwater"; } }; SAWhiteBalanceInterpreter saWhiteBalanceInterpreter; @@ -383,23 +384,31 @@ class SASceneModeInterpreter : public ChoiceInterpreter public: SASceneModeInterpreter () { - choices[0] = "Normal (P,A,S or M)"; + choices[0] = "Standard"; choices[1] = "Portrait"; choices[2] = "Text"; choices[3] = "Night Scene"; choices[4] = "Sunset"; choices[5] = "Sports"; choices[6] = "Landscape"; + choices[7] = "Night Portrait"; choices[8] = "Macro"; choices[9] = "Super Macro"; choices[16] = "Auto"; - choices[17] = "Night Portrait"; + choices[17] = "Night View/Portrait"; choices[18] = "Sweep Panorama"; choices[19] = "Handheld Night Shot"; choices[20] = "Anti Motion Blur"; - choices[21] = "Cont.Priority AE"; + choices[21] = "Cont. Priority AE"; choices[22] = "Auto+"; choices[23] = "3D Sweep Panorama"; + choices[24] = "Superior Auto"; + choices[25] = "High Sensitivity"; + choices[26] = "Fireworks"; + choices[27] = "Food"; + choices[28] = "Pet"; + choices[33] = "HDR"; + choices[65535] = "n/a"; } }; SASceneModeInterpreter saSceneModeInterpreter; @@ -449,14 +458,14 @@ public: choices[2] = "Portrait"; choices[3] = "Landscape"; choices[4] = "Sunset"; - choices[5] = "Night Scene"; + choices[5] = "Night View/Portrait"; choices[6] = "B&W"; choices[7] = "Adobe RGB"; choices[12] = "Neutral"; choices[13] = "Clear"; choices[14] = "Deep"; choices[15] = "Light"; - choices[16] = "Autumn"; + choices[16] = "Autumn Leaves"; choices[17] = "Sepia"; choices[100] = "Neutral"; choices[101] = "Clear"; @@ -473,18 +482,19 @@ class SAExposureModeInterpreter : public ChoiceInterpreter public: SAExposureModeInterpreter () { - choices[0] = "Auto"; + choices[0] = "Program AE"; choices[1] = "Portrait"; choices[2] = "Beach"; + choices[3] = "Sports"; choices[4] = "Snow"; choices[5] = "Landscape"; - choices[6] = "Program"; - choices[7] = "Aperture Priority"; - choices[8] = "Shutter Priority"; - choices[9] = "Night Scene"; + choices[6] = "Auto"; + choices[7] = "Aperture-priority AE"; + choices[8] = "Shutter speed priority AE"; + choices[9] = "Night Scene / Twilight"; choices[10] = "Hi-Speed Shutter"; choices[11] = "Twilight Portrait"; - choices[12] = "Soft Snap"; + choices[12] = "Soft Snap/Portrait"; choices[13] = "Fireworks"; choices[14] = "Smile Shutter"; choices[15] = "Manual"; @@ -492,13 +502,17 @@ public: choices[19] = "Macro"; choices[20] = "Advanced Sports Shooting"; choices[29] = "Underwater"; - choices[33] = "Gourmet"; - choices[34] = "Panorama"; - choices[35] = "Handheld Twilight"; + choices[33] = "Food"; + choices[34] = "Sweep Panorama"; + choices[35] = "Handheld Night Shot"; choices[36] = "Anti Motion Blur"; choices[37] = "Pet"; choices[38] = "Backlight Correction HDR"; + choices[39] = "Superior Auto"; choices[40] = "Background Defocus"; + choices[41] = "Soft Skin"; + choices[42] = "3D Image"; + choices[65535] = "n/a"; } }; SAExposureModeInterpreter saExposureModeInterpreter; @@ -611,7 +625,7 @@ public: choices.insert(p_t(55, "Sony DT 18-55mm f/3.5-5.6 SAM (SAL1855) or SAM II")); choices.insert(p_t(55, "Sony DT 18-55mm f/3.5-5.6 SAM II (SAL18552)")); choices.insert(p_t(56, "Sony DT 55-200mm f/4-5.6 SAM (SAL55200-2)")); - choices.insert(p_t(57, "Sony DT 50mm f/1.8 SAM (SAL50F18) or Tamron Lens")); + choices.insert(p_t(57, "Sony DT 50mm f/1.8 SAM (SAL50F18) or Tamron Lens or Commlite CM-EF-NEX adapter")); choices.insert(p_t(57, "Tamron SP AF 60mm f/2 Di II LD [IF] Macro 1:1")); choices.insert(p_t(57, "Tamron 18-270mm f/3.5-6.3 Di II PZD")); choices.insert(p_t(58, "Sony DT 30mm f/2.8 Macro SAM (SAL30M28)")); @@ -648,6 +662,7 @@ public: choices.insert(p_t(128, "Tamron AF 28-105mm f/4-5.6 [IF]")); choices.insert(p_t(128, "Sigma 35mm f/1.4 DG HSM")); choices.insert(p_t(128, "Sigma 18-35mm f/1.8 DC HSM")); + choices.insert(p_t(128, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM")); choices.insert(p_t(129, "Tamron Lens (129)")); choices.insert(p_t(129, "Tamron 200-400mm f/5.6 LD")); choices.insert(p_t(129, "Tamron 70-300mm f/4-5.6 LD")); @@ -675,6 +690,7 @@ public: choices.insert(p_t(255, "Tamron SP AF 70-200mm f/2.8 Di LD IF Macro")); choices.insert(p_t(255, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical IF")); choices.insert(p_t(255, "Tamron AF 90-300mm f/4.5-5.6 Telemacro")); + choices.insert(p_t(1868, "Sigma MC-11 Adapter")); choices.insert(p_t(2550, "Minolta AF 50mm f/1.7")); choices.insert(p_t(2551, "Minolta AF 35-70mm f/4 or Other Lens")); choices.insert(p_t(2551, "Sigma UC AF 28-70mm f/3.5-4.5")); @@ -723,7 +739,7 @@ public: choices.insert(p_t(2563, "Sigma 400mm f/5.6 APO")); choices.insert(p_t(2564, "Minolta AF 50mm f/2.8 Macro or Sigma Lens")); choices.insert(p_t(2564, "Sigma 50mm f/2.8 EX Macro")); - choices.insert(p_t(2565, "Minolta AF 600mm f/4")); + choices.insert(p_t(2565, "Minolta AF 600mm f/4 APO")); choices.insert(p_t(2566, "Minolta AF 24mm f/2.8 or Sigma Lens")); choices.insert(p_t(2566, "Sigma 17-35mm f/2.8-4 EX Aspherical")); choices.insert(p_t(2572, "Minolta/Sony AF 500mm f/8 Reflex")); @@ -749,7 +765,7 @@ public: choices.insert(p_t(2590, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 1.4x APO")); choices.insert(p_t(2591, "Minolta AF 35mm f/1.4")); choices.insert(p_t(2592, "Minolta AF 85mm f/1.4 G (D)")); - choices.insert(p_t(2593, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(2593, "Minolta AF 200mm f/2.8 APO")); choices.insert(p_t(2594, "Minolta AF 3x-1x f/1.7-2.8 Macro")); choices.insert(p_t(2596, "Minolta AF 28mm f/2")); choices.insert(p_t(2597, "Minolta AF 35mm f/2 [New]")); @@ -771,7 +787,7 @@ public: choices.insert(p_t(2620, "Minolta AF 28-70mm f/2.8 G")); choices.insert(p_t(2621, "Minolta AF 100-300mm f/4.5-5.6 xi")); choices.insert(p_t(2624, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); - choices.insert(p_t(2628, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(2628, "Minolta AF 80-200mm f/2.8 HS-APO G")); choices.insert(p_t(2629, "Minolta AF 85mm f/1.4 New")); choices.insert(p_t(2631, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); choices.insert(p_t(2632, "Minolta AF 24-50mm f/4 New")); @@ -795,7 +811,8 @@ public: choices.insert(p_t(4585, "Tamron SP AF 300mm f/2.8 LD IF")); choices.insert(p_t(4586, "Tamron SP AF 35-105mm f/2.8 LD Aspherical IF")); choices.insert(p_t(4587, "Tamron AF 70-210mm f/2.8 SP LD")); - choices.insert(p_t(6118, "Metabones Canon EF Adapter")); + choices.insert(p_t(4812, "Metabones Canon EF Speed Booster Ultra")); + choices.insert(p_t(6118, "Canon EF Adapter")); choices.insert(p_t(6553, "E-Mount, T-Mount, Other Lens or no lens")); choices.insert(p_t(6553, "Sony E 16mm f/2.8")); choices.insert(p_t(6553, "Sony E 18-55mm f/3.5-5.6 OSS")); @@ -824,14 +841,22 @@ public: choices.insert(p_t(6553, "Sony FE 24-240mm f/3.5-6.3 OSS")); choices.insert(p_t(6553, "Sony FE 28mm f/2")); choices.insert(p_t(6553, "Sony FE PZ 28-135mm f/4 G OSS")); + choices.insert(p_t(6553, "Sony FE 24-70mm f/2.8 GM")); + choices.insert(p_t(6553, "Sony FE 85mm f/1.4 GM")); + choices.insert(p_t(6553, "Sony FE 50mm f/1.8")); choices.insert(p_t(6553, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)")); choices.insert(p_t(6553, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)")); + choices.insert(p_t(6553, "Sony FE 70-300mm f/4.5-5.6 G OSS")); + choices.insert(p_t(6553, "Sony FE 70-200mm f/2.8 GM OSS")); choices.insert(p_t(6553, "Sigma 19mm f/2.8 [EX] DN")); choices.insert(p_t(6553, "Sigma 30mm f/2.8 [EX] DN")); choices.insert(p_t(6553, "Sigma 60mm f/2.8 DN")); + choices.insert(p_t(6553, "Sigma 30mm f/1.4 DC DN | C")); choices.insert(p_t(6553, "Tamron 18-200mm f/3.5-6.3 Di III VC")); choices.insert(p_t(6553, "Zeiss Batis 25mm f/2")); choices.insert(p_t(6553, "Zeiss Batis 85mm f/1.8")); + choices.insert(p_t(6553, "Zeiss Batis 18mm f/2.8")); + choices.insert(p_t(6553, "Zeiss Loxia 21mm f/2.8")); choices.insert(p_t(6553, "Zeiss Loxia 35mm f/2")); choices.insert(p_t(6553, "Zeiss Loxia 50mm f/2")); choices.insert(p_t(6553, "Zeiss Touit 12mm f/2.8")); @@ -844,6 +869,7 @@ public: choices.insert(p_t(6553, "Pentacon Auto 135mm f/2.8")); choices.insert(p_t(6553, "Pentacon Auto 29mm f/2.8")); choices.insert(p_t(6553, "Helios 44-2 58mm f/2.0")); + choices.insert(p_t(18688, "Sigma MC-11 Adapter")); choices.insert(p_t(25501, "Minolta AF 50mm f/1.7")); choices.insert(p_t(25511, "Minolta AF 35-70mm f/4 or Other Lens")); choices.insert(p_t(25511, "Sigma UC AF 28-70mm f/3.5-4.5")); @@ -892,7 +918,7 @@ public: choices.insert(p_t(25631, "Sigma 400mm f/5.6 APO")); choices.insert(p_t(25641, "Minolta AF 50mm f/2.8 Macro or Sigma Lens")); choices.insert(p_t(25641, "Sigma 50mm f/2.8 EX Macro")); - choices.insert(p_t(25651, "Minolta AF 600mm f/4")); + choices.insert(p_t(25651, "Minolta AF 600mm f/4 APO")); choices.insert(p_t(25661, "Minolta AF 24mm f/2.8 or Sigma Lens")); choices.insert(p_t(25661, "Sigma 17-35mm f/2.8-4 EX Aspherical")); choices.insert(p_t(25721, "Minolta/Sony AF 500mm f/8 Reflex")); @@ -918,7 +944,7 @@ public: choices.insert(p_t(25901, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 1.4x APO")); choices.insert(p_t(25911, "Minolta AF 35mm f/1.4")); choices.insert(p_t(25921, "Minolta AF 85mm f/1.4 G (D)")); - choices.insert(p_t(25931, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(25931, "Minolta AF 200mm f/2.8 APO")); choices.insert(p_t(25941, "Minolta AF 3x-1x f/1.7-2.8 Macro")); choices.insert(p_t(25961, "Minolta AF 28mm f/2")); choices.insert(p_t(25971, "Minolta AF 35mm f/2 [New]")); @@ -940,7 +966,7 @@ public: choices.insert(p_t(26201, "Minolta AF 28-70mm f/2.8 G")); choices.insert(p_t(26211, "Minolta AF 100-300mm f/4.5-5.6 xi")); choices.insert(p_t(26241, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); - choices.insert(p_t(26281, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(26281, "Minolta AF 80-200mm f/2.8 HS-APO G")); choices.insert(p_t(26291, "Minolta AF 85mm f/1.4 New")); choices.insert(p_t(26311, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); choices.insert(p_t(26321, "Minolta AF 24-50mm f/4 New")); @@ -964,7 +990,8 @@ public: choices.insert(p_t(45851, "Tamron SP AF 300mm f/2.8 LD IF")); choices.insert(p_t(45861, "Tamron SP AF 35-105mm f/2.8 LD Aspherical IF")); choices.insert(p_t(45871, "Tamron AF 70-210mm f/2.8 SP LD")); - choices.insert(p_t(61184, "Metabones Canon EF Adapter")); + choices.insert(p_t(48128, "Metabones Canon EF Speed Booster Ultra")); + choices.insert(p_t(61184, "Canon EF Adapter")); choices.insert(p_t(65535, "E-Mount, T-Mount, Other Lens or no lens")); choices.insert(p_t(65535, "Sony E 16mm f/2.8")); choices.insert(p_t(65535, "Sony E 18-55mm f/3.5-5.6 OSS")); @@ -993,14 +1020,22 @@ public: choices.insert(p_t(65535, "Sony FE 24-240mm f/3.5-6.3 OSS")); choices.insert(p_t(65535, "Sony FE 28mm f/2")); choices.insert(p_t(65535, "Sony FE PZ 28-135mm f/4 G OSS")); + choices.insert(p_t(65535, "Sony FE 24-70mm f/2.8 GM")); + choices.insert(p_t(65535, "Sony FE 85mm f/1.4 GM")); + choices.insert(p_t(65535, "Sony FE 50mm f/1.8")); choices.insert(p_t(65535, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)")); choices.insert(p_t(65535, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)")); + choices.insert(p_t(65535, "Sony FE 70-300mm f/4.5-5.6 G OSS")); + choices.insert(p_t(65535, "Sony FE 70-200mm f/2.8 GM OSS")); choices.insert(p_t(65535, "Sigma 19mm f/2.8 [EX] DN")); choices.insert(p_t(65535, "Sigma 30mm f/2.8 [EX] DN")); choices.insert(p_t(65535, "Sigma 60mm f/2.8 DN")); + choices.insert(p_t(65535, "Sigma 30mm f/1.4 DC DN | C")); choices.insert(p_t(65535, "Tamron 18-200mm f/3.5-6.3 Di III VC")); choices.insert(p_t(65535, "Zeiss Batis 25mm f/2")); choices.insert(p_t(65535, "Zeiss Batis 85mm f/1.8")); + choices.insert(p_t(65535, "Zeiss Batis 18mm f/2.8")); + choices.insert(p_t(65535, "Zeiss Loxia 21mm f/2.8")); choices.insert(p_t(65535, "Zeiss Loxia 35mm f/2")); choices.insert(p_t(65535, "Zeiss Loxia 50mm f/2")); choices.insert(p_t(65535, "Zeiss Touit 12mm f/2.8")); @@ -1060,8 +1095,8 @@ public: choices.insert(p_t(3, "Sony LA-EA3 Adapter")); choices.insert(p_t(6, "Sony LA-EA4 Adapter")); choices.insert(p_t(44, "Metabones Canon EF Smart Adapter")); - choices.insert(p_t(78, "Metabones Canon EF Smart Adapter Mark III or IV")); - choices.insert(p_t(234, "Adapter only - no lens attached")); + choices.insert(p_t(78, "Metabones Canon EF Smart Adapter Mark III or Other Adapter")); + choices.insert(p_t(234, "Metabones Canon EF Smart Adapter Mark IV")); choices.insert(p_t(239, "Metabones Canon EF Speed Booster")); choices.insert(p_t(32784, "Sony E 16mm f/2.8")); choices.insert(p_t(32785, "Sony E 18-55mm f/3.5-5.6 OSS")); @@ -1090,10 +1125,35 @@ public: choices.insert(p_t(32815, "Sony FE 24-240mm f/3.5-6.3 OSS")); choices.insert(p_t(32816, "Sony FE 28mm f/2")); choices.insert(p_t(32817, "Sony FE PZ 28-135mm f/4 G OSS")); + choices.insert(p_t(32821, "Sony FE 24-70mm f/2.8 GM")); + choices.insert(p_t(32823, "Sony FE 85mm f/1.4 GM")); + choices.insert(p_t(32824, "Sony FE 50mm f/1.8")); choices.insert(p_t(32826, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)")); choices.insert(p_t(32827, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)")); + choices.insert(p_t(32828, "Sony FE 70-300mm f/4.5-5.6 G OSS")); + choices.insert(p_t(32830, "Sony FE 70-200mm f/2.8 GM OSS")); + choices.insert(p_t(49201, "Zeiss Touit 12mm f/2.8")); + choices.insert(p_t(49202, "Zeiss Touit 32mm f/1.8")); + choices.insert(p_t(49203, "Zeiss Touit 50mm f/2.8 Macro")); choices.insert(p_t(49216, "Zeiss Batis 25mm f/2")); choices.insert(p_t(49217, "Zeiss Batis 85mm f/1.8")); + choices.insert(p_t(49218, "Zeiss Batis 18mm f/2.8")); + choices.insert(p_t(49232, "Zeiss Loxia 50mm f/2")); + choices.insert(p_t(49233, "Zeiss Loxia 35mm f/2")); + choices.insert(p_t(49234, "Zeiss Loxia 21mm f/2.8")); + choices.insert(p_t(50480, "Sigma 30mm f/1.4 DC DN | C 016")); + choices.insert(p_t(50481, "Sigma 50mm f/1.4 DG HSM | A 014 + MC-11")); + choices.insert(p_t(50482, "Sigma 18-300mm f/3.5-6.3 DC MACRO OS HSM | C 014 + MC-11")); + choices.insert(p_t(50483, "Sigma 18-35mm f/1.8 DC HSM | A 013 + MC-11")); + choices.insert(p_t(50484, "Sigma 24-35mm f/2 DG HSM | A 015 + MC-11")); + choices.insert(p_t(50486, "Sigma 150-600mm f/5-6.3 DG OS HSM | C 015 + MC-11")); + choices.insert(p_t(50487, "Sigma 20mm f/1.4 DG HSM | A 015 + MC-11")); + choices.insert(p_t(50488, "Sigma 35mm f/1.4 DG HSM | A 012 + MC-11")); + choices.insert(p_t(50489, "Sigma 150-600mm f/5-6.3 DG OS HSM | S 014 + MC-11")); + choices.insert(p_t(50490, "Sigma 120-300mm f/2.8 DG OS HSM | S 013 + MC-11")); + choices.insert(p_t(50492, "Sigma 24-105mm f/4 DG OS HSM | A 013 + MC-11")); + choices.insert(p_t(50493, "Sigma 17-70mm f/2.8-4 DC MACRO OS HSM | C 013 + MC-11")); + choices.insert(p_t(50495, "Sigma 50-100mm f/1.8 DC HSM | A 016 + MC-11")); } virtual std::string toString (Tag* t) @@ -1135,11 +1195,15 @@ class MATeleconverterInterpreter : public ChoiceInterpreter public: MATeleconverterInterpreter () { - choices[0] = "None "; - choices[0x48] = "Minolta AF 2x APO (D)"; - choices[0x50] = "Minolta AF 2x APO II"; - choices[0x88] = "Minolta AF 1.4x APO (D)"; - choices[0x90] = "Minolta AF 1.4x APO II"; + choices[0x0] = "None"; + choices[0x4] = "Minolta/Sony AF 1.4x APO (D) (0x04)"; + choices[0x5] = "Minolta/Sony AF 2x APO (D) (0x05)"; + choices[0x48] = "Minolta/Sony AF 2x APO (D)"; + choices[0x50] = "Minolta AF 2x APO II"; + choices[0x60] = "Minolta AF 2x APO"; + choices[0x88] = "Minolta/Sony AF 1.4x APO (D)"; + choices[0x90] = "Minolta AF 1.4x APO II"; + choices[0xa0] = "Minolta AF 1.4x APO"; } }; MATeleconverterInterpreter maTeleconverterInterpreter; @@ -1149,15 +1213,15 @@ class MAQualityInterpreter : public ChoiceInterpreter public: MAQualityInterpreter () { - choices[0] = "Raw"; - choices[1] = "Super Fine"; - choices[2] = "Fine"; - choices[3] = "Standard"; - choices[4] = "Economy"; - choices[5] = "Extra fine"; - choices[6] = "RAW + JPEG"; - choices[7] = "cRAW"; - choices[8] = "cRAW + JPEG"; + choices[0] = "RAW"; + choices[1] = "Super Fine"; + choices[2] = "Fine"; + choices[3] = "Standard"; + choices[4] = "Economy"; + choices[5] = "Extra Fine"; + choices[6] = "RAW + JPEG"; + choices[7] = "Compressed RAW"; + choices[8] = "Compressed RAW + JPEG"; } }; MAQualityInterpreter maQualityInterpreter; @@ -1211,14 +1275,19 @@ class SADriveMode : public ChoiceInterpreter public: SADriveMode () { - choices[0] = "Single Frame"; - choices[1] = "Continuous High"; + choices[1] = "Single Frame"; + choices[2] = "Continuous High"; choices[4] = "Self-timer 10 sec"; - choices[5] = "Self-timer 2 sec"; + choices[5] = "Self-timer 2 sec, Mirror Lock-up"; + choices[6] = "Single-frame Bracketing"; choices[7] = "Continuous Bracketing"; - choices[12] = "Continuous Low"; - choices[18] = "White Balance Bracketing Low"; - choices[19] = "D-Range Optimizer Bracketing Low"; + choices[10] = "Remote Commander"; + choices[11] = "Mirror Lock-up"; + choices[18] = "Continuous Low"; + choices[24] = "White Balance Bracketing Low"; + choices[25] = "D-Range Optimizer Bracketing Low"; + choices[40] = "White Balance Bracketing High"; + choices[41] = "D-Range Optimizer Bracketing High"; } }; SADriveMode saDriveMode; @@ -1228,7 +1297,7 @@ class SADriveMode2 : public ChoiceInterpreter public: SADriveMode2 () { - choices[0] = "Single Frame"; + choices[1] = "Single Frame"; choices[2] = "Continuous High"; choices[4] = "Self-timer 10 sec"; choices[5] = "Self-timer 2 sec, Mirror Lock-up"; @@ -1244,23 +1313,23 @@ class SADriveMode3 : public ChoiceInterpreter public: SADriveMode3 () { - choices[0x10] = "Single Frame"; - choices[0x21] = "Continuous High"; - choices[0x22] = "Continuous Low"; - choices[0x30] = "Speed Priority Continuous"; - choices[0x51] = "Self-timer 10 sec"; - choices[0x52] = "Self-timer 2 sec, Mirror Lock-up"; - choices[0x71] = "Continuous Bracketing 0.3 EV"; - choices[0x75] = "Continuous Bracketing 0.7 EV"; - choices[0x91] = "White Balance Bracketing Low"; - choices[0x92] = "White Balance Bracketing High"; - choices[0xC0] = "Remote Commander"; - choices[0xD1] = "Continuous - HDR"; - choices[0xD2] = "Continuous - Multi Frame NR"; - choices[0xD3] = "Continuous - Handheld Night Shot"; - choices[0xD4] = "Continuous - Anti Motion Blur"; - choices[0xD5] = "Continuous - Sweep Panorama"; - choices[0xD6] = "Continuous - 3D Sweep Panorama"; + choices[16] = "Single Frame"; + choices[33] = "Continuous High"; + choices[34] = "Continuous Low"; + choices[48] = "Speed Priority Continuous"; + choices[81] = "Self-timer 10 sec"; + choices[82] = "Self-timer 2 sec, Mirror Lock-up"; + choices[113] = "Continuous Bracketing 0.3 EV"; + choices[117] = "Continuous Bracketing 0.7 EV"; + choices[145] = "White Balance Bracketing Low"; + choices[146] = "White Balance Bracketing High"; + choices[192] = "Remote Commander"; + choices[209] = "Continuous - HDR"; + choices[210] = "Continuous - Multi Frame NR"; + choices[211] = "Continuous - Handheld Night Shot"; + choices[212] = "Continuous - Anti Motion Blur"; + choices[213] = "Continuous - Sweep Panorama"; + choices[214] = "Continuous - 3D Sweep Panorama"; } }; SADriveMode3 saDriveMode3; @@ -1320,8 +1389,8 @@ public: choices[3] = "Spot AF"; choices[4] = "Flexible Spot AF"; choices[6] = "Touch AF"; - choices[14] = "Manual Focus"; - choices[15] = "Face Detected"; + choices[14] = "Tracking"; + choices[15] = "Face Tracking"; choices[65535] = "n/a"; } }; @@ -1624,27 +1693,27 @@ class SAExposureProgram2: public ChoiceInterpreter public: SAExposureProgram2 () { - choices[1] = "Program AE"; - choices[2] = "Aperture-priority AE"; - choices[3] = "Shutter speed priority AE"; - choices[4] = "Manual"; - choices[5] = "Cont. Priority AE"; - choices[16] = "Auto"; - choices[17] = "Auto (no flash)"; - choices[18] = "Auto+"; - choices[49] = "Portrait"; - choices[50] = "Landscape"; - choices[51] = "Macro"; - choices[52] = "Sports"; - choices[53] = "Sunset"; - choices[54] = "Night view"; - choices[55] = "Night view/portrait"; - choices[56] = "Handheld Night Shot"; - choices[57] = "3D Sweep Panorama"; - choices[64] = "Auto 2"; - choices[65] = "Auto 2 (no flash)"; - choices[80] = "Sweep Panorama"; - choices[96] = "Anti Motion Blur"; + choices[1] = "Program AE"; + choices[2] = "Aperture-priority AE"; + choices[3] = "Shutter speed priority AE"; + choices[4] = "Manual"; + choices[5] = "Cont. Priority AE"; + choices[16] = "Auto"; + choices[17] = "Auto (no flash)"; + choices[18] = "Auto+"; + choices[49] = "Portrait"; + choices[50] = "Landscape"; + choices[51] = "Macro"; + choices[52] = "Sports"; + choices[53] = "Sunset"; + choices[54] = "Night view"; + choices[55] = "Night view/portrait"; + choices[56] = "Handheld Night Shot"; + choices[57] = "3D Sweep Panorama"; + choices[64] = "Auto 2"; + choices[65] = "Auto 2 (no flash)"; + choices[80] = "Sweep Panorama"; + choices[96] = "Anti Motion Blur"; choices[128] = "Toy Camera"; choices[129] = "Pop Color"; choices[130] = "Posterization"; @@ -1785,9 +1854,10 @@ public: SAReleaseModeInterpreter () { choices[0] = "Normal"; - choices[2] = "Burst"; + choices[2] = "Continuous"; choices[5] = "Exposure Bracketing"; choices[6] = "White Balance Bracketing"; + choices[8] = "DRO Bracketing"; choices[65535] = "n/a"; } }; @@ -1800,11 +1870,19 @@ public: { choices[1] = "Standard"; choices[2] = "Vivid"; + choices[3] = "Portrait"; + choices[4] = "Landscape"; + choices[5] = "Sunset"; + choices[7] = "Night View/Portrait"; + choices[8] = "B&W"; choices[9] = "Adobe RGB"; choices[11] = "Neutral"; choices[129] = "StyleBox1"; choices[130] = "StyleBox2"; choices[131] = "StyleBox3"; + choices[132] = "StyleBox4"; + choices[133] = "StyleBox5"; + choices[134] = "StyleBox6"; } }; SAImageStyleInterpreter saImageStyleInterpreter; @@ -1814,27 +1892,42 @@ class SAPictureEffectInterpreter: public ChoiceInterpreter public: SAPictureEffectInterpreter() { - choices[0] = "Off"; - choices[1] = "Toy Camera"; - choices[2] = "Pop Color"; - choices[3] = "Posterization"; - choices[4] = "Posterization B/W"; - choices[5] = "Retro Photo"; - choices[6] = "Soft High Key"; - choices[7] = "Partial Color Red"; - choices[8] = "Partial Color Green"; - choices[9] = "Partial Color Blue"; - choices[10] = "Partial Color Yellow"; + choices[0] = "Off"; + choices[1] = "Toy Camera"; + choices[2] = "Pop Color"; + choices[3] = "Posterization"; + choices[4] = "Posterization B/W"; + choices[5] = "Retro Photo"; + choices[6] = "Soft High Key"; + choices[7] = "Partial Color (red)"; + choices[8] = "Partial Color (green)"; + choices[9] = "Partial Color (blue)"; + choices[10] = "Partial Color (yellow)"; choices[13] = "High Contrast Monochrome"; - choices[16] = "Toy Camera 2"; + choices[16] = "Toy Camera (normal)"; + choices[17] = "Toy Camera (cool)"; + choices[18] = "Toy Camera (warm)"; + choices[19] = "Toy Camera (green)"; + choices[20] = "Toy Camera (magenta)"; + choices[32] = "Soft Focus (low)"; choices[33] = "Soft Focus"; - choices[48] = "Miniature"; - choices[50] = "Miniature 2"; - choices[51] = "Miniature 3"; + choices[34] = "Soft Focus (high)"; + choices[48] = "Miniature (auto)"; + choices[49] = "Miniature (top)"; + choices[50] = "Miniature (middle horizontal)"; + choices[51] = "Miniature (bottom)"; + choices[52] = "Miniature (left)"; + choices[53] = "Miniature (middle vertical)"; + choices[54] = "Miniature (right)"; + choices[64] = "HDR Painting (low)"; choices[65] = "HDR Painting"; + choices[66] = "HDR Painting (high)"; choices[80] = "Rich-tone Monochrome"; - choices[98] = "Water Color"; - choices[114] = "Illustration"; + choices[97] = "Water Color"; + choices[98] = "Water Color 2"; + choices[112] = "Illustration (low)"; + choices[113] = "Illustration"; + choices[114] = "Illustration (high)"; } }; SAPictureEffectInterpreter saPictureEffectInterpreter; @@ -1862,7 +1955,7 @@ public: double a = t->toDouble(); if(a > 0) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%.4f", a); return buffer; } else { @@ -1922,7 +2015,7 @@ public: double a = double(t->toDouble()); if(a) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%.1f", a / 100. ); return buffer; } else { @@ -1982,7 +2075,7 @@ public: int a = t->toInt(); if(a) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%d", a ); return buffer; } else { @@ -2021,7 +2114,7 @@ public: virtual std::string toString (Tag* t) { double a = t->toDouble(); - char buffer[10]; + char buffer[32]; sprintf (buffer, "%.2f", a ); return buffer; } @@ -2041,7 +2134,7 @@ public: SAAFMicroAdjValueInterpreter() {} virtual std::string toString (Tag* t) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%d", t->getValue()[0] - 20); return buffer; } @@ -2080,7 +2173,7 @@ public: SAAFMicroAdjRegisteredLensesInterpreter() {} virtual std::string toString (Tag* t) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%d", t->getValue()[0] & 0x7f); return buffer; } @@ -2136,7 +2229,7 @@ public: SAColorTemperatureSettingInterpreter () {} virtual std::string toString (Tag* t) { - char buffer[10]; + char buffer[32]; sprintf (buffer, "%d", t->toInt()); return buffer; } diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc index 0d7c38ff9..98594e64c 100644 --- a/rtexif/stdattribs.cc +++ b/rtexif/stdattribs.cc @@ -386,7 +386,7 @@ public: ShutterSpeedInterpreter () {} virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; double d = pow (2.0, -t->toDouble()); if (d > 0.0 && d < 0.9) { @@ -406,7 +406,7 @@ public: ExposureTimeInterpreter () {} virtual std::string toString (Tag* t) { - char buffer[1024]; + char buffer[32]; double d = t->toDouble(); if (d > 0.0 && d < 0.9) { diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 244c22946..580874e5a 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -4,119 +4,119 @@ // UPDATE THE DEFAULT VALUE IN OPTIONS.CC int babehav[] TOO !!! +enum { + ADDSET_TC_EXPCOMP, + ADDSET_TC_BRIGHTNESS, + ADDSET_TC_BLACKLEVEL, + ADDSET_TC_CONTRAST, + ADDSET_SH_HIGHLIGHTS, + ADDSET_SH_SHADOWS, + ADDSET_SH_LOCALCONTRAST, + ADDSET_LC_BRIGHTNESS, + ADDSET_LC_CONTRAST, + ADDSET_SHARP_AMOUNT, + ADDSET_WB_TEMPERATURE, + ADDSET_WB_GREEN, + ADDSET_ROTATE_DEGREE, + ADDSET_DIST_AMOUNT, + ADDSET_PERSPECTIVE, + ADDSET_CA, + ADDSET_VIGN_AMOUNT, + ADDSET_VIGN_RADIUS, + ADDSET_VIGN_STRENGTH, + ADDSET_VIGN_CENTER, + ADDSET_LC_CHROMATICITY, + ADDSET_TC_SATURATION, + ADDSET_TC_HLCOMPAMOUNT, + ADDSET_TC_HLCOMPTHRESH, + ADDSET_TC_SHCOMP, + ADDSET_DIRPYREQ, + ADDSET_DIRPYRDN_LUMA, + ADDSET_DIRPYRDN_LUMDET, + ADDSET_DIRPYRDN_CHROMA, + ADDSET_DIRPYRDN_CHROMARED, + ADDSET_DIRPYRDN_CHROMABLUE, + ADDSET_DIRPYRDN_GAMMA, + ADDSET_CHMIXER, + ADDSET_PREPROCESS_GREENEQUIL, + ADDSET_PREPROCESS_LINEDENOISE, + ADDSET_RAWCACORR, + ADDSET_RAWEXPOS_LINEAR, + ADDSET_RAWEXPOS_PRESER, + ADDSET_RAWEXPOS_BLACKS, + ADDSET_SHARPENEDGE_AMOUNT, + ADDSET_SHARPENMICRO_AMOUNT, + ADDSET_SHARPENEDGE_PASS, + ADDSET_SHARPENMICRO_UNIFORMITY, + ADDSET_VIBRANCE_PASTELS, + ADDSET_VIBRANCE_SATURATED, + ADDSET_FREE_OUPUT_GAMMA, + ADDSET_FREE_OUTPUT_SLOPE, + ADDSET_CAT_DEGREE, + ADDSET_CAT_ADAPTSCENE, + ADDSET_CAT_ADAPTVIEWING, + ADDSET_CAT_LIGHT, + ADDSET_CAT_CHROMA, + ADDSET_CAT_CONTRAST, + ADDSET_CAT_RSTPRO, + ADDSET_CAT_BRIGHT, + ADDSET_CAT_CONTRAST_Q, + ADDSET_CAT_CHROMA_S, + ADDSET_CAT_CHROMA_M, + ADDSET_CAT_HUE, + ADDSET_CAT_BADPIX, + ADDSET_WB_EQUAL, + ADDSET_GRADIENT_DEGREE, + ADDSET_GRADIENT_FEATHER, + ADDSET_GRADIENT_STRENGTH, + ADDSET_GRADIENT_CENTER, + ADDSET_PCVIGNETTE_STRENGTH, + ADDSET_PCVIGNETTE_FEATHER, + ADDSET_PCVIGNETTE_ROUNDNESS, + ADDSET_BLACKWHITE_HUES, + ADDSET_BLACKWHITE_GAMMA, + ADDSET_DIRPYREQ_THRESHOLD, + ADDSET_DIRPYREQ_SKINPROTECT, + ADDSET_COLORTONING_SPLIT, + ADDSET_COLORTONING_SATTHRESHOLD, + ADDSET_COLORTONING_SATOPACITY, + ADDSET_COLORTONING_BALANCE, + ADDSET_COLORTONING_STRENGTH, + ADDSET_DIRPYRDN_PASSES, + ADDSET_RAWFFCLIPCONTROL, + ADDSET_FILMSIMULATION_STRENGTH, + ADDSET_WA, + ADDSET_WA_SKINPROTECT, + ADDSET_WA_THRR, + ADDSET_WA_THRRH, + ADDSET_WA_THRES, + ADDSET_WA_THRESHOLD, + ADDSET_WA_THRESHOLD2, + ADDSET_WA_CHRO, + ADDSET_WA_CHROMA, + ADDSET_WA_CONTRAST, + ADDSET_WA_RESCON, + ADDSET_WA_RESCONH, + ADDSET_WA_RESCHRO, + ADDSET_WA_SKYPROTECT, + ADDSET_WA_EDGRAD, + ADDSET_WA_EDGVAL, + ADDSET_WA_STRENGTH, + ADDSET_WA_EDGEDETECT, + ADDSET_WA_EDGEDETECTTHR, + ADDSET_WA_EDGEDETECTTHR2, + ADDSET_WA_TMRS, + ADDSET_WA_GAMMA, + ADDSET_RETI_STR, + ADDSET_RETI_NEIGH, + ADDSET_RETI_LIMD, + ADDSET_RETI_GAIN, + ADDSET_RETI_OFFS, + ADDSET_RETI_VART, + ADDSET_RETI_GAM, + ADDSET_RETI_SLO, -#define ADDSET_TC_EXPCOMP 0 -#define ADDSET_TC_BRIGHTNESS 1 -#define ADDSET_TC_BLACKLEVEL 2 -#define ADDSET_TC_CONTRAST 3 -#define ADDSET_SH_HIGHLIGHTS 4 -#define ADDSET_SH_SHADOWS 5 -#define ADDSET_SH_LOCALCONTRAST 6 -#define ADDSET_LC_BRIGHTNESS 7 -#define ADDSET_LC_CONTRAST 8 -#define ADDSET_SHARP_AMOUNT 9 -#define ADDSET_WB_TEMPERATURE 10 -#define ADDSET_WB_GREEN 11 -#define ADDSET_ROTATE_DEGREE 12 -#define ADDSET_DIST_AMOUNT 13 -#define ADDSET_PERSPECTIVE 14 -#define ADDSET_CA 15 -#define ADDSET_VIGN_AMOUNT 16 -#define ADDSET_VIGN_RADIUS 17 -#define ADDSET_VIGN_STRENGTH 18 -#define ADDSET_VIGN_CENTER 19 -#define ADDSET_LC_CHROMATICITY 20 -#define ADDSET_TC_SATURATION 21 -#define ADDSET_TC_HLCOMPAMOUNT 22 -#define ADDSET_TC_HLCOMPTHRESH 23 -#define ADDSET_TC_SHCOMP 24 -#define ADDSET_DIRPYREQ 25 -#define ADDSET_DIRPYRDN_LUMA 26 -#define ADDSET_DIRPYRDN_LUMDET 27 -#define ADDSET_DIRPYRDN_CHROMA 28 -#define ADDSET_DIRPYRDN_CHROMARED 29 -#define ADDSET_DIRPYRDN_CHROMABLUE 30 -#define ADDSET_DIRPYRDN_GAMMA 31 -#define ADDSET_CHMIXER 32 -#define ADDSET_PREPROCESS_GREENEQUIL 33 -#define ADDSET_PREPROCESS_LINEDENOISE 34 -#define ADDSET_RAWCACORR 35 -#define ADDSET_RAWEXPOS_LINEAR 36 -#define ADDSET_RAWEXPOS_PRESER 37 -#define ADDSET_RAWEXPOS_BLACKS 38 -#define ADDSET_SHARPENEDGE_AMOUNT 39 -#define ADDSET_SHARPENMICRO_AMOUNT 40 -#define ADDSET_SHARPENEDGE_PASS 41 -#define ADDSET_SHARPENMICRO_UNIFORMITY 42 -#define ADDSET_VIBRANCE_PASTELS 43 -#define ADDSET_VIBRANCE_SATURATED 44 -#define ADDSET_FREE_OUPUT_GAMMA 45 -#define ADDSET_FREE_OUTPUT_SLOPE 46 -#define ADDSET_CAT_DEGREE 47 -#define ADDSET_CAT_ADAPTSCENE 48 -#define ADDSET_CAT_ADAPTVIEWING 49 -#define ADDSET_CAT_LIGHT 50 -#define ADDSET_CAT_CHROMA 51 -#define ADDSET_CAT_CONTRAST 52 -#define ADDSET_CAT_RSTPRO 53 -#define ADDSET_CAT_BRIGHT 54 -#define ADDSET_CAT_CONTRAST_Q 55 -#define ADDSET_CAT_CHROMA_S 56 -#define ADDSET_CAT_CHROMA_M 57 -#define ADDSET_CAT_HUE 58 -#define ADDSET_CAT_BADPIX 59 -#define ADDSET_WB_EQUAL 60 -#define ADDSET_GRADIENT_DEGREE 61 -#define ADDSET_GRADIENT_FEATHER 62 -#define ADDSET_GRADIENT_STRENGTH 63 -#define ADDSET_GRADIENT_CENTER 64 -#define ADDSET_PCVIGNETTE_STRENGTH 65 -#define ADDSET_PCVIGNETTE_FEATHER 66 -#define ADDSET_PCVIGNETTE_ROUNDNESS 67 -#define ADDSET_BLACKWHITE_HUES 68 -#define ADDSET_BLACKWHITE_GAMMA 69 -#define ADDSET_DIRPYREQ_THRESHOLD 70 -#define ADDSET_DIRPYREQ_SKINPROTECT 71 -#define ADDSET_COLORTONING_SPLIT 72 -#define ADDSET_COLORTONING_SATTHRESHOLD 73 -#define ADDSET_COLORTONING_SATOPACITY 74 -#define ADDSET_COLORTONING_BALANCE 75 -#define ADDSET_COLORTONING_STRENGTH 76 -#define ADDSET_DIRPYRDN_PASSES 77 -#define ADDSET_RAWFFCLIPCONTROL 78 -#define ADDSET_FILMSIMULATION_STRENGTH 79 -#define ADDSET_WA 80 -#define ADDSET_WA_SKINPROTECT 81 -#define ADDSET_WA_THRR 82 -#define ADDSET_WA_THRRH 83 -#define ADDSET_WA_THRES 84 -#define ADDSET_WA_THRESHOLD 85 -#define ADDSET_WA_THRESHOLD2 86 -#define ADDSET_WA_CHRO 87 -#define ADDSET_WA_CHROMA 88 -#define ADDSET_WA_CONTRAST 89 -#define ADDSET_WA_RESCON 90 -#define ADDSET_WA_RESCONH 91 -#define ADDSET_WA_RESCHRO 92 -#define ADDSET_WA_SKYPROTECT 93 -#define ADDSET_WA_EDGRAD 94 -#define ADDSET_WA_EDGVAL 95 -#define ADDSET_WA_STRENGTH 96 -#define ADDSET_WA_EDGEDETECT 97 -#define ADDSET_WA_EDGEDETECTTHR 98 -#define ADDSET_WA_EDGEDETECTTHR2 99 -#define ADDSET_WA_TMRS 100 -#define ADDSET_WA_GAMMA 101 -#define ADDSET_RETI_STR 102 -#define ADDSET_RETI_NEIGH 103 -#define ADDSET_RETI_LIMD 104 -#define ADDSET_RETI_GAIN 105 -#define ADDSET_RETI_OFFS 106 -#define ADDSET_RETI_VART 107 -#define ADDSET_RETI_GAM 108 -#define ADDSET_RETI_SLO 109 - -// When adding items, make sure to update ADDSET_PARAM_NUM -#define ADDSET_PARAM_NUM 110 // THIS IS USED AS A DELIMITER!! + ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! +}; #endif diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 7c63fce11..333ad8d4f 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -34,7 +34,7 @@ #include "batchqueuebuttonset.h" #include "guiutils.h" #include "rtimage.h" - +#include using namespace std; using namespace rtengine; @@ -365,8 +365,12 @@ bool BatchQueue::loadBatchQueue () return !fd.empty (); } -Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename ) +Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring &filename ) { + timeval tv; + gettimeofday(&tv, 0); + char mseconds[4]; + sprintf(mseconds, "%d", (int)(tv.tv_usec / 1000)); time_t rawtime; struct tm *timeinfo; char stringTimestamp [80]; @@ -378,6 +382,7 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename g_mkdir_with_parents (savedParamPath.c_str (), 0755); savedParamPath += Glib::path_get_basename (filename); savedParamPath += stringTimestamp; + savedParamPath += mseconds; savedParamPath += paramFileExtension; return savedParamPath; } diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index b5a3c2167..3bf3cb228 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -63,7 +63,7 @@ protected: BatchQueueListener* listener; Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format); - Glib::ustring getTempFilenameForParams( const Glib::ustring filename ); + Glib::ustring getTempFilenameForParams( const Glib::ustring &filename ); bool saveBatchQueue (); void notifyListener (bool queueEmptied); diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 0e8b66136..b8bc45601 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -32,11 +32,10 @@ Glib::RefPtr BatchQueueEntry::savedAsIcon; BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm) : ThumbBrowserEntryBase(fname), opreview(NULL), origpw(prevw), origph(prevh), opreviewDone(false), - job(pjob), progress(0), outFileName(""), sequence(0), forceFormatOpts(false) + job(pjob), progress(0), outFileName(""), sequence(0), forceFormatOpts(false), params(pparams) { thumbnail = thm; - params = pparams; #if 1 //ndef WIN32 // The BatchQueueEntryIdleHelper tracks if an entry has been deleted while it was sitting waiting for "idle" diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 9a4e15b89..0b3d65961 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -247,6 +247,10 @@ void BatchToolPanelCoordinator::initSession () pparams.toneCurve.contrast = 0; } + if (options.baBehav[ADDSET_TC_SATURATION]) { + pparams.toneCurve.saturation = 0; + } + if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) { pparams.sh.highlights = 0; } diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc index 040036049..596811c58 100644 --- a/rtgui/bqentryupdater.cc +++ b/rtgui/bqentryupdater.cc @@ -42,7 +42,7 @@ void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQ // look up if an older version is in the queue std::list::iterator i; - for (i = jqueue.begin(); i != jqueue.end(); i++) + for (i = jqueue.begin(); i != jqueue.end(); ++i) if (i->oimg == oimg && i->listener == listener) { i->ow = ow; i->oh = oh; @@ -169,7 +169,7 @@ void BatchQueueEntryUpdater::removeJobs (BQEntryUpdateListener* listener) ready = true; std::list::iterator i; - for (i = jqueue.begin(); i != jqueue.end(); i++) + for (i = jqueue.begin(); i != jqueue.end(); ++i) if (i->listener == listener) { jqueue.erase (i); ready = false; diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc index 192f791fe..64e60b136 100644 --- a/rtgui/coloredbar.cc +++ b/rtgui/coloredbar.cc @@ -100,7 +100,7 @@ void ColoredBar::draw() break; } - for (std::vector::iterator i = bgGradient.begin(); i != bgGradient.end(); i++) { + for (std::vector::iterator i = bgGradient.begin(); i != bgGradient.end(); ++i) { bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b); } diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index da0e2e00c..c4b555e8f 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -511,7 +511,7 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y) state = SNormal; - for (std::list::iterator i = listeners.begin(); i != listeners.end(); i++) { + for (std::list::iterator i = listeners.begin(); i != listeners.end(); ++i) { (*i)->cropPositionChanged (this); } @@ -1029,8 +1029,7 @@ bool CropWindow::onArea (CursorArea a, int x, int y) } getObservedFrameArea (x1, y1, w, h); - return x > x1 - 6 && y > y1 - 6 && x < x1 + w - 1 + 6 && y < y1 + h - 1 + 6 && - !(x > x1 + 2 && y > y1 + 2 && x < x1 + w - 1 - 2 && y < y1 + h - 1 - 2); + return x >= x1 && x <= x1 + w && y >= y1 && y <= y1 + h; } return false; @@ -2278,7 +2277,7 @@ void CropWindow::delCropWindowListener (CropWindowListener* l) if (*i == l) { i = listeners.erase (i); } else { - i++; + ++i; } } diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 040985e16..9eaf38587 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -59,7 +59,7 @@ std::vector listSubDirs (const Glib::RefPtr& dir, bool } catch (const Glib::Exception& exception) { if (options.rtSettings.verbose) { - std::cerr << "Failed to list subdirectories of \"" << dir << "\": " << exception.what () << std::endl; + std::cerr << "Failed to list subdirectories of \"" << dir->get_parse_name() << "\": " << exception.what () << std::endl; } } @@ -181,7 +181,7 @@ void DirBrowser::addRoot (char letter) void DirBrowser::updateDirTreeRoot () { - for (Gtk::TreeModel::iterator i = dirTreeModel->children().begin(); i != dirTreeModel->children().end(); i++) { + for (Gtk::TreeModel::iterator i = dirTreeModel->children().begin(); i != dirTreeModel->children().end(); ++i) { updateDirTree (i); } } @@ -192,7 +192,7 @@ void DirBrowser::updateDirTree (const Gtk::TreeModel::iterator& iter) if (dirtree->row_expanded (dirTreeModel->get_path (iter))) { updateDir (iter); - for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); i++) { + for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); ++i) { updateDirTree (i); } } @@ -208,7 +208,7 @@ void DirBrowser::updateVolumes () for (int i = 0; i < 32; i++) if (((volumes >> i) & 1) && !((nvolumes >> i) & 1)) { // volume i has been deleted - for (Gtk::TreeModel::iterator iter = dirTreeModel->children().begin(); iter != dirTreeModel->children().end(); iter++) + for (Gtk::TreeModel::iterator iter = dirTreeModel->children().begin(); iter != dirTreeModel->children().end(); ++iter) if (iter->get_value (dtColumns.filename).c_str()[0] - 'A' == i) { dirTreeModel->erase (iter); break; @@ -333,7 +333,7 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) while (change) { change = false; - for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end(); it++) + for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end(); ++it) if (!Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS) || !Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) { GThreadLock lock; @@ -350,7 +350,7 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) for (int i = 0; i < subDirs.size(); i++) { bool found = false; - for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end() && !found ; it++) { + for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end() && !found ; ++it) { found = (it->get_value (dtColumns.filename) == subDirs[i]); } @@ -432,7 +432,7 @@ Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) } ix++; - i++; + ++i; } count++; diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index 5eac04b2a..5bff14ef2 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -218,21 +218,21 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP methodmedconn = methodmed->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::methodmedChanged) ); rgbmethod = Gtk::manage (new MyComboBoxText ()); - rgbmethod->append_text (M("TP_DIRPYRDENOISE_SOFT")); - rgbmethod->append_text (M("TP_DIRPYRDENOISE_33")); - rgbmethod->append_text (M("TP_DIRPYRDENOISE_55SOFT")); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_3X3_SOFT")); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_3X3")); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_5X5_SOFT")); rgbmethod->set_active (0); rgbmethod->set_tooltip_text (M("TP_DIRPYRDENOISE_MET_TOOLTIP")); rgbmethodconn = rgbmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::rgbmethodChanged) ); medmethod = Gtk::manage (new MyComboBoxText ()); - medmethod->append_text (M("TP_DIRPYRDENOISE_SOFT")); - medmethod->append_text (M("TP_DIRPYRDENOISE_33")); - medmethod->append_text (M("TP_DIRPYRDENOISE_55SOFT")); - medmethod->append_text (M("TP_DIRPYRDENOISE_55")); - medmethod->append_text (M("TP_DIRPYRDENOISE_77")); - medmethod->append_text (M("TP_DIRPYRDENOISE_99")); + medmethod->append_text (M("TP_DIRPYRDENOISE_3X3_SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_3X3")); + medmethod->append_text (M("TP_DIRPYRDENOISE_5X5_SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_5X5")); + medmethod->append_text (M("TP_DIRPYRDENOISE_7X7")); + medmethod->append_text (M("TP_DIRPYRDENOISE_9X9")); medmethod->set_active (0); medmethod->set_tooltip_text (M("TP_DIRPYRDENOISE_MET_TOOLTIP")); medmethodconn = medmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::medmethodChanged) ); diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index 7996a340e..53b4805ff 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * © 2010 Emil Martinec + * (C) 2010 Emil Martinec */ #include "dirpyrequalizer.h" diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index 9b806989c..d30e4d307 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * © 2010 Emil Martinec + * (C) 2010 Emil Martinec */ #ifndef DIRPYREQUALIZER_H_INCLUDED diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 80dc3dfae..93a20c294 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -781,6 +781,7 @@ void EditorPanel::close () if(iareapanel) { iareapanel->imageArea->setPreviewHandler (NULL); iareapanel->imageArea->setImProcCoordinator (NULL); + iareapanel->imageArea->unsubscribe(); } rtengine::StagedImageProcessor::destroy (ipc); diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index 76e351569..605e915af 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -227,7 +227,7 @@ bool EditWindow::on_delete_event(GdkEventAny* event) // Check if any editor is still processing, and do NOT quit if so. Otherwise crashes and inconsistent caches bool isProcessing = false; - for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end() && !isProcessing; iter++ ) { + for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end() && !isProcessing; ++iter ) { if (epanels[*iter]->getIsProcessing()) { isProcessing = true; } @@ -237,7 +237,7 @@ bool EditWindow::on_delete_event(GdkEventAny* event) return true; } - for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end(); iter++ ) { + for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end(); ++iter ) { mainNB->remove_page (*epanels[*iter]); } diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 8c39edc02..c7e47ef57 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -275,7 +275,7 @@ void ExifPanel::delIt (Gtk::TreeModel::iterator iter) } if (recursiveOp) - for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); i++) { + for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); ++i) { delIt (i); } } @@ -306,7 +306,7 @@ void ExifPanel::keepIt (Gtk::TreeModel::iterator iter) } if (recursiveOp) - for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); i++) { + for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); ++i) { keepIt (i); } } @@ -472,7 +472,7 @@ void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib // look up first segment of the path Gtk::TreeModel::iterator iter; - for (iter = root.begin(); iter != root.end(); iter++) + for (iter = root.begin(); iter != root.end(); ++iter) if (iter->get_value (exifColumns.field_nopango) == fseg) { break; } @@ -581,7 +581,7 @@ void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string pre Gtk::TreeModel::iterator iter; - for (iter = root.begin(); iter != root.end(); iter++) { + for (iter = root.begin(); iter != root.end(); ++iter) { if (iter->get_value (exifColumns.edited) == true) { changeList[ prefix + iter->get_value (exifColumns.field_nopango) ] = iter->get_value (exifColumns.value_nopango); } else if (iter->get_value (exifColumns.action) == AC_WRITE && iter->get_value (exifColumns.icon) == delicon) { @@ -606,7 +606,7 @@ void ExifPanel::updateChangeList () void ExifPanel::applyChangeList () { - for (rtengine::procparams::ExifPairs::iterator i = changeList.begin(); i != changeList.end(); i++) { + for (rtengine::procparams::ExifPairs::iterator i = changeList.begin(); i != changeList.end(); ++i) { editTag (exifTreeModel->children(), i->first, i->second); } } diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 4f0018ab9..06f99826d 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -250,7 +250,10 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #elif defined __APPLE__ - auto cmdLine = Glib::ustring("open -a /Applications/GIMP.app \'") + fileName + Glib::ustring("\'"); + // Apps should be opened using the simplest, case-insensitive form, "open -a NameOfProgram" + // Calling the executable directly is said to often cause trouble, + // https://discuss.pixls.us/t/affinity-photo-as-external-editor-how-to/1756/18 + auto cmdLine = Glib::ustring("open -a GIMP \'") + fileName + Glib::ustring("\'"); auto success = spawnCommandAsync (cmdLine); #else @@ -279,7 +282,7 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #elif defined __APPLE__ - cmdLine = Glib::ustring("open -a /Applications/Gimp.app/Contents/Resources/start \'") + fileName + Glib::ustring("\'"); + cmdLine = Glib::ustring("open -a GIMP-dev \'") + fileName + Glib::ustring("\'"); success = ExtProgStore::spawnCommandAsync (cmdLine); #else @@ -301,7 +304,7 @@ bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName) #elif defined __APPLE__ - const auto cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir, "Photoshop.app\' ") + Glib::ustring("\'") + fileName + Glib::ustring("\'"); + const auto cmdLine = Glib::ustring("open -a Photoshop \'") + fileName + Glib::ustring("\'"); #else diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 8ce4caf8f..658390391 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -97,7 +97,7 @@ void FavoritBrowser::addPressed () return; } - iter++; + ++iter; } Glib::RefPtr hfile = Gio::File::create_for_parse_name (lastSelectedDir); diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index f8a8f225f..68825c696 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -623,7 +623,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) std::vector::iterator i = fd.begin(); while (i != fd.end() && *entry < * ((FileBrowserEntry*)*i)) { - i++; + ++i; } fd.insert (i, entry); @@ -640,7 +640,7 @@ FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) { MYWRITERLOCK(l, entryRW); - for (std::vector::iterator i = fd.begin(); i != fd.end(); i++) + for (std::vector::iterator i = fd.begin(); i != fd.end(); ++i) if ((*i)->filename == fname) { ThumbBrowserEntryBase* entry = *i; entry->selected = false; diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index 07f85df94..f916a5397 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -72,7 +72,7 @@ void FilmSimulation::onClutSelected() if ( getEnabled() && !currentClutFilename.empty() && listener && currentClutFilename != m_oldClutFilename ) { Glib::ustring clutName, dummy; - splitClutFilename( currentClutFilename, clutName, dummy, dummy ); + HaldCLUT::splitClutFilename( currentClutFilename, clutName, dummy, dummy ); listener->panelChanged( EvFilmSimulationFilename, clutName ); m_oldClutFilename = currentClutFilename; @@ -132,7 +132,7 @@ void FilmSimulation::read( const rtengine::procparams::ProcParams* pp, const Par if ( !get_inconsistent() && !pp->filmSimulation.enabled ) { if (options.clutCacheSize == 1) { - clutStore.clearCache(); + CLUTStore::getInstance().clearCache(); } } @@ -279,7 +279,7 @@ int ClutComboBox::parseDir (const Glib::ustring& path) for (const auto& entry : entries) { Glib::ustring name, extension, profileName; - splitClutFilename (entry, name, extension, profileName); + HaldCLUT::splitClutFilename (entry, name, extension, profileName); extension = extension.casefold (); if (extension.compare ("tif") != 0 && extension.compare ("png") != 0) { diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index bc4396aca..5a118d6e1 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -212,7 +212,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) expcomp->clear_items(); curefs.expcomp.clear(); - for (std::set::iterator i = defefs.expcomp.begin(); i != defefs.expcomp.end(); i++) { + for (std::set::iterator i = defefs.expcomp.begin(); i != defefs.expcomp.end(); ++i) { expcomp->append_text (*i); curefs.expcomp.insert(*i); } @@ -222,7 +222,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) lens->clear_items(); curefs.lenses.clear(); - for (std::set::iterator i = defefs.lenses.begin(); i != defefs.lenses.end(); i++) { + for (std::set::iterator i = defefs.lenses.begin(); i != defefs.lenses.end(); ++i) { lens->append_text (*i); curefs.lenses.insert(*i); } @@ -232,7 +232,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) camera->clear_items(); curefs.cameras.clear(); - for (std::set::iterator i = defefs.cameras.begin(); i != defefs.cameras.end(); i++) { + for (std::set::iterator i = defefs.cameras.begin(); i != defefs.cameras.end(); ++i) { camera->append_text(*i); curefs.cameras.insert(*i); } @@ -242,14 +242,14 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) filetype->clear_items(); curefs.filetypes.clear(); - for (std::set::iterator i = defefs.filetypes.begin(); i != defefs.filetypes.end(); i++) { + for (std::set::iterator i = defefs.filetypes.begin(); i != defefs.filetypes.end(); ++i) { filetype->append_text(*i); curefs.filetypes.insert(*i); } ftselection->select_all(); } else { - for( Gtk::TreeModel::Children::iterator iter = expcomp->get_model()->children().begin(); iter != expcomp->get_model()->children().end(); iter++) { + for( Gtk::TreeModel::Children::iterator iter = expcomp->get_model()->children().begin(); iter != expcomp->get_model()->children().end(); ++iter) { Glib::ustring v; iter->get_value(0, v); @@ -260,7 +260,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) } } - for( Gtk::TreeModel::Children::iterator iter = lens->get_model()->children().begin(); iter != lens->get_model()->children().end(); iter++) { + for( Gtk::TreeModel::Children::iterator iter = lens->get_model()->children().begin(); iter != lens->get_model()->children().end(); ++iter) { Glib::ustring v; iter->get_value(0, v); @@ -271,7 +271,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) } } - for( Gtk::TreeModel::Children::iterator iter = camera->get_model()->children().begin(); iter != camera->get_model()->children().end(); iter++) { + for( Gtk::TreeModel::Children::iterator iter = camera->get_model()->children().begin(); iter != camera->get_model()->children().end(); ++iter) { Glib::ustring v; iter->get_value(0, v); @@ -282,7 +282,7 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) } } - for( Gtk::TreeModel::Children::iterator iter = filetype->get_model()->children().begin(); iter != filetype->get_model()->children().end(); iter++) { + for( Gtk::TreeModel::Children::iterator iter = filetype->get_model()->children().begin(); iter != filetype->get_model()->children().end(); ++iter) { Glib::ustring v; iter->get_value(0, v); diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index e5d3d560e..9c8163c8e 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -25,8 +25,7 @@ #include "rtimage.h" #include "../rtengine/improccoordinator.h" #include "../rtengine/color.h" - - +#include "../rtengine/opthelper.h" using namespace rtengine; extern Glib::ustring argv0; @@ -852,7 +851,7 @@ void HistogramArea::update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu g_idle_add (histupdateUI, haih); } -void HistogramArea::renderHistogram () +SSEFUNCTION void HistogramArea::renderHistogram () { if (!is_realized ()) { @@ -878,7 +877,7 @@ void HistogramArea::renderHistogram () // make double copies of LUT, one for faster access, another one to scale down the raw histos LUTu rhchanged(256), ghchanged(256), bhchanged(256); - unsigned int lhisttemp[256], chisttemp[256], rhtemp[256], ghtemp[256], bhtemp[256]; + unsigned int lhisttemp[256] ALIGNED16 {0}, chisttemp[256] ALIGNED16 {0}, rhtemp[256] ALIGNED16 {0}, ghtemp[256] ALIGNED16 {0}, bhtemp[256] ALIGNED16 {0}; const int scale = (rawMode ? 8 : 1); for(int i = 0; i < 256; i++) { @@ -937,31 +936,48 @@ void HistogramArea::renderHistogram () if (!fullMode) { int area = 0; - if(!rawMode) - for (int i = 0; i < fullhistheight; i++) { - for (int j = 0; j < 256; j++) - if ((needLuma && lhisttemp[j] > i) || (needChroma && chisttemp[j] > i) || (needRed && rhtemp[j] > i) || (needGreen && ghtemp[j] > i) || (needBlue && bhtemp[j] > i)) { - area++; - } +#ifdef __SSE2__ + vint onev = _mm_set1_epi32(1); + vint iv = (vint)ZEROV; +#endif - if ((double)area / (256 * (i + 1)) < 0.3) { - realhistheight = i; - break; - } - } - else - for (int i = 0; i < fullhistheight; i++) { - for (int j = 0; j < 256; j++) - if ((needRed && rhtemp[j] > i) || (needGreen && ghtemp[j] > i) || (needBlue && bhtemp[j] > i)) { - area++; - } + for (int i = 0; i < fullhistheight; i++) { +#ifdef __SSE2__ + vint areatempv = (vint)ZEROV; + + for (int j = 0; j < 256; j += 4) { + vmask mask1v = _mm_cmpgt_epi32(LVI(lhisttemp[j]), iv); + vmask mask2v = _mm_cmpgt_epi32(LVI(rhtemp[j]), iv); + vmask mask3v = _mm_cmpgt_epi32(LVI(ghtemp[j]), iv); + vmask mask4v = _mm_cmpgt_epi32(LVI(bhtemp[j]), iv); + mask1v = _mm_or_si128(mask1v, mask2v); + mask3v = _mm_or_si128(mask3v, mask4v); + mask2v = _mm_cmpgt_epi32(LVI(chisttemp[j]), iv); + mask1v = _mm_or_si128(mask1v, mask3v); + mask1v = _mm_or_si128(mask1v, mask2v); + areatempv = _mm_add_epi32(areatempv, _mm_and_si128(mask1v, onev)); - if ((double)area / (256 * (i + 1)) < 0.3) { - realhistheight = i; - break; - } } + areatempv = _mm_add_epi32(areatempv, (vint)_mm_movehl_ps((vfloat)areatempv, (vfloat)areatempv)); + areatempv = _mm_add_epi32(areatempv, _mm_shuffle_epi32(areatempv, 1)); + area += _mm_cvtsi128_si32(areatempv); + iv = _mm_add_epi32(iv, onev); + +#else + + for (int j = 0; j < 256; j++) + if (lhisttemp[j] > i || rhtemp[j] > i || ghtemp[j] > i || bhtemp[j] > i || chisttemp[j] > i) { + area++; + } + +#endif + + if ((double)area / (256 * (i + 1)) < 0.3) { + realhistheight = i; + break; + } + } } if (realhistheight < winh - 2) { diff --git a/rtgui/history.cc b/rtgui/history.cc index 689ea6394..fa1ba372b 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -222,7 +222,7 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring // remove all rows after the selection if (iter) { - iter++; + ++iter; while (iter) { iter = historyModel->erase (iter); @@ -356,7 +356,7 @@ void History::redo () Gtk::TreeModel::iterator iter = selection->get_selected(); if (iter) { - iter++; + ++iter; if (iter != historyModel->children().end()) { selection->select (iter); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index efce343c0..cc2cbc039 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -361,9 +361,9 @@ void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name) DCPProfile* dcp = NULL; if(dcp_name == "(cameraICC)") { - dcp = dcpStore->getStdProfile(camName); - } else if (ifromfile->get_active() && dcpStore->isValidDCPFileName(dcp_name)) { - dcp = dcpStore->getProfile(dcp_name); + dcp = DCPStore::getInstance()->getStdProfile(camName); + } else if (ifromfile->get_active() && DCPStore::getInstance()->isValidDCPFileName(dcp_name)) { + dcp = DCPStore::getInstance()->getProfile(dcp_name); } if (dcp) { @@ -385,24 +385,21 @@ void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name) ckbApplyHueSatMap->set_sensitive (true); } - int i1, i2; - double temp1, temp2; - bool willInterpolate; - dcp->getIlluminants(i1, temp1, i2, temp2, willInterpolate); + const DCPProfile::Illuminants illuminants = dcp->getIlluminants(); - if (willInterpolate) { - if (dcpTemperatures[0] != temp1 || dcpTemperatures[1] != temp2) { + if (illuminants.will_interpolate) { + if (dcpTemperatures[0] != illuminants.temperature_1 || dcpTemperatures[1] != illuminants.temperature_2) { char tempstr1[64], tempstr2[64]; - sprintf(tempstr1, "%.0fK", temp1); - sprintf(tempstr2, "%.0fK", temp2); + sprintf(tempstr1, "%.0fK", illuminants.temperature_1); + sprintf(tempstr2, "%.0fK", illuminants.temperature_2); int curr_active = dcpIll->get_active_row_number(); ignoreDcpSignal = true; dcpIll->clear_items (); dcpIll->append_text (M("TP_ICM_DCPILLUMINANT_INTERPOLATED")); dcpIll->append_text (tempstr1); dcpIll->append_text (tempstr2); - dcpTemperatures[0] = temp1; - dcpTemperatures[1] = temp2; + dcpTemperatures[0] = illuminants.temperature_1; + dcpTemperatures[1] = illuminants.temperature_2; dcpIll->set_active (curr_active); ignoreDcpSignal = false; } @@ -631,10 +628,10 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) DCPProfile* dcp = NULL; - if (ifromfile->get_active() && pp->icm.input.substr(0, 5) == "file:" && dcpStore->isValidDCPFileName(pp->icm.input.substr(5))) { - dcp = dcpStore->getProfile(pp->icm.input.substr(5)); + if (ifromfile->get_active() && pp->icm.input.substr(0, 5) == "file:" && DCPStore::getInstance()->isValidDCPFileName(pp->icm.input.substr(5))) { + dcp = DCPStore::getInstance()->getProfile(pp->icm.input.substr(5)); } else if(icameraICC->get_active()) { - dcp = dcpStore->getStdProfile(camName); + dcp = DCPStore::getInstance()->getStdProfile(camName); } if (dcp) { @@ -920,7 +917,7 @@ void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta) iembedded->set_active (!raw); icamera->set_sensitive (raw); camName = pMeta->getCamera(); - icameraICC->set_sensitive (raw && (iccStore->getStdProfile(pMeta->getCamera()) != NULL || dcpStore->getStdProfile(pMeta->getCamera()) != NULL)); + icameraICC->set_sensitive (raw && (iccStore->getStdProfile(pMeta->getCamera()) != NULL || DCPStore::getInstance()->getStdProfile(pMeta->getCamera()) != NULL)); iembedded->set_sensitive (!raw); enableListener (); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 5383058e3..0b757d8ec 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -213,7 +213,7 @@ bool ImageArea::on_expose_event(GdkEventExpose* event) cr->fill (); } - for (std::list::reverse_iterator i = cropWins.rbegin(); i != cropWins.rend(); i++) { + for (std::list::reverse_iterator i = cropWins.rbegin(); i != cropWins.rend(); ++i) { (*i)->expose (cr); } diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 301f7fc27..3a9b3e81c 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -402,7 +402,7 @@ void IPTCPanel::addKeyWord () keyword->prepend_text (keyword->get_entry()->get_text()); std::vector items; - for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i != keyword->get_model()->children().end(); i++) { + for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i != keyword->get_model()->children().end(); ++i) { Glib::ustring s; i->get_value (0, s); items.push_back (s); @@ -454,7 +454,7 @@ void IPTCPanel::addSuppCategory () suppCategory->prepend_text (suppCategory->get_entry()->get_text()); std::vector items; - for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i != suppCategory->get_model()->children().end(); i++) { + for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i != suppCategory->get_model()->children().end(); ++i) { Glib::ustring s; i->get_value (0, s); items.push_back (s); @@ -557,7 +557,7 @@ void IPTCPanel::applyChangeList () keyword->get_entry()->set_text (""); suppCategory->get_entry()->set_text (""); - for (rtengine::procparams::IPTCPairs::iterator i = changeList.begin(); i != changeList.end(); i++) { + for (rtengine::procparams::IPTCPairs::iterator i = changeList.begin(); i != changeList.end(); ++i) { if (i->first == "Caption" && !i->second.empty()) { captionText->set_text (i->second.at(0)); } else if (i->first == "CaptionWriter" && !i->second.empty()) { diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 69c4737bc..07f86542c 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -43,6 +43,11 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGE show_all (); } +LensGeometry::~LensGeometry () +{ + g_idle_remove_by_data(this); +} + void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited) { @@ -113,3 +118,30 @@ void LensGeometry::setBatchMode (bool batchMode) ToolPanel::setBatchMode (batchMode); removeIfThere (this, autoCrop); } + +void LensGeometry::disableAutoFillIfActive () +{ + g_idle_add(doDisableAutoFillIfActive, this); +} + +int LensGeometry::doDisableAutoFillIfActive (void* data) +{ + GThreadLock lock; // Is this really needed? + + LensGeometry* const instance = static_cast(data); + + if (!instance->batchMode) { + if (instance->fill->get_active()) { + instance->fillConn.block (true); + instance->fill->set_active(false); + + if (instance->listener) { + instance->listener->panelChanged (EvTransAutoFill, M("GENERAL_DISABLED")); + } + + instance->fillConn.block (false); + } + } + + return 0; +} diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index f6b41b632..51a6e108c 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -32,11 +32,12 @@ protected: Gtk::CheckButton* fill; bool lastFill; sigc::connection fillConn; - ToolParamBlock* packBox; + ToolParamBlock* packBox; public: LensGeometry (); + ~LensGeometry (); Gtk::Box* getPackBox () { @@ -53,6 +54,11 @@ public: { rlistener = l; } + void disableAutoFillIfActive (); + +private: + static int doDisableAutoFillIfActive (void* data); + }; #endif diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index eda3992c3..c24bc5cf0 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -67,7 +67,7 @@ LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("T conLCPFile = fcbLCPFile->signal_file_set().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileChanged), true); btnReset->signal_clicked().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileReset), true); - ckbUseDist->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseDistChanged) ); + conUseDist = ckbUseDist->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseDistChanged) ); ckbUseVign->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseVignChanged) ); ckbUseCA->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseCAChanged) ); @@ -77,6 +77,7 @@ LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("T void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { disableListener (); + conUseDist.block(true); if (!pp->lensProf.lcpFile.empty() && lcpStore->isValidLCPFileName(pp->lensProf.lcpFile)) { fcbLCPFile->set_filename (pp->lensProf.lcpFile); @@ -102,6 +103,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa lcpFileChanged = useDistChanged = useVignChanged = useCAChanged = false; enableListener (); + conUseDist.block(false); } void LensProfilePanel::setRawMeta(bool raw, const rtengine::ImageMetaData* pMeta) @@ -142,6 +144,10 @@ void LensProfilePanel::write( rtengine::procparams::ProcParams* pp, ParamsEdited void LensProfilePanel::onLCPFileChanged() { + + // Disable Auto-Fill when enabling LCP Distortion Correction, #1791 + lensgeomLcpFill->disableAutoFillIfActive(); + lcpFileChanged = true; updateDisabled(lcpStore->isValidLCPFileName(fcbLCPFile->get_filename())); @@ -164,6 +170,12 @@ void LensProfilePanel::onLCPFileReset() void LensProfilePanel::onUseDistChanged() { + + // Disable Auto-Fill when enabling LCP Distortion Correction, #1791 + if (ckbUseDist->get_active()) { + lensgeomLcpFill->disableAutoFillIfActive(); + } + useDistChanged = true; if (listener) { diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 0397388d5..cb3a5cc6c 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -22,6 +22,7 @@ #include #include "toolpanel.h" #include "guiutils.h" +#include "lensgeom.h" class LensProfilePanel : public ToolParamBlock, public FoldableToolPanel { @@ -38,6 +39,7 @@ protected: void updateDisabled(bool enable); bool allowFocusDep; bool isRaw; + LensGeometry *lensgeomLcpFill; public: @@ -52,6 +54,10 @@ public: void onUseDistChanged(); void onUseVignChanged(); void onUseCAChanged(); + void setLensGeomRef( LensGeometry *foo) + { + lensgeomLcpFill = foo ; + }; }; #endif diff --git a/rtgui/main.cc b/rtgui/main.cc index 4a4511f34..114204858 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -264,7 +264,9 @@ int main(int argc, char **argv) if (argc > 1 || options.rtSettings.verbose) { // printing RT's version in all case, particularly useful for the 'verbose' mode, but also for the batch processing std::cout << "RawTherapee, version " << VERSION << std::endl; +#ifdef WIN32 std::cout << "WARNING: closing this window will close RawTherapee!" << std::endl << std::endl; +#endif if (argc > 1) { int ret = processLineParams( argc, argv); @@ -579,59 +581,73 @@ int processLineParams( int argc, char **argv ) case '?': default: { Glib::ustring pparamsExt = paramFileExtension.substr(1); - std::cout << " indicate parameters you can change." << std::endl; - std::cout << "[Square brackets] mean the parameter is not mandatory." << std::endl; - std::cout << "The pipe symbol | indicates a choice of one or the other." << std::endl; - std::cout << "The dash symbol - denotes a range of possible values from one to the other." << std::endl; - cout << std::endl; + std::cout << " An advanced, cross-platform program for developing raw photos." << std::endl; + std::cout << std::endl; + std::cout << " Website: http://www.rawtherapee.com/" << std::endl; + std::cout << " Documentation: http://rawpedia.rawtherapee.com/" << std::endl; + std::cout << " Forum: https://discuss.pixls.us/c/software/rawtherapee" << std::endl; + std::cout << " Code and bug reports: https://github.com/Beep6581/RawTherapee" << std::endl; + std::cout << std::endl; + std::cout << "Symbols:" << std::endl; + std::cout << " indicate parameters you can change." << std::endl; + std::cout << " [Square brackets] mean the parameter is optional." << std::endl; + std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; + std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; + std::cout << std::endl; std::cout << "Usage:" << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " Start File Browser inside directory." << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " Start File Browser inside folder." << std::endl; std::cout << " " << Glib::path_get_basename(argv[0]) << " Start Image Editor with file." << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " -c | Convert files in batch with default parameters." << std::endl << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " -c | Convert files in batch with default parameters." << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " -c | Convert files in batch with your own settings." << std::endl; + std::cout << std::endl; #ifdef WIN32 std::cout << " -w Do not open the Windows console" << std::endl; + std::cout << std::endl; #endif - std::cout << "Other options used with -c (-c must be the last option):" << std::endl; - std::cout << Glib::path_get_basename(argv[0]) << " [-o |-O ] [-s|-S] [-p ] [-d] [-j[1-100] [-js<1-3>]|[-b<8|16>] <[-t[z] | [-n]]] [-Y] -c " << std::endl; - std::cout << " -o | Select output file or directory." << std::endl; - std::cout << " -O | Select output file or directory and copy " << pparamsExt << " file into it." << std::endl; - std::cout << " -s Include the " << pparamsExt << " file next to the input file (with the same" << std::endl; - std::cout << " name) to build the image parameters," << std::endl; - std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in" << std::endl; - std::cout << " the same directory. If the file does not exist, internal" << std::endl; - std::cout << " default (neutral) values (not those in Default." << pparamsExt << ") will be" << std::endl; - std::cout << " used." << std::endl; - std::cout << " -S Like -s but skip if the " << pparamsExt << " file does not exist." << std::endl; - std::cout << " -p Specify " << pparamsExt << " file to be used for all conversions." << std::endl; - std::cout << " You can specify as many -p options as you like (see" << std::endl; - std::cout << " description below)." << std::endl; - std::cout << " -d Use the default raw or non-raw " << pparamsExt << " file as set in" << std::endl; + std::cout << "Options:" << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " [-o |-O ] [-s|-S] [-p [-p ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] -c " << std::endl; + std::cout << std::endl; + std::cout << " -c Specify one or more input files." << std::endl; + std::cout << " -c must be the last option." << std::endl; + std::cout << " -o | Set output file or folder." << std::endl; + std::cout << " Saves output file alongside input file if -o is not specified." << std::endl; + std::cout << " -O | Set output file or folder and copy " << pparamsExt << " file into it." << std::endl; + std::cout << " Saves output file alongside input file if -O is not specified." << std::endl; + std::cout << " -s Use the existing sidecar file to build the processing parameters," << std::endl; + std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in the same folder." << std::endl; + std::cout << " If the sidecar file does not exist, neutral values will be used." << std::endl; + std::cout << " -S Like -s but skip if the sidecar file does not exist." << std::endl; + std::cout << " -p Specify processing profile to be used for all conversions." << std::endl; + std::cout << " You can specify as many sets of \"-p \" options as you like," << std::endl; + std::cout << " each will be built on top of the previous one, as explained below." << std::endl; + std::cout << " -d Use the default raw or non-raw processing profile as set in" << std::endl; std::cout << " Preferences > Image Processing > Default Processing Profile" << std::endl; - std::cout << " -j[1-100] Specify output to be JPEG (on by default). Optionally add" << std::endl; - std::cout << " compression 1-100 (default value: 92)." << std::endl; + std::cout << " -j[1-100] Specify output to be JPEG (default, if -t and -n are not set)." << std::endl; + std::cout << " Optionally, specify compression 1-100 (default value: 92)." << std::endl; std::cout << " -js<1-3> Specify the JPEG chroma subsampling parameter, where:" << std::endl; - std::cout << " 1 = Best compression: 2x2, 1x1, 1x1 (4:2:0)" << std::endl; + std::cout << " 1 = Best compression: 2x2, 1x1, 1x1 (4:2:0)" << std::endl; std::cout << " Chroma halved vertically and horizontally." << std::endl; - std::cout << " 2 = Balanced: 2x1, 1x1, 1x1 (4:2:2)" << std::endl; + std::cout << " 2 = Balanced (default): 2x1, 1x1, 1x1 (4:2:2)" << std::endl; std::cout << " Chroma halved horizontally." << std::endl; - std::cout << " 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4)" << std::endl; + std::cout << " 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4)" << std::endl; std::cout << " No chroma subsampling." << std::endl; - std::cout << " -b<8|16> Specify bit depth per channel (only applies to TIFF and PNG output)." << std::endl; - std::cout << " -t[z] Specify output to be TIFF (16-bit if -b8 is not set)." << std::endl; - std::cout << " Uncompressed by default, or ZIP compression with 'z'" << std::endl; - std::cout << " -n Specify output to be compressed PNG (16-bit if -b8 is not set)." << std::endl; - std::cout << " -Y Overwrite output if present." << std::endl << std::endl; - std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will set the values as follows:" << std::endl; - std::cout << " 1- A new profile is created using internal default (neutral) values" << std::endl; - std::cout << " (hard-coded into RawTherapee)," << std::endl; - std::cout << " 2- then overridden by those found in the default raw or non-raw " << pparamsExt << " file" << std::endl; - std::cout << " (if -d has been set)," << std::endl; - std::cout << " 3- then overridden by those found in the " << pparamsExt << " files provided by -p, each one" << std::endl; - std::cout << " overriding the previous values," << std::endl; - std::cout << " 4- then overridden by the sidecar file if -s is set and if the file exists;" << std::endl; - std::cout << " the time where the sidecar file is used depends on the position of the -s" << std::endl; - std::cout << " switch in the command line relative to the -p parameters," << std::endl; - std::cout << " e.g. -p first." << pparamsExt << " -p second." << pparamsExt << " -s -p fourth." << pparamsExt << std::endl; + std::cout << " -b<8|16> Specify bit depth per channel (default value: 16 for TIFF, 8 for PNG)." << std::endl; + std::cout << " Only applies to TIFF and PNG output, JPEG is always 8." << std::endl; + std::cout << " -t[z] Specify output to be TIFF." << std::endl; + std::cout << " Uncompressed by default, or deflate compression with 'z'." << std::endl; + std::cout << " -n Specify output to be compressed PNG." << std::endl; + std::cout << " Compression is hard-coded to 6." << std::endl; + std::cout << " -Y Overwrite output if present." << std::endl; + std::cout << std::endl; + std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will build the final values as follows:" << std::endl; + std::cout << " 1- A new processing profile is created using neutral values," << std::endl; + std::cout << " 2- If the \"-d\" option is set, the values are overridden by those found in" << std::endl; + std::cout << " the default raw or non-raw processing profile." << std::endl; + std::cout << " 3- If one or more \"-p\" options are set, the values are overridden by those" << std::endl; + std::cout << " found in these processing profiles." << std::endl; + std::cout << " 4- If the \"-s\" or \"-S\" options are set, the values are finally overridden by those" << std::endl; + std::cout << " found in the sidecar files." << std::endl; + std::cout << " The processing profiles are processed in the order specified on the command line." << std::endl; return -1; } } diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 55e566ada..626eef4f1 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -21,10 +21,9 @@ #include #include -MyCurve::MyCurve () : pipetteR(-1.f), pipetteG(-1.f), pipetteB(-1.f), pipetteVal(-1.f), listener(NULL) +MyCurve::MyCurve () : pipetteR(-1.f), pipetteG(-1.f), pipetteB(-1.f), pipetteVal(-1.f), listener(NULL), cursor_type( CSArrow) { - cursor_type = CSArrow; graphX = get_allocation().get_width() - RADIUS * 2; graphY = get_allocation().get_height() - RADIUS * 2; prevGraphW = graphW; diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index 2a70e9b7c..fd57633fb 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -591,8 +591,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) ity = curve.y.begin(); for (int i = 0; i < closest_point; i++) { - itx++; - ity++; + ++itx; + ++ity; } curve.x.insert (itx, 0); @@ -1111,8 +1111,8 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi ity = curve.y.begin(); for (int i = 0; i < closest_point; i++) { - itx++; - ity++; + ++itx; + ++ity; } lit_point = closest_point; diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index fe53565d2..4127d1ae8 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -641,10 +641,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) itrt = curve.rightTangent.begin(); for (int i = 0; i < closest_point; i++) { - itx++; - ity++; - itlt++; - itrt++; + ++itx; + ++ity; + ++itlt; + ++itrt; } curve.x.insert (itx, 0); @@ -1327,10 +1327,10 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier itrt = curve.rightTangent.begin(); for (int i = 0; i < closest_point; i++) { - itx++; - ity++; - itlt++; - itrt++; + ++itx; + ++ity; + ++itlt; + ++itrt; } curve.x.insert (itx, 0); @@ -1807,6 +1807,7 @@ void MyFlatCurve::setPoints (const std::vector& p) stopNumericalAdjustment(); FlatCurveType t = (FlatCurveType)p[ix++]; curve.type = t; + lit_point = -1; if (t == FCT_MinMaxCPoints) { curve.x.clear (); diff --git a/rtgui/myicon.rc b/rtgui/myicon.rc index 94f2ab31a..b5f390783 100644 --- a/rtgui/myicon.rc +++ b/rtgui/myicon.rc @@ -1 +1 @@ -1 ICON "RT.ico" +1 ICON "../rtdata/icons/RT.ico" diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc index 4f7e638f2..049b4ec7e 100644 --- a/rtgui/navigator.cc +++ b/rtgui/navigator.cc @@ -26,9 +26,11 @@ #include "../rtengine/rt_math.h" #include "options.h" +extern Options options; + using namespace rtengine; -Navigator::Navigator () +Navigator::Navigator () : currentRGBUnit(options.navRGBUnit), currentHSVUnit(options.navHSVUnit) { set_label (M("MAIN_MSG_NAVIGATOR")); @@ -127,6 +129,7 @@ Navigator::Navigator () // RGB + Gtk::EventBox *evBox1 = Gtk::manage (new Gtk::EventBox()); Gtk::HBox* hbox1 = Gtk::manage (new Gtk::HBox ()); // container Gtk::Table* table1 = Gtk::manage (new Gtk::Table (3, 2)); @@ -139,11 +142,15 @@ Navigator::Navigator () table1->attach (*lB, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 4, 0); table1->attach (*B, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 0, 0); - hbox1->pack_start (*table1, Gtk::PACK_EXPAND_WIDGET, 4); + evBox1->add (*table1); + evBox1->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &Navigator::cycleUnitsRGB)); + + hbox1->pack_start (*evBox1, Gtk::PACK_EXPAND_WIDGET, 4); hbox1->pack_start (*Gtk::manage (new Gtk::VSeparator()), Gtk::PACK_SHRINK, 4); table0->attach (*hbox1, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 0, 0); // HSV + Gtk::EventBox *evBox2 = Gtk::manage (new Gtk::EventBox()); Gtk::HBox* hbox2 = Gtk::manage (new Gtk::HBox ()); // container Gtk::Table* table2 = Gtk::manage (new Gtk::Table (3, 2)); @@ -156,7 +163,10 @@ Navigator::Navigator () table2->attach (*lV, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 4, 0); table2->attach (*V, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 0, 0); - hbox2->pack_start (*table2, Gtk::PACK_EXPAND_WIDGET, 4); + evBox2->add (*table2); + evBox2->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &Navigator::cycleUnitsHSV)); + + hbox2->pack_start (*evBox2, Gtk::PACK_EXPAND_WIDGET, 4); hbox2->pack_start (*Gtk::manage (new Gtk::VSeparator()), Gtk::PACK_SHRINK, 4); table0->attach (*hbox2, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 0, 0); @@ -214,15 +224,45 @@ void Navigator::pointerMoved (bool validPos, Glib::ustring profile, Glib::ustrin } else { position->set_text (Glib::ustring::compose ("x: %1, y: %2", x, y)); - R->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), r * 100.f / 255.f) + Glib::ustring("%")); - G->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), g * 100.f / 255.f) + Glib::ustring("%")); - B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), b * 100.f / 255.f) + Glib::ustring("%")); + switch (currentRGBUnit) { + case (Options::NavigatorUnit::R0_1): + R->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), r / 255.f)); + G->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), g / 255.f)); + B->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), b / 255.f)); + break; + case (Options::NavigatorUnit::R0_255): + R->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), r)); + G->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), g)); + B->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), b)); + break; + case (Options::NavigatorUnit::PERCENT): + default: + R->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), r * 100.f / 255.f) + Glib::ustring("%")); + G->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), g * 100.f / 255.f) + Glib::ustring("%")); + B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), b * 100.f / 255.f) + Glib::ustring("%")); + break; + } float h, s, v; Color::rgb2hsv (r * 0xffff / 0xff, g * 0xffff / 0xff, b * 0xffff / 0xff, h, s, v); - H->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), h * 360.f) + Glib::ustring("\xc2\xb0")); - S->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), s * 100.f) + Glib::ustring("%")); - V->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), v * 100.f) + Glib::ustring("%")); + switch (currentHSVUnit) { + case (Options::NavigatorUnit::R0_1): + H->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), h)); + S->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), s)); + V->set_text (Glib::ustring::format(std::fixed, std::setprecision(4), v)); + break; + case (Options::NavigatorUnit::R0_255): + H->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), h * 255)); + S->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), s * 255)); + V->set_text (Glib::ustring::format(std::fixed, std::setprecision(0), v * 255)); + break; + case (Options::NavigatorUnit::PERCENT): + default: + H->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), h * 360.f) + Glib::ustring("\xc2\xb0")); + S->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), s * 100.f) + Glib::ustring("%")); + V->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), v * 100.f) + Glib::ustring("%")); + break; + } float LAB_a, LAB_b, LAB_l; //rgb2lab (r, g, b, LAB_l, LAB_a, LAB_b); @@ -233,6 +273,61 @@ void Navigator::pointerMoved (bool validPos, Glib::ustring profile, Glib::ustrin } } +void Navigator::cycleUnitsRGB (GdkEventButton *event) { + uint16_t v = (uint16_t)currentRGBUnit; + ++v; + if (v == (uint16_t)Options::NavigatorUnit::_COUNT) { + v = 0; + } + options.navRGBUnit = currentRGBUnit = (Options::NavigatorUnit)v; + + switch (currentRGBUnit) { + case Options::NavigatorUnit::R0_1: + R->set_text ("[0-1]"); + G->set_text ("[0-1]"); + B->set_text ("[0-1]"); + break; + case Options::NavigatorUnit::R0_255: + R->set_text ("[0-255]"); + G->set_text ("[0-255]"); + B->set_text ("[0-255]"); + break; + case Options::NavigatorUnit::PERCENT: + default: + R->set_text ("[%]"); + G->set_text ("[%]"); + B->set_text ("[%]"); + break; + } +} + +void Navigator::cycleUnitsHSV (GdkEventButton *event) { + uint16_t v = (uint16_t)currentHSVUnit; + ++v; + if (v == (uint16_t)Options::NavigatorUnit::_COUNT) { + v = 0; + } + options.navHSVUnit = currentHSVUnit = (Options::NavigatorUnit)v; + + switch (currentHSVUnit) { + case Options::NavigatorUnit::R0_1: + H->set_text ("[0-1]"); + S->set_text ("[0-1]"); + V->set_text ("[0-1]"); + break; + case Options::NavigatorUnit::R0_255: + H->set_text ("[0-255]"); + S->set_text ("[0-255]"); + V->set_text ("[0-255]"); + break; + case Options::NavigatorUnit::PERCENT: + default: + H->set_text ("[\xc2\xb0]"); + S->set_text ("[%]"); + V->set_text ("[%]"); + break; + } +} void Navigator::rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b) { diff --git a/rtgui/navigator.h b/rtgui/navigator.h index 3abf34a2f..e0b79d8dd 100644 --- a/rtgui/navigator.h +++ b/rtgui/navigator.h @@ -22,6 +22,7 @@ #include #include "previewwindow.h" #include "pointermotionlistener.h" +#include "options.h" #include "../rtengine/iccstore.h" class Navigator : public Gtk::Frame, public PointerMotionListener @@ -29,6 +30,12 @@ class Navigator : public Gtk::Frame, public PointerMotionListener typedef const double (*TMatrix)[3]; +private: + Options::NavigatorUnit currentRGBUnit; + Options::NavigatorUnit currentHSVUnit; + void cycleUnitsRGB (GdkEventButton *event); + void cycleUnitsHSV (GdkEventButton *event); + protected: Gtk::Label* position; Gtk::Label *R, *G, *B; diff --git a/rtgui/options.cc b/rtgui/options.cc index ff5cf9676..d6a327dc8 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -353,6 +353,8 @@ void Options::setDefaults () fbShowExpComp = false; fbShowHidden = false; fbArrangement = 2; // was 0 + navRGBUnit = NavigatorUnit::PERCENT; + navHSVUnit = NavigatorUnit::PERCENT; multiUser = true; profilePath = "profiles"; loadSaveProfilePath = ""; // will be corrected in load as otherwise construction fails @@ -498,116 +500,114 @@ void Options::setDefaults () #endif // Reminder: 0 = SET mode, 1 = ADD mode - int babehav[] = { - 0, // ADDSET_TC_EXPCOMP - 0, // ADDSET_TC_BRIGHTNESS - 0, // ADDSET_TC_BLACKLEVEL - 0, // ADDSET_TC_CONTRAST - 0, // ADDSET_SH_HIGHLIGHTS - 0, // ADDSET_SH_SHADOWS - 0, // ADDSET_SH_LOCALCONTRAST - 0, // ADDSET_LC_BRIGHTNESS - 0, // ADDSET_LC_CONTRAST - 0, // ADDSET_SHARP_AMOUNT - 0, // ADDSET_WB_TEMPERATURE - 0, // ADDSET_WB_GREEN - 0, // ADDSET_ROTATE_DEGREE - 0, // ADDSET_DIST_AMOUNT - 0, // ADDSET_PERSPECTIVE - 0, // ADDSET_CA - 0, // ADDSET_VIGN_AMOUNT - 0, // ADDSET_VIGN_RADIUS - 0, // ADDSET_VIGN_STRENGTH - 0, // ADDSET_VIGN_CENTER - 0, // ADDSET_LC_CHROMATICITY - 0, // ADDSET_TC_SATURATION - 0, // ADDSET_TC_HLCOMPAMOUNT - 0, // ADDSET_TC_HLCOMPTHRESH - 0, // ADDSET_TC_SHCOMP - 0, // ADDSET_DIRPYREQ - 0, // ADDSET_DIRPYRDN_LUMA - 0, // ADDSET_DIRPYRDN_LUDET - 0, // ADDSET_DIRPYRDN_CHROMA - 0, // ADDSET_DIRPYRDN_CHROMARED - 0, // ADDSET_DIRPYRDN_CHROMABLUE - 0, // ADDSET_DIRPYRDN_GAMMA - 0, // ADDSET_CHMIXER - 0, // ADDSET_PREPROCESS_GREENEQUIL - 0, // ADDSET_PREPROCESS_LINEDENOISE - 0, // ADDSET_RAWCACORR - 0, // ADDSET_RAWEXPOS_LINEAR - 0, // ADDSET_RAWEXPOS_PRESER - 0, // ADDSET_RAWEXPOS_BLACKS - 0, // ADDSET_SHARPENEDGE_AMOUNT - 0, // ADDSET_SHARPENMICRO_AMOUNT - 0, // ADDSET_SHARPENEDGE_PASS - 0, // ADDSET_SHARPENMICRO_UNIFORMITY - 0, // ADDSET_VIBRANCE_PASTELS - 0, // ADDSET_VIBRANCE_SATURATED - 0, // ADDSET_FREE_OUPUT_GAMMA - 0, // ADDSET_FREE_OUTPUT_SLOPE - 0, // ADDSET_CAT_DEGREE - 0, // ADDSET_CAT_ADAPSCEN - 0, // ADDSET_CAT_ADAPLUM - 0, // ADDSET_CAT_LIGHT - 0, // ADDSET_CAT_RSTPRO - 0, // ADDSET_CAT_BADPIX - 0, // ADDSET_CAT_JLIGHT - 0, // ADDSET_CAT_CHROMA - 0, // ADDSET_CAT_CONTRAST - 0, // ADDSET_CAT_CHROMA_S - 0, // ADDSET_CAT_CHROMA_M - 0, // ADDSET_CAT_HUE - 0, // ADDSET_CAT_BADPIX - 0, // ADDSET_WB_EQUAL - 0, // ADDSET_GRADIENT_DEGREE - 0, // ADDSET_GRADIENT_FEATHER - 0, // ADDSET_GRADIENT_STRENGTH - 0, // ADDSET_GRADIENT_CENTER - 0, // ADDSET_PCVIGNETTE_STRENGTH - 0, // ADDSET_PCVIGNETTE_FEATHER - 0, // ADDSET_PCVIGNETTE_ROUNDNESS - 0, // ADDSET_BLACKWHITE_HUES - 0, // ADDSET_BLACKWHITE_GAMMA - 0, // ADDSET_DIRPYREQ_THRESHOLD - 0, // ADDSET_DIRPYREQ_SKINPROTECT - 0, // ADDSET_COLORTONING_SPLIT - 0, //ADDSET_DIRPYRDN_PASSES - 0, // ADDSET_RAWFFCLIPCONTROL - 0, // ADDSET_FILMSIMULATION_STRENGTH - 0, //ADDSET_WA - 0, //ADDSET_WA_THRESHOLD - 0, //ADDSET_WA_THRESHOLD2 - 0, //ADDSET_WA_THRES - 0, //ADDSET_WA_CHRO - 0, //ADDSET_WA_CHROMA - 0, //ADDSET_WA_CONTRAST - 0, //ADDSET_WA_SKINPROTECT - 0, //ADDSET_WA_RESCHRO - 0, //ADDSET_WA_RESCON - 0, //ADDSET_WA_RESCONH - 0, //ADDSET_WA_THRR - 0, //ADDSET_WA_THRRH - 0, //ADDSET_WA_SKYPROTECT - 0, //ADDSET_WA_EDGRAD - 0, //ADDSET_WA_EDGVAL - 0, //ADDSET_WA_STRENGTH - 0, //ADDSET_WA_EDGEDETECT - 0, //ADDSET_WA_EDGEDETECTTHR - 0, //ADDSET_WA_EDGEDETECTTHR2 - 0, //ADDSET_WA_TMRS - 0, //ADDSET_WA_GAMMA - 0, //ADDSET_RETI_STR - 0, //ADDSET_RETI_NEIGH - 0, //ADDSET_RETI_LIMD - 0, //ADDSET_RETI_GAIN - 0, //ADDSET_RETI_OFFS - 0, //ADDSET_RETI_VART - 0, //ADDSET_RETI_GAM - 0, //ADDSET_RETI_SLO - + baBehav = { + 0, // ADDSET_TC_EXPCOMP + 0, // ADDSET_TC_BRIGHTNESS + 0, // ADDSET_TC_BLACKLEVEL + 0, // ADDSET_TC_CONTRAST + 0, // ADDSET_SH_HIGHLIGHTS + 0, // ADDSET_SH_SHADOWS + 0, // ADDSET_SH_LOCALCONTRAST + 0, // ADDSET_LC_BRIGHTNESS + 0, // ADDSET_LC_CONTRAST + 0, // ADDSET_SHARP_AMOUNT + 0, // ADDSET_WB_TEMPERATURE + 0, // ADDSET_WB_GREEN + 0, // ADDSET_ROTATE_DEGREE + 0, // ADDSET_DIST_AMOUNT + 0, // ADDSET_PERSPECTIVE + 0, // ADDSET_CA + 0, // ADDSET_VIGN_AMOUNT + 0, // ADDSET_VIGN_RADIUS + 0, // ADDSET_VIGN_STRENGTH + 0, // ADDSET_VIGN_CENTER + 0, // ADDSET_LC_CHROMATICITY + 0, // ADDSET_TC_SATURATION + 0, // ADDSET_TC_HLCOMPAMOUNT + 0, // ADDSET_TC_HLCOMPTHRESH + 0, // ADDSET_TC_SHCOMP + 0, // ADDSET_DIRPYREQ + 0, // ADDSET_DIRPYRDN_LUMA + 0, // ADDSET_DIRPYRDN_LUDET + 0, // ADDSET_DIRPYRDN_CHROMA + 0, // ADDSET_DIRPYRDN_CHROMARED + 0, // ADDSET_DIRPYRDN_CHROMABLUE + 0, // ADDSET_DIRPYRDN_GAMMA + 0, // ADDSET_CHMIXER + 0, // ADDSET_PREPROCESS_GREENEQUIL + 0, // ADDSET_PREPROCESS_LINEDENOISE + 0, // ADDSET_RAWCACORR + 0, // ADDSET_RAWEXPOS_LINEAR + 0, // ADDSET_RAWEXPOS_PRESER + 0, // ADDSET_RAWEXPOS_BLACKS + 0, // ADDSET_SHARPENEDGE_AMOUNT + 0, // ADDSET_SHARPENMICRO_AMOUNT + 0, // ADDSET_SHARPENEDGE_PASS + 0, // ADDSET_SHARPENMICRO_UNIFORMITY + 0, // ADDSET_VIBRANCE_PASTELS + 0, // ADDSET_VIBRANCE_SATURATED + 0, // ADDSET_FREE_OUPUT_GAMMA + 0, // ADDSET_FREE_OUTPUT_SLOPE + 0, // ADDSET_CAT_DEGREE + 0, // ADDSET_CAT_ADAPSCEN + 0, // ADDSET_CAT_ADAPLUM + 0, // ADDSET_CAT_LIGHT + 0, // ADDSET_CAT_RSTPRO + 0, // ADDSET_CAT_BADPIX + 0, // ADDSET_CAT_JLIGHT + 0, // ADDSET_CAT_CHROMA + 0, // ADDSET_CAT_CONTRAST + 0, // ADDSET_CAT_CHROMA_S + 0, // ADDSET_CAT_CHROMA_M + 0, // ADDSET_CAT_HUE + 0, // ADDSET_CAT_BADPIX + 0, // ADDSET_WB_EQUAL + 0, // ADDSET_GRADIENT_DEGREE + 0, // ADDSET_GRADIENT_FEATHER + 0, // ADDSET_GRADIENT_STRENGTH + 0, // ADDSET_GRADIENT_CENTER + 0, // ADDSET_PCVIGNETTE_STRENGTH + 0, // ADDSET_PCVIGNETTE_FEATHER + 0, // ADDSET_PCVIGNETTE_ROUNDNESS + 0, // ADDSET_BLACKWHITE_HUES + 0, // ADDSET_BLACKWHITE_GAMMA + 0, // ADDSET_DIRPYREQ_THRESHOLD + 0, // ADDSET_DIRPYREQ_SKINPROTECT + 0, // ADDSET_COLORTONING_SPLIT + 0, // ADDSET_DIRPYRDN_PASSES + 0, // ADDSET_RAWFFCLIPCONTROL + 0, // ADDSET_FILMSIMULATION_STRENGTH + 0, // ADDSET_WA + 0, // ADDSET_WA_THRESHOLD + 0, // ADDSET_WA_THRESHOLD2 + 0, // ADDSET_WA_THRES + 0, // ADDSET_WA_CHRO + 0, // ADDSET_WA_CHROMA + 0, // ADDSET_WA_CONTRAST + 0, // ADDSET_WA_SKINPROTECT + 0, // ADDSET_WA_RESCHRO + 0, // ADDSET_WA_RESCON + 0, // ADDSET_WA_RESCONH + 0, // ADDSET_WA_THRR + 0, // ADDSET_WA_THRRH + 0, // ADDSET_WA_SKYPROTECT + 0, // ADDSET_WA_EDGRAD + 0, // ADDSET_WA_EDGVAL + 0, // ADDSET_WA_STRENGTH + 0, // ADDSET_WA_EDGEDETECT + 0, // ADDSET_WA_EDGEDETECTTHR + 0, // ADDSET_WA_EDGEDETECTTHR2 + 0, // ADDSET_WA_TMRS + 0, // ADDSET_WA_GAMMA + 0, // ADDSET_RETI_STR + 0, // ADDSET_RETI_NEIGH + 0, // ADDSET_RETI_LIMD + 0, // ADDSET_RETI_GAIN + 0, // ADDSET_RETI_OFFS + 0, // ADDSET_RETI_VART + 0, // ADDSET_RETI_GAM + 0, // ADDSET_RETI_SLO }; - baBehav = std::vector (babehav, babehav + ADDSET_PARAM_NUM); rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; @@ -646,6 +646,7 @@ void Options::setDefaults () rtSettings.bruce = "Bruce"; rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; + rtSettings.rec2020 = "Rec2020"; rtSettings.verbose = false; rtSettings.gamutICC = true; rtSettings.gamutLch = true; @@ -735,8 +736,6 @@ int Options::readFromFile (Glib::ustring fname) try { if (keyFile.load_from_file (fname)) { - setDefaults (); - // -------------------------------------------------------------------------------------------------------- if (keyFile.has_group ("General")) { @@ -1408,6 +1407,14 @@ int Options::readFromFile (Glib::ustring fname) histogramFullMode = keyFile.get_boolean ("GUI", "HistogramFullMode"); } + if (keyFile.has_key ("GUI", "NavigatorRGBUnit")) { + navRGBUnit = (NavigatorUnit)keyFile.get_integer ("GUI", "NavigatorRGBUnit"); + } + + if (keyFile.has_key ("GUI", "NavigatorHSVUnit")) { + navHSVUnit = (NavigatorUnit)keyFile.get_integer ("GUI", "NavigatorHSVUnit"); + } + if (keyFile.has_key ("GUI", "ShowFilmStripToolBar")) { showFilmStripToolBar = keyFile.get_boolean ("GUI", "ShowFilmStripToolBar"); } @@ -1544,6 +1551,10 @@ int Options::readFromFile (Glib::ustring fname) rtSettings.best = keyFile.get_string("Color Management", "Best"); } + if( keyFile.has_key ("Color Management", "Rec2020")) { + rtSettings.rec2020 = keyFile.get_string("Color Management", "Rec2020"); + } + if( keyFile.has_key ("Color Management", "Bruce")) { rtSettings.bruce = keyFile.get_string("Color Management", "Bruce"); } @@ -1778,12 +1789,10 @@ int Options::readFromFile (Glib::ustring fname) if (options.rtSettings.verbose) { printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } - setDefaults (); } catch (...) { if (options.rtSettings.verbose) { printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); } - setDefaults (); } return 1; @@ -1812,309 +1821,312 @@ int Options::saveToFile (Glib::ustring fname) try { - Glib::KeyFile keyFile; + Glib::KeyFile keyFile; - keyFile.set_boolean ("General", "TabbedEditor", tabbedUI); - keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit); + keyFile.set_boolean ("General", "TabbedEditor", tabbedUI); + keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit); - if (startupDir == STARTUPDIR_HOME) { - keyFile.set_string ("General", "StartupDirectory", "home"); - } else if (startupDir == STARTUPDIR_CURRENT) { - keyFile.set_string ("General", "StartupDirectory", "current"); - } else if (startupDir == STARTUPDIR_CUSTOM) { - keyFile.set_string ("General", "StartupDirectory", "custom"); - } else if (startupDir == STARTUPDIR_LAST) { - keyFile.set_string ("General", "StartupDirectory", "last"); - } - - keyFile.set_string ("General", "StartupPath", startupPath); - keyFile.set_string ("General", "DateFormat", dateFormat); - keyFile.set_integer ("General", "AdjusterMinDelay", adjusterMinDelay); - keyFile.set_integer ("General", "AdjusterMaxDelay", adjusterMaxDelay); - keyFile.set_boolean ("General", "MultiUser", multiUser); - keyFile.set_string ("General", "Language", language); - keyFile.set_boolean ("General", "LanguageAutoDetect", languageAutoDetect); - keyFile.set_string ("General", "Theme", theme); - keyFile.set_boolean ("General", "SlimUI", slimUI); - keyFile.set_boolean ("General", "UseSystemTheme", useSystemTheme); - keyFile.set_string ("General", "Version", VERSION); - keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); - keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); - keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); - keyFile.set_double ("General", "BotLeft", rtSettings.bot_left); - keyFile.set_double ("General", "TopLeft", rtSettings.top_left); - keyFile.set_double ("General", "TopRight", rtSettings.top_right); - keyFile.set_double ("General", "BotRight", rtSettings.bot_right); - keyFile.set_double ("General", "EDdetec", rtSettings.ed_detec); - keyFile.set_double ("General", "EDdetecStr", rtSettings.ed_detecStr); - keyFile.set_double ("General", "EDLow", rtSettings.ed_low); - keyFile.set_double ("General", "EDLipinfl", rtSettings.ed_lipinfl); - keyFile.set_double ("General", "EDLipampl", rtSettings.ed_lipampl); - - - keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); - keyFile.set_string ("External Editor", "GimpDir", gimpDir); - keyFile.set_string ("External Editor", "PhotoshopDir", psDir); - keyFile.set_string ("External Editor", "CustomEditor", customEditorProg); - - keyFile.set_boolean ("File Browser", "BrowseOnlyRaw", fbOnlyRaw); - keyFile.set_boolean ("File Browser", "BrowserShowsDate", fbShowDateTime); - keyFile.set_boolean ("File Browser", "BrowserShowsExif", fbShowBasicExif); - keyFile.set_boolean ("File Browser", "BrowserShowsExpComp", fbShowExpComp); - keyFile.set_boolean ("File Browser", "BrowserShowsHidden", fbShowHidden); - keyFile.set_integer ("File Browser", "ThumbnailSize", thumbSize); - keyFile.set_integer ("File Browser", "ThumbnailSizeTab", thumbSizeTab); - keyFile.set_integer ("File Browser", "ThumbnailSizeQueue", thumbSizeQueue); - keyFile.set_integer ("File Browser", "SameThumbSize", sameThumbSize); - keyFile.set_integer ("File Browser", "MaxPreviewHeight", maxThumbnailHeight); - keyFile.set_integer ("File Browser", "MaxCacheEntries", maxCacheEntries); - Glib::ArrayHandle pext = parseExtensions; - keyFile.set_string_list ("File Browser", "ParseExtensions", pext); - Glib::ArrayHandle pextena = parseExtensionsEnabled; - keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena); - keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement); - keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp); - keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails); - Glib::ArrayHandle pfav = favoriteDirs; - keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav); - Glib::ArrayHandle pren = renameTemplates; - keyFile.set_string_list ("File Browser", "RenameTemplates", pren); - keyFile.set_boolean ("File Browser", "RenameUseTemplates", renameUseTemplates); - Glib::ArrayHandle ptzoom = thumbnailZoomRatios; - keyFile.set_double_list ("File Browser", "ThumbnailZoomRatios", ptzoom); - keyFile.set_boolean ("File Browser", "OverlayedFileNames", overlayedFileNames); - keyFile.set_boolean ("File Browser", "FilmStripOverlayedFileNames", filmStripOverlayedFileNames); - keyFile.set_boolean ("File Browser", "ShowFileNames", showFileNames ); - keyFile.set_boolean ("File Browser", "FilmStripShowFileNames", filmStripShowFileNames ); - keyFile.set_boolean ("File Browser", "InternalThumbIfUntouched", internalThumbIfUntouched ); - keyFile.set_boolean ("File Browser", "menuGroupRank", menuGroupRank); - keyFile.set_boolean ("File Browser", "menuGroupLabel", menuGroupLabel); - keyFile.set_boolean ("File Browser", "menuGroupFileOperations", menuGroupFileOperations); - keyFile.set_boolean ("File Browser", "menuGroupProfileOperations", menuGroupProfileOperations); - keyFile.set_boolean ("File Browser", "menuGroupExtProg", menuGroupExtProg); - keyFile.set_integer ("File Browser", "MaxRecentFolders", maxRecentFolders); - { - std::vector temp; - temp.reserve(maxRecentFolders); - - for(unsigned int i = 0; i < std::min(recentFolders.size(), maxRecentFolders); i++) { - temp.push_back(recentFolders[i]); + if (startupDir == STARTUPDIR_HOME) { + keyFile.set_string ("General", "StartupDirectory", "home"); + } else if (startupDir == STARTUPDIR_CURRENT) { + keyFile.set_string ("General", "StartupDirectory", "current"); + } else if (startupDir == STARTUPDIR_CUSTOM) { + keyFile.set_string ("General", "StartupDirectory", "custom"); + } else if (startupDir == STARTUPDIR_LAST) { + keyFile.set_string ("General", "StartupDirectory", "last"); } - keyFile.set_string_list ("File Browser", "RecentFolders", temp); - } - keyFile.set_integer ("Clipping Indication", "HighlightThreshold", highlightThreshold); - keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); - keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); + keyFile.set_string ("General", "StartupPath", startupPath); + keyFile.set_string ("General", "DateFormat", dateFormat); + keyFile.set_integer ("General", "AdjusterMinDelay", adjusterMinDelay); + keyFile.set_integer ("General", "AdjusterMaxDelay", adjusterMaxDelay); + keyFile.set_boolean ("General", "MultiUser", multiUser); + keyFile.set_string ("General", "Language", language); + keyFile.set_boolean ("General", "LanguageAutoDetect", languageAutoDetect); + keyFile.set_string ("General", "Theme", theme); + keyFile.set_boolean ("General", "SlimUI", slimUI); + keyFile.set_boolean ("General", "UseSystemTheme", useSystemTheme); + keyFile.set_string ("General", "Version", VERSION); + keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); + keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); + keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); + keyFile.set_double ("General", "BotLeft", rtSettings.bot_left); + keyFile.set_double ("General", "TopLeft", rtSettings.top_left); + keyFile.set_double ("General", "TopRight", rtSettings.top_right); + keyFile.set_double ("General", "BotRight", rtSettings.bot_right); + keyFile.set_double ("General", "EDdetec", rtSettings.ed_detec); + keyFile.set_double ("General", "EDdetecStr", rtSettings.ed_detecStr); + keyFile.set_double ("General", "EDLow", rtSettings.ed_low); + keyFile.set_double ("General", "EDLipinfl", rtSettings.ed_lipinfl); + keyFile.set_double ("General", "EDLipampl", rtSettings.ed_lipampl); - keyFile.set_integer ("Performance", "RgbDenoiseThreadLimit", rgbDenoiseThreadLimit); - keyFile.set_double ("Performance", "NRauto", rtSettings.nrauto); - keyFile.set_double ("Performance", "NRautomax", rtSettings.nrautomax); - keyFile.set_double ("Performance", "NRhigh", rtSettings.nrhigh); - keyFile.set_integer ("Performance", "NRWavlevel", rtSettings.nrwavlevel); - keyFile.set_integer ("Performance", "LevNR", rtSettings.leveldnv); - keyFile.set_integer ("Performance", "LevNRTI", rtSettings.leveldnti); - keyFile.set_integer ("Performance", "LevNRAUT", rtSettings.leveldnaut); - keyFile.set_integer ("Performance", "LevNRLISS", rtSettings.leveldnliss); - keyFile.set_integer ("Performance", "SIMPLNRAUT", rtSettings.leveldnautsimpl); - keyFile.set_integer ("Performance", "ClutCacheSize", clutCacheSize); - keyFile.set_integer ("Performance", "MaxInspectorBuffers", maxInspectorBuffers); - keyFile.set_integer ("Performance", "PreviewDemosaicFromSidecar", prevdemo); - keyFile.set_boolean ("Performance", "Daubechies", rtSettings.daubech); - keyFile.set_boolean ("Performance", "SerializeTiffRead", serializeTiffRead); - keyFile.set_string ("Output", "Format", saveFormat.format); - keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); - keyFile.set_integer ("Output", "JpegSubSamp", saveFormat.jpegSubSamp); - keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); - keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); - keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); - keyFile.set_boolean ("Output", "TiffUncompressed", saveFormat.tiffUncompressed); - keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams); + keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); + keyFile.set_string ("External Editor", "GimpDir", gimpDir); + keyFile.set_string ("External Editor", "PhotoshopDir", psDir); + keyFile.set_string ("External Editor", "CustomEditor", customEditorProg); - keyFile.set_string ("Output", "FormatBatch", saveFormatBatch.format); - keyFile.set_integer ("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality); - keyFile.set_integer ("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp); - keyFile.set_integer ("Output", "PngCompressionBatch", saveFormatBatch.pngCompression); - keyFile.set_integer ("Output", "PngBpsBatch", saveFormatBatch.pngBits); - keyFile.set_integer ("Output", "TiffBpsBatch", saveFormatBatch.tiffBits); - keyFile.set_boolean ("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed); - keyFile.set_boolean ("Output", "SaveProcParamsBatch", saveFormatBatch.saveParams); + keyFile.set_boolean ("File Browser", "BrowseOnlyRaw", fbOnlyRaw); + keyFile.set_boolean ("File Browser", "BrowserShowsDate", fbShowDateTime); + keyFile.set_boolean ("File Browser", "BrowserShowsExif", fbShowBasicExif); + keyFile.set_boolean ("File Browser", "BrowserShowsExpComp", fbShowExpComp); + keyFile.set_boolean ("File Browser", "BrowserShowsHidden", fbShowHidden); + keyFile.set_integer ("File Browser", "ThumbnailSize", thumbSize); + keyFile.set_integer ("File Browser", "ThumbnailSizeTab", thumbSizeTab); + keyFile.set_integer ("File Browser", "ThumbnailSizeQueue", thumbSizeQueue); + keyFile.set_integer ("File Browser", "SameThumbSize", sameThumbSize); + keyFile.set_integer ("File Browser", "MaxPreviewHeight", maxThumbnailHeight); + keyFile.set_integer ("File Browser", "MaxCacheEntries", maxCacheEntries); + Glib::ArrayHandle pext = parseExtensions; + keyFile.set_string_list ("File Browser", "ParseExtensions", pext); + Glib::ArrayHandle pextena = parseExtensionsEnabled; + keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena); + keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement); + keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp); + keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails); + Glib::ArrayHandle pfav = favoriteDirs; + keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav); + Glib::ArrayHandle pren = renameTemplates; + keyFile.set_string_list ("File Browser", "RenameTemplates", pren); + keyFile.set_boolean ("File Browser", "RenameUseTemplates", renameUseTemplates); + Glib::ArrayHandle ptzoom = thumbnailZoomRatios; + keyFile.set_double_list ("File Browser", "ThumbnailZoomRatios", ptzoom); + keyFile.set_boolean ("File Browser", "OverlayedFileNames", overlayedFileNames); + keyFile.set_boolean ("File Browser", "FilmStripOverlayedFileNames", filmStripOverlayedFileNames); + keyFile.set_boolean ("File Browser", "ShowFileNames", showFileNames ); + keyFile.set_boolean ("File Browser", "FilmStripShowFileNames", filmStripShowFileNames ); + keyFile.set_boolean ("File Browser", "InternalThumbIfUntouched", internalThumbIfUntouched ); + keyFile.set_boolean ("File Browser", "menuGroupRank", menuGroupRank); + keyFile.set_boolean ("File Browser", "menuGroupLabel", menuGroupLabel); + keyFile.set_boolean ("File Browser", "menuGroupFileOperations", menuGroupFileOperations); + keyFile.set_boolean ("File Browser", "menuGroupProfileOperations", menuGroupProfileOperations); + keyFile.set_boolean ("File Browser", "menuGroupExtProg", menuGroupExtProg); + keyFile.set_integer ("File Browser", "MaxRecentFolders", maxRecentFolders); + { + std::vector temp; + temp.reserve(maxRecentFolders); - keyFile.set_string ("Output", "PathTemplate", savePathTemplate); - keyFile.set_string ("Output", "PathFolder", savePathFolder); - keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix); - keyFile.set_boolean ("Output", "ForceFormatOpts", forceFormatOpts); - keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum); - keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate); - keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); - keyFile.set_boolean ("Output", "OverwriteOutputFile", overwriteOutputFile); - keyFile.set_boolean ("Output", "TunnelMetaData", tunnelMetaData); + for(unsigned int i = 0; i < std::min(recentFolders.size(), maxRecentFolders); i++) { + temp.push_back(recentFolders[i]); + } - keyFile.set_string ("Profiles", "Directory", profilePath); - keyFile.set_boolean ("Profiles", "UseBundledProfiles", useBundledProfiles); - keyFile.set_string ("Profiles", "LoadSaveProfilePath", loadSaveProfilePath); - keyFile.set_string ("Profiles", "RawDefault", defProfRaw); - keyFile.set_string ("Profiles", "ImgDefault", defProfImg); - keyFile.set_boolean ("Profiles", "FilledProfile", filledProfile); - keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); - keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); - keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); - keyFile.set_string ("Profiles", "CustomProfileBuilderPath", CPBPath); - keyFile.set_integer ("Profiles", "CustomProfileBuilderKeys", CPBKeys); + keyFile.set_string_list ("File Browser", "RecentFolders", temp); + } + keyFile.set_integer ("Clipping Indication", "HighlightThreshold", highlightThreshold); + keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); + keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); - keyFile.set_string ("GUI", "Font", font); - keyFile.set_integer ("GUI", "WindowWidth", windowWidth); - keyFile.set_integer ("GUI", "WindowHeight", windowHeight); - keyFile.set_integer ("GUI", "WindowX", windowX); - keyFile.set_integer ("GUI", "WindowY", windowY); - keyFile.set_boolean ("GUI", "WindowMaximized", windowMaximized); - keyFile.set_integer ("GUI", "DetailWindowWidth", detailWindowWidth); - keyFile.set_integer ("GUI", "DetailWindowHeight", detailWindowHeight); - keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth); - keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight); - keyFile.set_integer ("GUI", "SortType", dirBrowserSortType); - keyFile.set_integer ("GUI", "PreferencesWidth", preferencesWidth); - keyFile.set_integer ("GUI", "PreferencesHeight", preferencesHeight); - keyFile.set_integer ("GUI", "SaveAsDialogWidth", saveAsDialogWidth); - keyFile.set_integer ("GUI", "SaveAsDialogHeight", saveAsDialogHeight); - keyFile.set_integer ("GUI", "ToolPanelWidth", toolPanelWidth); - keyFile.set_integer ("GUI", "BrowserToolPanelWidth", browserToolPanelWidth); - keyFile.set_integer ("GUI", "BrowserToolPanelHeight", browserToolPanelHeight); - keyFile.set_boolean ("GUI", "BrowserToolPanelOpened", browserToolPanelOpened); - keyFile.set_boolean ("GUI", "EditorFilmStripOpened", editorFilmStripOpened); - keyFile.set_boolean ("GUI", "BrowserDirPanelOpened", browserDirPanelOpened); - keyFile.set_integer ("GUI", "HistoryPanelWidth", historyPanelWidth); - keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); - keyFile.set_integer ("GUI", "PanAccelFactor", panAccelFactor); - keyFile.set_boolean ("GUI", "RememberZoomAndPan", rememberZoomAndPan); - keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); - keyFile.set_boolean ("GUI", "ShowHistory", showHistory); - keyFile.set_integer ("GUI", "ShowFilePanelState", showFilePanelState); - keyFile.set_boolean ("GUI", "ShowInfo", showInfo); - keyFile.set_boolean ("GUI", "MainNBVertical", mainNBVertical); - keyFile.set_boolean ("GUI", "ShowClippedHighlights", showClippedHighlights); - keyFile.set_boolean ("GUI", "ShowClippedShadows", showClippedShadows); - keyFile.set_integer ("GUI", "FrameColor", bgcolor); - keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); - Glib::ArrayHandle tpopen = tpOpen; - keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); - keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); - keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); - keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); - keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); - keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); - keyFile.set_boolean ("GUI", "HistogramFullMode", histogramFullMode); - keyFile.set_boolean ("GUI", "ShowFilmStripToolBar", showFilmStripToolBar); - keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); - keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); - keyFile.set_boolean ("GUI", "UseIconNoText", UseIconNoText); - keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking); - keyFile.set_integer ("GUI", "CurveBBoxPosition", curvebboxpos); + keyFile.set_integer ("Performance", "RgbDenoiseThreadLimit", rgbDenoiseThreadLimit); + keyFile.set_double ("Performance", "NRauto", rtSettings.nrauto); + keyFile.set_double ("Performance", "NRautomax", rtSettings.nrautomax); + keyFile.set_double ("Performance", "NRhigh", rtSettings.nrhigh); + keyFile.set_integer ("Performance", "NRWavlevel", rtSettings.nrwavlevel); + keyFile.set_integer ("Performance", "LevNR", rtSettings.leveldnv); + keyFile.set_integer ("Performance", "LevNRTI", rtSettings.leveldnti); + keyFile.set_integer ("Performance", "LevNRAUT", rtSettings.leveldnaut); + keyFile.set_integer ("Performance", "LevNRLISS", rtSettings.leveldnliss); + keyFile.set_integer ("Performance", "SIMPLNRAUT", rtSettings.leveldnautsimpl); + keyFile.set_integer ("Performance", "ClutCacheSize", clutCacheSize); + keyFile.set_integer ("Performance", "MaxInspectorBuffers", maxInspectorBuffers); + keyFile.set_integer ("Performance", "PreviewDemosaicFromSidecar", prevdemo); + keyFile.set_boolean ("Performance", "Daubechies", rtSettings.daubech); + keyFile.set_boolean ("Performance", "SerializeTiffRead", serializeTiffRead); - //Glib::ArrayHandle crvopen = crvOpen; - //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); + keyFile.set_string ("Output", "Format", saveFormat.format); + keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); + keyFile.set_integer ("Output", "JpegSubSamp", saveFormat.jpegSubSamp); + keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); + keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); + keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); + keyFile.set_boolean ("Output", "TiffUncompressed", saveFormat.tiffUncompressed); + keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams); - keyFile.set_integer ("Crop Settings", "PPI", cropPPI); + keyFile.set_string ("Output", "FormatBatch", saveFormatBatch.format); + keyFile.set_integer ("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality); + keyFile.set_integer ("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp); + keyFile.set_integer ("Output", "PngCompressionBatch", saveFormatBatch.pngCompression); + keyFile.set_integer ("Output", "PngBpsBatch", saveFormatBatch.pngBits); + keyFile.set_integer ("Output", "TiffBpsBatch", saveFormatBatch.tiffBits); + keyFile.set_boolean ("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed); + keyFile.set_boolean ("Output", "SaveProcParamsBatch", saveFormatBatch.saveParams); - keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); - keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); - keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); - keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); - keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); - keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent); - keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); - keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); - keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); + keyFile.set_string ("Output", "PathTemplate", savePathTemplate); + keyFile.set_string ("Output", "PathFolder", savePathFolder); + keyFile.set_boolean ("Output", "AutoSuffix", autoSuffix); + keyFile.set_boolean ("Output", "ForceFormatOpts", forceFormatOpts); + keyFile.set_integer ("Output", "SaveMethodNum", saveMethodNum); + keyFile.set_boolean ("Output", "UsePathTemplate", saveUsePathTemplate); + keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); + keyFile.set_boolean ("Output", "OverwriteOutputFile", overwriteOutputFile); + keyFile.set_boolean ("Output", "TunnelMetaData", tunnelMetaData); - keyFile.set_string ("Color Management", "AdobeRGB", rtSettings.adobe); - keyFile.set_string ("Color Management", "ProPhoto", rtSettings.prophoto); - keyFile.set_string ("Color Management", "ProPhoto10", rtSettings.prophoto10); - keyFile.set_string ("Color Management", "WideGamut", rtSettings.widegamut); - keyFile.set_string ("Color Management", "sRGB", rtSettings.srgb); - keyFile.set_string ("Color Management", "sRGB10", rtSettings.srgb10); - keyFile.set_string ("Color Management", "Beta", rtSettings.beta); - keyFile.set_string ("Color Management", "Best", rtSettings.best); - keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce); - keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); - keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); + keyFile.set_string ("Profiles", "Directory", profilePath); + keyFile.set_boolean ("Profiles", "UseBundledProfiles", useBundledProfiles); + keyFile.set_string ("Profiles", "LoadSaveProfilePath", loadSaveProfilePath); + keyFile.set_string ("Profiles", "RawDefault", defProfRaw); + keyFile.set_string ("Profiles", "ImgDefault", defProfImg); + keyFile.set_boolean ("Profiles", "FilledProfile", filledProfile); + keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); + keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); + keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); + keyFile.set_string ("Profiles", "CustomProfileBuilderPath", CPBPath); + keyFile.set_integer ("Profiles", "CustomProfileBuilderKeys", CPBKeys); + + keyFile.set_string ("GUI", "Font", font); + keyFile.set_integer ("GUI", "WindowWidth", windowWidth); + keyFile.set_integer ("GUI", "WindowHeight", windowHeight); + keyFile.set_integer ("GUI", "WindowX", windowX); + keyFile.set_integer ("GUI", "WindowY", windowY); + keyFile.set_boolean ("GUI", "WindowMaximized", windowMaximized); + keyFile.set_integer ("GUI", "DetailWindowWidth", detailWindowWidth); + keyFile.set_integer ("GUI", "DetailWindowHeight", detailWindowHeight); + keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth); + keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight); + keyFile.set_integer ("GUI", "SortType", dirBrowserSortType); + keyFile.set_integer ("GUI", "PreferencesWidth", preferencesWidth); + keyFile.set_integer ("GUI", "PreferencesHeight", preferencesHeight); + keyFile.set_integer ("GUI", "SaveAsDialogWidth", saveAsDialogWidth); + keyFile.set_integer ("GUI", "SaveAsDialogHeight", saveAsDialogHeight); + keyFile.set_integer ("GUI", "ToolPanelWidth", toolPanelWidth); + keyFile.set_integer ("GUI", "BrowserToolPanelWidth", browserToolPanelWidth); + keyFile.set_integer ("GUI", "BrowserToolPanelHeight", browserToolPanelHeight); + keyFile.set_boolean ("GUI", "BrowserToolPanelOpened", browserToolPanelOpened); + keyFile.set_boolean ("GUI", "EditorFilmStripOpened", editorFilmStripOpened); + keyFile.set_boolean ("GUI", "BrowserDirPanelOpened", browserDirPanelOpened); + keyFile.set_integer ("GUI", "HistoryPanelWidth", historyPanelWidth); + keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); + keyFile.set_integer ("GUI", "PanAccelFactor", panAccelFactor); + keyFile.set_boolean ("GUI", "RememberZoomAndPan", rememberZoomAndPan); + keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); + keyFile.set_boolean ("GUI", "ShowHistory", showHistory); + keyFile.set_integer ("GUI", "ShowFilePanelState", showFilePanelState); + keyFile.set_boolean ("GUI", "ShowInfo", showInfo); + keyFile.set_boolean ("GUI", "MainNBVertical", mainNBVertical); + keyFile.set_boolean ("GUI", "ShowClippedHighlights", showClippedHighlights); + keyFile.set_boolean ("GUI", "ShowClippedShadows", showClippedShadows); + keyFile.set_integer ("GUI", "FrameColor", bgcolor); + keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); + Glib::ArrayHandle tpopen = tpOpen; + keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); + keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); + keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); + keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); + keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); + keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); + keyFile.set_boolean ("GUI", "HistogramFullMode", histogramFullMode); + keyFile.set_integer ("GUI", "NavigatorRGBUnit", (int)navRGBUnit); + keyFile.set_integer ("GUI", "NavigatorHSVUnit", (int)navHSVUnit); + keyFile.set_boolean ("GUI", "ShowFilmStripToolBar", showFilmStripToolBar); + keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); + keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); + keyFile.set_boolean ("GUI", "UseIconNoText", UseIconNoText); + keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking); + keyFile.set_integer ("GUI", "CurveBBoxPosition", curvebboxpos); + + //Glib::ArrayHandle crvopen = crvOpen; + //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); + + keyFile.set_integer ("Crop Settings", "PPI", cropPPI); + + keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); + keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); + keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); + keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); + keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); + keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent); + keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); + keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); + keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); + + keyFile.set_string ("Color Management", "AdobeRGB", rtSettings.adobe); + keyFile.set_string ("Color Management", "ProPhoto", rtSettings.prophoto); + keyFile.set_string ("Color Management", "ProPhoto10", rtSettings.prophoto10); + keyFile.set_string ("Color Management", "WideGamut", rtSettings.widegamut); + keyFile.set_string ("Color Management", "sRGB", rtSettings.srgb); + keyFile.set_string ("Color Management", "sRGB10", rtSettings.srgb10); + keyFile.set_string ("Color Management", "Beta", rtSettings.beta); + keyFile.set_string ("Color Management", "Best", rtSettings.best); + keyFile.set_string ("Color Management", "Rec2020", rtSettings.rec2020); + keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce); + keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); + keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); // keyFile.set_boolean ("Color Management", "BWcomplement", rtSettings.bw_complementary); - keyFile.set_boolean ("Color Management", "Ciecamfloat", rtSettings.ciecamfloat); - keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch); - keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); - keyFile.set_integer ("Color Management", "Amountchroma", rtSettings.amchroma); - keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); - keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); - keyFile.set_integer ("Color Management", "DenoiseLabgamma", rtSettings.denoiselabgamma); + keyFile.set_boolean ("Color Management", "Ciecamfloat", rtSettings.ciecamfloat); + keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch); + keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); + keyFile.set_integer ("Color Management", "Amountchroma", rtSettings.amchroma); + keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); + keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); + keyFile.set_integer ("Color Management", "DenoiseLabgamma", rtSettings.denoiselabgamma); // keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); - keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); - keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); - keyFile.set_double ("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); + keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); // keyFile.set_double ("Color Management", "Colortoningab", rtSettings.colortoningab); // keyFile.set_double ("Color Management", "Decaction", rtSettings.decaction); - keyFile.set_string ("Color Management", "ClutsDirectory", clutsDir); + keyFile.set_string ("Color Management", "ClutsDirectory", clutsDir); - Glib::ArrayHandle bab = baBehav; - keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); + Glib::ArrayHandle bab = baBehav; + keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); - keyFile.set_boolean ("Sounds", "Enable", sndEnable); - keyFile.set_string ("Sounds", "BatchQueueDone", sndBatchQueueDone); - keyFile.set_string ("Sounds", "LngEditProcDone", sndLngEditProcDone); - keyFile.set_double ("Sounds", "LngEditProcDoneSecs", sndLngEditProcDoneSecs); + keyFile.set_boolean ("Sounds", "Enable", sndEnable); + keyFile.set_string ("Sounds", "BatchQueueDone", sndBatchQueueDone); + keyFile.set_string ("Sounds", "LngEditProcDone", sndLngEditProcDone); + keyFile.set_double ("Sounds", "LngEditProcDoneSecs", sndLngEditProcDoneSecs); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpening" , fastexport_bypass_sharpening ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenEdge" , fastexport_bypass_sharpenEdge ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenMicro" , fastexport_bypass_sharpenMicro ); - //keyFile.set_boolean ("Fast Export", "fastexport_bypass_lumaDenoise" , fastexport_bypass_lumaDenoise ); - //keyFile.set_boolean ("Fast Export", "fastexport_bypass_colorDenoise" , fastexport_bypass_colorDenoise ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_defringe" , fastexport_bypass_defringe ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrDenoise" , fastexport_bypass_dirpyrDenoise ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_sh_hq" , fastexport_bypass_sh_hq ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrequalizer" , fastexport_bypass_dirpyrequalizer ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_wavelet" , fastexport_bypass_wavelet ); - keyFile.set_string ("Fast Export", "fastexport_raw_bayer_method" , fastexport_raw_bayer_method ); - //keyFile.set_boolean ("Fast Export", "fastexport_bypass_bayer_raw_all_enhance" , fastexport_bypass_raw_bayer_all_enhance ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations" , fastexport_bypass_raw_bayer_dcb_iterations ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance" , fastexport_bypass_raw_bayer_dcb_enhance ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations", fastexport_bypass_raw_bayer_lmmse_iterations); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_linenoise" , fastexport_bypass_raw_bayer_linenoise ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_greenthresh" , fastexport_bypass_raw_bayer_greenthresh ); - keyFile.set_string ("Fast Export", "fastexport_raw_xtrans_method" , fastexport_raw_xtrans_method ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" , fastexport_bypass_raw_ccSteps ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ca" , fastexport_bypass_raw_ca ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_df" , fastexport_bypass_raw_df ); - keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ff" , fastexport_bypass_raw_ff ); - keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); - keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); - keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); - keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); - keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); - keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); - keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); - keyFile.set_string ("Fast Export", "fastexport_resize_appliesTo" , fastexport_resize_appliesTo ); - keyFile.set_string ("Fast Export", "fastexport_resize_method" , fastexport_resize_method ); - keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec" , fastexport_resize_dataspec ); - keyFile.set_integer ("Fast Export", "fastexport_resize_width" , fastexport_resize_width ); - keyFile.set_integer ("Fast Export", "fastexport_resize_height" , fastexport_resize_height ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpening" , fastexport_bypass_sharpening ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenEdge" , fastexport_bypass_sharpenEdge ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenMicro" , fastexport_bypass_sharpenMicro ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_lumaDenoise" , fastexport_bypass_lumaDenoise ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_colorDenoise" , fastexport_bypass_colorDenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_defringe" , fastexport_bypass_defringe ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrDenoise" , fastexport_bypass_dirpyrDenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sh_hq" , fastexport_bypass_sh_hq ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrequalizer" , fastexport_bypass_dirpyrequalizer ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_wavelet" , fastexport_bypass_wavelet ); + keyFile.set_string ("Fast Export", "fastexport_raw_bayer_method" , fastexport_raw_bayer_method ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_bayer_raw_all_enhance" , fastexport_bypass_raw_bayer_all_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations" , fastexport_bypass_raw_bayer_dcb_iterations ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance" , fastexport_bypass_raw_bayer_dcb_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations", fastexport_bypass_raw_bayer_lmmse_iterations); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_linenoise" , fastexport_bypass_raw_bayer_linenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_greenthresh" , fastexport_bypass_raw_bayer_greenthresh ); + keyFile.set_string ("Fast Export", "fastexport_raw_xtrans_method" , fastexport_raw_xtrans_method ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" , fastexport_bypass_raw_ccSteps ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ca" , fastexport_bypass_raw_ca ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_df" , fastexport_bypass_raw_df ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ff" , fastexport_bypass_raw_ff ); + keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); + keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); + keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); + keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); + keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); + keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); + keyFile.set_string ("Fast Export", "fastexport_resize_appliesTo" , fastexport_resize_appliesTo ); + keyFile.set_string ("Fast Export", "fastexport_resize_method" , fastexport_resize_method ); + keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec" , fastexport_resize_dataspec ); + keyFile.set_integer ("Fast Export", "fastexport_resize_width" , fastexport_resize_width ); + keyFile.set_integer ("Fast Export", "fastexport_resize_height" , fastexport_resize_height ); - keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir); - keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir); - keyFile.set_string ("Dialogs", "LastFlatfieldDir", lastFlatfieldDir); - keyFile.set_string ("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); - keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); - keyFile.set_string ("Dialogs", "LastRetinexDir", lastRetinexDir); - keyFile.set_string ("Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); - keyFile.set_string ("Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); - keyFile.set_string ("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); - keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); - keyFile.set_string ("Dialogs", "LastBWCurvesDir", lastBWCurvesDir); - keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir); - keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); - keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); + keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir); + keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir); + keyFile.set_string ("Dialogs", "LastFlatfieldDir", lastFlatfieldDir); + keyFile.set_string ("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); + keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); + keyFile.set_string ("Dialogs", "LastRetinexDir", lastRetinexDir); + keyFile.set_string ("Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); + keyFile.set_string ("Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); + keyFile.set_string ("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); + keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); + keyFile.set_string ("Dialogs", "LastBWCurvesDir", lastBWCurvesDir); + keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir); + keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); + keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); - keyData = keyFile.to_data (); + keyData = keyFile.to_data (); } catch (Glib::KeyFileError&) {} diff --git a/rtgui/options.h b/rtgui/options.h index 4da827f36..c25708674 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -86,6 +86,13 @@ private: const Glib::ustring& entryName, Glib::ustring& destination); public: + + enum class NavigatorUnit { + PERCENT, + R0_255, + R0_1, + _COUNT + }; bool savesParamsAtExit; SaveFormat saveFormat, saveFormatBatch; Glib::ustring savePathTemplate; @@ -133,6 +140,8 @@ public: bool fbShowExpComp; bool fbShowHidden; int fbArrangement; + NavigatorUnit navRGBUnit; + NavigatorUnit navHSVUnit; bool multiUser; static Glib::ustring rtdir; Glib::ustring version; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0af4e9fdb..a84251607 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -73,9 +73,10 @@ void ParamsEdited::set (bool v) retinex.limd = v; retinex.highl = v; retinex.baselog = v; -// retinex.grbl = v; + retinex.skal = v; retinex.medianmap = v; retinex.transmissionCurve = v; + retinex.gaintransmissionCurve = v; retinex.highlights = v; retinex.htonalwidth = v; retinex.shadows = v; @@ -551,6 +552,7 @@ void ParamsEdited::initFrom (const std::vector retinex.cdHcurve = retinex.cdHcurve && p.retinex.cdHcurve == other.retinex.cdHcurve; retinex.lhcurve = retinex.lhcurve && p.retinex.lhcurve == other.retinex.lhcurve; retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve; + retinex.gaintransmissionCurve = retinex.gaintransmissionCurve && p.retinex.gaintransmissionCurve == other.retinex.gaintransmissionCurve; retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod; retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod; retinex.viewMethod = retinex.viewMethod && p.retinex.viewMethod == other.retinex.viewMethod; @@ -570,7 +572,7 @@ void ParamsEdited::initFrom (const std::vector retinex.limd = retinex.limd && p.retinex.limd == other.retinex.limd; retinex.highl = retinex.highl && p.retinex.highl == other.retinex.highl; retinex.baselog = retinex.baselog && p.retinex.baselog == other.retinex.baselog; -// retinex.grbl = retinex.grbl && p.retinex.grbl == other.retinex.grbl; + retinex.skal = retinex.skal && p.retinex.skal == other.retinex.skal; retinex.medianmap = retinex.medianmap && p.retinex.medianmap == other.retinex.medianmap; retinex.highlights = retinex.highlights && p.retinex.highlights == other.retinex.highlights; retinex.htonalwidth = retinex.htonalwidth && p.retinex.htonalwidth == other.retinex.htonalwidth; @@ -1099,6 +1101,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.transmissionCurve = mods.retinex.transmissionCurve; } + if (retinex.gaintransmissionCurve) { + toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; + } + if (retinex.retinexMethod) { toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; } @@ -1171,9 +1177,9 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.baselog = mods.retinex.baselog; } -// if (retinex.grbl) { -// toEdit.retinex.grbl = mods.retinex.grbl; -// } + if (retinex.skal) { + toEdit.retinex.skal = mods.retinex.skal; + } if (retinex.gain) { toEdit.retinex.gain = dontforceSet && options.baBehav[ADDSET_RETI_GAIN] ? toEdit.retinex.gain + mods.retinex.gain : mods.retinex.gain; @@ -2773,13 +2779,13 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten // Exif changes are added to the existing ones if (exif) - for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); i++) { + for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { toEdit.exif[i->first] = i->second; } // IPTC changes are added to the existing ones if (iptc) - for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); i++) { + for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); ++i) { toEdit.iptc[i->first] = i->second; } } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index cf3beb380..94b69389c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -78,9 +78,10 @@ public: bool limd; bool highl; bool baselog; -// bool grbl; + bool skal; bool method; bool transmissionCurve; + bool gaintransmissionCurve; bool cdcurve; bool mapcurve; bool cdHcurve; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 10800d527..14c9cb0eb 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -572,9 +572,9 @@ Gtk::Widget* Preferences::getPerformancePanel () clutCacheSizeSB->set_increments (1, 5); clutCacheSizeSB->set_max_length(2); // Will this be sufficient? :) #ifdef _OPENMP - clutCacheSizeSB->set_range (1, 2 * omp_get_num_procs()); + clutCacheSizeSB->set_range (1, 3 * omp_get_num_procs()); #else - clutCacheSizeSB->set_range (1, 8); + clutCacheSizeSB->set_range (1, 12); #endif clutCacheSizeHB->pack_start (*CLUTLl, Gtk::PACK_SHRINK, 0); clutCacheSizeHB->pack_end (*clutCacheSizeSB, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc index 9ba62230f..e6ef30bca 100644 --- a/rtgui/previewhandler.cc +++ b/rtgui/previewhandler.cc @@ -239,7 +239,7 @@ Glib::RefPtr PreviewHandler::getRoughImage (int desiredW, int desir void PreviewHandler::previewImageChanged () { - for (std::list::iterator i = listeners.begin(); i != listeners.end(); i++) { + for (std::list::iterator i = listeners.begin(); i != listeners.end(); ++i) { (*i)->previewImageChanged (); } } diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc index 482f83188..acbbfba63 100644 --- a/rtgui/profilestore.cc +++ b/rtgui/profilestore.cc @@ -252,7 +252,7 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath int ProfileStore::findFolderId(const Glib::ustring &path) { - for (std::vector::iterator i = folders.begin(); i != folders.end(); i++) { + for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) { if (*i == path) { return i - folders.begin(); } diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index 22a70e8a4..7dd097a90 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -18,7 +18,6 @@ */ #include "prsharpening.h" #include -#include "guiutils.h" using namespace rtengine; using namespace rtengine::procparams; @@ -46,10 +45,10 @@ PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PR pack_start (*hb); rld = new Gtk::VBox (); - dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75)); - damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75)); - ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20)); - diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.45)); + damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 100)); + ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 0)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 100)); rld->pack_start (*dradius); rld->pack_start (*damount); rld->pack_start (*ddamping); @@ -86,7 +85,7 @@ PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PR edgesonly->set_active (false); edgebox = new Gtk::VBox (); eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); - etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1800)); usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); usm->pack_start(*edgesonly); edgebox->pack_start(*eradius); diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 820ffe1d7..fead40b88 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -54,6 +54,9 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), dhbox->pack_start(*retinexcolorspace); retinexVBox->pack_start(*dhbox); + Gtk::VBox *equalVBox = Gtk::manage (new Gtk::VBox()); + + equalFrame = Gtk::manage (new Gtk::Frame(M("TP_RETINEX_EQUAL"))); // Histogram equalizer Lab curve curveEditorGD = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_LAB")); @@ -161,11 +164,11 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), grad = Gtk::manage (new Adjuster (M("TP_RETINEX_GRAD"), -2., 2., 1., 1.)); grads = Gtk::manage (new Adjuster (M("TP_RETINEX_GRADS"), -2., 2., 1., 1.)); gain = Gtk::manage (new Adjuster (M("TP_RETINEX_GAIN"), 20, 200, 1, 50)); - offs = Gtk::manage (new Adjuster (M("TP_RETINEX_OFFSET"), -10000, 10000, 1, 0)); + offs = Gtk::manage (new Adjuster (M("TP_RETINEX_OFFSET"), -1000, 5000, 1, 0)); // vart = Gtk::manage (new Adjuster (M("TP_RETINEX_VARIANCE"), 50, 500, 1, 125)); limd = Gtk::manage (new Adjuster (M("TP_RETINEX_THRESHOLD"), 2, 100, 1, 8)); - baselog = Gtk::manage (new Adjuster (M("TP_RETINEX_BASELOG"), 1.1, 100., 0.001, 2.718)); -// grbl = Gtk::manage (new Adjuster (M("TP_RETINEX_HIGHLIGHT3"), 1, 100, 1, 50)); + baselog = Gtk::manage (new Adjuster (M("TP_RETINEX_BASELOG"), 1., 10., 1., 3.)); + skal = Gtk::manage (new Adjuster (M("TP_RETINEX_SKAL"), 1, 8, 1, 3)); gain->set_tooltip_markup (M("TP_RETINEX_GAIN_TOOLTIP")); scal->set_tooltip_markup (M("TP_RETINEX_SCALES_TOOLTIP")); iter->set_tooltip_markup (M("TP_RETINEX_ITER_TOOLTIP")); @@ -175,6 +178,21 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), limd->set_tooltip_markup (M("TP_RETINEX_THRESHOLD_TOOLTIP")); baselog->set_tooltip_markup (M("TP_RETINEX_BASELOG_TOOLTIP")); + // Gain Transmission map curve + gaintransmissionCurve = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_GAINTRANSMISSION")); + gaintransmissionCurve->setCurveListener (this); + +// std::vector defaultCurve; + rtengine::RetinexParams::getDefaultgaintransmissionCurve(defaultCurve); + gaintransmissionShape = static_cast(gaintransmissionCurve->addCurve(CT_Flat, "", NULL, false)); + gaintransmissionShape->setIdentityValue(0.); + gaintransmissionShape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + gaintransmissionShape->setBottomBarBgGradient(milestones); + gaintransmissionCurve->set_tooltip_markup (M("TP_RETINEX_GAINTRANSMISSION_TOOLTIP")); + + gaintransmissionCurve->curveListComplete(); + + Gtk::Frame *p1Frame; p1Frame = Gtk::manage (new Gtk::Frame(M("TP_RETINEX_LABEL_MASK")) ); p1Frame->set_border_width(0); @@ -251,52 +269,81 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), settingsVBox->pack_start (*transLabels2); transLabels2->show (); - settingsVBox->pack_start (*curveEditorGD, Gtk::PACK_SHRINK, 4); + equalVBox->pack_start (*curveEditorGD, Gtk::PACK_SHRINK, 4); curveEditorGD->show(); - settingsVBox->pack_start (*curveEditorGDH, Gtk::PACK_SHRINK, 4); + equalVBox->pack_start (*curveEditorGDH, Gtk::PACK_SHRINK, 4); curveEditorGDH->show(); - settingsVBox->pack_start (*curveEditorGH, Gtk::PACK_SHRINK, 4); + equalVBox->pack_start (*curveEditorGH, Gtk::PACK_SHRINK, 4); curveEditorGH->show(); gambox->pack_start(*gammaretinex); - settingsVBox->pack_start(*gambox); + equalVBox->pack_start(*gambox); gammaretinex->show(); - settingsVBox->pack_start (*gam); + equalVBox->pack_start (*gam); gam->show (); - settingsVBox->pack_start (*slope); + equalVBox->pack_start (*slope); slope->show (); + equalFrame->add(*equalVBox); + settingsVBox->pack_start (*equalFrame); - settingsVBox->pack_start (*iter); + + Gtk::VBox *iterVBox = Gtk::manage (new Gtk::VBox()); + + iterFrame = Gtk::manage (new Gtk::Frame(M("TP_RETINEX_ITERF"))); + + iterVBox->pack_start (*iter); iter->show (); - settingsVBox->pack_start (*scal); + iterVBox->pack_start (*scal); scal->show (); - settingsVBox->pack_start (*grad); + iterVBox->pack_start (*grad); grad->show (); - settingsVBox->pack_start (*grads); + iterVBox->pack_start (*grads); grads->show (); - settingsVBox->pack_start (*gain); - gain->show (); + iterFrame->add(*iterVBox); + settingsVBox->pack_start (*iterFrame); - settingsVBox->pack_start (*offs); - offs->show (); + Gtk::VBox *tranVBox = Gtk::manage (new Gtk::VBox()); -// settingsVBox->pack_start (*vart); -// vart->show (); + tranFrame = Gtk::manage (new Gtk::Frame(M("TP_RETINEX_TRANF"))); - settingsVBox->pack_start (*limd); + tranVBox->pack_start( *transmissionCurveEditorG, Gtk::PACK_SHRINK, 2); + transmissionCurveEditorG->show(); + + tranVBox->pack_start (*skal); + skal->show (); + + tranVBox->pack_start (*limd); limd->show (); - // settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); + tranVBox->pack_start (*medianmap); + medianmap->show (); + + tranFrame->add(*tranVBox); + settingsVBox->pack_start (*tranFrame); + + Gtk::VBox *gainBox = Gtk::manage (new Gtk::VBox()); + + Gtk::HSeparator *separator = Gtk::manage (new Gtk::HSeparator()); + settingsVBox->pack_start(*separator, Gtk::PACK_SHRINK, 2); + gainFrame = Gtk::manage (new Gtk::Frame(M("TP_RETINEX_GAINOFFS"))); + + gainBox->pack_start( *gaintransmissionCurve, Gtk::PACK_SHRINK, 2); + gaintransmissionCurve->show(); + + gainBox->pack_start (*offs); + offs->show (); + gainFrame->add(*gainBox); + settingsVBox->pack_start (*gainFrame); viewbox->pack_start(*viewMethod); // settingsVBox->pack_start(*viewbox); @@ -326,18 +373,12 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), // settingsVBox->pack_start (*highl); // highl->show (); -// settingsVBox->pack_start (*baselog); -// baselog->show (); +// settingsVBox->pack_start (*baselog); +// baselog->show (); -// settingsVBox->pack_start (*grbl); -// grbl->show (); // settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); - settingsVBox->pack_start( *transmissionCurveEditorG, Gtk::PACK_SHRINK, 2); - transmissionCurveEditorG->show(); - settingsVBox->pack_start (*medianmap); - medianmap->show (); expsettings->add(*settingsVBox); neutrHBox = Gtk::manage (new Gtk::HBox ()); @@ -468,12 +509,12 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), s_tonalwidth->delay = 200; } - /* grbl->setAdjusterListener (this); + skal->setAdjusterListener (this); + + if (skal->delay < 200) { + skal->delay = 200; + } - if (grbl->delay < 200) { - grbl->delay = 200; - } - */ pack_start (*retinexVBox); p1Frame->add(*p1VBox); pack_start (*p1Frame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -494,6 +535,7 @@ Retinex::~Retinex() delete curveEditorGD; delete curveEditorGDH; delete transmissionCurveEditorG; + delete gaintransmissionCurve; delete curveEditorGH; delete curveEditormap; @@ -525,6 +567,7 @@ void Retinex::neutral_pressed () retinexcolorspace->set_active(0); gammaretinex->set_active(0); transmissionShape->reset(); + gaintransmissionShape->reset(); cdshape->reset(); cdshapeH->reset(); lhshape->reset(); @@ -656,7 +699,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) limd->setEditedState (pedited->retinex.limd ? Edited : UnEdited); highl->setEditedState (pedited->retinex.highl ? Edited : UnEdited); baselog->setEditedState (pedited->retinex.baselog ? Edited : UnEdited); -// grbl->setEditedState (pedited->retinex.grbl ? Edited : UnEdited); + skal->setEditedState (pedited->retinex.skal ? Edited : UnEdited); set_inconsistent (multiImage && !pedited->retinex.enabled); medianmap->set_inconsistent (!pedited->retinex.medianmap); radius->setEditedState (pedited->retinex.radius ? Edited : UnEdited); @@ -689,6 +732,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) cdshape->setUnChanged (!pedited->retinex.cdcurve); cdshapeH->setUnChanged (!pedited->retinex.cdHcurve); transmissionShape->setUnChanged (!pedited->retinex.transmissionCurve); + gaintransmissionShape->setUnChanged (!pedited->retinex.gaintransmissionCurve); lhshape->setUnChanged (!pedited->retinex.lhcurve); mapshape->setUnChanged (!pedited->retinex.mapcurve); @@ -715,7 +759,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) shadows->setValue (pp->retinex.shadows); s_tonalwidth->setValue (pp->retinex.stonalwidth); -// grbl->setValue (pp->retinex.grbl); + skal->setValue (pp->retinex.skal); + if(pp->retinex.iter == 1) { grad->set_sensitive(false); scal->set_sensitive(false); @@ -809,6 +854,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) mapMethodConn.block(false); viewMethodConn.block(false); transmissionShape->setCurve (pp->retinex.transmissionCurve); + gaintransmissionShape->setCurve (pp->retinex.gaintransmissionCurve); enableListener (); @@ -833,12 +879,13 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pp->retinex.limd = (int)limd->getValue (); pp->retinex.highl = (int)highl->getValue (); pp->retinex.baselog = baselog->getValue (); -// pp->retinex.grbl = (int)grbl->getValue (); + pp->retinex.skal = (int)skal->getValue (); pp->retinex.cdcurve = cdshape->getCurve (); pp->retinex.lhcurve = lhshape->getCurve (); pp->retinex.cdHcurve = cdshapeH->getCurve (); pp->retinex.mapcurve = mapshape->getCurve (); pp->retinex.transmissionCurve = transmissionShape->getCurve (); + pp->retinex.gaintransmissionCurve = gaintransmissionShape->getCurve (); pp->retinex.enabled = getEnabled(); pp->retinex.medianmap = medianmap->get_active(); @@ -870,10 +917,11 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pedited->retinex.limd = limd->getEditedState (); pedited->retinex.highl = highl->getEditedState (); pedited->retinex.baselog = baselog->getEditedState (); -// pedited->retinex.grbl = grbl->getEditedState (); + pedited->retinex.skal = skal->getEditedState (); pedited->retinex.cdcurve = !cdshape->isUnChanged (); pedited->retinex.cdHcurve = !cdshapeH->isUnChanged (); pedited->retinex.transmissionCurve = !transmissionShape->isUnChanged (); + pedited->retinex.gaintransmissionCurve = !gaintransmissionShape->isUnChanged (); pedited->retinex.mapcurve = !mapshape->isUnChanged (); pedited->retinex.enabled = !get_inconsistent(); pedited->retinex.medianmap = !medianmap->get_inconsistent(); @@ -1131,7 +1179,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi limd->setDefault (defParams->retinex.limd); highl->setDefault (defParams->retinex.highl); baselog->setDefault (defParams->retinex.baselog); -// grbl->setDefault (defParams->retinex.grbl); + skal->setDefault (defParams->retinex.skal); gam->setDefault (defParams->retinex.gam); slope->setDefault (defParams->retinex.slope); @@ -1154,7 +1202,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited); highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited); baselog->setDefaultEditedState (pedited->retinex.baselog ? Edited : UnEdited); -// grbl->setDefaultEditedState (pedited->retinex.grbl ? Edited : UnEdited); + skal->setDefaultEditedState (pedited->retinex.skal ? Edited : UnEdited); gam->setDefaultEditedState (pedited->retinex.gam ? Edited : UnEdited); slope->setDefaultEditedState (pedited->retinex.slope ? Edited : UnEdited); @@ -1172,7 +1220,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi limd->setDefaultEditedState (Irrelevant); highl->setDefaultEditedState (Irrelevant); baselog->setDefaultEditedState (Irrelevant); -// grbl->setDefaultEditedState (Irrelevant); + skal->setDefaultEditedState (Irrelevant); str->setDefaultEditedState (Irrelevant); scal->setDefaultEditedState (Irrelevant); iter->setDefaultEditedState (Irrelevant); @@ -1245,8 +1293,8 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvLhighl, highl->getTextValue()); } else if (a == baselog) { listener->panelChanged (EvLbaselog, baselog->getTextValue()); -// } else if (a == grbl) { -// listener->panelChanged (EvLgrbl, grbl->getTextValue()); + } else if (a == skal) { + listener->panelChanged (EvLskal, skal->getTextValue()); } else if (a == gam) { listener->panelChanged (EvLgam, gam->getTextValue()); } else if (a == slope) { @@ -1274,6 +1322,7 @@ void Retinex::autoOpenCurve () cdshape->openIfNonlinear(); cdshapeH->openIfNonlinear(); transmissionShape->openIfNonlinear(); + gaintransmissionShape->openIfNonlinear(); lhshape->openIfNonlinear(); mapshape->openIfNonlinear(); @@ -1289,6 +1338,8 @@ void Retinex::curveChanged (CurveEditor* ce) listener->panelChanged (EvLCDHCurve, M("HISTORY_CUSTOMCURVE")); } else if (ce == transmissionShape) { listener->panelChanged (EvRetinextransmission, M("HISTORY_CUSTOMCURVE")); + } else if (ce == gaintransmissionShape) { + listener->panelChanged (EvRetinexgaintransmission, M("HISTORY_CUSTOMCURVE")); } else if (ce == lhshape) { listener->panelChanged (EvRetinexlhcurve, M("HISTORY_CUSTOMCURVE")); } else if (ce == mapshape) { @@ -1410,10 +1461,11 @@ void Retinex::setBatchMode (bool batchMode) shadows->showEditedCB (); s_tonalwidth->showEditedCB (); -// grbl->showEditedCB (); + skal->showEditedCB (); curveEditorGD->setBatchMode (batchMode); curveEditorGDH->setBatchMode (batchMode); transmissionCurveEditorG->setBatchMode (batchMode); + gaintransmissionCurve->setBatchMode (batchMode); curveEditorGH->setBatchMode (batchMode); curveEditormap->setBatchMode (batchMode); diff --git a/rtgui/retinex.h b/rtgui/retinex.h index d24254757..064756a7b 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -35,7 +35,7 @@ protected: Adjuster* limd; Adjuster* highl; Adjuster* baselog; - Adjuster* grbl; + Adjuster* skal; Adjuster* gam; Adjuster* slope; Adjuster* highlights; @@ -76,15 +76,21 @@ protected: Gtk::Label* mMLabels; Gtk::Label* transLabels; Gtk::Label* transLabels2; + Gtk::Frame *gainFrame; + Gtk::Frame *tranFrame; + Gtk::Frame *iterFrame; + Gtk::Frame *equalFrame; DiagonalCurveEditor* cdshape; DiagonalCurveEditor* cdshapeH; DiagonalCurveEditor* mapshape; CurveEditorGroup* transmissionCurveEditorG; + CurveEditorGroup* gaintransmissionCurve; sigc::connection retinexMethodConn, neutralconn, mapMethodConn, viewMethodConn; sigc::connection retinexColorSpaceConn; sigc::connection gammaretinexConn; FlatCurveEditor* transmissionShape; + FlatCurveEditor* gaintransmissionShape; FlatCurveEditor* lhshape; bool lastmedianmap; sigc::connection medianmapConn; diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index ba6c0cbd8..e64c64d8e 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -670,7 +670,7 @@ bool RTWindow::on_delete_event(GdkEventAny* event) Gtk::Widget *w = mainNB->get_nth_page(page); bool optionsWritten = false; - for (std::map::iterator i = epanels.begin(); i != epanels.end(); i++) { + for (std::map::iterator i = epanels.begin(); i != epanels.end(); ++i) { if (i->second == w) { i->second->writeOptions(); optionsWritten = true; diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 09207a883..6af30c68b 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -81,7 +81,7 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI edgesonly->set_active (false); edgebox = new Gtk::VBox (); eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); - etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1800)); usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); usm->pack_start(*edgesonly); edgebox->pack_start(*eradius); diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index 80a961292..796f958e6 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -272,16 +272,16 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) if (pts.size() >= 4) { std::vector::iterator i = pts.begin(); double x = *i; - i++; + ++i; double y = *i; - i++; + ++i; cr->move_to (hb + hwslider + iw * x + 0.5, (yEnd - yStart)*y + yStart); for (; i < pts.end(); ) { x = *i; - i++; + ++i; y = *i; - i++; + ++i; cr->line_to (hb + hwslider + iw * x + 0.5, (yEnd - yStart)*y + yStart); } } else { diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 60f990d6d..ea2bb00dd 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -25,9 +25,8 @@ using namespace std; ThumbBrowserBase::ThumbBrowserBase () - : lastClicked(NULL), previewHeight(options.thumbSize), numOfCols(1), inspector(NULL), isInspectorActive(false) + : lastClicked(NULL), previewHeight(options.thumbSize), numOfCols(1), inspector(NULL), isInspectorActive(false), location(THLOC_FILEBROWSER) { - location = THLOC_FILEBROWSER; inW = -1; inH = -1; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 673c49efe..b9d23e46d 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -499,6 +499,8 @@ void Thumbnail::decreaseRef () void Thumbnail::getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams) { + MyMutex::MyLock lock(mutex); + int tw_ = tw; int th_ = th; float imgRatio_ = imgRatio; @@ -903,7 +905,7 @@ Glib::ustring Thumbnail::getCacheFileName (const Glib::ustring& subdir, const Gl return cachemgr->getCacheFileName (subdir, fname, fext, cfs.md5); } -void Thumbnail::setFileName (const Glib::ustring fn) +void Thumbnail::setFileName (const Glib::ustring &fn) { fname = fn; diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 8656543f0..ca2f898ec 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -146,7 +146,7 @@ public: { return fname; } - void setFileName (const Glib::ustring fn); + void setFileName (const Glib::ustring &fn); bool isSupported (); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 9349fc5f6..65e006361 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -54,6 +54,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), editDataProvider(n colortoning = Gtk::manage (new ColorToning ()); lensgeom = Gtk::manage (new LensGeometry ()); lensProf = Gtk::manage (new LensProfilePanel ()); + lensProf->setLensGeomRef(lensgeom); distortion = Gtk::manage (new Distortion ()); rotate = Gtk::manage (new Rotate ()); vibrance = Gtk::manage (new Vibrance ());