118 |
|
case MG_E_CSPEC: /* assign spectral values */ |
119 |
|
if (ac < 5) |
120 |
|
return(MG_EARGC); |
121 |
< |
if (!isint(av[1]) || !isint(av[2])) |
121 |
> |
if (!isflt(av[1]) || !isflt(av[2])) |
122 |
|
return(MG_ETYPE); |
123 |
< |
return(setspectrum(c_ccolor, atoi(av[1]), atoi(av[2]), |
123 |
> |
return(setspectrum(c_ccolor, atof(av[1]), atof(av[2]), |
124 |
|
ac-3, av+3)); |
125 |
|
case MG_E_CMIX: /* mix colors */ |
126 |
|
if (ac < 5 || (ac-1)%2) |
457 |
|
y += cie_yf.ssamp[i] * clr->ssamp[i]; |
458 |
|
z += cie_zf.ssamp[i] * clr->ssamp[i]; |
459 |
|
} |
460 |
+ |
x /= (double)cie_xf.ssum; |
461 |
+ |
y /= (double)cie_yf.ssum; |
462 |
+ |
z /= (double)cie_zf.ssum; |
463 |
|
z += x + y; |
464 |
|
clr->cx = x / z; |
465 |
|
clr->cy = y / z; |
495 |
|
static int |
496 |
|
setspectrum(clr, wlmin, wlmax, ac, av) /* convert a spectrum */ |
497 |
|
register C_COLOR *clr; |
498 |
< |
int wlmin, wlmax; |
498 |
> |
double wlmin, wlmax; |
499 |
|
int ac; |
500 |
|
char **av; |
501 |
|
{ |
502 |
|
double scale; |
503 |
< |
float *va; |
504 |
< |
register int i; |
505 |
< |
int wl, pos; |
503 |
> |
float va[C_CNSS]; |
504 |
> |
register int i, pos; |
505 |
> |
int n, imax; |
506 |
> |
int wl; |
507 |
|
double wl0, wlstep; |
508 |
< |
|
509 |
< |
if (wlmin < C_CMINWL || wlmin >= wlmax || wlmax > C_CMAXWL) |
508 |
> |
/* check bounds */ |
509 |
> |
if (wlmax <= C_CMINWL | wlmax <= wlmin | wlmin >= C_CMAXWL) |
510 |
|
return(MG_EILL); |
511 |
< |
if ((va = (float *)malloc(ac*sizeof(float))) == NULL) |
512 |
< |
return(MG_EMEM); |
511 |
> |
wlstep = (wlmax - wlmin)/(ac-1); |
512 |
> |
while (wlmin < C_CMINWL) { |
513 |
> |
wlmin += wlstep; |
514 |
> |
ac--; av++; |
515 |
> |
} |
516 |
> |
while (wlmax > C_CMAXWL) { |
517 |
> |
wlmax -= wlstep; |
518 |
> |
ac--; |
519 |
> |
} |
520 |
> |
if (ac < 2) |
521 |
> |
return(MG_EILL); |
522 |
> |
imax = ac; /* box filter if necessary */ |
523 |
> |
if (wlstep < C_CWLI) { |
524 |
> |
wlstep = C_CWLI; |
525 |
> |
imax = (wlmax - wlmin)/wlstep; |
526 |
> |
} |
527 |
|
scale = 0.; /* get values and maximum */ |
528 |
< |
for (i = 0; i < ac; i++) { |
529 |
< |
if (!isflt(av[i])) |
530 |
< |
return(MG_ETYPE); |
531 |
< |
va[i] = atof(av[i]); |
528 |
> |
pos = 0; |
529 |
> |
for (i = 0; i < imax; i++) { |
530 |
> |
va[i] = 0.; n = 0; |
531 |
> |
while (pos < (i+.5)*ac/imax) { |
532 |
> |
if (!isflt(av[pos])) |
533 |
> |
return(MG_ETYPE); |
534 |
> |
va[i] += atof(av[pos++]); |
535 |
> |
n++; |
536 |
> |
} |
537 |
> |
if (n > 1) |
538 |
> |
va[i] /= (double)n; |
539 |
|
if (va[i] < 0.) |
540 |
|
return(MG_EILL); |
541 |
|
if (va[i] > scale) |
546 |
|
scale = C_CMAXV / scale; |
547 |
|
clr->ssum = 0; /* convert to our spacing */ |
548 |
|
wl0 = wlmin; |
524 |
– |
wlstep = (double)(wlmax - wlmin)/(ac-1); |
549 |
|
pos = 0; |
550 |
|
for (i = 0, wl = C_CMINWL; i < C_CNSS; i++, wl += C_CWLI) |
551 |
< |
if (wl < wlmin || wl > wlmax) |
551 |
> |
if (wl < wlmin | wl > wlmax) |
552 |
|
clr->ssamp[i] = 0; |
553 |
|
else { |
554 |
|
while (wl0 + wlstep < wl+FTINY) { |
555 |
|
wl0 += wlstep; |
556 |
|
pos++; |
557 |
|
} |
558 |
< |
if (wl+FTINY >= wl0 && wl-FTINY <= wl0) |
558 |
> |
if (wl+FTINY >= wl0 & wl-FTINY <= wl0) |
559 |
|
clr->ssamp[i] = scale*va[pos]; |
560 |
|
else /* interpolate if necessary */ |
561 |
|
clr->ssamp[i] = scale / wlstep * |
565 |
|
} |
566 |
|
clr->flags = C_CDSPEC|C_CSSPEC; |
567 |
|
clr->clock++; |
544 |
– |
free((MEM_PTR)va); |
568 |
|
return(MG_OK); |
569 |
|
} |
570 |
|
|
582 |
|
c_ccvt(c1, C_CSSPEC|C_CSEFF); |
583 |
|
c_ccvt(c2, C_CSSPEC|C_CSEFF); |
584 |
|
w1 /= c1->eff*c1->ssum; |
585 |
< |
w2 /= c1->eff*c2->ssum; |
585 |
> |
w2 /= c2->eff*c2->ssum; |
586 |
|
scale = 0.; |
587 |
|
for (i = 0; i < C_CNSS; i++) { |
588 |
|
cmix[i] = w1*c1->ssamp[i] + w2*c2->ssamp[i]; |