Exemple #1
0
char *stringNodeStatus(byte fieldNodeStatus) {

  if ( fieldNodeStatus == VALID_NODE_STATUS )
    return "Valid";
  else
    return inst_name(fieldNodeStatus);
}
Exemple #2
0
static void
init_table (void) {
	int i;
	OpDesc *desc;

	table = g_hash_table_new (g_str_hash, g_str_equal);

	opcodes = g_new0 (OpDesc, OP_LAST);
	for (i = OP_LOAD; i < OP_LAST; ++i) {
		desc = opcodes + i;
		desc->num = i;
		desc->name = inst_name (i);
		g_hash_table_insert (table, (char *)desc->name, desc);
	}
}
Exemple #3
0
void printTrieNode(FILE *fp, BTNptr pTN) {

  fprintf(fp, "Trie Node: Addr(%p)", pTN);
  if ( IsDeletedNode(pTN) )
    fprintf(fp, "  (DELETED)");
  fprintf(fp, "\n\tInstr(%s), Status(%s), NodeType(%s),\n"
	  "\tTrieType(%s), Symbol(",
	  inst_name(TN_Instr(pTN)),
	  stringNodeStatus(TN_Status(pTN)),
	  stringNodeType(TN_NodeType(pTN)),
	  stringTrieType(TN_TrieType(pTN)));
  printTrieSymbol(fp, TN_Symbol(pTN));
  fprintf(fp, ")");
  if ( IsInTimeStampedTrie(pTN) )
    fprintf(fp, ", TimeStamp(%ld)", TSTN_TimeStamp((TSTNptr)pTN));
  fprintf(fp, "\n\tParent(%p), Child(%p), Sibling(%p)\n",
	 TN_Parent(pTN), TN_Child(pTN), TN_Sibling(pTN));
}
Exemple #4
0
int main(int argc, char *argv[])
{
	int i, j;
	int fa,nfa;				/* current argument we're looking at */
	int verb = 0;
	int out2 = 0;			/* Create dumy .ti2 file output */
	int disp = 0;			/* nz if this is a display device */
	int inp = 0;			/* nz if this is an input device */
	static char devname[MAXNAMEL+1] = { 0 };		/* Input CMYK/Device .txt file (may be null) */
	static char ciename[MAXNAMEL+1] = { 0 };		/* Input CIE .txt file (may be null) */
	static char specname[MAXNAMEL+1] = { 0 };		/* Input Device / Spectral .txt file */
	static char outname[MAXNAMEL+9] = { 0 };		/* Output cgats .ti3 file base name */
	static char outname2[MAXNAMEL+9] = { 0 };		/* Output cgats .ti2 file base name */
	cgats *cmy = NULL;		/* Input RGB/CMYK reference file */
	int f_id1 = -1, f_c, f_m, f_y, f_k = 0;	/* Field indexes */
	double dev_scale = 1.0;	/* Device value scaling */
	cgats *ncie = NULL;		/* Input CIE readings file (may be Dev & spectral too) */
	int f_id2, f_cie[3];	/* Field indexes */
	cgats *spec = NULL;		/* Input spectral readings (NULL if none) */
	double spec_scale = 1.0;	/* Spectral value scaling */
	int f_id3 = 0;			/* Field indexes */
	int spi[XSPECT_MAX_BANDS];	/* CGATS indexes for each wavelength */
	cgats *ocg;				/* output cgats structure for .ti3 */
	cgats *ocg2;			/* output cgats structure for .ti2 */
	time_t clk = time(0);
	struct tm *tsp = localtime(&clk);
	char *atm = asctime(tsp); /* Ascii time */
	int islab = 0;			/* CIE is Lab rather than XYZ */
	int specmin = 0, specmax = 0, specnum = 0;	/* Min and max spectral in nm, inclusive */
	int npat = 0;			/* Number of patches */
	int ndchan = 0;			/* Number of device channels, 0 = no device, RGB = 3, CMYK = 4 */
	int tlimit = -1;		/* Not set */
	double mxsum = -1.0;	/* Maximim sum of inks found in file */
	int mxsumix = 0;

	error_program = "txt2ti3";

	if (argc <= 1)
		usage("Too few arguments");

	/* 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(NULL);

			else if (argv[fa][1] == '2')
				out2 = 1;

			else if (argv[fa][1] == 'l') {
				if (na == NULL) usage("No ink limit parameter");
				fa = nfa;
				tlimit = atoi(na);
				if (tlimit < 1)
					tlimit = -1;
			}

			else if (argv[fa][1] == 'd') {
				disp = 1;
				inp = 0;

			} else if (argv[fa][1] == 'i') {
				disp = 0;
				inp = 1;

			} else if (argv[fa][1] == 'v')
				verb = 1;
			else 
				usage("Unknown flag");
		} else
			break;
	}

	/* See how many arguments remain */
	switch (argc - fa) {
		case 2:		/* Must be a new combined device + cie/spectral */
			if (fa >= argc || argv[fa][0] == '-') usage("Bad dev filename");
			strcpy(devname,argv[fa]);
			strcpy(ciename,argv[fa++]);
			if (fa >= argc || argv[fa][0] == '-') usage("Bad output filename");
			strcpy(outname, argv[fa++]);
			if (verb) printf("Single source file, assumed dev/cie/spectral\n");
			break;
		case 3:		/* Device + cie or spectral */
					/* or combined cie + spectral */
			if (fa >= argc || argv[fa][0] == '-') usage("Bad dev filename");
			strcpy(devname,argv[fa++]);
			if (fa >= argc || argv[fa][0] == '-') usage("Bad cie/spec filename");
			strcpy(ciename,argv[fa++]);	
			if (fa >= argc || argv[fa][0] == '-') usage("Bad output filename");
			strcpy(outname, argv[fa++]);
			if (verb) printf("Two source files, assumed dev + cie/spectral or dev/cie + spectral\n");
			break;
		case 4:		/* Device, ci and spectral */
			if (fa >= argc || argv[fa][0] == '-') usage("Bad dev filename");
			strcpy(devname,argv[fa++]);
			if (fa >= argc || argv[fa][0] == '-') usage("Bad cie filename");
			strcpy(ciename,argv[fa++]);	
			if (fa >= argc || argv[fa][0] == '-') usage("Bad spec filename");
			strcpy(specname,argv[fa++]);	
			if (fa >= argc || argv[fa][0] == '-') usage("Bad output filename");
			strcpy(outname, argv[fa++]);
			if (verb) printf("Three source files, assumed dev + cie + spectral\n");
			break;
		default:
			usage("Wrong number of filenames");
	}

	if (out2) {
		strcpy (outname2, outname);
		strcat(outname2,".ti2");
	}

	/* Convert basename into .ti3 */
	strcat(outname,".ti3");

	/* Open up the Input CMYK/RGB reference file (might be same as ncie/spec) */
	cmy = new_cgats();	/* Create a CGATS structure */
	cmy->add_other(cmy, "LGOROWLENGTH"); 	/* Gretag/Logo Target file */
	cmy->add_other(cmy, "Date:");			/* Gretag/Logo Target file */
	cmy->add_other(cmy, "ECI2002");			/* Gretag/Logo Target file */
	cmy->add_other(cmy, ""); 				/* Wildcard */
	if (cmy->read_name(cmy, devname))
		error ("Read: Can't read dev file '%s'. Unknown format, missing or corrupted file ? (%s)",devname,cmy->err);
	if (cmy->ntables != 1)
		warning("Input file '%s' doesn't contain exactly one table",devname);

	if ((npat = cmy->t[0].nsets) <= 0)
		error("No patches");

	if ((f_id1 = cmy->find_field(cmy, 0, "SampleName")) < 0
	 && (f_id1 = cmy->find_field(cmy, 0, "Sample_Name")) < 0
	 && (f_id1 = cmy->find_field(cmy, 0, "SAMPLE_NAME")) < 0
	 && (f_id1 = cmy->find_field(cmy, 0, "SAMPLE_ID")) < 0)
		error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",devname);
	if (cmy->t[0].ftype[f_id1] != nqcs_t
	 && cmy->t[0].ftype[f_id1] != cs_t
	 && cmy->t[0].ftype[f_id1] != i_t)
		error("Field SampleName (%s) from CMYK/RGB file '%s' is wrong type",cmy->t[0].fsym[f_id1],devname);

	if (cmy->find_field(cmy, 0, "RGB_R") >= 0) {
		ndchan = 3;
		if (verb)  {
			if (inp || disp)
				printf("Seems to be an RGB device\n");
			else
				printf("Seems to be a psuedo-RGB device\n");
		}
	} else if (cmy->find_field(cmy, 0, "CMYK_C") >= 0) {
		ndchan = 4;
		if (verb)
			printf("Seems to be a CMYK device\n");
	} else {
		printf("No device values found - hope that's OK!\n");
	}

	if (ndchan == 3) {
		if ((f_c = cmy->find_field(cmy, 0, "RGB_R")) < 0) {
			error("Input file '%s' doesn't contain field RGB_R",devname);
		}
		if (cmy->t[0].ftype[f_c] != r_t)
			error("Field RGB_R from file '%s' is wrong type - expect float",devname);

		if ((f_m = cmy->find_field(cmy, 0, "RGB_G")) < 0)
			error("Input file '%s' doesn't contain field RGB_G",devname);
		if (cmy->t[0].ftype[f_m] != r_t)
			error("Field RGB_G from file '%s' is wrong type - expect float",devname);

		if ((f_y = cmy->find_field(cmy, 0, "RGB_B")) < 0)
			error("Input file '%s' doesn't contain field RGB_B",devname);
		if (cmy->t[0].ftype[f_y] != r_t)
			error("Field RGB_B from file '%s' is wrong type - expect float",devname);

	} else if (ndchan == 4) {
		if ((f_c = cmy->find_field(cmy, 0, "CMYK_C")) < 0) {
			error("Input file '%s' doesn't contain field CMYK_C",devname);
		}
		if (cmy->t[0].ftype[f_c] != r_t)
			error("Field CMYK_C from file '%s' is wrong type - expect float",devname);

		if ((f_m = cmy->find_field(cmy, 0, "CMYK_M")) < 0)
			error("Input file '%s' doesn't contain field CMYK_M",devname);
		if (cmy->t[0].ftype[f_m] != r_t)
			error("Field CMYK_M from file '%s' is wrong type - expect float",devname);

		if ((f_y = cmy->find_field(cmy, 0, "CMYK_Y")) < 0)
			error("Input file '%s' doesn't contain field CMYK_Y",devname);
		if (cmy->t[0].ftype[f_y] != r_t)
			error("Field CMYK_Y from file '%s' is wrong type - expect float",devname);

		if ((f_k = cmy->find_field(cmy, 0, "CMYK_K")) < 0)
			error("Input file '%s' doesn't contain field CMYK_Y",devname);
		if (cmy->t[0].ftype[f_k] != r_t)
			error("Field CMYK_K from file '%s' is wrong type - expect float",devname);
	}
	if (verb && ndchan > 0) printf("Read device values\n");

	if (cmy->find_field(cmy, 0, "XYZ_X") >= 0
	 || cmy->find_field(cmy, 0, "LAB_L") >= 0) {
		/* We've got a new combined device+cie file as the first one. */
		/* Shuffle it into ciename , and ciename into specname */

		strcpy(specname, ciename);
		strcpy(ciename, devname);

		if (verb) printf("We've got a combined device + instrument readings file\n");
	}

	/* Open up the input nCIE or Spectral device data file */
	ncie = new_cgats();	/* Create a CGATS structure */
	ncie->add_other(ncie, "LGOROWLENGTH"); 	/* Gretag/Logo Target file */
	ncie->add_other(ncie, "ECI2002"); 		/* Gretag/Logo Target file */
	ncie->add_other(ncie, ""); 				/* Wildcard */
	if (ncie->read_name(ncie, ciename))
		error ("Read: Can't read cie file '%s'. Unknown format, missing or corrupted file ?",ciename);
	if (ncie->ntables != 1)
		warning("Input file '%s' doesn't contain exactly one table",ciename);

	if (npat != ncie->t[0].nsets)
		error("Number of patches between '%s' and '%s' doesn't match",devname,ciename);

	if ((f_id2 = ncie->find_field(ncie, 0, "SampleName")) < 0
	 && (f_id2 = ncie->find_field(ncie, 0, "Sample_Name")) < 0
	 && (f_id2 = ncie->find_field(ncie, 0, "SAMPLE_NAME")) < 0
	 && (f_id2 = ncie->find_field(ncie, 0, "SAMPLE_ID")) < 0)
		error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",ciename);
	if (ncie->t[0].ftype[f_id2] != nqcs_t
	 && ncie->t[0].ftype[f_id2] != cs_t
	 && cmy->t[0].ftype[f_id2] != i_t)
		error("Field SampleName (%s) from cie file '%s' is wrong type",ncie->t[0].fsym[f_id2],ciename);

	if (ncie->find_field(ncie, 0, "XYZ_X") < 0
	 && ncie->find_field(ncie, 0, "LAB_L") < 0) {

		/* Not a cie file. See if it's a spectral file */
		if (ncie->find_field(ncie, 0, "nm500") < 0
		 && ncie->find_field(ncie, 0, "NM_500") < 0
		 && ncie->find_field(ncie, 0, "SPECTRAL_NM_500") < 0
		 && ncie->find_field(ncie, 0, "R_500") < 0
		 && ncie->find_field(ncie, 0, "SPECTRAL_500") < 0)
			error("Input file '%s' doesn't contain field XYZ_X or spectral",ciename);	/* Nope */

		/* We have a spectral file only. Fix things and drop through */
		ncie->del(ncie);
		ncie = NULL;
		strcpy(specname, ciename);
		ciename[0] = '\000';

	} else {	/* Continue dealing with cie value file */
		char *fields[2][3] = {
			{ "XYZ_X", "XYZ_Y", "XYZ_Z" },
			{ "LAB_L", "LAB_A", "LAB_B" }
		};

		if (ncie->find_field(ncie, 0, "nm500") >= 0
		 || ncie->find_field(ncie, 0, "NM_500") < 0
		 || ncie->find_field(ncie, 0, "SPECTRAL_NM_500") >= 0
		 || ncie->find_field(ncie, 0, "R_500") >= 0
		 || ncie->find_field(ncie, 0, "SPECTRAL_500") >= 0) {
			if (verb) printf("Found spectral values\n");
			/* It's got spectral data too. Make sure we read it */
			strcpy(specname, ciename);
		}

		if (ncie->find_field(ncie, 0, "LAB_L") >= 0)
			islab = 1;

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

			if ((f_cie[i] = ncie->find_field(ncie, 0, fields[islab][i])) < 0)
				error("Input file '%s' doesn't contain field XYZ_Y",fields[islab][i], ciename);

			if (ncie->t[0].ftype[f_cie[i]] != r_t)
				error("Field %s from file '%s' is wrong type - expect float",fields[islab][i], ciename);
		}
	
		if (verb) printf("Found CIE values\n");
	}

	/* Open up the input Spectral device data file */
	if (specname[0] != '\000') {
		char bufs[5][50];

		spec = new_cgats();	/* Create a CGATS structure */
		spec->add_other(spec, "LGOROWLENGTH"); 	/* Gretag/Logo Target file */
		spec->add_other(spec, "ECI2002"); 		/* Gretag/Logo Target file */
		spec->add_other(spec, ""); 				/* Wildcard */
		if (spec->read_name(spec, specname))
			error ("Read: Can't read spec file '%s'. Unknown format, missing or corrupted file ?",specname);
		if (spec->ntables != 1)
			warning("Input file '%s' doesn't contain exactly one table",specname);

		if (npat != spec->t[0].nsets)
			error("Number of patches between '%s' and '%s' doesn't match",specname);

		if ((f_id3 = spec->find_field(spec, 0, "SampleName")) < 0
		 && (f_id3 = spec->find_field(spec, 0, "Sample_Name")) < 0
		 && (f_id3 = spec->find_field(spec, 0, "SAMPLE_NAME")) < 0
		 && (f_id3 = spec->find_field(spec, 0, "SAMPLE_ID")) < 0)
			error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",specname);
		if (spec->t[0].ftype[f_id3] != nqcs_t
		 && spec->t[0].ftype[f_id3] != cs_t
		 && cmy->t[0].ftype[f_id3] != i_t)
			error("Field SampleName (%s) from spec file '%s' is wrong type",spec->t[0].fsym[f_id3],specname);

		/* Find the spectral readings nm range */
		for (specmin = 500; specmin >= 300; specmin -= 10) {
			sprintf(bufs[0],"nm%03d", specmin);
			sprintf(bufs[1],"NM_%03d", specmin);
			sprintf(bufs[2],"SPECTRAL_NM_%03d", specmin);
			sprintf(bufs[3],"R_%03d", specmin);
			sprintf(bufs[4],"SPECTRAL_%03d", specmin);

			if (spec->find_field(spec, 0, bufs[0]) < 0
			 && spec->find_field(spec, 0, bufs[1]) < 0
			 && spec->find_field(spec, 0, bufs[2]) < 0
			 && spec->find_field(spec, 0, bufs[3]) < 0
			 && spec->find_field(spec, 0, bufs[4]) < 0)	/* Not found */
			break;
		}
		specmin += 10;
		for (specmax = 500; specmax <= 900; specmax += 10) {
			sprintf(bufs[0],"nm%03d", specmax);
			sprintf(bufs[1],"NM_%03d", specmax);
			sprintf(bufs[2],"SPECTRAL_NM_%03d", specmax);
			sprintf(bufs[3],"R_%03d", specmax);
			sprintf(bufs[4],"SPECTRAL_%03d", specmax);

			if (spec->find_field(spec, 0, bufs[0]) < 0
			 && spec->find_field(spec, 0, bufs[1]) < 0
			 && spec->find_field(spec, 0, bufs[2]) < 0
			 && spec->find_field(spec, 0, bufs[3]) < 0
			 && spec->find_field(spec, 0, bufs[4]) < 0) /* Not found */
			break;
		}
		specmax -= 10;
				
		if (specmin > 420 || specmax < 680) {	/* Not enough range to be useful */
			spec->del(spec);
			spec = NULL;
			specname[0] = '\000';
		} else {

			specnum = (specmax - specmin)/10 + 1;

			if (verb)
				printf("Found there are %d spectral values, from %d to %d nm\n",specnum,specmin,specmax);
			

			/* Locate the fields for spectral values */
			for (j = 0; j < specnum; j++) {
				sprintf(bufs[0],"nm%03d", specmin + 10 * j);
				sprintf(bufs[1],"NM_%03d", specmin + 10 * j);
				sprintf(bufs[2],"SPECTRAL_NM_%03d", specmin + 10 * j);
				sprintf(bufs[3],"R_%03d", specmin + 10 * j);
				sprintf(bufs[4],"SPECTRAL_%03d", specmin + 10 * j);
	
				if ((spi[j] = spec->find_field(spec, 0, bufs[0])) < 0
				 && (spi[j] = spec->find_field(spec, 0, bufs[1])) < 0
				 && (spi[j] = spec->find_field(spec, 0, bufs[2])) < 0
				 && (spi[j] = spec->find_field(spec, 0, bufs[3])) < 0
				 && (spi[j] = spec->find_field(spec, 0, bufs[4])) < 0) {	/* Not found */
					
					spec->del(spec);
					spec = NULL;
					specname[0] = '\000';
					error("Failed to find spectral band %d nm in file '%s'\n",specmin + 10 * j,specname);
				} else {
					if (spec->t[0].ftype[spi[j]] != r_t)
						error("Field '%s' from file '%s' is wrong type - expect float",spec->t[0].fsym[spi[j]], specname);
				}

			}
		}
	}

	if (ciename[0] == '\000' && specname[0] == '\000')
		error("Input file doesn't contain either CIE or spectral data");

	/* Setup output cgats file */
	ocg = new_cgats();	/* Create a CGATS structure */
	ocg->add_other(ocg, "CTI3"); 	/* our special type is Calibration Target Information 3 */
	ocg->add_table(ocg, tt_other, 0);	/* Start the first table */

	ocg->add_kword(ocg, 0, "DESCRIPTOR", "Argyll Calibration Target chart information 3",NULL);
	ocg->add_kword(ocg, 0, "ORIGINATOR", "Argyll target", NULL);
	atm[strlen(atm)-1] = '\000';	/* Remove \n from end */
	ocg->add_kword(ocg, 0, "CREATED",atm, NULL);
	if (disp)
		ocg->add_kword(ocg, 0, "DEVICE_CLASS","DISPLAY", NULL);	/* What sort of device this is */
	else if (inp)
		ocg->add_kword(ocg, 0, "DEVICE_CLASS","INPUT", NULL);	/* What sort of device this is */
	else
		ocg->add_kword(ocg, 0, "DEVICE_CLASS","OUTPUT", NULL);	/* What sort of device this is */

	/* Note what instrument the chart was read with */
	/* Assume this - could try reading from file INSTRUMENTATION "SpectroScan" ?? */
	ocg->add_kword(ocg, 0, "TARGET_INSTRUMENT", inst_name(instSpectrolino) , NULL);

	/* Fields we want */
	ocg->add_field(ocg, 0, "SAMPLE_ID", nqcs_t);
	if (f_id1 >= 0) 
		ocg->add_field(ocg, 0, "SAMPLE_NAME", cs_t);

	if (ndchan == 3) {
		ocg->add_field(ocg, 0, "RGB_R", r_t);
		ocg->add_field(ocg, 0, "RGB_G", r_t);
		ocg->add_field(ocg, 0, "RGB_B", r_t);
		if (inp) {
			if (islab)
				ocg->add_kword(ocg, 0, "COLOR_REP","LAB_RGB", NULL);
			else
				ocg->add_kword(ocg, 0, "COLOR_REP","XYZ_RGB", NULL);
		} else if (disp) {
			if (islab)
				ocg->add_kword(ocg, 0, "COLOR_REP","RGB_LAB", NULL);
			else
				ocg->add_kword(ocg, 0, "COLOR_REP","RGB_XYZ", NULL);
		} else {
			if (islab)
				ocg->add_kword(ocg, 0, "COLOR_REP","iRGB_LAB", NULL);
			else
				ocg->add_kword(ocg, 0, "COLOR_REP","iRGB_XYZ", NULL);
		}
	} else if (ndchan == 4) {
		ocg->add_field(ocg, 0, "CMYK_C", r_t);
		ocg->add_field(ocg, 0, "CMYK_M", r_t);
		ocg->add_field(ocg, 0, "CMYK_Y", r_t);
		ocg->add_field(ocg, 0, "CMYK_K", r_t);
		if (inp) {	/* Does this make any sense ? */
			if (islab)
				ocg->add_kword(ocg, 0, "COLOR_REP","LAB_CMYK", NULL);
			else
				ocg->add_kword(ocg, 0, "COLOR_REP","XYZ_CMYK", NULL);
		} else {
			if (islab)
				ocg->add_kword(ocg, 0, "COLOR_REP","CMYK_LAB", NULL);
			else
				ocg->add_kword(ocg, 0, "COLOR_REP","CMYK_XYZ", NULL);
		}
	}

	if (ncie != NULL) {
		if (islab) {
			ocg->add_field(ocg, 0, "LAB_L", r_t);
			ocg->add_field(ocg, 0, "LAB_A", r_t);
			ocg->add_field(ocg, 0, "LAB_B", r_t);
		} else {
			ocg->add_field(ocg, 0, "XYZ_X", r_t);
			ocg->add_field(ocg, 0, "XYZ_Y", r_t);
			ocg->add_field(ocg, 0, "XYZ_Z", r_t);
		}
	}

	/* Guess the device data scaling */
	if (ndchan > 0) {
		double maxv = 0.0;
		int f_dev[4] = { f_c, f_m, f_y, f_k };

		/* Guess what scale the spectral data is set to */
		for (i = 0; i < npat; i++) {
			for (j = 0; j < ndchan; j++) {
				double vv;
				vv = *((double *)cmy->t[0].fdata[i][f_dev[j]]);
				if (vv > maxv)
					maxv = vv;
			}
		}
		if (maxv < 10.0) {
			dev_scale = 100.0/1.0;
			if (verb) printf("Device max found = %f, scale by 100.0\n",maxv);
		} else if (maxv > 160.0) {
			dev_scale = 100.0/255.0;
			if (verb) printf("Device max found = %f, scale by 100/255\n",maxv);
		} else {
			dev_scale = 100.0/100.0;
			if (verb) printf("Device max found = %f, scale by 1.0\n",maxv);
		}
	}

	if (spec != NULL) {
		char buf[100];
		double maxv = 0.0;
		sprintf(buf,"%d", specnum);
		ocg->add_kword(ocg, 0, "SPECTRAL_BANDS",buf, NULL);
		sprintf(buf,"%d", specmin);
		ocg->add_kword(ocg, 0, "SPECTRAL_START_NM",buf, NULL);
		sprintf(buf,"%d", specmax);
		ocg->add_kword(ocg, 0, "SPECTRAL_END_NM",buf, NULL);

		/* Generate fields for spectral values */
		for (j = 0; j < specnum; j++) {
			sprintf(buf,"SPEC_%03d", specmin + 10 * j);
			ocg->add_field(ocg, 0, buf, r_t);
		}

		/* Guess what scale the spectral data is set to */
		for (i = 0; i < npat; i++) {
			for (j = 0; j < specnum; j++) {
				double vv;
				vv = *((double *)spec->t[0].fdata[i][spi[j]]);
				if (vv > maxv)
					maxv = vv;
			}
		}
		if (maxv < 10.0) {
			spec_scale = 100.0/1.0;
			if (verb) printf("Spectral max found = %f, scale by 100.0\n",maxv);
		} else if (maxv > 160.0) {
			spec_scale = 100.0/255.0;
			if (verb) printf("Spectral max found = %f, scale by 100/255\n",maxv);
		} else {
			spec_scale = 100.0/100.0;
			if (verb) printf("Spectral max found = %f, scale by 1.0\n",maxv);
		}
	}

	/* Write out the patch info to the output CGATS file */
	{
		cgats_set_elem *setel;	/* Array of set value elements */

		if ((setel = (cgats_set_elem *)malloc(
		     sizeof(cgats_set_elem) * ocg->t[0].nfields)) == NULL)
			error("Malloc failed!");

		/* Write out the patch info to the output CGATS file */
		for (i = 0; i < npat; i++) {
			char id[100];
			int k = 0;

			if (ncie != NULL) {
				if (strcmp(((char *)cmy->t[0].rfdata[i][f_id1]), 
				           ((char *)ncie->t[0].rfdata[i][f_id2])) != 0) {
					error("Patch label mismatch to CIE values, patch %d, '%s' != '%s'\n",
					       i, ((char *)cmy->t[0].rfdata[i][f_id1]), 
				              ((char *)ncie->t[0].rfdata[i][f_id2]));
				}
			}

			if (spec != NULL) {
				if (strcmp(((char *)cmy->t[0].rfdata[i][f_id1]), 
				           ((char *)spec->t[0].rfdata[i][f_id3])) != 0) {
					error("Patch label mismatch to spectral values, patch %d, '%s' != '%s'\n",
					       i, ((char *)cmy->t[0].rfdata[i][f_id1]), 
				              ((char *)spec->t[0].rfdata[i][f_id3]));
				}
			}

			/* SAMPLE ID */
			sprintf(id, "%d", i+1);
			setel[k++].c = id;

			/* SAMPLE NAME */
			if (f_id1 >= 0) 
				setel[k++].c = (char *)cmy->t[0].rfdata[i][f_id1];
			
			if (ndchan == 3) {
				setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_c]);
				setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_m]);
				setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_y]);
			} else if (ndchan == 4){
				double sum = 0.0;
				sum += setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_c]);
				sum += setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_m]);
				sum += setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_y]);
				sum += setel[k++].d = dev_scale * *((double *)cmy->t[0].fdata[i][f_k]);
				if (sum > mxsum) {
					mxsum = sum;
					mxsumix = i;
				}
			}
	
			if (ncie != NULL) {
				setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[0]]);	
				setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[1]]);
				setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[2]]);
			}
	
			if (spec) {
				for (j = 0; j < specnum; j++) {
					setel[k++].d = spec_scale * *((double *)spec->t[0].fdata[i][spi[j]]);
				}
			}

			ocg->add_setarr(ocg, 0, setel);
		}

		free(setel);
	}

	if (tlimit < 0 && mxsum > 0.0) {
		if (verb)
			printf("No ink limit given, using maximum %f found in file at %d\n",mxsum,mxsumix+1);

		tlimit = (int)(mxsum + 0.5);
	}

	if (tlimit > 0) {
		char buf[100];
		sprintf(buf, "%d", tlimit);
		ocg->add_kword(ocg, 0, "TOTAL_INK_LIMIT", buf, NULL);
	}

	if (ocg->write_name(ocg, outname))
		error("Write error : %s",ocg->err);

	/* Create a dummy .ti2 file (used with scanin -r) */
	if (out2) {

		/* Setup output cgats file */
		ocg2 = new_cgats();	/* Create a CGATS structure */
		ocg2->add_other(ocg2, "CTI2"); 	/* our special type is Calibration Target Information 2 */
		ocg2->add_table(ocg2, tt_other, 0);	/* Start the first table */

		ocg2->add_kword(ocg2, 0, "DESCRIPTOR", "Argyll Calibration Target chart information 2",NULL);
		ocg2->add_kword(ocg2, 0, "ORIGINATOR", "Argyll txt2ti3", NULL);
		atm[strlen(atm)-1] = '\000';	/* Remove \n from end */
		ocg2->add_kword(ocg2, 0, "CREATED",atm, NULL);
		if (disp)
			ocg2->add_kword(ocg2, 0, "DEVICE_CLASS","DISPLAY", NULL);	/* What sort of device this is */
		else
			ocg2->add_kword(ocg2, 0, "DEVICE_CLASS","OUTPUT", NULL);	/* What sort of device this is */
		/* Note what instrument the chart was read with */
		/* Assume this - could try reading from file INSTRUMENTATION "SpectroScan" ?? */
		ocg2->add_kword(ocg2, 0, "TARGET_INSTRUMENT", inst_name(instSpectrolino) , NULL);

		/* Fields we want */
		ocg2->add_field(ocg2, 0, "SAMPLE_ID", nqcs_t);
		ocg2->add_field(ocg2, 0, "SAMPLE_LOC", nqcs_t);

		/* We're missing lots of .ti2 stuff like: */
		/* ocg->add_kword(ocg, 0, "APPROX_WHITE_POINT",icg->t[0].kdata[fi], NULL); */
		/* ocg->add_kword(ocg, 0, "PATCH_LENGTH", buf, NULL); */
		/* ocg->add_kword(ocg, 0, "GAP_LENGTH", buf, NULL); */
		/* ocg->add_kword(ocg, 0, "TRAILER_LENGTH", buf, NULL); */
		/* ocg->add_kword(ocg, 0, "STEPS_IN_PASS", buf, NULL); */
		/* ocg->add_kword(ocg, 0, "PASSES_IN_STRIPS", pis, NULL); */
		/* ocg->add_kword(ocg, 0, "STRIP_INDEX_PATTERN", sixpat, NULL); */
		/* ocg->add_kword(ocg, 0, "PATCH_INDEX_PATTERN", pixpat, NULL); */
		/* ocg->add_kword(ocg, 0, "INDEX_ORDER", ixord ? "PATCH_THEN_STRIP" : "STRIP_THEN_PATCH", NULL); */

		if (tlimit > 0) {
			char buf[100];
			sprintf(buf, "%d", tlimit);
			ocg2->add_kword(ocg2, 0, "TOTAL_INK_LIMIT", buf, NULL);
		}

		if (ndchan == 3) {
			ocg2->add_field(ocg2, 0, "RGB_R", r_t);
			ocg2->add_field(ocg2, 0, "RGB_G", r_t);
			ocg2->add_field(ocg2, 0, "RGB_B", r_t);
			if (inp || disp) {
				ocg2->add_kword(ocg2, 0, "COLOR_REP","RGB", NULL);
			} else {
				ocg2->add_kword(ocg2, 0, "COLOR_REP","iRGB", NULL);
			}
		} else if (ndchan == 4) {
			ocg2->add_field(ocg2, 0, "CMYK_C", r_t);
			ocg2->add_field(ocg2, 0, "CMYK_M", r_t);
			ocg2->add_field(ocg2, 0, "CMYK_Y", r_t);
			ocg2->add_field(ocg2, 0, "CMYK_K", r_t);
			ocg2->add_kword(ocg2, 0, "COLOR_REP","CMYK", NULL);
		}

		if (ncie != NULL) {
			if (islab) {
				ocg2->add_field(ocg2, 0, "LAB_L", r_t);
				ocg2->add_field(ocg2, 0, "LAB_A", r_t);
				ocg2->add_field(ocg2, 0, "LAB_B", r_t);
			} else {
				ocg2->add_field(ocg2, 0, "XYZ_X", r_t);
				ocg2->add_field(ocg2, 0, "XYZ_Y", r_t);
				ocg2->add_field(ocg2, 0, "XYZ_Z", r_t);
			}
		}

		/* Write out the patch info to the output CGATS file */
		{
			cgats_set_elem *setel;	/* Array of set value elements */

			if ((setel = (cgats_set_elem *)malloc(
			     sizeof(cgats_set_elem) * (2 + (ndchan) + (ncie != NULL ? 3 : 0)))) == NULL)
				error("Malloc failed!");

			/* Write out the patch info to the output CGATS file */
			for (i = 0; i < npat; i++) {
				char id[100];
				int k = 0;

				if (ncie != NULL) {
					if (strcmp(((char *)cmy->t[0].rfdata[i][f_id1]), 
					           ((char *)ncie->t[0].rfdata[i][f_id2])) != 0) {
						error("Patch label mismatch to CIE values, patch %d, '%s' != '%s'\n",
						       i, ((char *)cmy->t[0].rfdata[i][f_id1]), 
					              ((char *)ncie->t[0].rfdata[i][f_id2]));
					}
				}

				if (spec != NULL) {
					if (strcmp(((char *)cmy->t[0].rfdata[i][f_id1]), 
					           ((char *)spec->t[0].rfdata[i][f_id3])) != 0) {
						error("Patch label mismatch to spectral values, patch %d, '%s' != '%s'\n",
						       i, ((char *)cmy->t[0].rfdata[i][f_id1]), 
					              ((char *)spec->t[0].rfdata[i][f_id3]));
					}
				}

				sprintf(id, "%d", i+1);
				setel[k++].c = id;						/* ID */
				setel[k++].c = ((char *)cmy->t[0].rfdata[i][f_id1]); 	/* Location */

				if (ndchan == 3) {
					setel[k++].d = 100.0/255.0 * *((double *)cmy->t[0].fdata[i][f_c]);
					setel[k++].d = 100.0/255.0 * *((double *)cmy->t[0].fdata[i][f_m]);
					setel[k++].d = 100.0/255.0 * *((double *)cmy->t[0].fdata[i][f_y]);
				} else if (ndchan == 4) {
					setel[k++].d = *((double *)cmy->t[0].fdata[i][f_c]);
					setel[k++].d = *((double *)cmy->t[0].fdata[i][f_m]);
					setel[k++].d = *((double *)cmy->t[0].fdata[i][f_y]);
					setel[k++].d = *((double *)cmy->t[0].fdata[i][f_k]);
				}
		
				if (ncie != NULL) {
					setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[0]]);	
					setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[1]]);
					setel[k++].d = *((double *)ncie->t[0].fdata[i][f_cie[2]]);
				}
				ocg2->add_setarr(ocg2, 0, setel);
			}

			free(setel);
		}

		if (ocg2->write_name(ocg2, outname2))
			error("Write error : %s",ocg2->err);

	}

	/* Clean up */
	cmy->del(cmy);
	if (ncie != NULL)
		ncie->del(ncie);
	if (spec != NULL)
		spec->del(spec);
	ocg->del(ocg);

	return 0;
}
int main(int argc, char** argv)
{
    std::string path("/home/chi/arco/test/build/temp/");
    std::string filename("temp_0_0");
    pcl::console::parse_argument(argc, argv, "--f", filename);
    pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>());
    pcl::io::loadPCDFile(path+filename+".pcd", *cloud);
    
    int w = cloud->width;
    int h = cloud->height;
    cv::Mat img = cv::Mat::zeros(h, w, CV_8UC3);
    for( size_t i = 0 ; i < cloud->size() ; i++ )
    {
        int r = i / w;
        int c = i % w;
        
        uint32_t rgb_tmp = cloud->at(i).rgba;
        
        img.at<uchar>(r, c*3+2) = (rgb_tmp >> 16) & 0x0000ff;
        img.at<uchar>(r, c*3+1) = (rgb_tmp >> 8) & 0x0000ff;
        img.at<uchar>(r, c*3+0) = (rgb_tmp) & 0x0000ff;
    }
    
    cv::imwrite(filename+".png", img);
    return 0;
    
    
    std::string in_path("/home/chi/JHUIT/raw/");
    std::string out_path("img_tmp/");
    std::string inst_name("driller_kel_0");
    std::string seq_id("1");;
    
    float elev = ELEV;
    int max_frames = 200;
    pcl::console::parse_argument(argc, argv, "--p", in_path);
    pcl::console::parse_argument(argc, argv, "--s", seq_id);
    pcl::console::parse_argument(argc, argv, "--i", inst_name);
    pcl::console::parse_argument(argc, argv, "--elev", elev);
    pcl::console::parse_argument(argc, argv, "--max", max_frames);
        
    std::cerr << "Loading-"<< inst_name << std::endl;
    if( exists_dir(out_path) == false )
            boost::filesystem::create_directories(out_path);
    
    std::ifstream fp;
    fp.open((in_path+"/PlaneCoef_"+ seq_id + ".txt").c_str(), std::ios::in);
    if( fp.is_open() == false )
    {
        std::cerr << "Failed to open: " << in_path+"/PlaneCoef_"+ seq_id + ".txt" << std::endl;
        exit(0);
    }
    pcl::ModelCoefficients::Ptr planeCoef(new pcl::ModelCoefficients());
    planeCoef->values.resize(4);
    fp >> planeCoef->values[0] >> planeCoef->values[1] >> planeCoef->values[2] >> planeCoef->values[3];
    fp.close();
    
    std::vector< pcl::PointCloud<PointT>::Ptr > cloud_set;
    std::vector< KEYSET > keypt_set;
    std::vector< cv::Mat > keydescr_set;
    
    for( size_t j = 0 ; j < max_frames ; j++ )
    {
        std::stringstream ss;
        ss << j;
        
        if( j % 3 != 0 )
            continue;
        
        std::string filename(in_path + inst_name + "/" + inst_name + "_" + seq_id + "_" + ss.str() + ".pcd");
        
        if( exists_test(filename) == false )
            continue;
        
        pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>());
        pcl::io::loadPCDFile(filename, *cloud);
        
        int w = cloud->width;
        int h = cloud->height;
        
        //std::cerr << w << " " << h << " " << cloud->size() << std::endl;
        
        cv::Mat rgb = cv::Mat::zeros(h, w, CV_8UC3);
        cv::Mat gray = cv::Mat::zeros(h, w, CV_8UC1);

        for(size_t i = 0 ; i < cloud->size() ; i++ )
        {
            int r_idx = i / w;
            int c_idx = i % w;
            
            uint32_t rgb_tmp = cloud->at(i).rgba;
            rgb.at<uchar>(r_idx, c_idx*3+2) = (rgb_tmp >> 16) & 0x0000ff;
            rgb.at<uchar>(r_idx, c_idx*3+1) = (rgb_tmp >> 8)  & 0x0000ff;
            rgb.at<uchar>(r_idx, c_idx*3+0) = (rgb_tmp)       & 0x0000ff;  
            
        }
        
        cv::cvtColor(rgb,gray,CV_BGR2GRAY);
        
        //cv::imshow("GRAY", rgb);
        //cv::waitKey();
        
        cv::SiftFeatureDetector *sift_det = new cv::SiftFeatureDetector(
            0, // nFeatures
            4, // nOctaveLayers
            0.04, // contrastThreshold 
            10, //edgeThreshold
            1.6 //sigma
            );
    
        cv::SiftDescriptorExtractor * sift_ext = new cv::SiftDescriptorExtractor();
        
        KEYSET keypoints;
        cv::Mat descriptors;
        sift_det->detect(gray, keypoints);
        sift_ext->compute(gray, keypoints, descriptors);
        printf("%d sift keypoints are found.\n", (int)keypoints.size());

        keypt_set.push_back(keypoints);
        keydescr_set.push_back(descriptors);
        
        cloud = cropCloud(cloud, planeCoef, 0.114);
        cloud_set.push_back(cloud);
        
        //cv::imshow("GRAY", in_rgb);
        //cv::waitKey();
        //cv::imwrite(out_path + ss.str() + ".jpg", in_rgb);
        
        //viewer->addPointCloud(cloud, "cloud");
        //viewer->spin();
        //if( show_keys )
        /*
        {
            cv::Mat out_image;
            cv::drawKeypoints(gray, keypoints, out_image);
            cv::imshow("keypoints", out_image);
            cv::waitKey();
        }
        //*/
        
    }
    
    int total = cloud_set.size();
    /*
    std::vector< pcl::PointCloud<PointT>::Ptr > first_half, second_half;
    std::vector< KEYSET > first_keypt, second_keypt;
    std::vector< cv::Mat > first_keydescr, second_keydescr;
    
    first_half.insert(first_half.end(), cloud_set.begin(), cloud_set.begin()+total/2);
    first_keypt.insert(first_keypt.end(), keypt_set.begin(), keypt_set.begin()+total/2);
    first_keydescr.insert(first_keydescr.end(), keydescr_set.begin(), keydescr_set.begin()+total/2);
    
    second_half.push_back(cloud_set[0]);
    second_keypt.push_back(keypt_set[0]);
    second_keydescr.push_back(keydescr_set[0]);
    for( int i = 1 ; i < total/2 ; i++ )
    {
        second_half.push_back(cloud_set[total-i]);
        second_keypt.push_back(keypt_set[total-i]);
        second_keydescr.push_back(keydescr_set[total-i]);
    }
    
    pcl::PointCloud<PointT>::Ptr first_model = Meshing(first_half, first_keypt, first_keydescr);
    pcl::PointCloud<PointT>::Ptr second_model = Meshing(second_half, second_keypt, second_keydescr);
    pcl::PointCloud<PointT>::Ptr full_model (new pcl::PointCloud<PointT>());
    full_model->insert(full_model->end(), first_model->begin(), first_model->end());
    full_model->insert(full_model->end(), second_model->begin(), second_model->end());
    */
    pcl::PointCloud<PointT>::Ptr full_model = Meshing(cloud_set, keypt_set, keydescr_set);
    
    full_model = cropCloud(full_model, planeCoef, elev);
    
    pcl::io::savePCDFile("temp_full.pcd", *full_model);
    
    pcl::PLYWriter ply_writer;
    ply_writer.write("temp_full.ply", *full_model, true);
    
    /*
    pcl::PointCloud<PointT>::Ptr full_model(new pcl::PointCloud<PointT>());
    pcl::io::loadPCDFile("temp_full.pcd", *full_model);
    
    std::vector<int> idx_ff;
    pcl::removeNaNFromPointCloud(*full_model, *full_model, idx_ff);
    
    pcl::PointCloud<NormalT>::Ptr full_model_normals (new pcl::PointCloud<NormalT>());
    computeNormals(full_model, full_model_normals, 0.02);
    
    AdjustCloudNormal(full_model, full_model_normals);
    
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer());
    viewer->initCameraParameters();
    viewer->addCoordinateSystem(0.1);
    viewer->setCameraPosition(0, 0, 0.1, 0, 0, 1, 0, -1, 0);
    
    //viewer->addPointCloud(full_model,  "full_model");
    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 1.0, 1.0, "full_model");
    //viewer->addPointCloudNormals<PointT, NormalT> (full_model, full_model_normals, 5, 0.01, "normals");
    //viewer->spin();
    
    pcl::PointCloud<pcl::PointNormal>::Ptr joint_model (new pcl::PointCloud<pcl::PointNormal>());
    
    pcl::copyPointCloud(*full_model, *joint_model);
    pcl::copyPointCloud(*full_model_normals, *joint_model);
    
    //std::cerr << full_model->size() << " " << full_model_normals->size() << " " << joint_model->size() << std::endl;
    
    //pcl::concatenateFields (*full_model, *full_model_normals, *joint_model);
    pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
    tree2->setInputCloud (joint_model);
    
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
    pcl::PolygonMesh model_mesh;

    gp3.setMu(2.5);
    gp3.setMaximumNearestNeighbors(100);
    gp3.setSearchRadius(0.03);
    gp3.setMaximumSurfaceAngle(M_PI/4);         // 45 degrees
    gp3.setMinimumAngle(M_PI/18);               // 10 degrees
    gp3.setMaximumAngle(2*M_PI/3);              // 120 degrees
    gp3.setNormalConsistency(false);

    // Get result
    gp3.setInputCloud (joint_model);
    gp3.setSearchMethod (tree2);
    gp3.reconstruct (model_mesh);
    
    //viewer->addPointCloud(full_model, "model");
    viewer->addPolygonMesh(model_mesh, "full_model_mesh");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.55, 0.05, "full_model_mesh");
    viewer->spin();
    */
    
    return 0;
}
Exemple #6
0
/* a serial connection, and instUnknown not serial. */
static instType ser_inst_type(
	icoms *p, 
	int port		/* Enumerated port number, 1..n */
) {
	instType rv = instUnknown;
	char buf[100];
	baud_rate brt[] = { baud_9600, baud_19200, baud_4800, baud_2400,
	                     baud_1200, baud_38400, baud_57600, baud_115200,
	                     baud_600, baud_300, baud_110, baud_nc };
	long etime;
	int bi, i;
	int se, len;
	int xrite = 0;
	int ss = 0;
	int so = 0;
	
	if (p->paths == NULL)
		p->get_paths(p);

	if (port <= 0 || port > p->npaths)
		return instUnknown;

#ifdef ENABLE_USB
	if (p->paths[port-1]->dev != NULL
	 || p->paths[port-1]->hev != NULL)
		return instUnknown;
#endif /* ENABLE_USB */

	if (p->debug) fprintf(stderr,"instType: About to init Serial I/O\n");

	bi = 0;

	/* The tick to give up on */
	etime = msec_time() + (long)(1000.0 * 20.0 + 0.5);

	if (p->debug) fprintf(stderr,"instType: Trying different baud rates (%lu msec to go)\n",etime - msec_time());

	/* Until we time out, find the correct baud rate */
	for (i = bi; msec_time() < etime; i++) {
		if (brt[i] == baud_nc)
			i = 0;
		p->set_ser_port(p, port, fc_none, brt[i], parity_none, stop_1, length_8);

//printf("~1 brt = %d\n",brt[i]);
		if ((se = p->write_read(p, ";D024\r\n", buf, 100, '\r', 1, 0.5)) != 0) {
			if ((se & ICOM_USERM) == ICOM_USER) {
				if (p->debug) fprintf(stderr,"instType: User aborted\n");
				return instUnknown;
			}
		}
		len = strlen(buf);

//printf("~1 len = %d\n",len);
		if (len < 4)
			continue;

		/* Is this an X-Rite error value such as "<01>" ? */
		if (buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') {
//printf("~1 xrite\n");
			xrite = 1;
			break;
		}

		/* Is this a Spectrolino error resonse ? */
		if (len >= 5 && strncmp(buf, ":26", 3) == 0) {
//printf("~1 spectrolino\n");
			so = 1;
			break;
		}
		/* Is this a SpectroScan response ? */
		if (len >= 7 && strncmp(buf, ":D183", 5) == 0) {
//printf("~1 spectroscan\n");
			ss = 1;
			break;
		}
	}

	if (msec_time() >= etime) {		/* We haven't established comms */
		if (p->debug) fprintf(stderr,"instType: Failed to establish coms\n");
		return instUnknown;
	}

	if (p->debug) fprintf(stderr,"instType: Got coms with instrument\n");

	/* Spectrolino */
	if (so) {
		rv = instSpectrolino;
	}

	/* SpectroScan */
	if (ss) {
		rv = instSpectroScan;
		if ((se = p->write_read(p, ";D030\r\n", buf, 100, '\n', 1, 1.5)) == 0)  {
			if (strlen(buf) >= 41) {
				hex2bin(&buf[5], 12);
//printf("~1 type = '%s'\n",buf);
				if (strncmp(buf, ":D190SpectroScanT", 17) == 0)
					rv = instSpectroScanT;
			}
		}
	}
	if (xrite) {

		/* Get the X-Rite model and version number */
		if ((se = p->write_read(p, "SV\r\n", buf, 100, '>', 1, 2.5)) != 0)
			return instUnknown;
	
		if (strlen(buf) >= 12) {
		    if (strncmp(buf,"X-Rite DTP22",12) == 0)
				rv = instDTP22;
		    if (strncmp(buf,"X-Rite DTP41",12) == 0)
				rv = instDTP41;
		    if (strncmp(buf,"X-Rite DTP42",12) == 0)
				rv = instDTP41;
		    if (strncmp(buf,"X-Rite DTP51",12) == 0)
				rv = instDTP51;
		    if (strncmp(buf,"X-Rite DTP52",12) == 0)
				rv = instDTP51;
		    if (strncmp(buf,"X-Rite DTP92",12) == 0)
				rv = instDTP92;
		    if (strncmp(buf,"X-Rite DTP94",12) == 0)
				rv = instDTP94;
		}
	}

	if (p->debug) fprintf(stderr,"instType: Instrument type is '%s'\n", inst_name(rv));

	return rv;
}