Characterization and calibration are accessed using the following KCMS "C" API calls:
KcsCreateProfile()
KcsUpdateProfile()
KcsSetAttribute()
KcsSaveProfile()
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.
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.
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); }