summaryrefslogtreecommitdiff
path: root/xicc/specsubsamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'xicc/specsubsamp.c')
-rw-r--r--xicc/specsubsamp.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/xicc/specsubsamp.c b/xicc/specsubsamp.c
new file mode 100644
index 0000000..b13ad94
--- /dev/null
+++ b/xicc/specsubsamp.c
@@ -0,0 +1,232 @@
+
+/*
+ * Author: Graeme W. Gill
+ * Date: 2007/3/21
+ * Version: 1.00
+ *
+ * Copyright 2007 Graeme W. Gill
+ * All rights reserved.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ *
+ */
+
+/*
+ * This is some utility code to subsample the 1 and 5nm spectral
+ * data in xspect to wider spacings using ANSI-CGATS the recommended
+ * triangular filter.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "xspect.h"
+#include "numlib.h"
+
+
+void usage(void) {
+ fprintf(stderr,"Downsample spectral data\n");
+ fprintf(stderr,"Author: Graeme W. Gill\n");
+ fprintf(stderr,"usage: specsubsamp -options\n");
+ fprintf(stderr," -i illum Choose illuminant for print/transparency spectral data:\n");
+ fprintf(stderr," A, C, D50, D50M2, D65, F5, F8, F10 or file.sp\n");
+ fprintf(stderr," -o observ Choose CIE Observer for spectral data:\n");
+ fprintf(stderr," 1931_2, 1964_10, S&B 1955_2, shaw, J&V 1978_2\n");
+ fprintf(stderr," -w st,en,sp Output start, end and spacing nm\n");
+ fprintf(stderr," -5 Commenf output wavelegths every 5\n");
+ exit(1);
+}
+
+int
+main(
+ int argc,
+ char *argv[]
+) {
+ int fa,nfa; /* argument we're looking at */
+ int verb = 0;
+ icxIllumeType illum = icxIT_D50; /* Spectral defaults */
+ xspect cust_illum; /* Custom illumination spectrum */
+ icxObserverType observ = icxOT_CIE_1931_2;
+ int obs = 0; /* If nz output observer */
+ double wl_short = 380.0, wl_long = 730.0, wl_width = 10.0;
+ int wl_n = 0;
+ int evy5 = 0;
+
+ error_program = argv[0];
+
+ /* Process the arguments */
+ for(fa = 1;fa < argc;fa++) {
+ nfa = fa; /* skip to nfa if next argument is used */
+ if (argv[fa][0] == '-') { /* Look for any flags */
+ char *na = NULL; /* next argument after flag, null if none */
+
+ if (argv[fa][2] != '\000')
+ na = &argv[fa][2]; /* next is directly after flag */
+ else {
+ if ((fa+1) < argc) {
+ if (argv[fa+1][0] != '-') {
+ nfa = fa + 1;
+ na = argv[nfa]; /* next is seperate non-flag argument */
+ }
+ }
+ }
+
+ /* Spectral Illuminant type */
+ if (argv[fa][1] == 'i' || argv[fa][1] == 'I') {
+ fa = nfa;
+ if (na == NULL) usage();
+ if (strcmp(na, "A") == 0) {
+ illum = icxIT_A;
+ } else if (strcmp(na, "C") == 0) {
+ illum = icxIT_C;
+ } else if (strcmp(na, "D50") == 0) {
+ illum = icxIT_D50;
+ } else if (strcmp(na, "D50M2") == 0) {
+ illum = icxIT_D50M2;
+ } else if (strcmp(na, "D65") == 0) {
+ illum = icxIT_D65;
+ } else if (strcmp(na, "F5") == 0) {
+ illum = icxIT_F5;
+ } else if (strcmp(na, "F8") == 0) {
+ illum = icxIT_F8;
+ } else if (strcmp(na, "F10") == 0) {
+ illum = icxIT_F10;
+ } else { /* Assume it's a filename */
+ illum = icxIT_custom;
+ if (read_xspect(&cust_illum, na) != 0)
+ usage();
+ }
+ }
+
+ /* Spectral Observer type */
+ else if (argv[fa][1] == 'o' || argv[fa][1] == 'O') {
+ fa = nfa;
+ if (na == NULL) usage();
+ if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */
+ obs = 1;
+ observ = icxOT_CIE_1931_2;
+ } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */
+ obs = 1;
+ observ = icxOT_CIE_1964_10;
+ } else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
+ obs = 1;
+ observ = icxOT_Stiles_Burch_2;
+ } else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */
+ obs = 1;
+ observ = icxOT_Judd_Voss_2;
+ } else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
+ obs = 1;
+ observ = icxOT_Shaw_Fairchild_2;
+ } else
+ usage();
+ }
+
+ else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') {
+ fa = nfa;
+ if (na == NULL) usage();
+ if (sscanf(na, " %lf,%lf,%lf ",&wl_short,&wl_long,&wl_width) != 3)
+
+ if (wl_short > wl_long)
+ usage();
+ }
+
+ else if (argv[fa][1] == '5') {
+ evy5 = 1;
+ }
+
+ /* Verbosity */
+ else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') {
+ verb = 1;
+ } else {
+ usage();
+ }
+ }
+ else
+ break;
+ }
+
+ wl_n = (int)((wl_long - wl_short)/wl_width + 1.5);
+
+ if ((fabs(wl_short + (wl_n - 1.0) * wl_width) - wl_long) > 0.001)
+ error("Not an integer number of output samples");
+
+
+ if (obs) {
+ int i, j, k;
+ xspect *sp[3];
+
+ if (standardObserver(sp, observ) != 0)
+ error ("standardObserver returned error");
+ printf("/* %f - %f, %f spacing, %d samples */\n",wl_short,wl_long,wl_width,wl_n);
+ printf("{\n");
+ for (k = 0; k < 3; k++) {
+
+ printf(" {\n");
+ for (i = 0; i < wl_n; i++) {
+ double cwl, swl, sw, tw, outv;
+ int ns;
+
+ cwl = XSPECT_WL(wl_short, wl_long, wl_n, i);
+ ns = (int)(wl_width/0.1 + 0.5);
+ tw = outv = 0.0;
+ for (j = -ns; j <= ns; j++) {
+ swl = cwl + (j * wl_width)/ns;
+ sw = (ns - abs(j))/(double)ns;
+ tw += sw;
+ outv += sw * value_xspect(sp[k], swl);
+ }
+ outv /= tw;
+ if (!evy5 || i % 5 == 0)
+ printf(" /* %3.1f */ %1.10f%s\n",cwl,outv, i < (wl_n-1) ? "," : "");
+ else
+ printf(" %1.10f%s\n",outv, i < (wl_n-1) ? "," : "");
+ }
+ printf(" }%s\n",k < (3-1) ? "," : "");
+ }
+ printf("}\n");
+
+ } else {
+ int i, j;
+ xspect sp;
+
+ if (illum == icxIT_custom)
+ sp = cust_illum;
+ else {
+ if (standardIlluminant(&sp, illum, 0) != 0)
+ error ("standardIlluminant returned error");
+ }
+
+ printf("/* %f - %f, %f spacing, %d samples */\n",wl_short,wl_long,wl_width,wl_n);
+ printf("{\n");
+ for (i = 0; i < wl_n; i++) {
+ double cwl, swl, sw, tw, outv;
+ int ns;
+
+ cwl = XSPECT_WL(wl_short, wl_long, wl_n, i);
+//printf("~1 output %f\n",cwl);
+ ns = (int)(wl_width/0.1 + 0.5);
+ tw = outv = 0.0;
+ for (j = -ns; j <= ns; j++) {
+ swl = cwl + (j * wl_width)/ns;
+ sw = (ns - abs(j))/(double)ns;
+ tw += sw;
+//printf("~1 sample %f weight %f\n",swl,sw);
+ outv += sw * value_xspect(&sp, swl);
+ }
+ outv /= tw;
+ if (!evy5 || i % 5 == 0)
+ printf(" /* %3.1f */ %1.10f%s\n",cwl,outv, i < (wl_n-1) ? "," : "");
+ else
+ printf(" %1.10f%s\n",outv, i < (wl_n-1) ? "," : "");
+ }
+ printf("}\n");
+ }
+ return 0;
+}
+
+
+
+
+
+
+
+