summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pnmcurve.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/pnmcurve.c b/src/pnmcurve.c
index 770de44..d843251 100644
--- a/src/pnmcurve.c
+++ b/src/pnmcurve.c
@@ -29,9 +29,9 @@ main(int argc, char **argv) {
char *curve = NULL;
struct pnm in_pnm;
int channels = 0;
- table_t *gTable[3];
+ table_t *table, *gTable[3];
- while ((c = getopt(argc, argv, "rgbC:h")) != EOF) {
+ while ((c = getopt(argc, argv, "rgbc:h")) != EOF) {
switch (c) {
case 'r':
channels |= RED;
@@ -42,7 +42,7 @@ main(int argc, char **argv) {
case 'b':
channels |= BLUE;
break;
- case 'C':
+ case 'c':
curve = optarg;
break;
@@ -52,22 +52,24 @@ main(int argc, char **argv) {
}
if (readPnmHeader(stdin, &in_pnm) != 0) {
+ fprintf(stderr, "failed to read PNM file\n");
exit(1);
}
- if (in_pnm.maxval == 255) {
- } else if (in_pnm.maxval == 65535) {
- } else {
+ if (in_pnm.maxval != 255 && in_pnm.maxval != 65535) {
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, in_pnm.maxval + 1, in_pnm.maxval);
+
+ if (!table) {
+ fprintf(stderr, "could not build table.\n");
+ exit(1);
+ }
gTable[0] = channels & RED ? table : NULL;
gTable[1] = channels & GREEN ? table : NULL;
@@ -89,8 +91,8 @@ pam_transform(FILE *in_fp, FILE *out_fp,
unsigned char *buf = malloc(in_pnm->width * nbytes * 3);
for (c = 0; c < 3; c++) {
- if (tables[c] && tables[c]->n < in_pnm->maxval) {
- fprintf(stderr, "Table %d too small (%d)\n", c, tables[c]->n);
+ if (tables[c] && tables[c]->n <= in_pnm->maxval) {
+ fprintf(stderr, "table %d too small (%d)\n", c, tables[c]->n);
return 1;
}
}
@@ -114,10 +116,10 @@ pam_transform(FILE *in_fp, FILE *out_fp,
if (nbytes == 1) {
buf[i * 3 + c] = (unsigned char) tables[c]->value[val];
- } else {
- int v1 = tables[c]->value[val];
- buf[(i * 3 + c) * 2] = (unsigned char) (v1 >> 8);
- buf[(i * 3 + c) * 2 + 1] = (unsigned char) v1;
+ } else if (nbytes == 2) {
+ val = tables[c]->value[val];
+ buf[(i * 3 + c) * 2] = (unsigned char) (val >> 8);
+ buf[(i * 3 + c) * 2 + 1] = (unsigned char) val;
}
}
}
@@ -142,15 +144,15 @@ buildCurve(const char *ctrl_points, int resolution, int maxval) {
gsl_spline *spline;
while (pstr = strsep(&buf, ",")) {
- if (n == MAX_CTRL) {
- fprintf(stderr, "Maximum number of control points (%d) reached.\n",
+ 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);
+ fprintf(stderr, "could not parse control point %s.\n", pstr);
free(buf);
return NULL;
}
@@ -160,6 +162,11 @@ buildCurve(const char *ctrl_points, int resolution, int maxval) {
free(buf);
+ if (n < 3) {
+ fprintf(stderr, "not enough control point specified.\n");
+ return NULL;
+ }
+
table = (table_t*) malloc(sizeof(table_t) + resolution * sizeof(short));
table->n = resolution;
@@ -170,11 +177,11 @@ buildCurve(const char *ctrl_points, int resolution, int maxval) {
for (i = 0; i < resolution; i++) {
double _x = (double) i / (resolution - 1);
double _y = gsl_spline_eval(spline, _x, acc);
- double dval = _y * maxval + .5;
- if (dval > maxval) dval = (double) maxval;
- if (dval < 0) dval = 0;
+ double val = _y * maxval + 0.5;
+ if (val > maxval) val = (double) maxval;
+ if (val < 0) val = 0;
- table->value[i] = (unsigned short) floor(dval);
+ table->value[i] = (unsigned short) floor(val);
}
gsl_spline_free(spline);