McoStatus XyztoRgb::xyz2rgb(Monitor *monitor) { double k1, k2, k3; Matrix phosmat(3); Matrix phosmat2(3); Matrix wcolmat(3, 1); Matrix cmat(3); Matrix ccolmat(3, 1); memcpy((char*)&_monitor, (char*)monitor, sizeof(Monitor)); phosmat.setval(1, 1, _monitor.setup[3]); phosmat.setval(2, 1, _monitor.setup[4]); phosmat.setval(3, 1, (1.0 - _monitor.setup[3] - _monitor.setup[4])); phosmat.setval(1, 2, _monitor.setup[5]); phosmat.setval(2, 2, _monitor.setup[6]); phosmat.setval(3, 2, (1.0 - _monitor.setup[5] - _monitor.setup[6])); phosmat.setval(1, 3, _monitor.setup[7]); phosmat.setval(2, 3, _monitor.setup[8]); phosmat.setval(3, 3, (1.0 - _monitor.setup[7] - _monitor.setup[8])); phosmat2 = phosmat; //compute inverse phosphor matrix phosmat.inv(); if( phosmat.get_status() != MCO_SUCCESS) return MCO_SINGULAR; //load white // Matrix wcolmat(3, 1); wcolmat.setval(1, 1, (_monitor.setup[1]/_monitor.setup[2])); wcolmat.setval(2, 1, (_monitor.setup[2]/_monitor.setup[2])); wcolmat.setval(3, 1, ((1.0 - _monitor.setup[1] - _monitor.setup[2])/_monitor.setup[2])); //compute k1, k2, k3 ccolmat = phosmat*wcolmat; ccolmat.getval(1, 1, &k1); ccolmat.getval(2, 1, &k2); ccolmat.getval(3, 1, &k3); //load k1,k2,k3 and inverse cmat.setval(1, 1, k1); cmat.setval(2, 2, k2); cmat.setval(3, 3, k3); //compute the RGB to XYZ conversion matrix; *_rgbtoxyzt = phosmat2*cmat; //transvers of RGB to XYZ conversion matrix _rgbtoxyzt->T(); //compute the xyz to rgb conversion matrix //actually, it's the transverse of conversion matrix *_xyztorgbt = *_rgbtoxyzt; _xyztorgbt->inv(); if(_xyztorgbt->get_status() != MCO_SUCCESS) return MCO_SINGULAR; return MCO_SUCCESS; }
//build rgb to xyz conversion //note the values are abosolute based on the input white point //return the value in rgbtoxyz and xyztorgb //if return 0, ok, else something wrong in the conversion McoStatus newbuildrgbxyz(double *monitor, double *xyztorgb, double *rgbtoxyz) { double k1, k2, k3; Matrix phosmat(3); Matrix wcolmat(3, 1); Matrix ccolmat(3, 1); Matrix rgbtoxyzmat(3); Matrix xyztorgbmat(3); //load chromaticity(phosphor) matrix phosmat.setval(1, 1, monitor[3]); phosmat.setval(2, 1, monitor[4]); phosmat.setval(3, 1, (1.0 - monitor[3] - monitor[4])); phosmat.setval(1, 2, monitor[5]); phosmat.setval(2, 2, monitor[6]); phosmat.setval(3, 2, (1.0 - monitor[5] - monitor[6])); phosmat.setval(1, 3, monitor[7]); phosmat.setval(2, 3, monitor[8]); phosmat.setval(3, 3, (1.0 - monitor[7] - monitor[8])); rgbtoxyzmat = phosmat; //inverse chromaticity(phosphor) matrix phosmat.inv(); //singular matrix or something strange happened if( phosmat.get_status() != MCO_SUCCESS) return MCO_SINGULAR; //load white wcolmat.setval(1, 1, monitor[1]/monitor[2]); wcolmat.setval(2, 1, 1); wcolmat.setval(3, 1, (1.0 - monitor[1] - monitor[2])/monitor[2]); //compute k1, k2, k3 ccolmat = phosmat*wcolmat; ccolmat.getval(1, 1, &k1); ccolmat.getval(2, 1, &k2); ccolmat.getval(3, 1, &k3); //substitude k1,k2,k3 back to the chromaticity matrix //to get the RGB to XYZ conversion matrix; rgbtoxyzmat.coltimes(1, k1); rgbtoxyzmat.coltimes(2, k2); rgbtoxyzmat.coltimes(3, k3); //compute the xyz to rgb conversion matrix xyztorgbmat = rgbtoxyzmat; xyztorgbmat.inv(); //singular matrix or something strange happened if(xyztorgbmat.get_status() != MCO_SUCCESS) return MCO_SINGULAR; //copy the conversion matrix to the data struct rgbtoxyzmat.savestruct(rgbtoxyz); xyztorgbmat.savestruct(xyztorgb); return MCO_SUCCESS; }