Solving issue 1196: "Strange blown highlights with control cage tone curve in 32 bit release builds"
This commit is contained in:
@@ -38,13 +38,7 @@ namespace rtengine {
|
|||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
ypp = 0;
|
ypp = 0;
|
||||||
hash = NULL;
|
hashSize = 1000; // has to be initiallised to the maximum value
|
||||||
hashSize = 1000; // has to be initiallised to the maximum value
|
|
||||||
}
|
|
||||||
|
|
||||||
Curve::~Curve () {
|
|
||||||
if (hash)
|
|
||||||
delete [] hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curve::AddPolygons ()
|
void Curve::AddPolygons ()
|
||||||
@@ -70,27 +64,48 @@ namespace rtengine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Curve::fillHash() {
|
void Curve::fillHash() {
|
||||||
hash = new unsigned short int[hashSize+2];
|
hash.resize(hashSize+2);
|
||||||
|
|
||||||
unsigned int polyIter = 0;
|
unsigned int polyIter = 0;
|
||||||
double const increment = 1./hashSize;
|
double const increment = 1./hashSize;
|
||||||
double milestone = 0.;
|
double milestone = 0.;
|
||||||
|
|
||||||
for (unsigned int i=0; i<(hashSize+1);) {
|
for (unsigned short i=0; i<(hashSize+1);) {
|
||||||
while(poly_x[polyIter] <= milestone) ++polyIter;
|
while(poly_x[polyIter] <= milestone) ++polyIter;
|
||||||
hash[i] = polyIter-1;
|
hash.at(i).smallerValue = polyIter-1;
|
||||||
milestone = (++i)*increment;
|
++i;
|
||||||
|
milestone = i*increment;
|
||||||
}
|
}
|
||||||
hash[hashSize+1] = poly_x.size()-1;
|
milestone = 0.;
|
||||||
|
polyIter = 0;
|
||||||
|
for (unsigned int i=0; i<(hashSize+1);) {
|
||||||
|
while(poly_x[polyIter] < (milestone+increment)) ++polyIter;
|
||||||
|
hash.at(i).higherValue = polyIter;
|
||||||
|
++i;
|
||||||
|
milestone = i*increment;
|
||||||
|
}
|
||||||
|
hash.at(hashSize+1).smallerValue = poly_x.size()-1;
|
||||||
|
hash.at(hashSize+1).higherValue = poly_x.size();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncoment the code below to dump the polygon points and the hash table in files
|
||||||
|
if (poly_x.size() > 500) {
|
||||||
|
printf("Files generated (%d points)\n", poly_x.size());
|
||||||
|
FILE* f = fopen ("hash.txt", "wt");
|
||||||
|
for (unsigned int i=0; i<hashSize;i++) {
|
||||||
|
unsigned short s = hash.at(i).smallerValue;
|
||||||
|
unsigned short h = hash.at(i).higherValue;
|
||||||
|
fprintf (f, "%d: %d<%d (%.5f<%.5f)\n", i, s, h, poly_x[s], poly_x[h]);
|
||||||
|
}
|
||||||
|
fclose (f);
|
||||||
|
f = fopen ("poly_x.txt", "wt");
|
||||||
|
for (unsigned int i=0; i<poly_x.size();i++) {
|
||||||
|
fprintf (f, "%d: %.5f, %.5f\n", i, poly_x[i], poly_y[i]);
|
||||||
|
}
|
||||||
|
fclose (f);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
// Debug output to file
|
|
||||||
FILE* f = fopen ("hash.txt", "wt");
|
|
||||||
for (int i=0; i<(hashSize+2); i++)
|
|
||||||
fprintf (f, "%d: %d > %.6f, %.6f\n", i, hash[i], poly_x[hash[i]], poly_y[hash[i]]);
|
|
||||||
fprintf (f, "\nppn: %d\npoly_x: %d\n", ppn, poly_x.size());
|
|
||||||
fclose (f);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value.
|
// Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value.
|
||||||
|
@@ -205,6 +205,11 @@ class CurveFactory {
|
|||||||
|
|
||||||
class Curve {
|
class Curve {
|
||||||
|
|
||||||
|
class HashEntry {
|
||||||
|
public:
|
||||||
|
unsigned short smallerValue;
|
||||||
|
unsigned short higherValue;
|
||||||
|
};
|
||||||
protected:
|
protected:
|
||||||
int N;
|
int N;
|
||||||
int ppn; // targeted polyline point number
|
int ppn; // targeted polyline point number
|
||||||
@@ -212,10 +217,10 @@ class Curve {
|
|||||||
double* y;
|
double* y;
|
||||||
std::vector<double> poly_x; // X points of the faceted curve
|
std::vector<double> poly_x; // X points of the faceted curve
|
||||||
std::vector<double> poly_y; // Y points of the faceted curve
|
std::vector<double> poly_y; // Y points of the faceted curve
|
||||||
unsigned short int* hash;
|
std::vector<HashEntry> hash;
|
||||||
unsigned int hashSize; // hash table's size, between [10, 100, 1000]
|
unsigned short hashSize; // hash table's size, between [10, 100, 1000]
|
||||||
|
|
||||||
double* ypp;
|
double* ypp;
|
||||||
|
|
||||||
// Fields for the elementary curve polygonisation
|
// Fields for the elementary curve polygonisation
|
||||||
double x1, y1, x2, y2, x3, y3;
|
double x1, y1, x2, y2, x3, y3;
|
||||||
@@ -233,7 +238,6 @@ class Curve {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Curve ();
|
Curve ();
|
||||||
~Curve ();
|
|
||||||
void AddPolygons ();
|
void AddPolygons ();
|
||||||
virtual double getVal (double t) = 0;
|
virtual double getVal (double t) = 0;
|
||||||
virtual void getVal (const std::vector<double>& t, std::vector<double>& res) = 0;
|
virtual void getVal (const std::vector<double>& t, std::vector<double>& res) = 0;
|
||||||
|
@@ -30,11 +30,11 @@ namespace rtengine {
|
|||||||
|
|
||||||
DiagonalCurve::DiagonalCurve (const std::vector<double>& p, int poly_pn) {
|
DiagonalCurve::DiagonalCurve (const std::vector<double>& p, int poly_pn) {
|
||||||
|
|
||||||
ppn = poly_pn;
|
ppn = poly_pn > 65500 ? 65500 : poly_pn;
|
||||||
bool identity = true;
|
bool identity = true;
|
||||||
|
|
||||||
if (ppn < 500) hashSize = 100; // Arbitrary cut-off value
|
if (ppn < 500) hashSize = 100; // Arbitrary cut-off value, but mutliple of 10
|
||||||
if (ppn < 50) hashSize = 10; // Arbitrary cut-off value
|
if (ppn < 50) hashSize = 10; // Arbitrary cut-off value, but mutliple of 10
|
||||||
|
|
||||||
if (p.size()<3) {
|
if (p.size()<3) {
|
||||||
kind = DCT_Empty;
|
kind = DCT_Empty;
|
||||||
@@ -210,7 +210,7 @@ void DiagonalCurve::NURBS_set () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// adding the final horizontal segment, always (see under)
|
// adding the final horizontal segment, always (see under)
|
||||||
poly_x.push_back(1.1); // 1.1 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range)
|
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]);
|
poly_y.push_back(y[N-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ double DiagonalCurve::getVal (double t) {
|
|||||||
unsigned short int i = (unsigned short int)(t*hashSize);
|
unsigned short int i = (unsigned short int)(t*hashSize);
|
||||||
|
|
||||||
if (i > (hashSize+1)) {
|
if (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[i], poly_x.size(), poly_x[hash[i]]);
|
//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);
|
printf("\nOVERFLOW: hash #%d is used while seeking for value %.8f\n\n", i, t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@@ -290,8 +290,8 @@ double DiagonalCurve::getVal (double t) {
|
|||||||
unsigned int k_lo = 0;
|
unsigned int k_lo = 0;
|
||||||
unsigned int k_hi = 0;
|
unsigned int k_hi = 0;
|
||||||
|
|
||||||
k_lo = hash[i];
|
k_lo = hash.at(i).smallerValue;
|
||||||
k_hi = hash[i+1];
|
k_hi = hash.at(i).higherValue;
|
||||||
|
|
||||||
// do a binary search for the right interval :
|
// do a binary search for the right interval :
|
||||||
while (k_hi - k_lo > 1){
|
while (k_hi - k_lo > 1){
|
||||||
|
@@ -31,7 +31,7 @@ namespace rtengine {
|
|||||||
|
|
||||||
FlatCurve::FlatCurve (const std::vector<double>& p, bool isPeriodic, int poly_pn) : leftTangent(NULL), rightTangent(NULL) {
|
FlatCurve::FlatCurve (const std::vector<double>& p, bool isPeriodic, int poly_pn) : leftTangent(NULL), rightTangent(NULL) {
|
||||||
|
|
||||||
ppn = poly_pn;
|
ppn = poly_pn > 65500 ? 65500 : poly_pn;
|
||||||
poly_x.clear();
|
poly_x.clear();
|
||||||
poly_y.clear();
|
poly_y.clear();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user