From db32301fa7a43dc737d09ec52fbb702630afcbc5 Mon Sep 17 00:00:00 2001 From: natureh Date: Wed, 11 Jan 2012 01:50:10 +0100 Subject: [PATCH] Solving issue 1196: "Strange blown highlights with control cage tone curve in 32 bit release builds" --- rtengine/curves.cc | 57 ++++++++++++++++++++++++-------------- rtengine/curves.h | 12 +++++--- rtengine/diagonalcurves.cc | 14 +++++----- rtengine/flatcurves.cc | 2 +- 4 files changed, 52 insertions(+), 33 deletions(-) diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 42f0751e2..189b6553c 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -38,15 +38,9 @@ namespace rtengine { x = 0; y = 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 () { if (firstPointIncluded) { @@ -68,29 +62,50 @@ namespace rtengine { poly_x.push_back(x3); poly_y.push_back(y3); } - + void Curve::fillHash() { - hash = new unsigned short int[hashSize+2]; + hash.resize(hashSize+2); unsigned int polyIter = 0; double const increment = 1./hashSize; 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; - hash[i] = polyIter-1; - milestone = (++i)*increment; + hash.at(i).smallerValue = polyIter-1; + ++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 %.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. diff --git a/rtengine/curves.h b/rtengine/curves.h index 2fc0be8a7..af1b11e77 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -205,6 +205,11 @@ class CurveFactory { class Curve { + class HashEntry { + public: + unsigned short smallerValue; + unsigned short higherValue; + }; protected: int N; int ppn; // targeted polyline point number @@ -212,10 +217,10 @@ class Curve { double* y; std::vector poly_x; // X points of the faceted curve std::vector poly_y; // Y points of the faceted curve - unsigned short int* hash; - unsigned int hashSize; // hash table's size, between [10, 100, 1000] + std::vector hash; + unsigned short hashSize; // hash table's size, between [10, 100, 1000] - double* ypp; + double* ypp; // Fields for the elementary curve polygonisation double x1, y1, x2, y2, x3, y3; @@ -233,7 +238,6 @@ class Curve { public: Curve (); - ~Curve (); void AddPolygons (); virtual double getVal (double t) = 0; virtual void getVal (const std::vector& t, std::vector& res) = 0; diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index 1cedcb794..335d5484b 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -30,11 +30,11 @@ namespace rtengine { DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) { - ppn = poly_pn; + ppn = poly_pn > 65500 ? 65500 : poly_pn; bool identity = true; - if (ppn < 500) hashSize = 100; // Arbitrary cut-off value - if (ppn < 50) hashSize = 10; // 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, but mutliple of 10 if (p.size()<3) { kind = DCT_Empty; @@ -210,7 +210,7 @@ void DiagonalCurve::NURBS_set () { } // 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]); } @@ -282,7 +282,7 @@ double DiagonalCurve::getVal (double t) { unsigned short int i = (unsigned short int)(t*hashSize); 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); return t; } @@ -290,8 +290,8 @@ double DiagonalCurve::getVal (double t) { unsigned int k_lo = 0; unsigned int k_hi = 0; - k_lo = hash[i]; - k_hi = hash[i+1]; + k_lo = hash.at(i).smallerValue; + k_hi = hash.at(i).higherValue; // do a binary search for the right interval : while (k_hi - k_lo > 1){ diff --git a/rtengine/flatcurves.cc b/rtengine/flatcurves.cc index d02b9ca17..68ddb6689 100644 --- a/rtengine/flatcurves.cc +++ b/rtengine/flatcurves.cc @@ -31,7 +31,7 @@ namespace rtengine { FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : leftTangent(NULL), rightTangent(NULL) { - ppn = poly_pn; + ppn = poly_pn > 65500 ? 65500 : poly_pn; poly_x.clear(); poly_y.clear();