/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #ifndef __CURVES_H__ #define __CURVES_H__ #include #include #include #include namespace rtengine { class Curve { protected: int N; double* x; double* y; double* ypp; Glib::ustring name; bool islinear; bool isempty; protected: void d3_np_fs (double a[], double b[]); void spline_cubic_set (); public: Curve (const char* iname, int iN, double ix[], double iy[]); Curve (const char* iname, const char* descr); Curve (const std::vector& points); ~Curve (); double getVal (double x); Glib::ustring getName (); bool isEmpty () { return isempty; } }; class CurveFactory { protected: static std::map curves; static int gammatab[65536]; static int igammatab_srgb[65536]; static int gammatab_srgb[65536]; static double solve_upper (double m, double c, double deriv); static double solve_lower (double m, double c, double deriv); static double dupper (const double b, const double m, const double c); static double dlower (const double b, const double m, const double c); static inline double basel (double x, double m1, double m2) { if (x==0.0) return 0.0; double k = sqrt ((m1-1.0)*(m1-m2)/2) / (1.0-m2); double l = (m1-m2) / (1.0-m2) + k; double lx = log(x); return m2*x + (1.0-m2)*(2.0 - exp(k*lx))*exp(l*lx); } static inline double baseu (double x, double m1, double m2) { return 1.0 - basel(1.0-x, m1, m2); } static inline double cupper (double x, double m, double hr) { if (hr>1.0) return baseu (x, m, 2.0*(hr-1.0)/m); double x1 = (1.0-hr)/m; double x2 = x1 + hr; if (x>=x2) return 1.0; if (x0) return brightnessbase (x, amount); else return 1.0 - brightnessbase (1.0-x, -amount); } public: static inline double softClip (double x, double d1, double d2, double a, double b, double c, double d); static inline double contrast (double x, double a); static inline double centercontrast (double x, double b, double m); static inline double brightness (double x, double a, double bd1, double bd2); static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){ return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add); } static inline double gamma2 (double x) { return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/2.4)-0.055; } static inline int gamma_srgb (int x) { return gammatab_srgb[x]; } static inline int gamma (int x) { return gammatab[x]; } static inline int igamma_srgb (int x) { return igammatab_srgb[x]; } static inline double igamma2 (double x) { return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*2.4); } static inline double levels (double x, double b_lower, double b_upper, double m, double cmax); public: static void loadCurves (Glib::ustring fname); static void updateCurve2 (int* curve, int* ohistogram, const std::vector& cpoints, double ecomp, double br, int black, double hlcompr, double shcompr, double contr, double gamma_, bool igamma, int skip=1); static void updateCurve3 (int* curve, int* ohistogram, const std::vector& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1); static std::vector curveNames (); }; }; #endif