KCMS CMM Developer's Guide

Loading a Profile From the Solaris File System

The framework must have a profile with which to operate. Example 3-1 is a KCMS "C" API code excerpt that loads a scanner profile with a file name.


Example 3-1 Loading a Profile from the Solaris File System

KcsProfileId      

scannerProfile; KcsProfileDesc						scannerDesc; KcsStatusId						status;

char			*in_prof= "kcmsEKmtk600zs";  scannerDesc.type =

KcsSolarisProfile; scannerDesc.desc.solarisFile.fileName = in_prof;

scannerDesc.desc.solarisFile.hostName = NULL;

scannerDesc.desc.solarisFile.oflag = O_RDONLY;

scannerDesc.desc.solarisFile.mode = 0;  /* Load the scanner profiles */ status

= KcsLoadProfile(&scannerProfile, &scannerDesc,  			KcsLoadAllNow); if

(status != KCS_SUCCESS) { 	fprintf(stderr,"scanner KcsLoadProfile failed

error =  			0x%x\n", status); 	return(-1); }

In the example, the KCMS API layer calls KcsLoadProfile()() to inform the KCMS framework that a profile description of type KcsSolarisProfile is to be loaded. The name of the profile and the options for opening that file are also specified using the solarisFile entry in the KcsProfileDesc structure.

Figure 3-3 Creating a KcsIO Object

Graphic

Creating a KcsIO Object

As a result of the call to KcsLoadProfile()() the framework creates a KcsIO object. Figure 3-3 illustrates how the KcsLoadProfile()() API call is implemented. The legend indicates the source of each call (KCMS "C" API layer, framework, "C" wrapper). In addition, the legend shows where the OWconfig file and the loadable CMM module fit into the overall scheme of loading the profile to creating a KcsIO object.

Looking ahead for a moment, Figure 3-4 , Figure 3-5 , and Figure 3-6 show the progression of framework calls that ultimately load the profile as chunks of data and return the profile Id to the calling application.

Returning now to Figure 3-3, the KCMS framework and the dynamic loading mechanism perform the following task sequence when KcsLoadProfile()() is called:

  1. The framework gets a new profile Id. The framework maintains a dynamically allocated global array of profiles. The getNewValidProfileIndex()() method allocates a new profile entry.

  2. The framework creates a KcsIO pointer. (All profiles access their data using the KcsIO independent access mechanism.) The KcsIO pointer is created based on the type field of the KcsProfileDesc structure pointer passed in from KcsLoadProfile()().

    Two externally available types are built into the libkcs library, KcsFile and KcsMemoryBlock. A third derivative, KcsRemoteFile, is used with the KcsSolarisFile and KcsXWindow classes. In this particular example, KcsSolarisFile is not built into the libkcs library, so the dynamic loading mechanism creates one.

  3. The dynamic loading mechanism turns the KcsProfileDesc->type structure pointer field into a 4-character string and searches entries in the OWconfig file for the entries that correspond to loadable KcsIO classes. If it finds a match, it dynamically loads the KcsIO module. This action supplies the framework with a shared object to load. (See "KcsIO Example" for details.)

    The KcsIO module contains calls to a list of known function names. The framework uses dlsym(3X) to bring these functions into the framework to create and load a pointer to a KcsIO derivative.

  4. Once the KcsSolarisFile object pointer is loaded, the framework uses the fileName, hostName, and open(2) arguments to search for the profile. First, it checks the hostName to see if the file is on a local or remote machine. Depending on the location, the KcsSolarisFile object reuses the existing KcsIO class derivatives.

    If the file is on a local machine, the fileName is opened using open(2), and a KcsFile object pointer is created. If, however, the file is located on a remote machine, the fileName and hostName are passed to KcsRemoteFile and a KcsRemoteFile object pointer is created.

    As shown in Example 3-2 , the KcsFile or KcsRemoteFile pointer that the KcsSolarisFile file object contains is then used to override the KcsIO methods of the same name.


    Example 3-2 Overriding KcsIO Methods With KcsSolarisFile

    // Just call myIO
    
    version of the call KcsStatus KcsSolarisFile::relRead(const long aBytesWanted,
    
    void *aBuffer, const char *aCallersName) {     KcsStatus status;      status =
    
    myIO->relRead(aBytesWanted, aBuffer, aCallersName);     return (status);
    
    }
    

Creating a KcsProfile Object

Once a KcsIO object has been created, the profile can be loaded. Figure 3-4 illustrates creating a KcsProfile object.

Figure 3-4 Creating a KcsProfile Object

Graphic

In Figure 3-4, the first step to loading the profile is to create a new KcsProfile object with the createProfile()() static KcsProfile method. This method uses the CMM Id of the profile, which is located in a fixed place (bytes 4-7) in the profile header. (See "ICC Profile Header " for details.) The CMM Id determines the KcsProfile derivative to be created. If the CMM Id has no corresponding entry in the OWconfig file, the default KcsProfile class is created.

Creating a KcsProfileFormat Object

Once a KcsProfile object has been created, you (???your CMM)can ask it to load itself using the generated KcsIO. Figure 3-5 illustrates the process.

Figure 3-5 Creating a KcsProfileFormat Object

Graphic

In Figure 3-5 , the KcsProfile object creates a KcsProfileFormat object pointer using createProfileFormat()(). Then createProfileFormat()() searches the OWconfig file for loadable entries based on the profile format Id. For ICC profiles, the profile format Id (also called the profile file signature) is always acsp. (See "ICC Profile Header " for details.) Once the KcsProfileFormat object is created, the library generates a KcsAttributeSet object and an array of pointers to KcsXform objects.

Loading a KcsProfileFormat Object

The pointers to objects contained within the KcsProfileFormat object load themselves using the KcsChunkSet class. Figure 3-6 illustrates the process.

Figure 3-6 Loading a KcsProfileFormat Object

Graphic

In Figure 3-6 , the KcsChunkSet class returns the blocks of data from the file, which were requested by the KcsAttributeSet and KcsXform objects. These objects interpret the block of data, turning it into tables for processing color data or sets of attributes. The KcsIO and KcsChunkSet classes do not interpret the data.

If the Solaris file system profile is successfully loaded, the framework increments the number of entries in the global profile array, and the profile Id is returned to the application.