diff options
| -rw-r--r-- | configure.ac | 21 | ||||
| -rw-r--r-- | src/CurveEditor.H | 32 | ||||
| -rw-r--r-- | src/CurveEditor.cxx | 128 | ||||
| -rw-r--r-- | src/Makefile.am | 10 | ||||
| -rw-r--r-- | src/flcurve.cxx | 89 | ||||
| -rw-r--r-- | src/pnmcurve.c | 168 | ||||
| -rw-r--r-- | src/pnmlcms.c | 229 |
7 files changed, 174 insertions, 503 deletions
diff --git a/configure.ac b/configure.ac index a478539..3a38988 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,9 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(pnmlcms, 0.0.1, Johannes.Hofmann@gmx.de) +AC_INIT(pnmcurve, 0.0.1, Johannes.Hofmann@gmx.de) AM_INIT_AUTOMAKE -AC_CONFIG_SRCDIR([src/pnmlcms.c]) +AC_CONFIG_SRCDIR([src/pnmcurve.c]) AC_CONFIG_HEADER(config.h) CPPFLAGS="-g $CPPFLAGS" @@ -15,7 +15,6 @@ LDFLAGS="-g $LDFLAGS" AC_PROG_CC AC_LANG_C -AC_LANG_CPLUSPLUS # Checks for libraries. @@ -37,16 +36,6 @@ AC_FUNC_REALLOC AC_TYPE_SIGNAL AC_CHECK_FUNCS([strchr strdup strrchr strstr]) -# Check for fltk -AC_PATH_PROG(FLTKCONFIG,fltk-config) -if test "x$FLTKCONFIG" = x; then - echo "fltk-config not found" - exit 1 -fi - -CXXFLAGS="`$FLTKCONFIG --use-images --cflags` $CXXFLAGS" -LIBS="`$FLTKCONFIG --use-images --ldflags` $LIBS" - # Check for gsl AC_PATH_PROG(GSLCONFIG,gsl-config) if test "x$GSLCONFIG" = x; then @@ -54,12 +43,8 @@ if test "x$GSLCONFIG" = x; then exit 1 fi -CXXFLAGS="`$GSLCONFIG --cflags` $CXXFLAGS" +CFLAGS="`$GSLCONFIG --cflags` $CFLAGS" LIBS="`$GSLCONFIG --libs` $LIBS" -# Check for lcms -AC_CHECK_HEADERS([lcms.h], [], [echo "Error: lcms.h not found."; exit 1;]) -AC_CHECK_LIB([lcms], [open], [], [echo "Error: liblcms.so not found."; exit 1;]) - AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT diff --git a/src/CurveEditor.H b/src/CurveEditor.H deleted file mode 100644 index c7f4691..0000000 --- a/src/CurveEditor.H +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> -// -// This software may be used and distributed according to the terms -// of the GNU General Public License, incorporated herein by reference. - -#ifndef CurveEditor_H -#define CurveEditor_H - -#include <FL/Fl_Widget.H> -#include <gsl/gsl_spline.h> - -class CurveEditor : public Fl_Widget { - private: - double *X; - double *Y; - int n; - int marked_point; - gsl_interp_accel *acc; - gsl_spline *spline; - - public: - CurveEditor(int _x, int _y, int _w, int _h); - - void add_point(double _x, double _y); - void init(); - void set_point(int i, double _x, double _y); - void draw(); - int handle(int e); -}; - -#endif diff --git a/src/CurveEditor.cxx b/src/CurveEditor.cxx deleted file mode 100644 index c163812..0000000 --- a/src/CurveEditor.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> -// -// This software may be used and distributed according to the terms -// of the GNU General Public License, incorporated herein by reference. - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#include <FL/Fl.H> -#include <FL/fl_draw.H> - -#include "CurveEditor.H" - -CurveEditor::CurveEditor(int my_x, int my_y, int my_w, int my_h) : - Fl_Widget(my_x, my_y, my_w, my_h) { - - marked_point = -1; - - n = 0; - X = NULL; - Y = NULL; - - acc = gsl_interp_accel_alloc (); - spline = NULL; -} - -void -CurveEditor::draw() { - fl_color(FL_BLACK); - fl_rectf(x(), y(), w(), h()); - - fl_color(FL_WHITE); - fl_begin_line(); - 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() - h() * _y); - } - fl_end_line(); - - for (int i = 0; i < n; i++) { - fl_rectf(x() + w() * X[i] - 2, y() + h() - h() * Y[i] - 2, 4, 4); - } -} - - -int -CurveEditor::handle(int event) { - int mark_x = Fl::event_x() - x(); - int mark_y = Fl::event_y() - y(); - - switch(event) { - - case FL_PUSH: - 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(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) { - marked_point = i; - redraw(); - break; - } - } - } - Fl::focus(this); - return 1; - case FL_DRAG: - set_point(marked_point, (double) mark_x / w(), 1.0 - (double) mark_y / h()); - - return 1; - case FL_RELEASE: - marked_point = -1; - printf("%g,%g", X[0], Y[0]); - for (int i = 1; i < n; i++) { - printf(";%g,%g", X[i], Y[i]); - } - printf("\n"); - fflush(stdout); - return 1; - case FL_FOCUS: - return 1; - case FL_UNFOCUS: - return 0; - } - return 0; -} - -void -CurveEditor::add_point(double _x, double _y) { - if ((_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || - n > 0 && _x <= X[n]) { - return; - } - n++; - X = (double*) realloc(X, n * sizeof(double)); - Y = (double*) realloc(Y, n * sizeof(double)); - - X[n - 1] = _x; - Y[n - 1] = _y; -} - -void -CurveEditor::init() { - if (spline) gsl_spline_free(spline); - spline = gsl_spline_alloc (gsl_interp_cspline, n); - gsl_spline_init (spline, X, Y, n); -} - -void -CurveEditor::set_point(int i, double _x, double _y) { - if (i >= n || - (_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || - (i < n - 1 && _x >= X[i + 1]) || - (i > 0 && _x <= X[i - 1])) { - return; - } - - X[i] = _x; - Y[i] = _y; - gsl_spline_init (spline, X, Y, n); - - redraw(); -} diff --git a/src/Makefile.am b/src/Makefile.am index 1715549..ddfb6b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,8 @@ -bin_PROGRAMS = pnmlcms flcurve +bin_PROGRAMS = pnmcurve -pnmlcms_SOURCES = \ - pnmlcms.c \ +pnmcurve_SOURCES = \ + pnmcurve.c \ pnm.c noinst_HEADERS = \ pnm.h - -flcurve_SOURCES = \ - CurveEditor.cxx \ - flcurve.cxx diff --git a/src/flcurve.cxx b/src/flcurve.cxx deleted file mode 100644 index 94908bc..0000000 --- a/src/flcurve.cxx +++ /dev/null @@ -1,89 +0,0 @@ -// -// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> -// -// This software may be used and distributed according to the terms -// of the GNU General Public License, incorporated herein by reference. - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <FL/Fl.H> -#include <FL/Fl_Window.H> -#include <FL/fl_draw.H> - -#include <../config.h> - -#include "CurveEditor.H" - -static void -parse_curve(CurveEditor *ce, const char *ctrl_points); - -void -usage() { - fprintf(stderr, - "flcurve %s\n" - VERSION); -} - -int -main(int argc, char **argv) { - int c, n, i, err; - char *curve = NULL; - - while ((c = getopt(argc, argv, "?hs:g:d:f:i:C:")) != EOF) { - switch (c) { - case '?': - case 'h': - usage(); - exit(0); - case 'C': - curve = optarg; - break; - default: - i = optind - 1; - n = Fl::arg(argc, argv, i); - if (n == 0) { - err++; - } else { - optind = i; - } - break; - } - } - - Fl_Window window(800, 800); - CurveEditor ce(10, 10, 780, 780); - window.end(); - window.resizable(ce); - - if (curve) { - parse_curve(&ce, curve); - } - - window.show(1, argv); - - return Fl::run(); -} - -static void -parse_curve(CurveEditor *ce, const char *ctrl_points) { - char *pstr, *buf = strdup(ctrl_points); - int i, n = 0; - double X, Y; - - while (pstr = strsep(&buf, ";")) { - if (sscanf(pstr, "%lf,%lf", &X, &Y) != 2 || - X < 0.0 || X > 1.0 || Y < 0.0 || Y > 1.0) { - fprintf(stderr, "Could not parse control point %s.\n", pstr); - continue; - } - - ce->add_point(X, Y); - } - - free(buf); - - ce->init(); -} diff --git a/src/pnmcurve.c b/src/pnmcurve.c new file mode 100644 index 0000000..e170f36 --- /dev/null +++ b/src/pnmcurve.c @@ -0,0 +1,168 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <math.h> + +#include <gsl/gsl_spline.h> + +#include "pnm.h" + +typedef struct { + int n; + short value[1]; +} table_t; + +static int +pam_transform(FILE *in_fp, FILE *out_fp, + const struct pnm *in_pnm, table_t **tables); + +static table_t* +buildCurve(const char *ctrl_points, int resolution); + +#define RED 0x1 +#define GREEN 0x2 +#define BLUE 0x4 + +int +main(int argc, char **argv) { + int c, i; + char *curve = NULL; + struct pnm in_pnm; + int channels = 0; + table_t *gTable[3]; + + while ((c = getopt(argc, argv, "rgbC:h")) != EOF) { + switch (c) { + case 'r': + channels |= RED; + break; + case 'g': + channels |= GREEN; + break; + case 'b': + channels |= BLUE; + break; + case 'C': + curve = optarg; + break; + + default: + break; + } + } + + if (readPnmHeader(stdin, &in_pnm) != 0) { + exit(1); + } + + if (in_pnm.maxval == 255) { + } else if (in_pnm.maxval == 65535) { + } else { + fprintf(stderr, "unsupported PNM maxval %d\n", in_pnm.maxval); + exit(1); + } + + if (curve) { + table_t *table; + + if (channels == 0) channels = RED | GREEN | BLUE; + + table = buildCurve(curve, 256); + + gTable[0] = channels & RED?table:NULL; + gTable[1] = channels & GREEN?table:NULL; + gTable[2] = channels & BLUE?table:NULL; + + } + + writePnmHeader(stdout, &in_pnm); + + pam_transform(stdin, stdout, &in_pnm, gTable); + + return 0; +} + +static int +pam_transform(FILE *in_fp, FILE *out_fp, + const struct pnm *in_pnm, table_t **tables) { + int row, col; + int nbytes = in_pnm->maxval == 65535?2:1; + char *buf = malloc(in_pnm->width * nbytes * 3); + + for (row = 0; row < in_pnm->height; row++) { + fread(buf, in_pnm->width, nbytes * 3, in_fp); + + for (i = 0; i < in_pnm->width; i++) { + for (c = 0; c < in_pnm->depth; c++) { + if (tables[c]) { + int val = (unsigned char) buf[(i * in_pnm->depth + c) * nbytes]; + if (nbytes == 2) { + val = (val << 8) | + (uchar) buf[(i * in_pnm->depth + c) * nbytes + 1]; + } + + bud + + } + } + } + + fwrite(buf, in_pnm->width, nbytes * 3, out_fp); + } + + free(buf); + return 0; +} + +#define MAX_CTRL 256 + +static table_t* +buildCurve(const char *ctrl_points, int resolution) { + table_t *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 = (table_t*) malloc(sizeof(table_t) + resolution * sizeof(short)); + table->n = 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->value[i] = (short) floor(dval); + } + + gsl_spline_free(spline); + gsl_interp_accel_free(acc); + + return table; +} diff --git a/src/pnmlcms.c b/src/pnmlcms.c deleted file mode 100644 index 426b923..0000000 --- a/src/pnmlcms.c +++ /dev/null @@ -1,229 +0,0 @@ -#include <lcms.h> -#include <gsl/gsl_spline.h> - -#include "pnm.h" - -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); - - -#define RED 0x1 -#define GREEN 0x2 -#define BLUE 0x4 -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; - cmsHTRANSFORM hTransform; - cmsHPROFILE profiles[3]; - DWORD type; - struct pnm in_pnm; - int channels = 0; - - while ((c = getopt(argc, argv, "i:o:rgbc:h:s:S:D:C:")) != EOF) { - switch (c) { - case 'i': - in_prof = optarg; - break; - case 'o': - out_prof = optarg; - break; - case 'r': - channels |= RED; - break; - case 'g': - channels |= GREEN; - break; - case 'b': - channels |= BLUE; - break; - case 'c': - contrast = atof(optarg); - break; - case 'h': - hue = atof(optarg); - break; - case 's': - saturation = atof(optarg); - break; - case 'S': - tempSrc = atoi(optarg); - 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]; - - gTable[0] = cmsBuildGamma(256, gamma); - gTable[1] = gTable[2] = cmsBuildGamma(256, 1.0); - - profiles[nProf++] = cmsCreateLinearizationDeviceLink( - icSigLabData, - gTable); - } - - if (curve) { - LPGAMMATABLE gTable[3]; - LPGAMMATABLE table, nopTable; - - if (channels == 0) channels = RED | GREEN | BLUE; - - table = buildGammaCurve(curve, 256); - nopTable = cmsBuildGamma(256, 1.0); - - gTable[0] = channels & RED?table:nopTable; - gTable[1] = channels & GREEN?table:nopTable; - gTable[2] = channels & BLUE?table:nopTable; - - profiles[nProf++] = cmsCreateLinearizationDeviceLink( - icSigLabData, - gTable); - } - -#if 0 - profiles[nProf++] = cmsCreateBCHSWabstractProfile( - 5, - bright, - contrast, - hue, - saturation, - tempSrc, - tempDst); - - if (out_prof) { - profiles[nProf++] = cmsOpenProfileFromFile(out_prof, "r"); - } else { - profiles[nProf++] = cmsCreate_sRGBProfile(); - } -#endif - - if (readPnmHeader(stdin, &in_pnm) != 0) { - exit(1); - } - - if (in_pnm.maxval == 255) { - type = TYPE_RGB_8; - } else if (in_pnm.maxval == 65535) { - type = TYPE_RGB_16_SE; - } else { - fprintf(stderr, "unsupported PNM maxval %d\n", in_pnm.maxval); - exit(1); - } - - hTransform = cmsCreateMultiprofileTransform( - profiles, - nProf, - type, - type, - INTENT_PERCEPTUAL, - cmsFLAGS_BLACKPOINTCOMPENSATION); - - writePnmHeader(stdout, &in_pnm); - - pam_transform(stdin, stdout, &in_pnm, &hTransform); - - cmsDeleteTransform(hTransform); - - for (i = 0; i < nProf; i++) { - // cmsCloseProfile(profiles[i]); - } - - return 0; -} - -static int -pam_transform(FILE *in_fp, FILE *out_fp, - const struct pnm *in_pnm, cmsHTRANSFORM *hTransform) -{ - int row, col; - int nbytes = in_pnm->maxval == 65535?2:1; - char *buf = malloc(in_pnm->width * nbytes * 3); - - for (row = 0; row < in_pnm->height; row++) { - fread(buf, in_pnm->width, nbytes * 3, in_fp); - - cmsDoTransform(*hTransform, buf, buf, in_pnm->width); - - fwrite(buf, in_pnm->width, nbytes * 3, out_fp); - } - - free(buf); - 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; -} |
