synced with master (merged master into retinex)
This commit is contained in:
commit
349c6d33a6
@ -37,7 +37,6 @@ namespace rtengine
|
||||
|
||||
SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh)
|
||||
{
|
||||
|
||||
#define HCLIP(x) x //is this still necessary???
|
||||
//min(clip_pt,x)
|
||||
|
||||
@ -1615,10 +1614,10 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw,
|
||||
if(plistener) {
|
||||
progresscounter++;
|
||||
|
||||
if(progresscounter % 4 == 0) {
|
||||
if(progresscounter % 16 == 0) {
|
||||
#pragma omp critical
|
||||
{
|
||||
progress += (double)4 * ((TS - 32) * (TS - 32)) / (height * width);
|
||||
progress += (double)16 * ((TS - 32) * (TS - 32)) / (height * width);
|
||||
|
||||
if (progress > 1.0)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Usage:
|
||||
*
|
||||
* array2D<type> name (X-size,Y-size);
|
||||
* array2D<type> name (X-size,Y-size type ** data);
|
||||
* array2D<type> name (X-size,Y-size,type ** data);
|
||||
*
|
||||
* creates an array which is valid within the normal C/C++ scope "{ ... }"
|
||||
*
|
||||
@ -75,7 +75,7 @@ private:
|
||||
T ** ptr;
|
||||
T * data;
|
||||
bool lock; // useful lock to ensure data is not changed anymore.
|
||||
void ar_realloc(int w, int h)
|
||||
void ar_realloc(int w, int h, int offset = 0)
|
||||
{
|
||||
if ((ptr) && ((h > y) || (4 * h < y))) {
|
||||
delete[] ptr;
|
||||
@ -92,14 +92,14 @@ private:
|
||||
}
|
||||
|
||||
if (data == NULL) {
|
||||
data = new T[h * w];
|
||||
data = new T[h * w + offset];
|
||||
}
|
||||
|
||||
x = w;
|
||||
y = h;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
ptr[i] = data + w * i;
|
||||
ptr[i] = data + offset + w * i;
|
||||
}
|
||||
|
||||
owner = 1;
|
||||
@ -184,6 +184,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
if ((owner) && (data)) {
|
||||
delete[] data;
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
delete [] ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// use with indices
|
||||
T * operator[](int index)
|
||||
{
|
||||
@ -207,7 +220,7 @@ public:
|
||||
|
||||
// useful within init of parent object
|
||||
// or use as resize of 2D array
|
||||
void operator()(int w, int h, unsigned int flgs = 0)
|
||||
void operator()(int w, int h, unsigned int flgs = 0, int offset = 0)
|
||||
{
|
||||
flags = flgs;
|
||||
|
||||
@ -223,10 +236,10 @@ public:
|
||||
|
||||
lock = flags & ARRAY2D_LOCK_DATA;
|
||||
|
||||
ar_realloc(w, h);
|
||||
ar_realloc(w, h, offset);
|
||||
|
||||
if (flags & ARRAY2D_CLEAR_DATA) {
|
||||
memset(data, 0, w * h * sizeof(T));
|
||||
memset(data + offset, 0, w * h * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,10 +311,10 @@ private:
|
||||
array2D<T> list[num];
|
||||
|
||||
public:
|
||||
multi_array2D(int x, int y, int flags = 0)
|
||||
multi_array2D(int x, int y, int flags = 0, int offset = 0)
|
||||
{
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
list[i](x, y, flags);
|
||||
list[i](x, y, flags, (i + 1) * offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,11 +325,7 @@ public:
|
||||
|
||||
array2D<T> & operator[](int index)
|
||||
{
|
||||
if (static_cast<size_t>(index) >= num) {
|
||||
printf("index %0u is out of range[0..%0lu]", index, num - 1);
|
||||
raise( SIGSEGV);
|
||||
}
|
||||
|
||||
assert(static_cast<size_t>(index) < num);
|
||||
return list[index];
|
||||
}
|
||||
};
|
||||
|
@ -814,7 +814,7 @@ const DCPProfile::HSBModify* DCPProfile::MakeHueSatMap(ColorTemp &wb, int prefer
|
||||
return aDeltas;
|
||||
}
|
||||
|
||||
DCPProfile::DCPProfile(Glib::ustring fname, bool isRTProfile)
|
||||
DCPProfile::DCPProfile(Glib::ustring fname)
|
||||
{
|
||||
const int TIFFFloatSize = 4;
|
||||
const int TagColorMatrix1 = 50721, TagColorMatrix2 = 50722, TagProfileHueSatMapDims = 50937;
|
||||
@ -989,7 +989,7 @@ DCPProfile::DCPProfile(Glib::ustring fname, bool isRTProfile)
|
||||
// Read tone curve points, if any, but disable to RTs own profiles
|
||||
tag = tagDir->getTag(TagProfileToneCurve);
|
||||
|
||||
if (tag != NULL && !isRTProfile) {
|
||||
if (tag != NULL) {
|
||||
std::vector<double> cPoints;
|
||||
cPoints.push_back(double(DCT_Spline)); // The first value is the curve type
|
||||
|
||||
@ -1760,7 +1760,7 @@ void DCPStore::init (Glib::ustring rtProfileDir)
|
||||
}
|
||||
}
|
||||
|
||||
DCPProfile* DCPStore::getProfile (Glib::ustring filename, bool isRTProfile)
|
||||
DCPProfile* DCPStore::getProfile (Glib::ustring filename)
|
||||
{
|
||||
MyMutex::MyLock lock(mtx);
|
||||
|
||||
@ -1771,7 +1771,7 @@ DCPProfile* DCPStore::getProfile (Glib::ustring filename, bool isRTProfile)
|
||||
}
|
||||
|
||||
// Add profile
|
||||
profileCache[filename] = new DCPProfile(filename, isRTProfile);
|
||||
profileCache[filename] = new DCPProfile(filename);
|
||||
|
||||
return profileCache[filename];
|
||||
}
|
||||
@ -1783,7 +1783,7 @@ DCPProfile* DCPStore::getStdProfile(Glib::ustring camShortName)
|
||||
// Warning: do NOT use map.find(), since it does not seem to work reliably here
|
||||
for (std::map<Glib::ustring, Glib::ustring>::iterator i = fileStdProfiles.begin(); i != fileStdProfiles.end(); i++)
|
||||
if (name2 == (*i).first) {
|
||||
return getProfile((*i).second, true);
|
||||
return getProfile((*i).second);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -76,7 +76,7 @@ class DCPProfile
|
||||
void HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, float &h, float &s, float &v) const;
|
||||
|
||||
public:
|
||||
DCPProfile(Glib::ustring fname, bool isRTProfile);
|
||||
DCPProfile(Glib::ustring fname);
|
||||
~DCPProfile();
|
||||
|
||||
bool getHasToneCurve()
|
||||
@ -122,7 +122,7 @@ public:
|
||||
|
||||
bool isValidDCPFileName(Glib::ustring filename) const;
|
||||
|
||||
DCPProfile* getProfile(Glib::ustring filename, bool isRTProfile = false);
|
||||
DCPProfile* getProfile(Glib::ustring filename);
|
||||
DCPProfile* getStdProfile(Glib::ustring camShortName);
|
||||
|
||||
static DCPStore* getInstance();
|
||||
|
@ -136,10 +136,10 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 };
|
||||
|
||||
#define SQR(x) rtengine::SQR(x)
|
||||
#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
|
||||
#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 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 CLIP(x) rtengine::CLIP(x)
|
||||
#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- dcraw.c 2015-08-15 15:35:27 +0000
|
||||
+++ dcraw.cc 2015-08-16 13:46:33 +0000
|
||||
--- dcraw.c 2015-09-21 10:08:04 +0000
|
||||
+++ dcraw.cc 2015-10-14 14:29:55 +0000
|
||||
@@ -1,3 +1,15 @@
|
||||
+/*RT*/#include <glib.h>
|
||||
+/*RT*/#include <glib/gstdio.h>
|
||||
@ -148,10 +148,10 @@
|
||||
-#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 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 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 CLIP(x) rtengine::CLIP(x)
|
||||
#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
|
||||
|
||||
|
@ -72,7 +72,11 @@ DiagonalCurve::DiagonalCurve (const std::vector<double>& 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.5f;
|
||||
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) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -226,13 +226,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
||||
}
|
||||
|
||||
imgsrc->demosaic( rp);//enabled demosaic
|
||||
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
|
||||
todo |= M_INIT;
|
||||
|
||||
if (highDetailNeeded) {
|
||||
highDetailRawComputed = true;
|
||||
|
||||
if (params.toneCurve.hrenabled && params.toneCurve.method == "Color") {
|
||||
todo |= M_INIT;
|
||||
}
|
||||
} else {
|
||||
highDetailRawComputed = false;
|
||||
}
|
||||
|
@ -887,8 +887,8 @@ void ColorManagementParams::setDefaults()
|
||||
{
|
||||
input = "(cameraICC)";
|
||||
blendCMSMatrix = false;
|
||||
toneCurve = true;
|
||||
applyLookTable = true;
|
||||
toneCurve = false;
|
||||
applyLookTable = false;
|
||||
applyBaselineExposureOffset = true;
|
||||
applyHueSatMap = true;
|
||||
dcpIlluminant = 0;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "curves.h"
|
||||
#include "dfmanager.h"
|
||||
#include "ffmanager.h"
|
||||
#include "slicer.h"
|
||||
#include "../rtgui/options.h"
|
||||
#include "dcp.h"
|
||||
#include "rt_math.h"
|
||||
@ -554,7 +553,9 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
|
||||
{
|
||||
static const float eps = 1.f;
|
||||
int counter = 0;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
|
||||
#endif
|
||||
|
||||
for( int row = 2; row < H - 2; row++ ) {
|
||||
for(int col = 2; col < W - 2; col++ ) {
|
||||
@ -669,7 +670,9 @@ int RawImageSource::interpolateBadPixelsNColours( PixelsMap &bitmapBads, const i
|
||||
{
|
||||
static const float eps = 1.f;
|
||||
int counter = 0;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
|
||||
#endif
|
||||
|
||||
for( int row = 2; row < H - 2; row++ ) {
|
||||
for(int col = 2; col < W - 2; col++ ) {
|
||||
@ -721,7 +724,7 @@ int RawImageSource::interpolateBadPixelsNColours( PixelsMap &bitmapBads, const i
|
||||
}
|
||||
}
|
||||
|
||||
if (LIKELY(norm[0] > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999%
|
||||
if (LIKELY(norm[0] > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
|
||||
for(int c = 0; c < colours; c++) {
|
||||
rawData[row][col * colours + c] = wtdsum[c] / (2.f * norm[c]); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
|
||||
}
|
||||
@ -763,13 +766,15 @@ int RawImageSource::interpolateBadPixelsNColours( PixelsMap &bitmapBads, const i
|
||||
return counter; // Number of interpolated pixels.
|
||||
}
|
||||
/* interpolateBadPixelsXtrans: correct raw pixels looking at the bitmap
|
||||
* takes into consideration if there are multiple bad pixels in the neighborhood
|
||||
* takes into consideration if there are multiple bad pixels in the neighbourhood
|
||||
*/
|
||||
int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
{
|
||||
static const float eps = 1.f;
|
||||
int counter = 0;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
|
||||
#endif
|
||||
|
||||
for( int row = 2; row < H - 2; row++ ) {
|
||||
for(int col = 2; col < W - 2; col++ ) {
|
||||
@ -791,10 +796,10 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
if(pixelColor == 1) {
|
||||
// green channel. A green pixel can either be a solitary green pixel or a member of a 2x2 square of green pixels
|
||||
if(ri->XTRANSFC(row, col - 1) == ri->XTRANSFC(row, col + 1)) {
|
||||
// If left and right neighbour have same color, then this is a solitary green pixel
|
||||
// For these the following pixels will be used for interpolation. Pixel to be interpolated is in center and marked with a P.
|
||||
// If left and right neighbour have same colour, then this is a solitary green pixel
|
||||
// For these the following pixels will be used for interpolation. Pixel to be interpolated is in centre and marked with a P.
|
||||
// Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad
|
||||
// 0 means, the pixel has a different color and will not be used
|
||||
// 0 means, the pixel has a different colour and will not be used
|
||||
// 0 1 0 2 0
|
||||
// 3 5 0 6 4
|
||||
// 0 0 P 0 0
|
||||
@ -833,12 +838,14 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
// this is a member of a 2x2 square of green pixels
|
||||
// For these the following pixels will be used for interpolation. Pixel to be interpolated is at position P in the example.
|
||||
// Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad
|
||||
// 0 means, the pixel has a different color and will not be used
|
||||
// 0 means, the pixel has a different colour and will not be used
|
||||
// 1 0 0 3
|
||||
// 0 P 2 0
|
||||
// 0 2 1 0
|
||||
// 3 0 0 0
|
||||
int offset1 = ri->XTRANSFC(row - 1, col - 1) == ri->XTRANSFC(row + 1, col + 1) ? 1 : -1; // pixels marked 1 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f
|
||||
|
||||
// pixels marked 1 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f
|
||||
int offset1 = ri->XTRANSFC(row - 1, col - 1) == ri->XTRANSFC(row + 1, col + 1) ? 1 : -1;
|
||||
|
||||
if( !(bitmapBads.get(col - offset1, row - 1) || bitmapBads.get(col + offset1, row + 1))) {
|
||||
float dirwt = 0.70710678f / ( fabsf( rawData[row - 1][col - offset1] - rawData[row + 1][col + offset1]) + eps);
|
||||
@ -846,6 +853,7 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
norm += dirwt;
|
||||
}
|
||||
|
||||
// pixels marked 2 in above example. Distance to P is 1 => weighting is 1.f
|
||||
int offsety = (ri->XTRANSFC(row - 1, col) != 1 ? 1 : -1);
|
||||
int offsetx = offset1 * offsety;
|
||||
|
||||
@ -869,9 +877,9 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
}
|
||||
} else {
|
||||
// red and blue channel.
|
||||
// Each red or blue pixel has exactly one neigbour of same color in distance 2 and four neighbours of same color which can be reached by a move of a knight in chess.
|
||||
// Each red or blue pixel has exactly one neighbour of same colour in distance 2 and four neighbours of same colour which can be reached by a move of a knight in chess.
|
||||
// For the distance 2 pixel (marked with an X) we generate a virtual counterpart (marked with a V)
|
||||
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center and marked with a P.
|
||||
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in centre and marked with a P.
|
||||
// Pairs of pixels used in this step are numbered except for distance 2 pixels which are marked X and V. A pair will be used if none of the pixels of the pair is marked bad
|
||||
// 0 1 0 0 0 0 0 X 0 0 remaining cases are symmetric
|
||||
// 0 0 0 0 2 1 0 0 0 2
|
||||
@ -879,12 +887,12 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
// 0 0 0 0 1 0 0 0 0 0
|
||||
// 0 2 0 0 0 0 2 V 1 0
|
||||
|
||||
// Find two knight moves landing on a pixel of same color as the pixel to be interpolated.
|
||||
// Find two knight moves landing on a pixel of same colour as the pixel to be interpolated.
|
||||
// If we look at first and last row of 5x5 square, we will find exactly two knight pixels.
|
||||
// Additionally we know that the column of this pixel has 1 or -1 horizontal distance to the center pixel
|
||||
// Additionally we know that the column of this pixel has 1 or -1 horizontal distance to the centre pixel
|
||||
// When we find a knight pixel, we get its counterpart, which has distance (+-3,+-3), where the signs of distance depend on the corner of the found knight pixel.
|
||||
// These pixels are marked 1 or 2 in above examples. Distance to P is sqrt(5) => weighting is 0.44721359f
|
||||
// The following loop simply scans the four possible places. To keep things simple, it doesn't stop after finding two knight pixels, because it will not find more than two
|
||||
// The following loop simply scans the four possible places. To keep things simple, it does not stop after finding two knight pixels, because it will not find more than two
|
||||
for(int d1 = -2, offsety = 3; d1 <= 2; d1 += 4, offsety -= 6) {
|
||||
for(int d2 = -1, offsetx = 3; d2 < 1; d2 += 2, offsetx -= 6) {
|
||||
if(ri->XTRANSFC(row + d1, col + d2) == pixelColor) {
|
||||
@ -930,10 +938,8 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
norm += dirwt;
|
||||
}
|
||||
|
||||
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999%
|
||||
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
|
||||
rawData[row][col] = wtdsum / (2.f * norm); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
|
||||
//#pragma omp critical
|
||||
// printf("%s Pixel at (col/row) : (%4d/%4d) : Original : %f, interpolated: %f\n",pixelColor == 0 ? "Red " : pixelColor==1 ? "Green" : "Blue ", col-7,row-7,oldval, rawData[row][col]);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
@ -944,95 +950,122 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads )
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
/* Search for hot or dead pixels in the image and update the map
|
||||
* For each pixel compare its value to the average of similar color surrounding
|
||||
* For each pixel compare its value to the average of similar colour surrounding
|
||||
* (Taken from Emil Martinec idea)
|
||||
* (Optimized by Ingo Weyrich 2013)
|
||||
* (Optimized by Ingo Weyrich 2013 and 2015)
|
||||
*/
|
||||
int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels )
|
||||
SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels )
|
||||
{
|
||||
float varthresh = (20.0 * (thresh / 100.0) + 1.0 );
|
||||
|
||||
// counter for dead or hot pixels
|
||||
int counter = 0;
|
||||
float varthresh = (20.0 * (thresh / 100.0) + 1.0 ) / 24.f;
|
||||
|
||||
// allocate temporary buffer
|
||||
float (*cfablur);
|
||||
cfablur = (float (*)) malloc (H * W * sizeof * cfablur);
|
||||
|
||||
// counter for dead or hot pixels
|
||||
int counter = 0;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
#pragma omp for
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16) nowait
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < H; i++) {
|
||||
int iprev, inext, jprev, jnext;
|
||||
float p[9], temp;
|
||||
for (int i = 2; i < H - 2; i++) {
|
||||
float p[9], temp; // we need this for med3x3 macro
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (j > W - 3) {
|
||||
jnext = j - 2;
|
||||
} else {
|
||||
jnext = j + 2;
|
||||
}
|
||||
|
||||
med3x3(rawData[iprev][jprev], rawData[iprev][j], rawData[iprev][jnext],
|
||||
rawData[i][jprev], rawData[i][j], rawData[i][jnext],
|
||||
rawData[inext][jprev], rawData[inext][j], rawData[inext][jnext], temp);
|
||||
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);
|
||||
cfablur[i * W + j] = rawData[i][j] - temp;
|
||||
}
|
||||
}
|
||||
|
||||
// process borders. Former version calculated the median using mirrored border which does not make sense because the original pixel loses weight
|
||||
// Setting the difference between pixel and median for border pixels to zero should do the job not worse then former version
|
||||
#ifdef _OPENMP
|
||||
#pragma omp single
|
||||
#endif
|
||||
{
|
||||
for(int i = 0; i < 2; i++) {
|
||||
for(int j = 0; j < W; j++) {
|
||||
cfablur[i * W + j] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 2; i < H - 2; i++) {
|
||||
for(int j = 0; j < 2; j++) {
|
||||
cfablur[i * W + j] = 0.f;
|
||||
}
|
||||
|
||||
for(int j = W - 2; j < W; j++) {
|
||||
cfablur[i * W + j] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = H - 2; i < H; i++) {
|
||||
for(int j = 0; j < W; j++) {
|
||||
cfablur[i * W + j] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp barrier // barrier because of nowait clause above
|
||||
|
||||
#pragma omp for reduction(+:counter) schedule(dynamic,16)
|
||||
#endif
|
||||
|
||||
//cfa pixel heat/death evaluation
|
||||
for (int rr = 0; rr < H; rr++) {
|
||||
int top = max(0, rr - 2);
|
||||
int bottom = min(H - 1, rr + 2);
|
||||
int rrmWpcc = rr * W;
|
||||
for (int rr = 2; rr < H - 2; rr++) {
|
||||
int rrmWpcc = rr * W + 2;
|
||||
|
||||
for (int cc = 0; cc < W; cc++, rrmWpcc++) {
|
||||
for (int cc = 2; cc < W - 2; cc++, rrmWpcc++) {
|
||||
//evaluate pixel for heat/death
|
||||
float pixdev = cfablur[rrmWpcc];
|
||||
|
||||
if((!findDeadPixels) && pixdev <= 0) {
|
||||
if(pixdev == 0.f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if((!findHotPixels) && pixdev >= 0) {
|
||||
if((!findDeadPixels) && pixdev < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if((!findHotPixels) && pixdev > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pixdev = fabsf(pixdev);
|
||||
float hfnbrave = -pixdev;
|
||||
int left = max(0, cc - 2);
|
||||
int right = min(W - 1, cc + 2);
|
||||
|
||||
for (int mm = top; mm <= bottom; mm++) {
|
||||
int mmmWpnn = mm * W + left;
|
||||
#ifdef __SSE2__
|
||||
// sum up 5*4 = 20 values using SSE
|
||||
vfloat sum = vabsf(LVFU(cfablur[(rr - 2) * W + cc - 2])) + vabsf(LVFU(cfablur[(rr - 1) * W + cc - 2]));
|
||||
sum += vabsf(LVFU(cfablur[(rr) * W + cc - 2]));
|
||||
sum += vabsf(LVFU(cfablur[(rr + 1) * W + cc - 2]));
|
||||
sum += vabsf(LVFU(cfablur[(rr + 2) * W + cc - 2]));
|
||||
// horizontally add the values and add the result to hfnbrave
|
||||
hfnbrave += vhadd(sum);
|
||||
|
||||
for (int nn = left; nn <= right; nn++, mmmWpnn++) {
|
||||
hfnbrave += fabsf(cfablur[mmmWpnn]);
|
||||
// add remaining 5 values of last column
|
||||
for (int mm = rr - 2; mm <= rr + 2; mm++) {
|
||||
hfnbrave += fabsf(cfablur[mm * W + cc + 2]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (int mm = rr - 2; mm <= rr + 2; mm++) {
|
||||
for (int nn = cc - 2; nn <= cc + 2; nn++) {
|
||||
hfnbrave += fabsf(cfablur[mm * W + nn]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pixdev * ((bottom - top + 1) * (right - left + 1) - 1) > varthresh * hfnbrave) {
|
||||
#endif
|
||||
|
||||
if (pixdev > varthresh * hfnbrave) {
|
||||
// mark the pixel as "bad"
|
||||
bpMap.set(cc, rr);
|
||||
counter++;
|
||||
@ -1543,7 +1576,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
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)
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for reduction(+:totBP)
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < H; i++)
|
||||
for(int j = 0; j < W; j++) {
|
||||
if(ri->data[i][j] == 0.f) {
|
||||
@ -1618,7 +1654,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
if (pLCPProf && idata->getFocalLen() > 0.f) {
|
||||
LCPMapper map(pLCPProf, idata->getFocalLen(), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < H; y++) {
|
||||
for (int x = 0; x < W; x++) {
|
||||
@ -1652,7 +1690,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
int ng1 = 0, ng2 = 0, i = 0;
|
||||
double avgg1 = 0., avgg2 = 0.;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for default(shared) private(i) reduction(+: ng1, ng2, avgg1, avgg2)
|
||||
#endif
|
||||
|
||||
for (i = border; i < H - border; i++)
|
||||
for (int j = border; j < W - border; j++)
|
||||
@ -1669,7 +1709,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
double corrg1 = ((double)avgg1 / ng1 + (double)avgg2 / ng2) / 2.0 / ((double)avgg1 / ng1);
|
||||
double corrg2 = ((double)avgg1 / ng1 + (double)avgg2 / ng2) / 2.0 / ((double)avgg2 / ng2);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for default(shared)
|
||||
#endif
|
||||
|
||||
for (int i = border; i < H - border; i++)
|
||||
for (int j = border; j < W - border; j++)
|
||||
@ -2461,10 +2503,14 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
float maxval = 0.f;
|
||||
int c = FC(m, n);
|
||||
int c4 = ( c == 1 && !(m & 1) ) ? 3 : c;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float maxvalthr = 0.f;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H - m; row += 2) {
|
||||
for (int col = 0; col < W - n; col += 2) {
|
||||
@ -2476,7 +2522,9 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
|
||||
if(maxvalthr > maxval) {
|
||||
@ -2506,11 +2554,15 @@ 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
|
||||
#endif
|
||||
{
|
||||
int c = FC(m, n);
|
||||
int c4 = ( c == 1 && !(m & 1) ) ? 3 : c;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H - m; row += 2)
|
||||
{
|
||||
@ -2546,10 +2598,14 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
int clipControlGui = 0;
|
||||
float maxval = 0.f;
|
||||
// xtrans files have only one black level actually, so we can simplify the code a bit
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float maxvalthr = 0.f;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16) nowait
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
@ -2561,7 +2617,9 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
if(maxvalthr > maxval) {
|
||||
maxval = maxvalthr;
|
||||
@ -2583,7 +2641,9 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
refcolor[c] *= limitFactor;
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
@ -2606,7 +2666,9 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
if(ri->getSensorType() == ST_BAYER) {
|
||||
for (int m = 0; m < 2; m++)
|
||||
for (int n = 0; n < 2; n++) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H - m; row += 2) {
|
||||
int c = FC(row, 0);
|
||||
@ -2620,7 +2682,9 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
|
||||
}
|
||||
}
|
||||
} else if(ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
@ -2729,9 +2793,13 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur
|
||||
cfatmp = (float (*)) calloc (H * W, sizeof * cfatmp);
|
||||
// const float hotdeadthresh = 0.5;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < H; i++) {
|
||||
int iprev, inext, jprev, jnext;
|
||||
@ -2780,7 +2848,9 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur
|
||||
|
||||
//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;
|
||||
@ -2819,7 +2889,9 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur
|
||||
__m128 onev = _mm_set1_ps( 1.0f );
|
||||
__m128 temp1v, temp2v, lenv, lenp1v, lenm1v;
|
||||
int row;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for
|
||||
#endif
|
||||
|
||||
for (int col = 0; col < W - 3; col += 4) {
|
||||
lenv = leninitv;
|
||||
@ -2908,7 +2980,9 @@ SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for
|
||||
#endif
|
||||
|
||||
for (int col = 0; col < W; col++) {
|
||||
int len = boxH / 2 + 1;
|
||||
@ -2990,12 +3064,15 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
// scale image colors
|
||||
|
||||
if( ri->getSensorType() == ST_BAYER) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float tmpchmax[3];
|
||||
tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for (int row = winy; row < winy + winh; row ++)
|
||||
{
|
||||
@ -3010,7 +3087,9 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
chmax[0] = max(tmpchmax[0], chmax[0]);
|
||||
chmax[1] = max(tmpchmax[1], chmax[1]);
|
||||
@ -3018,11 +3097,14 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
} else if ( ri->get_colors() == 1 ) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float tmpchmax = 0.0f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for (int row = winy; row < winy + winh; row ++)
|
||||
{
|
||||
@ -3035,18 +3117,23 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
chmax[0] = chmax[1] = chmax[2] = chmax[3] = max(tmpchmax, chmax[0]);
|
||||
}
|
||||
}
|
||||
} else if(ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float tmpchmax[3];
|
||||
tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for (int row = winy; row < winy + winh; row ++)
|
||||
{
|
||||
@ -3061,7 +3148,9 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
chmax[0] = max(tmpchmax[0], chmax[0]);
|
||||
chmax[1] = max(tmpchmax[1], chmax[1]);
|
||||
@ -3069,12 +3158,15 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
float tmpchmax[3];
|
||||
tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for (int row = winy; row < winy + winh; row ++)
|
||||
{
|
||||
@ -3089,7 +3181,9 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
chmax[0] = max(tmpchmax[0], chmax[0]);
|
||||
chmax[1] = max(tmpchmax[1], chmax[1]);
|
||||
@ -3402,8 +3496,9 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
|
||||
mat[i][j] += work[i][k] * camMatrix[k][j]; // rgb_xyz * imatrices.xyz_cam
|
||||
}
|
||||
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < im->height; i++)
|
||||
for (int j = 0; j < im->width; j++) {
|
||||
@ -3726,91 +3821,6 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
|
||||
// printf ("ICM TIME: %d usec\n", t3.etime(t1));
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
// Converts raw image including ICC input profile to working space - 16bit int version
|
||||
/*void RawImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], std::string camName) {
|
||||
cmsHPROFILE in;
|
||||
DCPProfile *dcpProf;
|
||||
|
||||
if (!findInputProfile(cmp.input, embedded, camName, &dcpProf, in)) return;
|
||||
|
||||
if (dcpProf!=NULL) {
|
||||
dcpProf->Apply(im, (DCPLightType)cmp.preferredProfile, cmp.working, cmp.toneCurve);
|
||||
} else {
|
||||
if (in==NULL) {
|
||||
// Take camprofile from DCRAW
|
||||
// in this case we avoid using the slllllooooooowwww lcms
|
||||
TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working);
|
||||
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] += work[i][k] * camMatrix[k][j]; // rgb_xyz * imatrices.xyz_cam
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int i=0; i<im->height; i++)
|
||||
for (int j=0; j<im->width; j++) {
|
||||
|
||||
float newr = mat[0][0]*im->r(i,j) + mat[0][1]*im->g(i,j) + mat[0][2]*im->b(i,j);
|
||||
float newg = mat[1][0]*im->r(i,j) + mat[1][1]*im->g(i,j) + mat[1][2]*im->b(i,j);
|
||||
float newb = mat[2][0]*im->r(i,j) + mat[2][1]*im->g(i,j) + mat[2][2]*im->b(i,j);
|
||||
|
||||
im->r(i,j) = CLIP((int)newr);
|
||||
im->g(i,j) = CLIP((int)newg);
|
||||
im->b(i,j) = CLIP((int)newb);
|
||||
}
|
||||
} else {
|
||||
// Gamma preprocessing
|
||||
float gammaFac, lineFac, lineSum;
|
||||
getProfilePreprocParams(in, gammaFac, lineFac, lineSum);
|
||||
|
||||
if (gammaFac>0) {
|
||||
#pragma omp parallel for
|
||||
for ( int h = 0; h < im->height; ++h )
|
||||
for ( int w = 0; w < im->width; ++w ) {
|
||||
im->r(h,w)= (int) (pow ((double)(im->r(h,w) / 65535.0), (double)gammaFac) * 65535.0);
|
||||
im->g(h,w)= (int) (pow ((double)(im->g(h,w) / 65535.0), (double)gammaFac) * 65535.0);
|
||||
im->b(h,w)= (int) (pow ((double)(im->b(h,w) / 65535.0), (double)gammaFac) * 65535.0);
|
||||
}
|
||||
}
|
||||
|
||||
cmsHPROFILE out = iccStore->workingSpace (cmp.working);
|
||||
//out = iccStore->workingSpaceGamma (wProfile);
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16, out, TYPE_RGB_16, settings->colorimetricIntent,
|
||||
cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
if (hTransform) {
|
||||
im->ExecCMSTransform(hTransform);
|
||||
|
||||
// There might be Nikon postprocessings
|
||||
if (lineSum>0) {
|
||||
#pragma omp parallel for
|
||||
for ( int h = 0; h < im->height; ++h )
|
||||
for ( int w = 0; w < im->width; ++w ) {
|
||||
im->r(h,w) *= im->r(h,w) * lineFac / 65535.0 + lineSum;
|
||||
im->g(h,w) *= im->g(h,w) * lineFac / 65535.0 + lineSum;
|
||||
im->b(h,w) *= im->b(h,w) * lineFac / 65535.0 + lineSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
lcmsMutex->lock ();
|
||||
hTransform = cmsCreateTransform (camprofile, TYPE_RGB_16, out, TYPE_RGB_16,
|
||||
settings->colorimetricIntent, cmsFLAGS_NOCACHE);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
im->ExecCMSTransform(hTransform);
|
||||
}
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
}
|
||||
}
|
||||
//t3.set ();
|
||||
//printf ("ICM TIME: %d\n", t3.etime(t1));
|
||||
}*/
|
||||
|
||||
// Determine RAW input and output profiles. Returns TRUE on success
|
||||
bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in)
|
||||
@ -4109,11 +4119,15 @@ void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr)
|
||||
histogram(65536 >> histcompr);
|
||||
histogram.clear();
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
LUTu tmphistogram(65536 >> histcompr);
|
||||
tmphistogram.clear();
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for (int i = border; i < H - border; i++) {
|
||||
int start, end;
|
||||
@ -4152,7 +4166,9 @@ void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
#endif
|
||||
{
|
||||
for(int i = 0; i < (65536 >> histcompr); i++) {
|
||||
histogram[i] += tmphistogram[i];
|
||||
|
@ -228,8 +228,8 @@ public:
|
||||
}
|
||||
static void inverse33 (const double (*coeff)[3], double (*icoeff)[3]);
|
||||
|
||||
void boxblur2(float** src, float** dst, int H, int W, int box );
|
||||
void boxblur_resamp(float **src, float **dst, int H, int W, int box, int samp );
|
||||
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, 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(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve);
|
||||
|
||||
|
@ -1322,5 +1322,11 @@ static inline void vswap( vmask condition, vfloat &a, vfloat &b) {
|
||||
b = temp;
|
||||
}
|
||||
|
||||
static inline float vhadd( vfloat a )
|
||||
{
|
||||
a += _mm_movehl_ps(a, a);
|
||||
return _mm_cvtss_f32(_mm_add_ss(a, _mm_shuffle_ps(a, a, 1)));
|
||||
}
|
||||
|
||||
#endif // __SSE2__
|
||||
#endif // SLEEFSSEAVX
|
||||
|
@ -92,7 +92,6 @@ public:
|
||||
|
||||
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);
|
||||
//static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded);
|
||||
|
||||
static inline double intpow (double a, int b)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "adjuster.h"
|
||||
#include <sigc++/class_slot.h>
|
||||
#include <sigc++/slot.h>
|
||||
#include <cmath>
|
||||
#include "multilangmgr.h"
|
||||
#include "../rtengine/rtengine.h"
|
||||
|
@ -30,7 +30,7 @@ using namespace rtengine::procparams;
|
||||
|
||||
extern Options options;
|
||||
|
||||
ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(NULL), icmplistener(NULL), lastRefFilename("")
|
||||
ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(NULL), icmplistener(NULL), lastRefFilename(""), camName("")
|
||||
{
|
||||
|
||||
isBatchMode = lastToneCurve = lastApplyLookTable = lastApplyBaselineExposureOffset = lastApplyHueSatMap = lastBlendCMSMatrix = lastgamfree = false;
|
||||
@ -348,8 +348,13 @@ void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name)
|
||||
dcpIll->set_sensitive (false);
|
||||
dcpFrame->set_sensitive(false);
|
||||
|
||||
if (ifromfile->get_active() && dcpStore->isValidDCPFileName(dcp_name)) {
|
||||
DCPProfile* dcp = dcpStore->getProfile(dcp_name, false);
|
||||
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);
|
||||
}
|
||||
|
||||
if (dcp) {
|
||||
dcpFrame->set_sensitive(true);
|
||||
@ -416,7 +421,6 @@ void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dcpIllLabel->get_sensitive() && dcpIll->get_active_row_number() != 0) {
|
||||
if (dcpTemperatures[0] != 0 || dcpTemperatures[1] != 0) {
|
||||
@ -467,7 +471,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
} else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||
icameraICC->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (true);
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() != Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
|
||||
// this is the case when (cameraICC) is instructed by packaged profiles, but ICC file is not found
|
||||
// therefore falling back UI to explicitly reflect the (camera) option
|
||||
@ -478,7 +482,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
// If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded).
|
||||
iembedded->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||
} else if ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||
icamera->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
@ -603,8 +607,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
|
||||
|
||||
pp->icm.freegamma = freegamma->get_active();
|
||||
|
||||
DCPProfile* dcp = NULL;
|
||||
|
||||
if (ifromfile->get_active() && pp->icm.input.substr(0, 5) == "file:" && dcpStore->isValidDCPFileName(pp->icm.input.substr(5))) {
|
||||
DCPProfile* dcp = dcpStore->getProfile(pp->icm.input.substr(5), false);
|
||||
dcp = dcpStore->getProfile(pp->icm.input.substr(5));
|
||||
} else if(icameraICC->get_active()) {
|
||||
dcp = dcpStore->getStdProfile(camName);
|
||||
}
|
||||
|
||||
if (dcp) {
|
||||
if (dcp->getHasToneCurve()) {
|
||||
@ -623,7 +632,6 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
|
||||
pp->icm.applyHueSatMap = ckbApplyHueSatMap->get_active ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active ();
|
||||
pp->icm.gampos = (double) gampos->getValue();
|
||||
@ -880,6 +888,7 @@ void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta)
|
||||
icamera->set_active (raw);
|
||||
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));
|
||||
iembedded->set_sensitive (!raw);
|
||||
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
double dcpTemperatures[2];
|
||||
bool enableLastICCWorkDirChange;
|
||||
Glib::ustring lastRefFilename;
|
||||
Glib::ustring camName;
|
||||
void updateDCP(int dcpIlluminant, Glib::ustring dcp_name);
|
||||
public:
|
||||
ICMPanel ();
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <sigc++/class_slot.h>
|
||||
#include <sigc++/slot.h>
|
||||
#include "preferences.h"
|
||||
#include "multilangmgr.h"
|
||||
#include "splash.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "thresholdadjuster.h"
|
||||
#include <sigc++/class_slot.h>
|
||||
#include <sigc++/slot.h>
|
||||
#include <cmath>
|
||||
#include "multilangmgr.h"
|
||||
#include "../rtengine/rtengine.h"
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
#include "tonecurve.h"
|
||||
#include "adjuster.h"
|
||||
#include <sigc++/class_slot.h>
|
||||
#include <sigc++/slot.h>
|
||||
#include <iomanip>
|
||||
#include "ppversion.h"
|
||||
#include "edit.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user