KCMS CMM Developer's Guide

Characterization and Calibration

Characterization and calibration are accessed using the following KCMS "C" API calls:

See the SDK manual KCMS Application Developer's Guide for more information on these calls.

The KcsProfile base class contains virtual methods to characterize and calibrate two types of devices: scanners and monitors. You must decide whether to override the base functionality to take characterization and calibration data and turn it into the appropriate KcsXform data.


Note -

Currently, the default CMM supports monitor and scanner characterization and calibration only. It does not support printer characterization and calibration. However enabling hooks exist in the source so you can write a CMM that supports printers.


Attributes are set using the normal mechanisms. The KCMS "C" API code excerpt in Example 3-9 shows characterization and calibration.


Example 3-9 Characterization and Calibration

KcsCalibrationData      

       *calData;     KcsCharacterizationData														*charData;    

float														Luminance_float_out[3][256];    

double														test_double[3];   /* this is a test which does not use

real data - just a gamma curve for the *  calibration structure and the same

curve *.75 for the characterization curve. */      /*create luminance tables

with a gamma = 2.22 */  	for (j=0; j<levels; j++) { 			input_val = j *

(1.0/255.0); 			Luminance_float_out[0][j] = pow(input_val, 2.22);

			Luminance_float_out[1][j] = pow(input_val, 2.22);

			Luminance_float_out[2][j] = pow(input_val, 2.22);     }     /* Fill out the

measurement structures - The illuminant must be D50 */     test_double[0] =

0.9642;     test_double[1] = 1.0;     test_double[2] = 0.8249;     sizemeas =

(int) (sizeof(KcsMeasurementBase) + sizeof(long) + 		  	

sizeof(KcsMeasurementSample) * levels);     charData =

(KcsCharacterizationData *) malloc(sizemeas);     

charData->base.countSupplied = levels;     charData->base.numInComp = 3;

    charData->base.numOutComp = 3;     charData->base.inputSpace =

KcsCIEXYZ;     charData->base.outputSpace = KcsRGB;     for (i=0; i<

levels; i++) { 			charData->val.patch[i].weight = 1.0;

			charData->val.patch[i].standardDeviation = 0.0;

			charData->val.patch[i].sampleType = KcsChromatic; 

			charData->val.patch[i].input[KcsRGB_R] = (float)i/255;

			charData->val.patch[i].input[KcsRGB_G] = (float)i/255;

			charData->val.patch[i].input[KcsRGB_B] = (float)i/255;

			charData->val.patch[i].input[3] = 0.0; 

			charData->val.patch[i].output[KcsRGB_R] =

(Luminance_float_out[0][i])/0.75;

			charData->val.patch[i].output[KcsRGB_G] =

(Luminance_float_out[1][i])/0.75;

			charData->val.patch[i].output[KcsRGB_B] =

(Luminance_float_out[2][i])/0.75; 			charData->val.patch[i].output[3] =

0.0;     }     charData->val.patch[0].sampleType = KcsBlack;    

charData->val.patch[255].sampleType = KcsWhite;      sizemeas = (int)

(sizeof(KcsMeasurementBase) + sizeof(long) + 		   	

sizeof(KcsMeasurementSample) * levels);     calData = (KcsCalibrationData *)

malloc(sizemeas);      calData->base.countSupplied = levels;    

calData->base.numInComp = 3;     calData->base.numOutComp = 3;    

calData->base.inputSpace = KcsRGB;     calData->base.outputSpace =

KcsRGB;     for (i=0; i< levels; i++) { 			calData->val.patch[i].weight

= 1.0; 			calData->val.patch[i].standardDeviation = 0.0;

			calData->val.patch[i].sampleType = KcsChromatic; 

			calData->val.patch[i].input[KcsRGB_R] = (float)i/255;

			calData->val.patch[i].input[KcsRGB_G] = (float)i/255;

			calData->val.patch[i].input[KcsRGB_B] = (float)i/255;

			calData->val.patch[i].input[3] = 0.0; 

			calData->val.patch[i].output[KcsRGB_R] = Luminance_float_out[0][i];

			calData->val.patch[i].output[KcsRGB_G] = Luminance_float_out[1][i];

			calData->val.patch[i].output[KcsRGB_B] = Luminance_float_out[2][i];

			calData->val.patch[i].output[3] = 0.0;     }     

calData->val.patch[0].sampleType = KcsBlack;    

calData->val.patch[255].sampleType = KcsWhite;      printf("Update a

profile with characterization and calibration data.\n");     rc =

KcsUpdateProfile(profileid, charData, calData, NULL);     if(rc !=

KCS_SUCCESS) {         KcsGetLastError(&errDesc);         fprintf(stderr, 

               "unable to update profile: %s\n", errDesc.desc);   

     KcsFreeProfile(profileid);         return(-1);     }