McoStatus ScanCal::_compute_cyan(PWlinear **linear, double *mea, double *ref) { McoStatus status; double *rgbref; double white[3]; white[0] = 96.42; white[1] = 100.0; white[2] = 82.49; //linearization stretch status = _linearstrech(3, linear, 12, mea); if(status != MCO_SUCCESS) return status; rgbref = ref; //convert lab to xyz labtonxyzinplace(rgbref, 12); nxyztoxyzinplace(rgbref, white, 12); _cyan = new MultiLcal(3, 3, 3, func3); status = _cyan->compute(12, mea, ref); if(status != MCO_SUCCESS){ delete _cyan; return status; } return MCO_SUCCESS; }
void labtontscrgbinplace(long num, double *LAB) { long i; double r, g, b; double *nxyz; labtonxyzinplace(LAB, num); nxyz = LAB; for(i = 0; i < num; i++){ r = (2.2608*nxyz[0] - 0.9234*nxyz[1] - 0.3111*nxyz[2])*255; if( r < 0) r = 0; if( r > 255) r = 255; g = (-1.0409*nxyz[0] + 2.0206*nxyz[1] - 0.0204*nxyz[2])*255; if( g < 0) g = 0; if( g > 255) g = 255; b = (-0.0750*nxyz[0] + 0.0306*nxyz[1] + 1.2625*nxyz[2])*255; if( b < 0) b = 0; if( b > 255) b = 255; nxyz[0] = r; nxyz[1] = g; nxyz[2] = b; nxyz += 3; } }
McoStatus ScanCal::_compute_local(PWlinear **linear, double *mea, double *ref) { McoStatus status; long i, j; double *rgbref; double white[3]; white[0] = 96.42; white[1] = 100.0; white[2] = 82.49; //linearization stretch status = _linearstrech(3, linear, 168, mea); if(status != MCO_SUCCESS) return status; rgbref = ref; //convert lab to xyz labtonxyzinplace(rgbref, 168); nxyztoxyzinplace(rgbref, white, 168); _lcal = new MultiLcal*[12]; if(!_lcal) return MCO_MEM_ALLOC_ERROR; for(i = 0; i < 12; i++){ _lcal[i] = new MultiLcal(3, 3, 3, func3); status = _lcal[i]->compute(36, &mea[12*3*i], &rgbref[12*3*i]); if(status != MCO_SUCCESS) { for(j = 0; j < 12; j++) delete _lcal[j]; return status; } } return MCO_SUCCESS; }
McoStatus ScanCal::_globalcal(Matrix &mat, long num, double *mea, double *ref) { McoStatus status; long i, j; double white[3]; Matrix matdata(num, 3); double *rgbref; white[0] = 96.42; white[1] = 100.0; white[2] = 82.49; rgbref = (double*)McoMalloc(sizeof(double)*num*3); if(!rgbref) return MCO_MEM_ALLOC_ERROR; for(i = 0; i < num*3; i++) rgbref[i] = ref[i]; //convert lab to XYZ labtonxyzinplace(rgbref, num); nxyztoxyzinplace(rgbref, white, num); //convert XYZ to rgb matdata.loadstruct(rgbref); matdata.T(); Matrix matrefrgb = mat*matdata; matrefrgb.T(); matrefrgb.savestruct(rgbref); //build linearization double x[LINEAR_NUM], y[LINEAR_NUM]; long start = num - 23; long end = num; _linear = new PWlinear*[3]; for(j = 0; j < 3; j++){ for(i = start; i < end; i++){ y[i-start] = rgbref[i*3 + j]; x[i-start] = mea[i*3 + j]; } _linear[j] = new PWlinear(LINEAR_NUM, x, y); } //linearization stretch status = _linearstrech(3, _linear, num, mea); if(status != MCO_SUCCESS) return status; //create matrix for(i = 0; i < num*3; i++) rgbref[i] = ref[i]; //convert lab to xyz labtonxyzinplace(rgbref, num); nxyztoxyzinplace(rgbref, white, num); _gcal = new MultiLcal(3, 3, 3, func3); status = _gcal->compute(num, mea, rgbref); if(status != MCO_SUCCESS) { delete _gcal; return status; } McoFree(rgbref); return MCO_SUCCESS; }
// build a polygon that is a CIELab refrence TQ3GeometryObject LogoWin2::NewPolyGCIELabRef(void) { TQ3GeometryObject geometryObject = NULL; //TQ3TriGridData ciepoly; TQ3PolygonData ciepoly; TQ3Vertex3D *vertices; long i; double Lxy[4]; double lab[4]; McoStatus state; TQ3ColorRGB color = { 0.0, 0.0, 0.0 }; double big_ab,big_rgb; TQ3Param2D param2D; ciepoly.numVertices = NumCIExyzRef; ciepoly.vertices = (TQ3Vertex3D *) NewPtr (NumCIExyzRef * sizeof(TQ3Vertex3D)); if (ciepoly.vertices == NULL) return NULL; vertices = ciepoly.vertices; ciepoly.polygonAttributeSet = NULL; for (i=0; i<NumCIExyzRef; i++) { Lxy[0] = 50; Lxy[1] = CIExyzRef2[i*4+1]; Lxy[2] = CIExyzRef2[i*4+2]; vertices[i].point.x = Lxy[1]; vertices[i].point.y = Lxy[2]; vertices[i].point.z = 0.5; sxyztolab(Lxy,lab); big_ab = bigger(fabs(lab[1]),fabs(lab[2])); if (big_ab>127) { lab[1] = lab[1]*127/big_ab; lab[2] = lab[2]*127/big_ab; } labtonxyzinplace(lab,1); state = xyztorgb->compute(lab, monitor_z, 1); if(state != MCO_SUCCESS) return NULL; big_rgb = bigger(lab[1],bigger(lab[2],lab[3])); if (big_rgb>255) { lab[0] = lab[0]*255/big_rgb; lab[1] = lab[1]*255/big_rgb; lab[2] = lab[2]*255/big_rgb; } color.r = lab[0]/256; color.g = lab[1]/256; color.b = lab[2]/256; vertices[i].attributeSet = Q3AttributeSet_New(); Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeDiffuseColor, &color); param2D.u = Lxy[1]*1.37; param2D.v = Lxy[2]*1.1; Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D); } geometryObject = Q3Polygon_New(&ciepoly); for (i = 0; i < NumCIExyzRef; i++) Q3Object_Dispose(vertices[i].attributeSet); DisposePtr ((char *) vertices); return geometryObject; }