From c0b89ac5bfb90835ef01573267020e42d4fe070c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 23 Aug 2015 12:17:05 +0200 Subject: Imported Upstream version 1.8.0 --- spectro/ccwin.c | 319 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 230 insertions(+), 89 deletions(-) mode change 100644 => 100755 spectro/ccwin.c (limited to 'spectro/ccwin.c') diff --git a/spectro/ccwin.c b/spectro/ccwin.c old mode 100644 new mode 100755 index 3c0d97f..1e9a18d --- a/spectro/ccwin.c +++ b/spectro/ccwin.c @@ -15,18 +15,6 @@ #include #include -#ifdef NT -# include -#endif -#ifdef UNIX -# include -# include -# include -# include -# ifdef __FreeBSD__ -# include -# 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; } -- cgit v1.2.3