Ejemplo n.º 1
0
int main(void) {
  sei(); // enable interrupts
  leds_init();
  pwm_init();
  bot_init();
  i2c_init();

  if (display_init()!=0) {
    leds_set_displaylight(50);
    if (display_type==2) {
      gfx_init();
    }
  }
  
  gfx_fill(0x00);
  gfx_move(15, 0);
  gfx_set_proportional(1);
  gfx_print_text("nibo");
  gfx_set_proportional(0);

  uint8_t pos=0;
  uint8_t state=0;

  gfx_term_print("Move 0\n");
  nds3_move(0);
  while (nds3_get_busy()) {
    delay(1);
  }
  
  while (1) {
    gfx_draw_mode(GFX_DM_JAM2);

    check_voltage();

   
    //gfx_term_print("Measure 90, 15\n");
      delay(1);
    nds3_measure(180, 1);
    while (nds3_get_busy()) {
      delay(1);
    }

      delay(1);
    //gfx_term_print("Read -90, 15\n");
    do_plot();

      delay(1);
    nds3_measure(0, 1);
    while (nds3_get_busy()) {
      delay(1);
    }

      delay(1);
    //gfx_term_print("Read 90, 15\n");
    nds3_read(0, 15);
    do_plot();
    
    
  }
}
Ejemplo n.º 2
0
void PlotArea::plot(const char *commands, int length, bool clear)
{
    if (last_commands.length() > 0 && 
	last_commands.data()[last_commands.length() - 1] != '\n')
    {
	// Last command was incomplete - complete it
	const char *s = last_commands.data();
	int line = last_commands.length() - 1;
	while (line > 0 && s[line - 1] != '\n')
	    line--;
	assert(line == 0 || s[line - 1] == '\n');

	const char *tail = commands;
	while (length > 0 && *commands != '\n')
	    commands++, length--;

	if (length > 0 && *commands == '\n')
	{
	    commands++, length--;
	    string command = string(s + line) + string(tail, commands - tail);

	    assert(isalpha(command[0]));
	    assert(command.contains('\n', -1));

	    do_plot(command.chars(), clear);

	    last_commands.append(tail, commands - tail);
	}
    }

    int discard = do_plot(commands, clear);

    if (discard >= 0)
    {
	// `G' command found - forget about old commands
	last_commands.discard();
	last_commands.append(commands + discard, length - discard);
    }
    else
    {
	// No `G' command found - append to previous commands
	last_commands.append(commands, length);
    }

    assert(last_commands.length() == 0 || last_commands.data()[0] == 'G');
}
Ejemplo n.º 3
0
void plot(int r,int run_length, unsigned char pixel) {
  int x2=x+run_length;

//  fprintf(stderr,"plot: x=%d,y=%d,length=%d,pixel=%d\n",x,y,run_length,pixel);
  while (x < x2) {
    do_plot(r,x,y,pixel);
    //fprintf(stderr,"%s",pixel==0?"  ":pixel==5?"..":pixel==6?"oo":pixel==7?"xx":pixel==8?"OO":"XX");
    x++;
  }
    
  //  x+=run_length;
}
Ejemplo n.º 4
0
int
main(int argc, char *argv[]) {
	int fa,nfa;				/* argument we're looking at */
	int np = 0;			/* Current number of input parameters */
	double params[MAX_PARM] =  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	int i;
	double x;
	double xx[XRES];
	double y1[XRES];

	error_program = "cv";

	/* Process the arguments */
	for(fa = 1;fa < argc;fa++) {
		nfa = fa;					/* skip to nfa if next argument is used */
		if (np >= MAX_PARM)
			break;

		params[np++] = atof(argv[fa]);
	}

	if (np == 0)
		np = 1;

	printf("There are %d parameters:\n",np); fflush(stdout);
	for (i = 0; i < np; i++) {
		printf("Paramter %d = %f\n",i, params[i]); fflush(stdout);
	}

	/* Display the result */
	for (i = 0; i < XRES; i++) {
		x = i/(double)(XRES-1);

		xx[i] = x;
		y1[i] = tfunc(params, np, x);

		if (y1[i] < -0.2)
			y1[i] = -0.2;
		else if (y1[i] > 1.2)
			y1[i] = 1.2;
	}
	do_plot(xx,y1,NULL,NULL,XRES);

	return 0;
}
Ejemplo n.º 5
0
int
main(int argc, char *argv[]) {
	int fa,nfa;					/* argument we're looking at */
	char prof_name[MAXNAMEL+1] = { '\000' };	/* ICC profile name, "" if none */
	char in_name[MAXNAMEL+1];			/* TIFF input file */
	char *xl = NULL, out_name[MAXNAMEL+4+1] = "locus.ts";	/* locus output file */
	int verb = 0;
	int dovrml = 0;
	int doaxes = 1;
	int usevec = 0;
	double vec[3];
	int rv = 0;

	icc *icco = NULL;
	xicc *xicco = NULL;
	icxViewCond vc;				/* Viewing Condition for CIECAM */
	int vc_e = -1;				/* Enumerated viewing condition */
	int vc_s = -1;				/* Surround override */
	double vc_wXYZ[3] = {-1.0, -1.0, -1.0};	/* Adapted white override in XYZ */
	double vc_wxy[2] = {-1.0, -1.0};		/* Adapted white override in x,y */
	double vc_a = -1.0;			/* Adapted luminance */
	double vc_b = -1.0;			/* Background % overid */
	double vc_f = -1.0;			/* Flare % overid */
	double vc_fXYZ[3] = {-1.0, -1.0, -1.0};	/* Flare color override in XYZ */
	double vc_fxy[2] = {-1.0, -1.0};		/* Flare color override in x,y */
	icxLuBase *luo = NULL;					/* Generic lookup object */
	icColorSpaceSignature ins = icSigLabData, outs;	/* Type of input and output spaces */
	int inn, outn;						/* Number of components */
	icmLuAlgType alg;					/* Type of lookup algorithm */
	icmLookupFunc     func   = icmFwd;				/* Must be */
	icRenderingIntent intent = -1;					/* Default */
	icColorSpaceSignature pcsor = icSigLabData;		/* Default */
	icmLookupOrder    order  = icmLuOrdNorm;		/* Default */

	TIFF *rh = NULL;
	int x, y, width, height;					/* Size of image */
	uint16 samplesperpixel, bitspersample;
	uint16 pconfig, photometric, pmtc;
	uint16 resunits;
	float resx, resy;
	tdata_t *inbuf;
	void (*cvt)(double *out, double *in);		/* TIFF conversion function, NULL if none */
	icColorSpaceSignature tcs;					/* TIFF colorspace */
	uint16 extrasamples;						/* Extra "alpha" samples */
	uint16 *extrainfo;							/* Info about extra samples */
	int sign_mask;								/* Handling of encoding sign */

	int i, j;
	int nipoints = 0;					/* Number of raster sample points */ 
	co *inp = NULL;						/* Input point values */
	double tdel = 0.0;					/* Total delta along locus */
	rspl *rr = NULL;
	int nopoints = 0;					/* Number of raster sample points */ 
	co *outp = NULL;

	error_program = argv[0];

	if (argc < 2)
		usage();

	/* 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 */
					}
				}
			}

			if (argv[fa][1] == '?')
				usage();

			/* Verbosity */
			else if (argv[fa][1] == 'v') {
				verb = 1;
			}

			/* Intent */
			else if (argv[fa][1] == 'i' || argv[fa][1] == 'I') {
				fa = nfa;
				if (na == NULL) usage();
    			switch (na[0]) {
					case 'd':
						intent = icmDefaultIntent;
						break;
					case 'a':
						intent = icAbsoluteColorimetric;
						break;
					case 'p':
						intent = icPerceptual;
						break;
					case 'r':
						intent = icRelativeColorimetric;
						break;
					case 's':
						intent = icSaturation;
						break;
					/* Argyll special intents to check spaces underlying */
					/* icxPerceptualAppearance & icxSaturationAppearance */
					case 'P':
						intent = icmAbsolutePerceptual;
						break;
					case 'S':
						intent = icmAbsoluteSaturation;
						break;
					default:
						usage();
				}
			}

			/* Search order */
			else if (argv[fa][1] == 'o') {
				fa = nfa;
				if (na == NULL) usage();
    			switch (na[0]) {
					case 'n':
					case 'N':
						order = icmLuOrdNorm;
						break;
					case 'r':
					case 'R':
						order = icmLuOrdRev;
						break;
					default:
						usage();
				}
			}

			/* PCS override */
			else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') {
				fa = nfa;
				if (na == NULL) usage();
    			switch (na[0]) {
					case 'l':
						pcsor = icSigLabData;
						break;
					case 'j':
						pcsor = icxSigJabData;
						break;
					default:
						usage();
				}
			}

			/* Viewing conditions */
			else if (argv[fa][1] == 'c' || argv[fa][1] == 'C') {
				fa = nfa;
				if (na == NULL) usage();

				/* Switch to Jab automatically */
				pcsor = icxSigJabData;

				/* Set the viewing conditions */
				if (na[1] != ':') {
					if ((vc_e = xicc_enum_viewcond(NULL, NULL, -2, na, 1, NULL)) == -999)
						usage();
				} else if (na[0] == 's' || na[0] == 'S') {
					if (na[1] != ':')
						usage();
					if (na[2] == 'a' || na[2] == 'A') {
						vc_s = vc_average;
					} else if (na[2] == 'm' || na[2] == 'M') {
						vc_s = vc_dim;
					} else if (na[2] == 'd' || na[2] == 'D') {
						vc_s = vc_dark;
					} else if (na[2] == 'c' || na[2] == 'C') {
						vc_s = vc_cut_sheet;
					} else
						usage();
				} else if (na[0] == 'w' || na[0] == 'W') {
					double x, y, z;
					if (sscanf(na+1,":%lf:%lf:%lf",&x,&y,&z) == 3) {
						vc_wXYZ[0] = x; vc_wXYZ[1] = y; vc_wXYZ[2] = z;
					} else if (sscanf(na+1,":%lf:%lf",&x,&y) == 2) {
						vc_wxy[0] = x; vc_wxy[1] = y;
					} else
						usage();
				} else if (na[0] == 'a' || na[0] == 'A') {
					if (na[1] != ':')
						usage();
					vc_a = atof(na+2);
				} else if (na[0] == 'b' || na[0] == 'B') {
					if (na[1] != ':')
						usage();
					vc_b = atof(na+2);
				} else if (na[0] == 'f' || na[0] == 'F') {
					double x, y, z;
					if (sscanf(na+1,":%lf:%lf:%lf",&x,&y,&z) == 3) {
						vc_fXYZ[0] = x; vc_fXYZ[1] = y; vc_fXYZ[2] = z;
					} else if (sscanf(na+1,":%lf:%lf",&x,&y) == 2) {
						vc_fxy[0] = x; vc_fxy[1] = y;
					} else if (sscanf(na+1,":%lf",&x) == 1) {
						vc_f = x;
					} else
						usage();
				} else
					usage();
			}

			/* VRML output */
			else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') {
				dovrml = 1;
			}
			/* No axis output */
			else if (argv[fa][1] == 'n' || argv[fa][1] == 'N') {
				doaxes = 0;
			}
			/* Vector direction for span */
			else if (argv[fa][1] == 'V') {
				usevec = 1;
				if (na == NULL) usage();
				fa = nfa;
				if (sscanf(na, " %lf , %lf , %lf ",&vec[0], &vec[1], &vec[2]) != 3)
						usage();
			}
			/* Output file name */
			else if (argv[fa][1] == 'O') {
				fa = nfa;
				if (na == NULL) usage();
				strncpy(out_name,na,MAXNAMEL); out_name[MAXNAMEL] = '\000';
			}

			else 
				usage();
		} else
			break;
	}

	if (fa >= argc || argv[fa][0] == '-') usage();
	if (fa < (argc-1))
		strncpy(prof_name,argv[fa++],MAXNAMEL); prof_name[MAXNAMEL] = '\000';

	if (fa >= argc || argv[fa][0] == '-') usage();
	strncpy(in_name,argv[fa],MAXNAMEL); in_name[MAXNAMEL] = '\000';

	if ((xl = strrchr(out_name, '.')) == NULL)	/* Figure where extention is */
		xl = out_name + strlen(out_name);

	if (verb) {
		printf("Profile     = '%s'\n",prof_name);
		printf("Input TIFF  = '%s'\n",in_name);
		printf("Output file = '%s'\n",out_name);
	}

	if (intent == -1) {
		if (pcsor == icxSigJabData)
			intent = icRelativeColorimetric;	/* Default to icxAppearance */
		else
			intent = icAbsoluteColorimetric;	/* Default to icAbsoluteColorimetric */
	}

	/* - - - - - - - - - - - - - - - - */
	/* If we were provided an ICC profile to use */
	if (prof_name[0] != '\000') {

		/* Open up the profile or TIFF embedded profile for reading */
		if ((icco = read_embedded_icc(prof_name)) == NULL)
			error ("Can't open profile in file '%s'",prof_name);
	
		if (verb) {
			icmFile *op;
			if ((op = new_icmFileStd_fp(stdout)) == NULL)
				error ("Can't open stdout");
			icco->header->dump(icco->header, op, 1);
			op->del(op);
		}
	
		/* Check that the profile is appropriate */
		if (icco->header->deviceClass != icSigInputClass
		 && icco->header->deviceClass != icSigDisplayClass
		 && icco->header->deviceClass != icSigOutputClass
		 && icco->header->deviceClass != icSigColorSpaceClass)
			error("Profile type isn't device or colorspace");
	
		/* Wrap with an expanded icc */
		if ((xicco = new_xicc(icco)) == NULL)
			error ("Creation of xicc failed");
	
		/* Setup the default viewing conditions */
		if (xicc_enum_viewcond(xicco, &vc, -1, NULL, 0, NULL) == -999)
			error ("%d, %s",xicco->errc, xicco->err);
	
		if (vc_e != -1)
			if (xicc_enum_viewcond(xicco, &vc, vc_e, NULL, 0, NULL) == -999)
				error ("%d, %s",xicco->errc, xicco->err);
		if (vc_s >= 0)
			vc.Ev = vc_s;
		if (vc_wXYZ[1] > 0.0) {
			/* Normalise it to current media white */
			vc.Wxyz[0] = vc_wXYZ[0]/vc_wXYZ[1] * vc.Wxyz[1];
			vc.Wxyz[2] = vc_wXYZ[2]/vc_wXYZ[1] * vc.Wxyz[1];
		} 
		if (vc_wxy[0] >= 0.0) {
			double x = vc_wxy[0];
			double y = vc_wxy[1];	/* If Y == 1.0, then X+Y+Z = 1/y */
			double z = 1.0 - x - y;
			vc.Wxyz[0] = x/y * vc.Wxyz[1];
			vc.Wxyz[2] = z/y * vc.Wxyz[1];
		}
		if (vc_a >= 0.0)
			vc.La = vc_a;
		if (vc_b >= 0.0)
			vc.Yb = vc_b/100.0;
		if (vc_f >= 0.0)
			vc.Yf = vc_f/100.0;
		if (vc_fXYZ[1] > 0.0) {
			/* Normalise it to current media white */
			vc.Fxyz[0] = vc_fXYZ[0]/vc_fXYZ[1] * vc.Fxyz[1];
			vc.Fxyz[2] = vc_fXYZ[2]/vc_fXYZ[1] * vc.Fxyz[1];
		}
		if (vc_fxy[0] >= 0.0) {
			double x = vc_fxy[0];
			double y = vc_fxy[1];	/* If Y == 1.0, then X+Y+Z = 1/y */
			double z = 1.0 - x - y;
			vc.Fxyz[0] = x/y * vc.Fxyz[1];
			vc.Fxyz[2] = z/y * vc.Fxyz[1];
		}
	
		/* Get a expanded color conversion object */
		if ((luo = xicco->get_luobj(xicco, ICX_CLIP_NEAREST
		           , func, intent, pcsor, order, &vc, NULL)) == NULL)
			error ("%d, %s",xicco->errc, xicco->err);
	
		luo->spaces(luo, &ins, &inn, &outs, &outn, &alg, NULL, NULL, NULL);
	
	}

	/* Establish the PCS range if we are filtering */
	{
		double pcsmin[3], pcsmax[3];		/* PCS range for filter stats array */
	
		if (luo) {
			gamut *csgam;

			if ((csgam = luo->get_gamut(luo, 20.0)) == NULL)
				error("Getting the gamut of the source colorspace failed");
			
			csgam->getrange(csgam, pcsmin, pcsmax);
			csgam->del(csgam);
		} else {
			pcsmin[0] = 0.0;
			pcsmax[0] = 100.0;
			pcsmin[1] = -128.0;
			pcsmax[1] = 128.0;
			pcsmin[2] = -128.0;
			pcsmax[2] = 128.0;
		}

		if (verb)
			printf("PCS range = %f..%f, %f..%f. %f..%f\n\n", pcsmin[0], pcsmax[0], pcsmin[1], pcsmax[1], pcsmin[2], pcsmax[2]);

		/* Allocate and initialize the filter */
		set_fminmax(pcsmin, pcsmax);
	}

	/* - - - - - - - - - - - - - - - */
	/* Open up input tiff file ready for reading */
	/* Got arguments, so setup to process the file */

	if ((rh = TIFFOpen(in_name, "r")) == NULL)
		error("error opening read file '%s'",in_name);

	TIFFGetField(rh, TIFFTAG_IMAGEWIDTH,  &width);
	TIFFGetField(rh, TIFFTAG_IMAGELENGTH, &height);

	TIFFGetField(rh, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	TIFFGetField(rh, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	if (bitspersample != 8 && bitspersample != 16)
		error("TIFF Input file must be 8 bit/channel");

	TIFFGetFieldDefaulted(rh, TIFFTAG_EXTRASAMPLES, &extrasamples, &extrainfo);
	TIFFGetField(rh, TIFFTAG_PHOTOMETRIC, &photometric);

	if (inn != (samplesperpixel-extrasamples))
		error ("TIFF Input file has %d input chanels mismatched to colorspace '%s'",
		       samplesperpixel, icm2str(icmColorSpaceSignature, ins));

	if ((tcs = TiffPhotometric2ColorSpaceSignature(&cvt, &sign_mask, photometric,
	                                     bitspersample, samplesperpixel, extrasamples)) == 0)
		error("Can't handle TIFF file photometric %s", Photometric2str(photometric));

	if (tcs != ins) {
		if (luo != NULL)
			error("TIFF photometric '%s' doesn't match ICC input colorspace '%s' !",
			      Photometric2str(photometric), icm2str(icmColorSpaceSignature,ins));
		else
			error("No profile provided and TIFF photometric '%s' isn't Lab !",
			      Photometric2str(photometric));
	}

	TIFFGetField(rh, TIFFTAG_PLANARCONFIG, &pconfig);
	if (pconfig != PLANARCONFIG_CONTIG)
		error ("TIFF Input file must be planar");

	TIFFGetField(rh, TIFFTAG_RESOLUTIONUNIT, &resunits);
	TIFFGetField(rh, TIFFTAG_XRESOLUTION, &resx);
	TIFFGetField(rh, TIFFTAG_YRESOLUTION, &resy);

	if (verb) {
		printf("Input TIFF file '%s'\n",in_name);
		printf("TIFF file colorspace is %s\n",icm2str(icmColorSpaceSignature,tcs));
		printf("TIFF file photometric is %s\n",Photometric2str(photometric));
		printf("\n");
	}

	/* - - - - - - - - - - - - - - - */
	/* Process colors to translate */
	/* (Should fix this to process a group of lines at a time ?) */

	nipoints = width * height;

//	if ((inp = malloc(sizeof(co) * nipoints)) == NULL)
//		error("Unable to allocate co array");

	inbuf  = _TIFFmalloc(TIFFScanlineSize(rh));

	for (i = y = 0; y < height; y++) {

		/* Read in the next line */
		if (TIFFReadScanline(rh, inbuf, y, 0) < 0)
			error ("Failed to read TIFF line %d",y);

		/* Do floating point conversion */
		for (x = 0; x < width; x++) {
			int e;
			double in[MAX_CHAN], out[MAX_CHAN];
			
			if (bitspersample == 8) {
				for (e = 0; e < samplesperpixel; e++) {
					int v = ((unsigned char *)inbuf)[x * samplesperpixel + e];
					if (sign_mask & (1 << i))		/* Treat input as signed */
						v = (v & 0x80) ? v - 0x80 : v + 0x80;
					in[e] = v/255.0;
				}
			} else {
				for (e = 0; e < samplesperpixel; e++) {
					int v = ((unsigned short *)inbuf)[x * samplesperpixel + e];
					if (sign_mask & (1 << i))		/* Treat input as signed */
						v = (v & 0x8000) ? v - 0x8000 : v + 0x8000;
					in[e] = v/65535.0;
				}
			}
			if (cvt != NULL) {	/* Undo TIFF encoding */
				cvt(in, in);
			}
			if (luo != NULL) {
				if ((rv = luo->lookup(luo, out, in)) > 1)
					error ("%d, %s",icco->errc,icco->err);
				
				if (outs == icSigXYZData)	/* Convert to Lab */
					icmXYZ2Lab(&icco->header->illuminant, out, out);
			} else {
				for (e = 0; e < samplesperpixel; e++)
					out[e] = in[e];
			}

//printf("~1 %f %f %f -> %f %f %f\n", in[0], in[1], in[2], out[0], out[1], out[2]);

			add_fpixel(out);

#ifdef NEVER
	 		/* Store PCS value in array */
			inp[i].v[0] = out[0];
			inp[i].v[1] = out[1];
			inp[i].v[2] = out[2];
			i++;
#endif
		}
	}

	_TIFFfree(inbuf);

	TIFFClose(rh);		/* Close Input file */

	/* Done with lookup object */
	if (luo != NULL) {
		luo->del(luo);
		xicco->del(xicco);		/* Expansion wrapper */
		icco->del(icco);		/* Icc */
	}


	nipoints = flush_filter(verb, 80.0);

	if ((inp = malloc(sizeof(co) * nipoints)) == NULL)
		error("Unable to allocate co array");

	get_filter(inp);

printf("~1 There are %d points\n",nipoints);
//for (i = 0; i < nipoints; i++)
//printf("~1 point %d = %f %f %f\n", i, inp[i].v[0], inp[i].v[1], inp[i].v[2]);

	del_filter();

	/* Create the locus */
	{
		double s0[3], s1[3];
		double t0[3], t1[3];
		double mm[3][4];
		double im[3][4];
		int gres[MXDI] = { 256 } ;

		if (usevec) {
			double max = -1e6; 
			double min = 1e6; 
			double dist;
					
			icmScale3(vec, vec, 1.0/icmNorm3(vec));

			/* Locate the two furthest distant points measured along the vector */
			for (i = 0; i < nipoints; i++) {
				double tt;
				tt = icmDot3(vec, inp[i].v);
				if (tt > max) {
					max = tt;
					icmAry2Ary(s1, inp[i].v);
				}
				if (tt < min) {
					min = tt;
					icmAry2Ary(s0, inp[i].v);
				}
			}
			dist = icmNorm33sq(s0, s1);

printf("~1 most distant in vector %f %f %f = %f %f %f -> %f %f %f dist %f\n",
vec[0], vec[1], vec[2], s0[0], s0[1], s0[2], s1[0], s1[1], s1[2], sqrt(dist));

			t0[0] = 0.0;
			t0[1] = 0.0;
			t0[2] = 0.0;
			t1[0] = sqrt(dist);
			t1[1] = 0.0;
			t1[2] = 0.0;

		} else {
			double dist = 0.0;

			/* Locate the two furthest distant points (brute force) */
			for (i = 0; i < (nipoints-1); i++) {
				for (j = i+1; j < nipoints; j++) {
					double tt;
					if ((tt = icmNorm33sq(inp[i].v, inp[j].v)) > dist) {
						dist = tt;
						icmAry2Ary(s0, inp[i].v);
						icmAry2Ary(s1, inp[j].v);
					}
				}
			}
printf("~1 most distant = %f %f %f -> %f %f %f dist %f\n",
s0[0], s0[1], s0[2], s1[0], s1[1], s1[2], sqrt(dist));

			t0[0] = 0.0;
			t0[1] = 0.0;
			t0[2] = 0.0;
			t1[0] = sqrt(dist);
			t1[1] = 0.0;
			t1[2] = 0.0;
		}

		/* Transform our direction vector to the L* axis, and create inverse too */
		icmVecRotMat(mm, s1, s0, t1, t0);
		icmVecRotMat(im, t1, t0, s1, s0);

		/* Setup for rspl to create smoothed locus */
		for (i = 0; i < nipoints; i++) {
			icmMul3By3x4(inp[i].v, mm, inp[i].v);
			inp[i].p[0] = inp[i].v[0];
			inp[i].v[0] = inp[i].v[1];
			inp[i].v[1] = inp[i].v[2];
//printf("~1 point %d = %f -> %f %f\n", i, inp[i].p[0], inp[i].v[0], inp[i].v[1]);
		}

		/* Create rspl */
		if ((rr = new_rspl(RSPL_NOFLAGS, 1, 2)) == NULL)
			error("Creating rspl failed");

		rr->fit_rspl(rr, RSPL_NOFLAGS,inp, nipoints, NULL, NULL, gres, NULL, NULL, 5.0, NULL, NULL);       
#ifdef DEBUG_PLOT
		{
#define	XRES 100
			double xx[XRES];
			double y1[XRES];
			double y2[XRES];

			for (i = 0; i < XRES; i++) {
				co pp;
				double x;
				x = i/(double)(XRES-1);
				xx[i] = x * (t1[0] - t0[0]);
				pp.p[0] = xx[i];
				rr->interp(rr, &pp);
				y1[i] = pp.v[0];
				y2[i] = pp.v[1];
			}
			do_plot(xx,y1,y2,NULL,XRES);
		}
#endif /* DEBUG_PLOT */

		free(inp);

		nopoints = t1[0] / DE_SPACE;
		if (nopoints < 2)
			nopoints = 2;

		/* Create the output points */
		if ((outp = malloc(sizeof(co) * nopoints)) == NULL)
			error("Unable to allocate co array");

		/* Setup initial division of locus */
		for (i = 0; i < nopoints; i++) {
			double xx;

			xx = i/(double)(nopoints-1);
			xx *= (t1[0] - t0[0]);
			
			outp[i].p[0] = xx;
//printf("~1 div %d = %f\n",i,outp[i].p[0]);
		}
		for (i = 0; i < (nopoints-1); i++) {
			outp[i].p[1] = outp[i+1].p[0] - outp[i].p[0];
//printf("~1 del div  %d = %f\n",i,outp[i].p[1]);
		}

		/* Itterate until the delta between samples is even */
		for (j = 0; j < 10; j++) {
			double alen, minl, maxl;
			double tdiv;
			
			alen = 0.0;
			minl = 1e38;
			maxl = -1.0;
			for (i = 0; i < nopoints; i++) {
				rr->interp(rr, &outp[i]);
				outp[i].v[2] = outp[i].v[1];
				outp[i].v[1] = outp[i].v[0];
				outp[i].v[0] = outp[i].p[0];
				icmMul3By3x4(outp[i].v, im, outp[i].v);

//printf("~1 locus pnt %d = %f %f %f\n", i,outp[i].v[0],outp[i].v[1],outp[i].v[1]);

				if (i > 0) {
					double tt[3], len;
					icmSub3(tt, outp[i].v, outp[i-1].v);
					len = icmNorm3(tt);
					outp[i-1].p[2] = len;
					if (len > maxl)
						maxl = len;
					if (len < minl)
						minl = len;
					alen += len;
				}
			}
			alen /= (nopoints-1.0);
printf("~1 itter %d, alen = %f, minl = %f, maxl = %f\n",j,alen,minl,maxl);

			/* Adjust spacing */
			tdiv = 0.0;
			for (i = 0; i < (nopoints-1); i++) {
				outp[i].p[1] *= pow(alen/outp[i].p[2], 1.0);
				tdiv += outp[i].p[1];
			}
//printf("~1 tdiv = %f\n",tdiv);
			for (i = 0; i < (nopoints-1); i++) {
				outp[i].p[1] *= (t1[0] - t0[0])/tdiv;
//printf("~1 del div %d = %f\n",i,outp[i].p[1]);
			}
			tdiv = 0.0;
			for (i = 0; i < (nopoints-1); i++) {
				tdiv += outp[i].p[1];
			}
//printf("~1 tdiv now = %f\n",tdiv);
			for (i = 1; i < nopoints; i++) {
				outp[i].p[0] = outp[i-1].p[0] + outp[i-1].p[1];
//printf("~1 div %d = %f\n",i,outp[i].p[0]);
			}
		}

		/* Write the CGATS file */
		{
			time_t clk = time(0);
			struct tm *tsp = localtime(&clk);
			char *atm = asctime(tsp); /* Ascii time */
			cgats *pp;

			pp = new_cgats();	/* Create a CGATS structure */
			pp->add_other(pp, "TS"); 	/* Test Set */

			pp->add_table(pp, tt_other, 0);	/* Add the first table for target points */
			pp->add_kword(pp, 0, "DESCRIPTOR", "Argyll Test Point set",NULL);
			pp->add_kword(pp, 0, "ORIGINATOR", "Argyll tiffgmts", NULL);
			atm[strlen(atm)-1] = '\000';	/* Remove \n from end */
			pp->add_kword(pp, 0, "CREATED",atm, NULL);

			pp->add_field(pp, 0, "SAMPLE_ID", cs_t);
			pp->add_field(pp, 0, "LAB_L", r_t);
			pp->add_field(pp, 0, "LAB_A", r_t);
			pp->add_field(pp, 0, "LAB_B", r_t);

			for (i = 0; i < nopoints; i++) {
				char buf[100];
				cgats_set_elem ary[1 + 3];

				sprintf(buf,"%d",i+1);
				ary[0].c = buf;
				ary[1 + 0].d = outp[i].v[0];
				ary[1 + 1].d = outp[i].v[1];
				ary[1 + 2].d = outp[i].v[2];
		
				pp->add_setarr(pp, 0, ary);
			}

			if (pp->write_name(pp, out_name))
			    error("Write error : %s",pp->err);
		}

		/* Create the VRML file */
		if (dovrml) {
			vrml *vv;
			
			strcpy(xl,".wrl");
			printf("Output vrml file '%s'\n",out_name);
			if ((vv = new_vrml(out_name, doaxes)) == NULL)
				error ("Creating VRML object failed");

#ifdef NEVER
			vv->start_line_set(vv);
			for (i = 0; i < nopoints; i++) {
				vv->add_vertex(vv, outp[i].v);
			}
			vv->make_lines(vv, nopoints);
#else
			for (i = 1; i < nopoints; i++) {
				vv->add_cone(vv, outp[i-1].v, outp[i].v, NULL, 0.5);
			}
#endif

			vv->del(vv);
		}
		free(outp);
	}

	rr->del(rr);

	return 0;
}
Ejemplo n.º 6
0
/* Might be easier to close it and re-open it ? */
static icxLuBase *
set_icxLuMatrix(
xicc               *xicp,
icmLuBase          *plu,			/* Pointer to Lu we are expanding (ours) */	
int                flags,			/* white/black point flags */
int                nodp,			/* Number of points */
cow                *ipoints,		/* Array of input points in XYZ space */
double             dispLuminance,	/* > 0.0 if display luminance value and is known */
double             wpscale,			/* > 0.0 if input white point is to be scaled */
int                quality			/* Quality metric, 0..3 */
) {
	icxLuMatrix *p;						/* Object being created */
	icc *icco = xicp->pp;				/* Underlying icc object */
	icmLuMatrix *pmlu = (icmLuMatrix *)plu;	/* icc matrix lookup object */
	int luflags = 0;					/* icxLuMatrix alloc clip, merge flags */
	int isLinear = 0;					/* NZ if pure linear, gamma = 1.0 */
	int isGamma = 0;					/* NZ if gamma rather than shaper */
	int isShTRC = 0;					/* NZ if shared TRCs */
	int inputChan = 3;					/* Must be RGB like */
	int outputChan = 3;					/* Must be the PCS */
	icmHeader *h = icco->header;		/* Pointer to icc header */
	int rsplflags = 0;					/* Flags for scattered data rspl */
	int e, f, i, j;
	int maxits = 200;					/* Optimisation stop params */
	double stopon = 0.01;				/* Absolute delta E change to stop on */
	cow *points;		/* Copy of ipoints */
	mxopt os;			/* Optimisation information */
	double rerr;

#ifdef DEBUG_PLOT
	#define	XRES 100
	double xx[XRES];
	double y1[XRES];
#endif /* DEBUG_PLOT */

	if (flags & ICX_VERBOSE)
		rsplflags |= RSPL_VERBOSE;

	luflags = flags;		/* Transfer straight though ? */

	/* Check out some things about the profile */
	{
		icmCurve *wor, *wog, *wob;
		wor = pmlu->redCurve;
		wog = pmlu->greenCurve;
		wob = pmlu->blueCurve;

		if (wor == wog) {
			if (wog != wob) {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_matrix: TRC sharing is inconsistent");
				return NULL;
			}
			isShTRC = 1;
		}
		if (wor->flag != wog->flag || wog->flag != wob->flag) {
			xicp->errc = 1;
			sprintf(xicp->err,"icx_set_matrix: TRC type is inconsistent");
			return NULL;
		}
		if (wor->flag == icmCurveGamma) {
			isGamma = 1;
		}

		if (flags & ICX_NO_IN_SHP_LUTS) {
			isLinear = 1;
		}
	}

	/* Do basic icxLu creation and initialisation */
	if ((p = alloc_icxLuMatrix(xicp, plu, 0, luflags)) == NULL)
		return NULL;

	p->func = icmFwd;		/* Assumed by caller */

	/* Get the effective spaces of underlying icm, and set icx the same */
	plu->spaces(plu, &p->ins, NULL, &p->outs, NULL, NULL, &p->intent, NULL, &p->pcs, NULL);

	/* For set_icx the effective pcs has to be the same as the native pcs */

	/* Sanity check for matrix */
	if (p->pcs != icSigXYZData) {
		p->pp->errc = 1;
		sprintf(p->pp->err,"Can't create matrix profile with PCS of Lab !");
		p->del((icxLuBase *)p);
		return NULL;
	}

	/* In general the native and effective ranges of the icx will be the same as the */
	/* underlying icm lookup object. */
	p->plu->get_lutranges(p->plu, p->ninmin, p->ninmax, p->noutmin, p->noutmax);
	p->plu->get_ranges(p->plu, p->inmin,  p->inmax,  p->outmin,  p->outmax);

	/* If we have a Jab PCS override, reflect this in the effective icx range. */
	/* Note that the ab ranges are nominal. They will exceed this range */
	/* for colors representable in L*a*b* PCS */
	if (p->ins == icxSigJabData) {
		p->inmin[0] = 0.0;		p->inmax[0] = 100.0;
		p->inmin[1] = -128.0;	p->inmax[1] = 128.0;
		p->inmin[2] = -128.0;	p->inmax[2] = 128.0;
	} else if (p->outs == icxSigJabData) {
		p->outmin[0] = 0.0;		p->outmax[0] = 100.0;
		p->outmin[1] = -128.0;	p->outmax[1] = 128.0;
		p->outmin[2] = -128.0;	p->outmax[2] = 128.0;
	} 

	/* ------------------------------- */

	/* Allocate the array passed to fit_rspl() */
	if ((points = (cow *)malloc(sizeof(cow) * nodp)) == NULL) {
		p->pp->errc = 2;
		sprintf(p->pp->err,"Allocation of scattered coordinate array failed");
		p->del((icxLuBase *)p);
		return NULL;
	}

	/* Setup points ready for optimisation */
	for (i = 0; i < nodp; i++) {
		for (e = 0; e < inputChan; e++)
			points[i].p[e] = ipoints[i].p[e];
		
		for (f = 0; f < outputChan; f++)
			points[i].v[f] = ipoints[i].v[f];

		points[i].w = ipoints[i].w;

		/* Make sure its Lab for delta E calculation */
		icmXYZ2Lab(&icmD50, points[i].v, points[i].v);
	}

	/* Setup for optimising run */
	if (flags & ICX_VERBOSE)
		os.verb = 1;
	else
		os.verb = 0;
	os.points = points;
	os.nodp   = nodp;
	os.isShTRC = 0;

	/* Set quality/effort  factors */
	if (quality >= 3) {			/* Ultra high */
		os.norders = 20;
		maxits = 5000;
		stopon = 0.000001;
	} else if (quality == 2) {	/* High */
		os.norders = 15;
		maxits = 2000;
		stopon = 0.00001;
	} else if (quality == 1) {	/* Medium */
		os.norders = 10;
		maxits = 1000;
		stopon = 0.0001;
	} else {					/* Low */
		os.norders = 5;
		maxits = 500;
		stopon = 0.001;
	}
	if (os.norders > MXNORDERS)
		os.norders = MXNORDERS;
	
	/* Set initial optimisation values */
	os.v[0] = 0.4;  os.v[1] = 0.4;  os.v[2] = 0.2;		/* Matrix */
	os.v[3] = 0.2;  os.v[4] = 0.8;  os.v[5] = 0.1;
	os.v[6] = 0.02; os.v[7] = 0.15; os.v[8] = 1.3;

	if (isLinear) {		/* Just gamma curve */
		os.isLinear = 1;
		os.isGamma = 1;
		os.optdim = 9;
		os.v[9] = os.v[10] = os.v[11] = 1.0;					/* Linear */ 
	} else if (isGamma) {		/* Just gamma curve */
		os.isLinear = 0;
		os.isGamma = 1;
		os.optdim = 12;
		os.v[9] = os.v[10] = os.v[11] = 2.4;					/* Gamma */ 
	} else {		/* Creating input curves */
		os.isLinear = 0;
		os.isGamma = 0;
		os.optdim = 12 + 3 * os.norders;
		os.v[9] = os.v[10] = os.v[11] = 0.0;	/* Offset */
		os.v[12] = os.v[13] = os.v[14] = 2.0; 	/* 0th Harmonic */
		for (i = 15; i < os.optdim; i++)
			os.v[i] = 0.0; 						/* Higher orders */
	}

	/* Set search area to starting values */
	for (j = 0; j < os.optdim; j++)
		os.sa[j] = 0.2;					/* Matrix, Gamma, Offsets, harmonics */

	if (isShTRC) {						/* Adjust things for shared */
		os.isShTRC = 1;

		if (os.optdim > 9) {
			/* Pack red paramenters down */
			for (i = 9; i < os.optdim; i++) {
				os.v[i] = os.v[(i - 9) * 3 + 9];
				os.sa[i] = os.sa[(i - 9) * 3 + 9];
			}
			os.optdim = ((os.optdim - 9)/3) + 9;
		}
	}

	if (os.verb) {
		if (os.isLinear)
			printf("Creating matrix...\n"); 
		else
			printf("Creating matrix and curves...\n"); 
	}

	if (powell(&rerr, os.optdim, os.v, os.sa, stopon, maxits,
	           mxoptfunc, (void *)&os, mxprogfunc, (void *)&os) != 0)
		warning("Powell failed to converge, residual error = %f",rerr);

#ifdef NEVER
printf("Matrix = %f %f %f\n",os.v[0], os.v[1], os.v[2]);
printf("         %f %f %f\n",os.v[3], os.v[4], os.v[5]);
printf("         %f %f %f\n",os.v[6], os.v[7], os.v[8]);
if (!isLinear) {		/* Creating input curves */
	if (isGamma) {		/* Creating input curves */
		if (isShTRC) 
			printf("Gamma = %f\n",os.v[9]);
		else
			printf("Gamma = %f %f %f\n",os.v[9], os.v[10], os.v[11]);
	} else {		/* Creating input curves */
		if (isShTRC) 
			printf("Offset = %f\n",os.v[9]);
		else
			printf("Offset = %f %f %f\n",os.v[9], os.v[10], os.v[11]);
		for (j = 0; j < os.norders; j++) {
			if (isShTRC) 
				printf("%d harmonics = %f\n",j, os.v[10 + j]);
			else
				printf("%d harmonics = %f %f %f\n",j, os.v[12 + j * 3], os.v[13 + j * 3],
				                                           os.v[14 + j * 3]);
		}
	}
}
#endif /* NEVER */

	/* Deal with white/black points */
	if (flags & (ICX_SET_WHITE | ICX_SET_BLACK)) {
		double wp[3];	/* Absolute White point in XYZ */
		double bp[3];	/* Absolute Black point in XYZ */

		if (flags & ICX_VERBOSE)
			printf("Find white & black points\n");

		icmXYZ2Ary(wp, icmD50); 		/* Set a default value - D50 */
		icmXYZ2Ary(bp, icmBlack); 		/* Set a default value - absolute black */

		/* Figure out the device values for white */
		if (h->deviceClass == icSigInputClass) {
			double dwhite[MXDI], dblack[MXDI];	/* Device white and black values */
			double Lmax = -1e60;
			double Lmin = 1e60;

			/* We assume that the input target is well behaved, */
			/* and that it includes a white and black point patch, */
			/* and that they have the extreme L values */

			/*
				NOTE that this may not be the best approach !
				It may be better to average the chromaticity
				of all the neutral seeming patches, since
				the whitest patch may have (for instance)
				a blue tint.
			 */

			/* Discover the white and black points */
			for (i = 0; i < nodp; i++) {
				if (points[i].v[0] > Lmax) {
					Lmax = 
					wp[0] = points[i].v[0];
					wp[1] = points[i].v[1];
					wp[2] = points[i].v[2];
					dwhite[0] = points[i].p[0];
					dwhite[1] = points[i].p[1];
					dwhite[2] = points[i].p[2];
				}
				if (points[i].v[0] < Lmin) {
					Lmin = 
					bp[0] = points[i].v[0];
					bp[1] = points[i].v[1];
					bp[2] = points[i].v[2];
					dblack[0] = points[i].p[0];
					dblack[1] = points[i].p[1];
					dblack[2] = points[i].p[2];
				}
			}

			/* Lookup device white/black values in model */
			mxmfunc(&os, os.v, wp, dwhite);
			mxmfunc(&os, os.v, bp, dblack);

			/* If we were given an input white point scale factor, apply it */
			if (wpscale >= 0.0) {
				wp[0] *= wpscale;
				wp[1] *= wpscale;
				wp[2] *= wpscale;
			}

		} else {	/* Assume Monitor class */

			switch(h->colorSpace) {

				case icSigCmyData: {
					double cmy[3];

					/* Lookup white value */
					for (e = 0; e < inputChan; e++)
						cmy[e] = 0.0;

					mxmfunc(&os, os.v, wp, cmy);

					if (flags & ICX_VERBOSE)
						printf("Initial white point = %f %f %f\n",wp[0],wp[1],wp[2]);

					/* Lookup black value */
					for (e = 0; e < inputChan; e++)
						cmy[e] = 1.0;

					mxmfunc(&os, os.v, bp, cmy);

					if (flags & ICX_VERBOSE)
						printf("Initial black point = %f %f %f\n",bp[0],bp[1],bp[2]);
					break;
				}

				case icSigRgbData: {
					double rgb[3];

					/* Lookup white value */
					for (e = 0; e < inputChan; e++)
						rgb[e] = 1.0;

					mxmfunc(&os, os.v, wp, rgb);

					if (flags & ICX_VERBOSE)
						printf("Initial white point = %f %f %f\n",wp[0],wp[1],wp[2]);

					/* Lookup black value */
					for (e = 0; e < inputChan; e++)
						rgb[e] = 0.0;

					mxmfunc(&os, os.v, bp, rgb);
					
					if (flags & ICX_VERBOSE)
						printf("Initial black point = %f %f %f\n",bp[0],bp[1],bp[2]);
					break;
				}

				default: {
					xicp->errc = 1;
					sprintf(xicp->err,"set_icxLuMatrix: can't handle color space %s",
					                           icm2str(icmColorSpaceSignature, h->colorSpace));
					p->del((icxLuBase *)p);
					return NULL;
					break;
				}
			}
		}

		/* If this is a display, adjust the white point to be */
		/* exactly Y = 1.0, and compensate the matrix, dispLuminance */
		/* and black point accordingly. */
		if (h->deviceClass == icSigDisplayClass) {
			double scale = 1.0/wp[1];
			int i;

			for (i = 0; i < 9; i++) {
				os.v[i] *= scale;
			}

			dispLuminance *= wp[1];

			for (i = 0; i < 3; i++) {
				wp[i] *= scale;
				bp[i] *= scale;
			}
		}

		/* Absolute luminance tag */
		if (flags & ICX_WRITE_WBL
		 && h->deviceClass == icSigDisplayClass
		 && dispLuminance > 0.0) {
			icmXYZArray *wo;
			if ((wo = (icmXYZArray *)icco->read_tag(
			           icco, icSigLuminanceTag)) == NULL)  {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_luminance: couldn't find luminance tag");
				p->del((icxLuBase *)p);
				return NULL;
			}
			if (wo->ttype != icSigXYZArrayType) {
				xicp->errc = 1;
				sprintf(xicp->err,"luminance: tag has wrong type");
				p->del((icxLuBase *)p);
				return NULL;
			}

			wo->size = 1;
			wo->allocate((icmBase *)wo);	/* Allocate space */
			wo->data[0].X = 0.0;
			wo->data[0].Y = dispLuminance;
			wo->data[0].Z = 0.0;

			if (flags & ICX_VERBOSE)
				printf("Display Luminance = %f\n", wo->data[0].Y);
		}

		/* Write white and black tags */
		if ((flags & ICX_WRITE_WBL)
		 && (flags & ICX_SET_WHITE)) { /* White Point Tag: */
			icmXYZArray *wo;
			if ((wo = (icmXYZArray *)icco->read_tag(
			           icco, icSigMediaWhitePointTag)) == NULL)  {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_white_black: couldn't find white tag");
				p->del((icxLuBase *)p);
				return NULL;
			}
			if (wo->ttype != icSigXYZArrayType) {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_white_black: white tag has wrong type");
				p->del((icxLuBase *)p);
				return NULL;
			}

			wo->size = 1;
			wo->allocate((icmBase *)wo);	/* Allocate space */
			wo->data[0].X = wp[0];
			wo->data[0].Y = wp[1];
			wo->data[0].Z = wp[2];

			if (flags & ICX_VERBOSE)
				printf("White point XYZ = %f %f %f\n",wp[0],wp[1],wp[2]);
		}
		if ((flags & ICX_WRITE_WBL)
		 && (flags & ICX_SET_BLACK)) { /* Black Point Tag: */
			icmXYZArray *wo;
			if ((wo = (icmXYZArray *)icco->read_tag(
			           icco, icSigMediaBlackPointTag)) == NULL)  {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_white_black: couldn't find black tag");
				p->del((icxLuBase *)p);
				return NULL;
				}
			if (wo->ttype != icSigXYZArrayType) {
				xicp->errc = 1;
				sprintf(xicp->err,"icx_set_white_black: black tag has wrong type");
				p->del((icxLuBase *)p);
				return NULL;
			}

			wo->size = 1;
			wo->allocate((icmBase *)wo);	/* Allocate space */
			wo->data[0].X = bp[0];
			wo->data[0].Y = bp[1];
			wo->data[0].Z = bp[2];

			if (flags & ICX_VERBOSE)
				printf("Black point XYZ = %f %f %f\n",bp[0],bp[1],bp[2]);
		}

		/* Fix matrix to be relative to D50 white point, rather than absolute */
		if (flags & ICX_SET_WHITE) {
			icmXYZNumber swp;
			double mat[3][3];
			
			if (flags & ICX_VERBOSE)
				printf("Fixup matrix for white point\n");

			icmAry2XYZ(swp, wp);

			/* Transfer from parameter to matrix */
			mat[0][0] = os.v[0]; mat[0][1] = os.v[1]; mat[0][2] = os.v[2];
			mat[1][0] = os.v[3]; mat[1][1] = os.v[4]; mat[1][2] = os.v[5];
			mat[2][0] = os.v[6]; mat[2][1] = os.v[7]; mat[2][2] = os.v[8];

			/* Adapt matrix */
			icmChromAdaptMatrix(ICM_CAM_MULMATRIX | ICM_CAM_BRADFORD, icmD50, swp, mat);

			/* Transfer back to parameters */ 
			os.v[0] = mat[0][0]; os.v[1] = mat[0][1]; os.v[2] = mat[0][2];
			os.v[3] = mat[1][0]; os.v[4] = mat[1][1]; os.v[5] = mat[1][2];
			os.v[6] = mat[2][0]; os.v[7] = mat[2][1]; os.v[8] = mat[2][2];
			if (flags & ICX_VERBOSE) {
				printf("After white point adjust:\n");
				printf("Matrix = %f %f %f\n",os.v[0], os.v[1], os.v[2]);
				printf("         %f %f %f\n",os.v[3], os.v[4], os.v[5]);
				printf("         %f %f %f\n",os.v[6], os.v[7], os.v[8]);
			}
		}
	}

	if (flags & ICX_VERBOSE)
		printf("Done gamma/shaper and matrix creation\n");

	/* Write the gamma/shaper and matrix to the icc memory structures */
	if (!isGamma) {		/* Creating input curves */
		unsigned int ui;
		icmCurve *wor, *wog, *wob;
		wor = pmlu->redCurve;
		wog = pmlu->greenCurve;
		wob = pmlu->blueCurve;

		for (ui = 0; ui < wor->size; ui++) {
			double in, rgb[3];

			for (j = 0; j < 3; j++) {

				in = (double)ui / (wor->size - 1.0);
	
				mxmfunc1(&os, j, os.v, &rgb[j], &in);

			}
			wor->data[ui] = rgb[0];	/* Curve values 0.0 - 1.0 */
			if (!isShTRC) {
				wog->data[ui] = rgb[1];
				wob->data[ui] = rgb[2];
			}
		}
#ifdef DEBUG_PLOT
		/* Display the result fit */
		for (j = 0; j < 3; j++) {
			for (i = 0; i < XRES; i++) {
				double x, y;
				xx[i] = x = i/(double)(XRES-1);
				mxmfunc1(&os, j, os.v, &y, &x);
				y1[i] = y;
			}
			do_plot(xx,y1,NULL,NULL,XRES);
		}
#endif /* DEBUG_PLOT */


	} else {			/* Gamma */
		icmCurve *wor, *wog, *wob;
		wor = pmlu->redCurve;
		wog = pmlu->greenCurve;
		wob = pmlu->blueCurve;
		wor->data[0] = os.v[9];	/* Gamma values */
		if (!isShTRC) {
			wog->data[0] = os.v[10];
			wob->data[0] = os.v[11];
		}
	}

	/* Matrix values */
	{
		icmXYZArray *wor, *wog, *wob;
		wor = pmlu->redColrnt;
		wog = pmlu->greenColrnt;
		wob = pmlu->blueColrnt;
		wor->data[0].X = os.v[0]; wor->data[0].Y = os.v[3]; wor->data[0].Z = os.v[6];
		wog->data[0].X = os.v[1]; wog->data[0].Y = os.v[4]; wog->data[0].Z = os.v[7];
		wob->data[0].X = os.v[2]; wob->data[0].Y = os.v[5]; wob->data[0].Z = os.v[8];

		/* Load into pmlu matrix and inverse ??? */
	}

	/* Free the coordinate lists */
	free(points);

	if (flags & ICX_VERBOSE)
		printf("Profile done\n");

	return (icxLuBase *)p;
}
Ejemplo n.º 7
0
void PlotArea::replot(bool clear)
{
    plot_reset("");

    do_plot(last_commands.data(), clear);
}
Ejemplo n.º 8
0
/* Do one set of tests and return the results */
static void do_test(
	double *trmse,		/* RETURN total RMS error */
	double *tmaxe,		/* RETURN total maximum error */
	double *tavge,		/* RETURN total average error */
	int verb,			/* Verbosity */
	int plot,			/* Plot graphs */
	int di,				/* Dimensions */
	int its,			/* Number of function tests */
	int res,			/* RSPL grid resolution */
	int ntps,			/* Number of sample points */
	double noise,		/* Sample point noise volume (total = 4 x average deviation) */
	int unif,			/* NZ if uniform rather than standard deistribution noise */
	double smooth,		/* Smoothness to test, +ve for extra, -ve for underlying */
	int autosm,			/* Use auto smoothing */
	int seed			/* Random seed value offset */
) {
	funcp fp;			/* Function parameters */
	sobol *so;			/* Sobol sequence generator */
	co *tps = NULL;
	rspl *rss;	/* Multi-resolution regularized spline structure */
	datai low,high;
	double avgdev[MXDO];
	int gres[MXDI];
	int i, j, it;
	int flags = RSPL_NOFLAGS;

	if (autosm)
		flags |=  RSPL_AUTOSMOOTH;

	*trmse = 0.0;
	*tmaxe = 0.0;
	*tavge = 0.0;

	for (j = 0; j < di; j++) {
		low[j] = 0.0;
		high[j] = 1.0;
		gres[j] = res;
	}
	
	if ((so = new_sobol(di)) == NULL)
		error("Creating sobol sequence generator failed");

	for (it = 0; it < its; it++) {
		double rmse, avge, maxe;
		double tnoise = 0.0;

		/* Make repeatable by setting random seed before a test set. */
		rand32(0x12345678 + seed + 0x1000 * it);

		/* New function */
		setup_func(&fp, di);

		/* Create the object */
		rss = new_rspl(RSPL_NOFLAGS,di, 1);

		/* Create the list of sampling points */
		if ((tps = (co *)malloc(ntps * sizeof(co))) == NULL)
			error ("malloc failed");

		so->reset(so);

		if (verb) printf("Generating the sample points\n");

		for (i = 0; i < ntps; i++) {
			double out, n;
			so->next(so, tps[i].p);
			out = lookup_func(&fp, tps[i].p);
			if (unif)
				n = d_rand(-0.5 * noise, 0.5 * noise);
			else
				n = noise * 0.25 * 1.2533 * norm_rand();

			tps[i].v[0] = out + n;
//printf("~1 data %d: %f %f %f -> %f, inc noise %f\n", i, tps[i].p[0], tps[i].p[1], tps[i].p[2], out, tps[i].v[0]);

			tnoise += fabs(n);
		}
		tnoise /= (double) ntps;
		if (verb) printf("Measured noise average deviation = %f%%\n",tnoise * 100.0); 

		/* Fit to scattered data */
		if (verb) printf("Fitting the scattered data, smooth = %f, avgdev = %f\n",smooth,avgdev != NULL ? avgdev[0] : 0.0);
		avgdev[0] = 0.25 * noise;
		rss->fit_rspl(rss,
		           flags,				/* Non-mon and clip flags */
		           tps,					/* Test points */
		           ntps,				/* Number of test points */
		           low, high, gres,		/* Low, high, resolution of grid */
		           low, high,			/* Default data scale */
		           smooth,				/* Smoothing to test */
		           avgdev,				/* Average deviation */
		           NULL);				/* iwidth */

		/* Plot out function values */
		if (plot) {
			int slice;
			printf("Black is target, Red is rspl\n");
			for (slice = 0; slice < (di+1); slice++) {
				co tp;	/* Test point */
				double x[PLOTRES];
				double ya[PLOTRES];
				double yb[PLOTRES];
				double yc[PLOTRES];
				double pp[MXDI], p1[MXDI], p2[MXDI], ss[MXDI];
				int n = PLOTRES;

				/* setup slices on each axis at 0.5 and diagonal */
				if (slice < di) {
					for (j = 0; j < di; j++)
						p1[j] = p2[j] = 0.5;
					p1[slice] = 0.0;
					p2[slice] = 1.0;
					printf("Slice along axis %d\n",slice);
				} else {
					for (j = 0; j < di; j++) {
						p1[j] = 0.0;
						p2[j] = 1.0;
					}
					printf("Slice along diagonal\n");
				}

				/* Start point and step increment */
				for (j = 0; j < di; j++) {
					ss[j] = (p2[j] - p1[j])/n;
					pp[j] = p1[j];
				}
				
				for (i = 0; i < n; i++) {
					double vv = i/(n-1.0);
					x[i] = vv;

					/* Reference */
					ya[i] = lookup_func(&fp, pp);

					/* RSPL aproximation */
					for (j = 0; j < di; j++)
						tp.p[j] = pp[j];

					if (rss->interp(rss, &tp))
						tp.v[0] = -0.1;
					yb[i] = tp.v[0];

					/* Crude way of setting the scale: */
					yc[i] = 0.0;
					if (i == (n-1))
						yc[0] = 1.0;

					for (j = 0; j < di; j++)
						pp[j] += ss[j];
				}

				/* Plot the result */
				do_plot(x,ya,yb,yc,n);
			}
		}

		/* Compute statistics */
		rmse = 0.0;
		avge = 0.0;
		maxe = 0.0;
//		so->reset(so);

		/* Fit to scattered data */
		if (verb) printf("Fitting the scattered data\n");
		for (i = 0; i <100000; i++) {
			co tp;	/* Test point */
			double aa, bb, err;

			so->next(so, tp.p);

			/* Reference */
			aa = lookup_func(&fp, tp.p);

			/* RSPL aproximation */
			rss->interp(rss, &tp);
			bb = tp.v[0];

			err = fabs(aa - bb);
			avge += err;
			rmse += err * err;
			if (err > maxe)
				maxe = err;
		}
		avge /= (double)i;
		rmse /= (double)i;

		if (verb)
			printf("Dim %d, res %d, noise %f, points %d, maxerr %f%%, rmserr %f%%, avgerr %f%%\n",
		       di, res, noise, ntps, maxe * 100.0, sqrt(rmse) * 100.0, avge * 100.0);

		*trmse += rmse;
		*tmaxe += maxe;
		*tavge += avge;

		rss->del(rss);
		free(tps);
	}
	so->del(so);

	*trmse = sqrt(*trmse/(double)its);
	*tmaxe /= (double)its;
	*tavge /= (double)its;
}
Ejemplo n.º 9
0
/* minimum RMS value. */
static double best(int n, double *rmse, double *smv) {
	int i, bi;
	rspl *curve;
	co *tps = NULL;
	int ns = 2000;			/* Number of samples */
	datai low,high;
	int gres[1];
	datai dlow,dhigh;
	double avgdev[1];
	double brmse;			/* best solution value */
	double blsmv = 0.0;		/* best solution location */
	double rv;				/* Return value */

	/* Create interpolated curve */
	if ((curve = new_rspl(RSPL_NOFLAGS,1, 1)) == NULL)
		error ("New rspl failed");

	/* Create the list of sampling points */
	if ((tps = (co *)malloc(n * sizeof(co))) == NULL)
		error ("malloc failed");

	for (i = 0; i < n; i++) {
		tps[i].p[0] = log10(smv[i]);
		tps[i].v[0] = rmse[i]; 
	}

	gres[0] = 100;
	low[0] = log10(smv[0]);
	high[0] = log10(smv[n-1]);
	dlow[0] = 0.0;
	dhigh[0] = 1.0;
	avgdev[0] = 0.0;

	curve->fit_rspl(curve,
	           0,					/* Non-mon and clip flags */
	           tps,					/* Test points */
	           n,					/* Number of test points */
	           NULL, NULL, gres,	/* Low, high, resolution of grid */
	           NULL, NULL,			/* Default data scale */
	           -0.0007,				/* Underlying smoothing */
	           avgdev,				/* Average deviation */
	           NULL);				/* iwidth */

#ifdef NEVER
	/* Check the fit */
	for (i = 0; i < n; i++) {
		co tp;

		tp.p[0] = log10(smv[i]);
		curve->interp(curve, &tp);

		printf("Point %d at %f, should be %f is %f\n",i,log10(smv[i]),rmse[i],tp.v[0]);
	}
#endif

	/* Choose a solution */
	brmse = 1e38;

	/* Find lowest rms error point */
	for (i = ns-1; i >= 0; i--) {
		co tp;
		double vi;

		vi = i/(ns-1.0);
		tp.p[0] = log10(smv[0]) + (log10(smv[n-1]) - log10(smv[0])) * vi;
		curve->interp(curve, &tp);

		if (tp.v[0] < brmse) {
			blsmv = tp.p[0];
			brmse = tp.v[0];
			bi = i;
		}
	}

	/* Then increase smoothness until fit error is 1% higher */
	for (i = bi+1; i < ns; i++) {
		co tp;
		double vi;

		vi = i/(ns-1.0);
		tp.p[0] = log10(smv[0]) + (log10(smv[n-1]) - log10(smv[0])) * vi;
		curve->interp(curve, &tp);

		if (tp.v[0] >= (1.01 * brmse)) {
			blsmv = tp.p[0];
			brmse = tp.v[0];
			break;
		}
	}
	rv = pow(10.0, blsmv);

#ifdef NEVER

#define TPRES 100
	/* Plot the result */
	{
		double xx[TPRES], yy[TPRES];

		for (i = 0; i < TPRES; i++) {
			co tp;
			double vi = i/(TPRES-1.0);
	
			tp.p[0] = log10(smv[0]) + (log10(smv[n-1]) - log10(smv[0])) * vi;
			curve->interp(curve, &tp);
			xx[i] = tp.p[0];
			yy[i] = tp.v[0];
		}
		printf("Best at %f\n",blsmv);
		do_plot(xx,yy,NULL,NULL,TPRES);
	}
#endif

	return rv;
}
Ejemplo n.º 10
0
static int do_spec(char *name, xspect *sp) {
	int i;
	double xyz[3];		/* Color temperature */
	double Yxy[3];
	double Lab[3];		/* D50 Lab value */
	double xx[XRES];
	double y1[XRES];
	double cct, vct;
	double cct_xyz[3], vct_xyz[3];
	double cct_lab[3], vct_lab[3];
	icmXYZNumber wp;
	double de;

	printf("\n");

	/* Compute XYZ of illuminant */
	if (icx_ill_sp2XYZ(xyz, icxOT_CIE_1931_2, NULL, icxIT_custom, 0, sp) != 0) 
		error ("icx_sp_temp2XYZ returned error");

	icmXYZ2Yxy(Yxy, xyz);
	icmXYZ2Lab(&icmD50, Lab, xyz);

	printf("Type = %s\n",name);
	printf("XYZ = %f %f %f, x,y = %f %f\n", xyz[0], xyz[1], xyz[2], Yxy[1], Yxy[2]);
	printf("D50 L*a*b* = %f %f %f\n", Lab[0], Lab[1], Lab[2]);
	
	/* Compute CCT */
	if ((cct = icx_XYZ2ill_ct(cct_xyz, BBTYPE, icxOT_CIE_1931_2, NULL, xyz, NULL, 0)) < 0)
		error ("Got bad cct\n");

	/* Compute VCT */
	if ((vct = icx_XYZ2ill_ct(vct_xyz, BBTYPE, icxOT_CIE_1931_2, NULL, xyz, NULL, 1)) < 0)
		error ("Got bad vct\n");

#ifdef PLANKIAN
	printf("CCT = %f, VCT = %f\n",cct, vct);
#else
	printf("CDT = %f, VDT = %f\n",cct, vct);
#endif

	{
		int invalid = 0;
		double cri;
		cri = icx_CIE1995_CRI(&invalid, sp);
		printf("CRI = %.1f%s\n",cri,invalid ? " (Invalid)" : "");
	}

	/* Use modern color difference - gives a better visual match */
	icmAry2XYZ(wp, vct_xyz);
	icmXYZ2Lab(&wp, cct_lab, cct_xyz);
	icmXYZ2Lab(&wp, vct_lab, vct_xyz);
	de = icmCIE2K(cct_lab, vct_lab);
	printf("CIEDE2000 Delta E = %f\n",de);

	/* Plot spectrum out */
	for (i = 0; i < XRES; i++) {
		double ww;

		ww = (sp->spec_wl_long - sp->spec_wl_short)
		   * ((double)i/(XRES-1.0)) + sp->spec_wl_short;
	
		xx[i] = ww;
		y1[i] = value_xspect(sp, ww);
	}
	do_plot(xx,y1,NULL,NULL,i);

	return 0;
}
Ejemplo n.º 11
0
int main(int argc, char *argv[]) {
	int fa,nfa;				/* argument we're looking at */
	int i,j, n;
	double x;
	double xx[XRES];
	double yy[6][XRES];
	rspl *rss;		/* incremental solution version */
	datai low,high;
	int gres[MXDI];
	double avgdev[MXDO];
	double wweight = 1.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 */
					}
				}
			}

			if (argv[fa][1] == '?') {
				usage();

			} else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') {
				fa = nfa;
				if (na == NULL) usage();
				wweight = atof(na);
			} else 
				usage();
		} else
			break;
	}

	low[0] = 0.0;
	high[0] = 1.0;
	avgdev[0] = AVGDEV;

	error_program = "Curve1";

	for (n = 0; n < TRIALS; n++) {
		double lrand = 0.0;	/* Amount of level randomness */
		int pnts;
		int fres;

		if (n == 0) {	/* Standard versions */
			pnts = PNTS;
			fres = GRES; 
			for (i = 0; i < pnts; i++) {
				xa[i] = t1xa[i];
				ya[i] = t1ya[i];
				wa[i] = t1wa[i];
			}
			printf("Trial %d, points = %d, res = %d, level randomness = %f\n",n,pnts,fres,lrand);
		} else {	/* Random versions */
			double xmx;
			lrand = d_rand(0.0,0.1);		/* Amount of level randomness */
			pnts = i_rand(MIN_PNTS,MAX_PNTS);
			fres = i_rand(MIN_RES,MAX_RES);

			printf("Trial %d, points = %d, res = %d, level randomness = %f\n",n,pnts,fres,lrand);

			/* Create X values */
			xa[0] = d_rand(0.3, 0.5);
			for (i = 1; i < pnts; i++)
				xa[i] = xa[i-1] + d_rand(0.2,0.7);
			xmx = d_rand(0.6, 0.9);
			for (i = 0; i < pnts; i++)	/* Divide out */
				xa[i] *= (xmx/xa[pnts-1]);

			/* Create y values */
			for (i = 0; i < pnts; i++) {
				ya[i] = xa[i] + d_rand(-lrand,lrand);
				wa[i] = 1.0;
			}
		}

		if (n < SKIP)
			continue;

		/* Create the object */
		rss =  new_rspl(RSPL_NOFLAGS, 1,				/* di */
		                  1);				/* fdi */

		for (i = 0; i < pnts; i++) {
			test_points[i].p[0] = xa[i];
			test_points[i].v[0] = ya[i];
			test_points[i].w = wa[i];
		}
		gres[0] = fres;

#ifdef RES2
		if (n != 0) {
#endif
		/* Fit to scattered data */
		rss->fit_rspl_w_df(rss,
#ifdef EXTRAFIT
		           RSPL_EXTRAFIT |	/* Extra fit flag */
#endif
		           0,
		           test_points,			/* Test points */
		           pnts,	/* Number of test points */
		           low, high, gres,		/* Low, high, resolution of grid */
		           low, high,			/* Data scale */
		           SMOOTH,				/* Smoothing */
		           avgdev,				/* Average deviation */
		           NULL,				/* iwidth */
                   wweight,				/* weak function weight */
				   NULL,				/* No context */
		           wfunc				/* Weak function */
		);

		/* Display the result */
		for (i = 0; i < XRES; i++) {
			co tp;	/* Test point */
			x = i/(double)(XRES-1);
			xx[i] = x;
			yy[0][i] = lin(x,xa,ya,pnts);
			tp.p[0] = x;
			rss->interp(rss, &tp);
			yy[1][i] = tp.v[0];
			if (yy[1][i] < -0.2)
				yy[1][i] = -0.2;
			else if (yy[1][i] > 1.2)
				yy[1][i] = 1.2;
		}
		
		do_plot(xx,yy[0],yy[1],NULL,XRES);

#ifdef RES2
		} else {	/* Multiple resolution version */
			int gresses[5];
			for (j = 0; j < 5; j++) {
#ifndef NEVER
				if (j == 0)
					gres[0] = fres/8;
				else if (j == 1)
					gres[0] = fres/4;
				else if (j == 2)
					gres[0] = fres/2;
				else if (j == 3)
					gres[0] = fres;
				else 
					gres[0] = fres * 2;
#else 	/* Check sensitivity to griding of data points */
				if (j == 0)
					gres[0] = 192;
				else if (j == 1)
					gres[0] = 193;
				else if (j == 2)
					gres[0] = 194;
				else if (j == 3)
					gres[0] = 195;
				else 
					gres[0] = 196;
#endif
				gresses[j] = gres[0];
	
				rss->fit_rspl_w_df(rss,
#ifdef EXTRAFIT
		           RSPL_EXTRAFIT |		/* Extra fit flag */
#endif
			           0,
			           test_points,			/* Test points */
			           pnts,	/* Number of test points */
			           low, high, gres,		/* Low, high, resolution of grid */
			           low, high,			/* Data scale */
			           SMOOTH,				/* Smoothing */
			           avgdev,				/* Average deviation */
			           NULL,				/* iwidth */
	                   wweight,				/* weak function weight */
					   NULL,				/* No context */
			           wfunc				/* Weak function */
			);
	
				/* Get the result */
				for (i = 0; i < XRES; i++) {
					co tp;	/* Test point */
					x = i/(double)(XRES-1);
					xx[i] = x;
					yy[0][i] = lin(x,xa,ya,pnts);
					tp.p[0] = x;
					rss->interp(rss, &tp);
					yy[1+j][i] = tp.v[0];
					if (yy[1+j][i] < -0.2)
						yy[1+j][i] = -0.2;
					else if (yy[1+j][i] > 1.2)
						yy[1+j][i] = 1.2;
				}
			}
	
		printf("Black = lin, Red = %d, Green = %d, Blue = %d, Yellow = %d, Purple = %d\n",
		       gresses[0], gresses[1], gresses[2], gresses[3], gresses[4]);
		do_plot6(xx,yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],XRES);
	}
#endif /* RES2 */
	}	/* next trial */
	return 0;
}