diff options
| -rw-r--r-- | src/CurveEditor.cxx | 14 | ||||
| -rw-r--r-- | src/pnmlcms.c | 78 |
2 files changed, 85 insertions, 7 deletions
diff --git a/src/CurveEditor.cxx b/src/CurveEditor.cxx index ad73758..8ff8671 100644 --- a/src/CurveEditor.cxx +++ b/src/CurveEditor.cxx @@ -43,7 +43,7 @@ CurveEditor::draw() { for (double _x = 0.0; _x < 1.0; _x = _x + 0.01) { double _y = gsl_spline_eval(spline, _x, acc); - fl_vertex(x() + _x * w(), y() + h() * _y); + fl_vertex(x() + _x * w(), y() + h() - h() * _y); } fl_end_line(); @@ -53,7 +53,7 @@ CurveEditor::draw() { } else { fl_color(FL_WHITE); } - fl_rect(x() + w() * X[i] - 2, y() + h() * Y[i] - 2, 4, 4); + fl_rect(x() + w() * X[i] - 2, y() + h() - h() * Y[i] - 2, 4, 4); } } @@ -69,7 +69,7 @@ CurveEditor::handle(int event) { if (Fl::event_button() == 1) { for (int i = 0; i < n; i++) { int x_i = (int) rint(X[i] * w()); - int y_i = (int) rint(Y[i] * h()); + int y_i = (int) rint(h() - Y[i] * h()); if (mark_x >= x_i - 2 && mark_x <= x_i + 2 && mark_y >= y_i - 2 && mark_y <= y_i + 2) { @@ -83,7 +83,7 @@ CurveEditor::handle(int event) { return 1; break; case FL_DRAG: - set(marked_point, (double) mark_x / w(), (double) mark_y / h()); + set(marked_point, (double) mark_x / w(), 1.0 - (double) mark_y / h()); return 1; break; @@ -113,5 +113,11 @@ CurveEditor::set(int i, double _x, double _y) { X[i] = _x; Y[i] = _y; gsl_spline_init (spline, X, Y, n); + + printf("%4f,%4f", X[0], Y[0]); + for (int i = 1; i < n; i++) { + printf(";%4f,%4f", X[i], Y[i]); + } + printf("\n"); redraw(); } diff --git a/src/pnmlcms.c b/src/pnmlcms.c index 0a8fdac..800af08 100644 --- a/src/pnmlcms.c +++ b/src/pnmlcms.c @@ -1,4 +1,5 @@ #include <lcms.h> +#include <gsl/gsl_spline.h> #include "pnm.h" @@ -6,10 +7,14 @@ static int pam_transform(FILE *in_fp, FILE *out_fp, const struct pnm *in_pnm, cmsHTRANSFORM *hTransform); +static LPGAMMATABLE +buildGammaCurve(const char *ctrl_points, int resolution); + int main(int argc, char **argv) { int c, i, nProf = 0; char *in_prof = NULL, *out_prof = NULL; + char *curve = NULL; double gamma = 0.0, bright = 0.0, contrast = 1.0, hue = 0.0; double saturation = 0.0; int tempSrc = 5000, tempDst = 5000; @@ -18,7 +23,7 @@ main(int argc, char **argv) { DWORD type; struct pnm in_pnm; - while ((c = getopt(argc, argv, "i:o:g:b:c:h:s:S:D:")) != EOF) { + while ((c = getopt(argc, argv, "i:o:g:b:c:h:s:S:D:C:")) != EOF) { switch (c) { case 'i': in_prof = optarg; @@ -46,18 +51,21 @@ main(int argc, char **argv) { break; case 'D': tempDst = atoi(optarg); + case 'C': + curve = optarg; break; default: break; } } - +#if 0 if (in_prof) { profiles[nProf++] = cmsOpenProfileFromFile(in_prof, "r"); } else { profiles[nProf++] = cmsCreate_sRGBProfile(); } +#endif if (gamma) { LPGAMMATABLE gTable[3]; @@ -70,8 +78,19 @@ main(int argc, char **argv) { gTable); } + if (curve) { + LPGAMMATABLE gTable[3]; + + gTable[0] = gTable[1] = gTable[2] = buildGammaCurve(curve, 256); + + profiles[nProf++] = cmsCreateLinearizationDeviceLink( + icSigLabData, + gTable); + } + +#if 0 profiles[nProf++] = cmsCreateBCHSWabstractProfile( - 10, + 5, bright, contrast, hue, @@ -84,6 +103,7 @@ main(int argc, char **argv) { } else { profiles[nProf++] = cmsCreate_sRGBProfile(); } +#endif if (readPnmHeader(stdin, &in_pnm) != 0) { exit(1); @@ -139,3 +159,55 @@ pam_transform(FILE *in_fp, FILE *out_fp, return 0; } +#define MAX_CTRL 256 + +static LPGAMMATABLE +buildGammaCurve(const char *ctrl_points, int resolution) { + LPGAMMATABLE table; + char *pstr, *buf = strdup(ctrl_points); + int i, n = 0; + double X[MAX_CTRL], Y[MAX_CTRL]; + gsl_interp_accel *acc; + gsl_spline *spline; + + while (pstr = strsep(&buf, ";")) { + if (n == MAX_CTRL) { + fprintf(stderr, "Maximum number of control points (%d) reached.\n", + MAX_CTRL); + break; + } + + if (sscanf(pstr, "%lf,%lf", &X[n], &Y[n]) != 2 || + X[n] < 0.0 || X[n] > 1.0 || Y[n] < 0.0 || Y[n] > 1.0) { + fprintf(stderr, "Could not parse control point %s.\n", pstr); + free(buf); + return NULL; + } + + n++; + } + + free(buf); + + table = (LPGAMMATABLE) calloc(resolution, sizeof(GAMMATABLE)); + table->nEntries = resolution; + + acc = gsl_interp_accel_alloc(); + spline = gsl_spline_alloc(gsl_interp_cspline, n); + gsl_spline_init (spline, X, Y, n); + + for (i = 0; i < resolution; i++) { + double _x = (double) i / (resolution - 1); + double _y = gsl_spline_eval(spline, _x, acc); + double dval = _y * 65535.0 + .5; + if (dval > 65535.) dval = 65535.0; + if (dval < 0) dval = 0; + + table->GammaTable[i] = (WORD) floor(dval); + } + + gsl_spline_free(spline); + gsl_interp_accel_free(acc); + + return table; +} |
