summaryrefslogtreecommitdiff
path: root/xicc/xcam.c
diff options
context:
space:
mode:
Diffstat (limited to 'xicc/xcam.c')
-rw-r--r--xicc/xcam.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/xicc/xcam.c b/xicc/xcam.c
new file mode 100644
index 0000000..99f3c67
--- /dev/null
+++ b/xicc/xcam.c
@@ -0,0 +1,214 @@
+
+/*
+ * Abstract interface to color appearance model transforms.
+ *
+ * This is to allow the rest of Argyll to use a default CAM.
+ *
+ * Author: Graeme W. Gill
+ * Date: 25/7/2004
+ * Version: 1.00
+ *
+ * Copyright 2004 Graeme W. Gill
+ * Please refer to COPYRIGHT file for details.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "xcam.h"
+#include "cam97s3.h"
+#include "cam02.h"
+
+static void icx_cam_free(icxcam *s);
+static int icx_set_view(icxcam *s, ViewingCondition Ev, double Wxyz[3],
+ double La, double Yb, double Lv, double Yf, double Fxyz[3],
+ int hk);
+static int icx_XYZ_to_cam(struct _icxcam *s, double Jab[3], double XYZ[3]);
+static int icx_cam_to_XYZ(struct _icxcam *s, double XYZ[3], double Jab[3]);
+static void settrace(struct _icxcam *s, int tracev);
+
+/* Return the default CAM */
+icxCAM icxcam_default(void) {
+// return cam_CIECAM97s3;
+ return cam_CIECAM02;
+}
+
+/* Return a string describing the given CAM */
+char *icxcam_description(icxCAM which) {
+ if (which == cam_default)
+ which = icxcam_default();
+
+ switch(which) {
+ case cam_CIECAM97s3:
+ return "CIECAM97s3";
+ case cam_CIECAM02:
+ return "CIECAM02";
+ default:
+ break;
+ }
+ return "Unknown CAM";
+}
+
+/* Create a cam conversion object */
+icxcam *new_icxcam(icxCAM which) {
+ icxcam *s;
+
+ if ((s = (icxcam *)calloc(1, sizeof(icxcam))) == NULL) {
+ fprintf(stderr,"icxcam: malloc failed allocating object\n");
+ return NULL;
+ }
+
+ /* Initialise methods */
+ s->del = icx_cam_free;
+ s->set_view = icx_set_view;
+ s->XYZ_to_cam = icx_XYZ_to_cam;
+ s->cam_to_XYZ = icx_cam_to_XYZ;
+ s->settrace = settrace;
+
+ /* We set the default CAM here */
+ if (which == cam_default)
+ which = icxcam_default();
+
+ s->tag = which;
+
+ switch(which) {
+ case cam_CIECAM97s3:
+ if ((s->p = (void *)new_cam97s3()) == NULL) {
+ fprintf(stderr,"icxcam: malloc failed allocating object\n");
+ free(s);
+ return NULL;
+ }
+ break;
+ case cam_CIECAM02:
+ if ((s->p = (void *)new_cam02()) == NULL) {
+ fprintf(stderr,"icxcam: malloc failed allocating object\n");
+ free(s);
+ return NULL;
+ }
+ break;
+
+ default:
+ fprintf(stderr,"icxcam: unknown CAM type\n");
+ free(s);
+ return NULL;
+ }
+ return s;
+}
+
+static void icx_cam_free(icxcam *s) {
+ if (s != NULL) {
+ switch(s->tag) {
+ case cam_CIECAM97s3: {
+ cam97s3 *pp = (cam97s3 *)s->p;
+ pp->del(pp);
+ break;
+ }
+ case cam_CIECAM02: {
+ cam02 *pp = (cam02 *)s->p;
+ pp->del(pp);
+ break;
+ }
+ default:
+ break;
+ }
+ free(s);
+ }
+}
+
+static int icx_set_view(
+icxcam *s,
+ViewingCondition Ev, /* Enumerated Viewing Condition */
+double Wxyz[3], /* Reference/Adapted White XYZ (Y range 0.0 .. 1.0) */
+double La, /* Adapting/Surround Luminance cd/m^2 */
+double Yb, /* Relative Luminance of Background to reference white */
+double Lv, /* Luminance of white in the Viewing/Scene/Image field (cd/m^2) */
+ /* Ignored if Ev is set to other than vc_none */
+double Yf, /* Flare as a fraction of the reference white (Y range 0.0 .. 1.0) */
+double Fxyz[3], /* The Flare white coordinates (typically the Ambient color) */
+int hk /* Flag, NZ to use Helmholtz-Kohlraush effect */
+) {
+ s->Wxyz[0] = Wxyz[0];
+ s->Wxyz[1] = Wxyz[1];
+ s->Wxyz[2] = Wxyz[2];
+
+ switch(s->tag) {
+ case cam_CIECAM97s3: {
+ cam97s3 *pp = (cam97s3 *)s->p;
+ return pp->set_view(pp, Ev, Wxyz, La, Yb, Lv, Yf, Fxyz, hk);
+ }
+ case cam_CIECAM02: {
+ cam02 *pp = (cam02 *)s->p;
+ return pp->set_view(pp, Ev, Wxyz, La, Yb, Lv, Yf, Fxyz, hk);
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* Conversions */
+static int icx_XYZ_to_cam(
+struct _icxcam *s,
+double Jab[3],
+double XYZ[3]
+) {
+ switch(s->tag) {
+ case cam_CIECAM97s3: {
+ cam97s3 *pp = (cam97s3 *)s->p;
+ return pp->XYZ_to_cam(pp, Jab, XYZ);
+ }
+ case cam_CIECAM02: {
+ cam02 *pp = (cam02 *)s->p;
+ return pp->XYZ_to_cam(pp, Jab, XYZ);
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int icx_cam_to_XYZ(
+struct _icxcam *s,
+double XYZ[3],
+double Jab[3]
+) {
+ switch(s->tag) {
+ case cam_CIECAM97s3: {
+ cam97s3 *pp = (cam97s3 *)s->p;
+ return pp->cam_to_XYZ(pp, XYZ, Jab);
+ }
+ case cam_CIECAM02: {
+ cam02 *pp = (cam02 *)s->p;
+ return pp->cam_to_XYZ(pp, XYZ, Jab);
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* Debug */
+static void settrace(
+struct _icxcam *s,
+int tracev
+) {
+ switch(s->tag) {
+ case cam_CIECAM97s3: {
+ cam97s3 *pp = (cam97s3 *)s->p;
+ pp->trace = tracev;
+ }
+ case cam_CIECAM02: {
+ cam02 *pp = (cam02 *)s->p;
+ pp->trace = tracev;
+ }
+ default:
+ break;
+ }
+}
+
+
+
+
+