summaryrefslogtreecommitdiff
path: root/spectro/ccwin.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/ccwin.c')
-rwxr-xr-x[-rw-r--r--]spectro/ccwin.c319
1 files changed, 230 insertions, 89 deletions
diff --git a/spectro/ccwin.c b/spectro/ccwin.c
index 3c0d97f..1e9a18d 100644..100755
--- a/spectro/ccwin.c
+++ b/spectro/ccwin.c
@@ -15,18 +15,6 @@
#include <stdio.h>
#include <string.h>
-#ifdef NT
-# include <winsock2.h>
-#endif
-#ifdef UNIX
-# include <sys/types.h>
-# include <ifaddrs.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef __FreeBSD__
-# include <sys/socket.h>
-# endif /* __FreeBSD__ */
-#endif
#include "copyright.h"
#include "aconfig.h"
#include "icc.h"
@@ -59,23 +47,18 @@
//#define STANDALONE_TEST
#ifdef DEBUG
-#define errout stderr
-# define debug(xx) fprintf(errout, xx )
-# define debug2(xx) fprintf xx
-# define debugr(xx) fprintf(errout, xx )
-# define debugr2(xx) fprintf xx
-# define debugrr(xx) fprintf(errout, xx )
-# define debugrr2(xx) fprintf xx
-# define debugrr2l(lev, xx) fprintf xx
+# pragma message("######### ccwin DEBUG is defined! ########")
+#define errout g_log,0
+# define debug2(xx) a1logd xx
+# define debugr2(xx) a1logd xx
+# define debugrr2(xx) a1logd xx
+# define debugrr2l(lev, xx) a1logd xx
#else
-#define errout stderr
-# define debug(xx)
-# define debug2(xx)
-# define debugr(xx) if (p->ddebug) fprintf(errout, xx )
-# define debugr2(xx) if (p->ddebug) fprintf xx
-# define debugrr(xx) if (callback_ddebug) fprintf(errout, xx )
-# define debugrr2(xx) if (callback_ddebug) fprintf xx
-# define debugrr2l(lev, xx) if (callback_ddebug >= lev) fprintf xx
+#define errout g_log,0
+# define debug2(xx) // Debug, args
+# define debugr2(xx) if (p->ddebug) a1logd xx // Run ->ddebug, args
+# define debugrr2(xx) if (callback_ddebug) a1logd xx // Run cback, args
+# define debugrr2l(lev, xx) if (callback_ddebug >= lev) a1logd xx // Run cback >= lev, args
#endif
/* ================================================================== */
@@ -93,13 +76,17 @@ typedef struct _chws {
// double hoff, voff; /* Input position of test square */
double x, y; /* position of test square in pixels */
double w, h; /* size of test square in pixels */
+ double bg[3]; /* Background color */
int pno; /* Index to generate a sequence of URLs */
unsigned char *ibuf; /* Memory image of .png file */
size_t ilen;
ccast *cc; /* ChromeCast */
- /* Update the png image */
+ /* Set a whole screen sized png image */
+ int (*set)(struct _chws *p, unsigned char *ibuf, size_t ilen);
+
+ /* Update the test patch png image */
int (*update)(struct _chws *p, unsigned char *ibuf, size_t ilen, double *bg);
/* Destroy ourselves */
@@ -109,9 +96,11 @@ typedef struct _chws {
static void chws_del(chws *p) {
+ /* delete mongoose, if we are using it */
if (p->mg != NULL)
mg_stop(p->mg);
+ /* Delete ChromeCast */
if (p->cc != NULL)
p->cc->del(p->cc);
@@ -124,12 +113,62 @@ static void chws_del(chws *p) {
free(p);
}
-/* Change the .png being served */
+/* Set a whole screen .png (size is assumed to be large enough) */
+/* Return nz on error */
+static int chws_set(chws *p, unsigned char *ibuf, size_t ilen) {
+ char url[200];
+ double bg[3] = { 0.0, 0.0, 0.0 };
+
+ debug2((errout,"\nUpdate png\n"));
+
+ if (p->ibuf != NULL)
+ free(p->ibuf);
+
+ p->ibuf = ibuf;
+ p->ilen = ilen;
+
+ /* Send the PNG swatch direct */
+ if (p->direct) {
+ double x, y, w, h;
+ /* Convert x,y,w,h to relative rather than pixel size */
+
+ debugr2((errout,"Got x %f y %f w %f h %f\n", p->x, p->y, p->w, p->h));
+
+ // Convert from quantized to direct loader parameters
+ x = 0.0;
+ y = 0.0;
+ w = 10.0; /* Scale */
+ h = 10.0 * 9.0/16.0;
+
+ debugr2((errout,"Sending direct x %f y %f w %f h %f\n", x, y, w, h));
+
+ if (p->cc->load(p->cc, NULL, p->ibuf, p->ilen, bg, x, y, w, h)) {
+ debugr2((errout,"ccwin_set direct load failed\n"));
+ return 1;
+ }
+
+ /* Using web server */
+ } else {
+
+#ifdef SEND_TEST_FILE
+ sprintf(url, "%s%s",p->ws_url, SEND_TEST_FILE);
+#else
+ sprintf(url, "%stpatch_%d.png",p->ws_url, ++p->pno);
+#endif
+ if (p->cc->load(p->cc, url, NULL, 0, NULL, 0.0, 0.0, 0.0, 0.0)) {
+ debugr2((errout,"ccwin_set server load failed\n"));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Change the test patch .png being served */
/* Return nz on error */
static int chws_update(chws *p, unsigned char *ibuf, size_t ilen, double *bg) {
char url[200];
- debug("\nUpdate png\n");
+ debug2((errout,"\nUpdate png\n"));
if (p->ibuf != NULL)
free(p->ibuf);
@@ -230,6 +269,65 @@ static void *ccwin_ehandler(enum mg_event event,
return "yes";
}
+/* Change the patch display parameters. */
+/* Optional - may be NULL */
+static int ccwin_set_patch_win(
+dispwin *p,
+double hoff, double voff, /* Offset from c. in fraction of screen, -1.0 .. 1.0 */
+double area, /* Patch area 0..1 */
+dw_bg_type bge /* Background */
+) {
+ chws *ws = (chws *)p->pcntx;
+ double width, height;
+
+ /* Set background color handling */
+ p->fullscreen = 1;
+ p->bge = bge;
+
+ if (area < 0.0)
+ area = 0.0;
+ else if (area > 1.0)
+ area = 1.0;
+
+ /* Can't do constant luma/power with larger than 50% area */
+ if (bge == dw_bg_cvideo
+ || bge == dw_bg_clight) {
+ if (area > 0.5)
+ area = 0.5;
+ }
+
+ p->area = area;
+
+ if (area < (IHEIGHT * IHEIGHT)/(IWIDTH * IHEIGHT)) { // Not height limited
+ width = height = sqrt(area * IWIDTH * IHEIGHT)/IWIDTH;
+
+ } else {
+ height = IHEIGHT/IWIDTH;
+ width = area;
+ }
+
+ /* Setup window size and position */
+ /* The default size is 10% of the width */
+ ws->w = floor(width * IWIDTH + 0.5);
+ if (ws->w > IWIDTH)
+ ws->w = IWIDTH;
+ ws->h = floor(height * IWIDTH + 0.5);
+ if (ws->h > IHEIGHT)
+ ws->h = IHEIGHT;
+
+ ws->x = floor((hoff * 0.5 + 0.5) * (IWIDTH - ws->w) + 0.5);
+ ws->y = floor((voff * 0.5 + 0.5) * (IHEIGHT - ws->h) + 0.5);
+
+ // Make offset be on an even pixel boundary, so that we know
+ // the up-filter phase.
+ if (((int)ws->x) & 1)
+ ws->x++;
+ if (((int)ws->y) & 1)
+ ws->y++;
+
+ return 0;
+}
+
chws *new_chws(
ccast_id *cc_id, /* ChromeCast to open */
double width, double height, /* Width and height as % */
@@ -249,6 +347,7 @@ int verb, int ddebug) {
p->verb = verb;
p->ddebug = ddebug;
+ p->set = chws_set;
p->update = chws_update;
p->del = chws_del;
@@ -265,10 +364,11 @@ int verb, int ddebug) {
if (p->h > IHEIGHT)
p->h = IHEIGHT;
- // Make offset be on an even pixel boundary, so that we know
- // the up-filter phase.
p->x = floor((hoff * 0.5 + 0.5) * (IWIDTH - p->w) + 0.5);
p->y = floor((voff * 0.5 + 0.5) * (IHEIGHT - p->h) + 0.5);
+
+ // Make offset be on an even pixel boundary, so that we know
+ // the up-filter phase.
if (((int)p->x) & 1)
p->x++;
if (((int)p->y) & 1)
@@ -282,8 +382,7 @@ int verb, int ddebug) {
/* Connect to the chrome cast */
if ((p->cc = new_ccast(cc_id, forcedef)) == NULL) {
- error("new_ccast: failed");
- chws_del(p);
+ debugr2((errout,"new_chws: new_ccast() failed\n"));
return NULL;
}
@@ -317,14 +416,14 @@ int verb, int ddebug) {
/* Get RAMDAC values. ->del() when finished. */
/* Return NULL if not possible */
static ramdac *ccwin_get_ramdac(dispwin *p) {
- debugr("webdisp doesn't have a RAMDAC\n");
+ debugr2((errout,"webdisp doesn't have a RAMDAC\n"));
return NULL;
}
/* Set the RAMDAC values. */
/* Return nz if not possible */
static int ccwin_set_ramdac(dispwin *p, ramdac *r, int persist) {
- debugr("webdisp doesn't have a RAMDAC\n");
+ debugr2((errout,"webdisp doesn't have a RAMDAC\n"));
return 1;
}
@@ -333,21 +432,21 @@ static int ccwin_set_ramdac(dispwin *p, ramdac *r, int persist) {
/* it the default for this display. */
/* Return nz if failed */
int ccwin_install_profile(dispwin *p, char *fname, ramdac *r, p_scope scope) {
- debugr("webdisp doesn't support installing profiles\n");
+ debugr2((errout,"webdisp doesn't support installing profiles\n"));
return 1;
}
/* Un-Install a display profile */
/* Return nz if failed, */
int ccwin_uninstall_profile(dispwin *p, char *fname, p_scope scope) {
- debugr("webdisp doesn't support uninstalling profiles\n");
+ debugr2((errout,"webdisp doesn't support uninstalling profiles\n"));
return 1;
}
/* Get the currently installed display profile. */
/* Return NULL if failed. */
icmFile *ccwin_get_profile(dispwin *p, char *name, int mxlen) {
- debugr("webdisp doesn't support getting the current profile\n");
+ debugr2((errout,"webdisp doesn't support getting the current profile\n"));
return NULL;
}
@@ -355,6 +454,7 @@ icmFile *ccwin_get_profile(dispwin *p, char *name, int mxlen) {
/* Change the window color. */
/* Return 1 on error, 2 on window being closed */
+/* inst_license, inst_licensenc or inst_tamper on licening problem */
static int ccwin_set_color(
dispwin *p,
double r, double g, double b /* Color values 0.0 - 1.0 */
@@ -365,10 +465,10 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
double kr, kf;
int update_delay = 0;
- debugr("ccwin_set_color called\n");
+ debugr2((errout, "ccwin_set_color called with %f %f %f\n",r,g,b));
if (p->nowin) {
- debugr("ccwin_set_color: nowin - give up\n");
+ debugr2((errout,"ccwin_set_color: nowin - give up\n"));
return 1;
}
@@ -404,7 +504,7 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
{
/* We want a raster of IWIDTH x IHEIGHT pixels for web server, */
/* or p->w x p->h for PNG direct. */
- render2d *r;
+ render2d *rr;
prim2d *rct;
depth2d depth = bpc8_2d;
#if DDITHER == 1
@@ -418,10 +518,10 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
double hres = 1.0; /* Resoltion in pix/mm */
double vres = 1.0; /* Resoltion in pix/mm */
double iw, ih; /* Size of page in mm (pixels) */
- double bg[3]; /* Background color */
color2d c;
unsigned char *ibuf; /* Memory image of .png file */
size_t ilen;
+ int rv;
#ifdef DO_TIMING
int stime;
#endif
@@ -434,42 +534,63 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
ih = IHEIGHT; /* Size of page in mm */
}
- if (p->blackbg) {
- bg[0] = 0.0;
- bg[1] = 0.0;
- bg[2] = 0.0;
+ /* Full screen background: */
+ if (p->fullscreen) {
+ if (p->bge == dw_bg_grey) {
+ ws->bg[0] = 0.2;
+ ws->bg[1] = 0.2;
+ ws->bg[2] = 0.2;
+ } else if (p->bge == dw_bg_cvideo) {
+ ws->bg[0] = p->area * (1.0 - r)/(1.0 - p->area);
+ ws->bg[1] = p->area * (1.0 - g)/(1.0 - p->area);
+ ws->bg[2] = p->area * (1.0 - b)/(1.0 - p->area);
+
+ } else if (p->bge == dw_bg_clight) {
+ double gamma = 2.3;
+ ws->bg[0] = pow(p->area * (1.0 - pow(r, gamma))/(1.0 - p->area), 1.0/gamma);
+ ws->bg[1] = pow(p->area * (1.0 - pow(g, gamma))/(1.0 - p->area), 1.0/gamma);
+ ws->bg[2] = pow(p->area * (1.0 - pow(b, gamma))/(1.0 - p->area), 1.0/gamma);
+
+ } else { /* Assume dw_bg_black */
+ ws->bg[0] = 0.0;
+ ws->bg[1] = 0.0;
+ ws->bg[2] = 0.0;
+ }
+
+ /* Use default dark gray background */
} else {
- bg[0] = 0.5;
- bg[1] = 0.5;
- bg[2] = 0.5;
+ ws->bg[0] = 0.2;
+ ws->bg[1] = 0.2;
+ ws->bg[2] = 0.2;
}
debugr2((errout, "ccwin_set_color iw %f ih %f\n",iw,ih));
- if ((r = new_render2d(iw, ih, NULL, hres, vres, rgb_2d,
+ if ((rr = new_render2d(iw, ih, NULL, hres, vres, rgb_2d,
0, depth, dither,
#if DDITHER == 1
- ccastQuant,
+ ccastQuant, NULL, 3.0/255.0
#else
- NULL,
+ NULL, NULL, 0.0
#endif
- NULL)) == NULL) {
- error("ccwin: new_render2d() failed");
+ )) == NULL) {
+ a1loge(g_log, 1,"ccwin: new_render2d() failed\n");
+ return 1;
}
/* Set the background color */
- c[0] = bg[0];
- c[1] = bg[1];
- c[2] = bg[2];
- r->set_defc(r, c);
+ c[0] = ws->bg[0];
+ c[1] = ws->bg[1];
+ c[2] = ws->bg[2];
+ rr->set_defc(rr, c);
c[0] = p->r_rgb[0];
c[1] = p->r_rgb[1];
c[2] = p->r_rgb[2];
if (ws->direct)
- r->add(r, rct = new_rect2d(r, 0.0, 0.0, ws->w, ws->h, c)) ;
+ rr->add(rr, rct = new_rect2d(rr, 0.0, 0.0, ws->w, ws->h, c));
else
- r->add(r, rct = new_rect2d(r, ws->x, ws->y, ws->w, ws->h, c)) ;
+ rr->add(rr, rct = new_rect2d(rr, ws->x, ws->y, ws->w, ws->h, c));
#if DDITHER == 2 /* Use dither pattern */
{
@@ -483,8 +604,10 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
rgb[i] = p->r_rgb[i] * 255.0;
get_ccast_dith(dpat, rgb);
- if ((cpat = malloc(sizeof(double) * MXPATSIZE * MXPATSIZE * TOTC2D)) == NULL)
- error("ccwin: malloc of dither pattern failed");
+ if ((cpat = malloc(sizeof(double) * MXPATSIZE * MXPATSIZE * TOTC2D)) == NULL) {
+ a1loge(g_log, 1, "ccwin: malloc of dither pattern failed\n");
+ return 1;
+ }
for (i = 0; i < CCDITHSIZE; i++) {
for (j = 0; j < CCDITHSIZE; j++) {
@@ -503,35 +626,50 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
#pragma message("############################# ccwin.c TEST_PATTERN defined ! ##")
if (getenv("ARGYLL_CCAST_TEST_PATTERN") != NULL) {
verbose(0, "Writing test pattern to '%s'\n","testpattern.png");
- if (r->write(r, "testpattern.png", 1, NULL, NULL, png_file))
- error("ccwin: render->write failed");
+ if (r->write(r, "testpattern.png", 1, NULL, NULL, png_file)) {
+ a1loge(g_log, 1, "ccwin: render->write failed\n");
+ return 1;
+ }
}
#else /* !CCTEST_PATTERN */
# ifdef WRITE_PNG /* Write it to a file so that we can look at it */
# pragma message("############################# spectro/ccwin.c WRITE_PNG is enabled ######")
- if (r->write(r, "ccwin.png", 1, NULL, NULL, png_file))
- error("ccwin: render->write failed");
+ if (r->write(rr, "ccwin.png", 1, NULL, NULL, png_file)) {
+ a1loge(g_log, 1, "ccwin: render->write failed\n");
+ return 1;
+ }
# endif /* WRITE_PNG */
#endif /* !CCTEST_PATTERN */
+
#ifdef DO_TIMING
stime = msec_time();
#endif
- if (r->write(r, "MemoryBuf", 1, &ibuf, &ilen, png_mem))
- error("ccwin: render->write failed");
+
+ rv = rr->write(rr, "MemoryBuf", 1, &ibuf, &ilen, png_mem);
+
+
+ if (rv) {
+ a1loge(g_log, 1, "ccwin: render->write failed\n");
+ return 1;
+ }
+ rr->del(rr);
#ifdef DO_TIMING
stime = msec_time() - stime;
printf("render->write took %d msec\n",stime);
#endif
- if (ws->update(ws, ibuf, ilen, bg))
- error("ccwin: color update failed");
+ if (ws->update(ws, ibuf, ilen, ws->bg)) {
+ a1loge(g_log, 1, "ccwin: color update failed\n");
+ return 1;
+ }
p->ccix = p->ncix;
}
+
/* If update is notified asyncronously ... */
-// while(p->ncix != p->ccix) {
-// msec_sleep(50);
-// }
+ while(p->ncix != p->ccix) {
+ msec_sleep(50);
+ }
//printf("#################################################################\n");
//printf("################# RGB update notified ################\n");
//printf("#################################################################\n");
@@ -544,10 +682,10 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
return 0;
}
-/* Set/unset the blackground color flag */
+/* Set/unset the full screen background color flag */
/* Return nz on error */
-static int ccwin_set_bg(dispwin *p, int blackbg) {
- p->blackbg = blackbg;
+static int ccwin_set_fc(dispwin *p, int fullscreen) {
+ p->fullscreen = fullscreen;
return 0;
}
@@ -571,7 +709,7 @@ dispwin *p
) {
chws *ws;
- debugr("ccwin_del called\n");
+ debugr2((errout,"ccwin_del called with %p\n",p));
if (p == NULL)
return;
@@ -593,7 +731,7 @@ dispwin *p
/* ----------------------------------------------- */
-/* Create a web display test window, default grey */
+/* Create a ChromeCast display test window, default grey */
dispwin *new_ccwin(
ccast_id *cc_id, /* ChromeCast to open */
double width, double height, /* Width and height in mm. (TV width assumed to b 1000mm) */
@@ -606,7 +744,8 @@ int native, /* X0 = use current per channel calibration curve */
int *noramdac, /* Return nz if no ramdac access. native is set to X0 */
int *nocm, /* Return nz if no CM cLUT access. native is set to 0X */
int out_tvenc, /* 1 = use RGB Video Level encoding */
-int blackbg, /* NZ if whole screen should be filled with black */
+int fullscreen, /* NZ if whole screen should be filled with black */
+int noinitpatch, /* NZ if no initial test patch should be shown */
int verb, /* NZ for verbose prompts */
int ddebug /* >0 to print debug statements to stderr */
) {
@@ -615,10 +754,10 @@ int ddebug /* >0 to print debug statements to stderr */
chws *ws = NULL;
const char *options[3];
- debug("new_ccwin called\n");
+ debug2((errout,"new_ccwin called\n"));
if ((p = (dispwin *)calloc(sizeof(dispwin), 1)) == NULL) {
- if (ddebug) fprintf(stderr,"new_ccwin failed because malloc failed\n");
+ debugr2((errout,"new_ccwin failed because malloc failed\n"));
return NULL;
}
@@ -629,7 +768,7 @@ int ddebug /* >0 to print debug statements to stderr */
p->nowin = nowin;
p->native = native;
p->out_tvenc = out_tvenc;
- p->blackbg = blackbg;
+ p->fullscreen = fullscreen;
p->ddebug = ddebug;
p->get_ramdac = ccwin_get_ramdac;
p->set_ramdac = ccwin_set_ramdac;
@@ -637,7 +776,8 @@ int ddebug /* >0 to print debug statements to stderr */
p->uninstall_profile = ccwin_uninstall_profile;
p->get_profile = ccwin_get_profile;
p->set_color = ccwin_set_color;
- p->set_bg = ccwin_set_bg;
+ p->set_fc = ccwin_set_fc;
+ p->set_patch_win = ccwin_set_patch_win;
p->set_update_delay = dispwin_set_update_delay;
p->set_settling_delay = dispwin_set_settling_delay;
p->enable_update_delay = dispwin_enable_update_delay;
@@ -663,7 +803,8 @@ int ddebug /* >0 to print debug statements to stderr */
/* Basic object is initialised, so create connection to ChromeCast */
if ((ws = new_chws(cc_id, width, height, hoff, voff, verb, ddebug)) == NULL) {
- if (ddebug) fprintf(stderr,"new_ccwin failed - new_chws() failed\n");
+ debugr2((errout,"new_ccwin failed - new_chws() failed\n"));
+ p->del(p);
return NULL;
}
@@ -680,13 +821,13 @@ int ddebug /* >0 to print debug statements to stderr */
}
// Set a default first color
- if (ccwin_set_color(p, 128.0, 128.0, 128.0)) {
- if (ddebug) fprintf(stderr,"new_ccwin set_color()\n");
+ if (!noinitpatch && ccwin_set_color(p, 128.0, 128.0, 128.0)) {
+ debugr2((errout,"new_ccwin failed because set_color() failed\n"));
p->del(p);
return NULL;
}
- debugr("new_ccwin: return sucessfully\n");
+ debugr2((errout,"new_ccwin: return sucessfully\n"));
return p;
}