Contained Within
Find More Documentation
Featured Support Resources
| Download this book in PDF
CMM Runtime Derivative
2
- This chapter briefly discusses how to create a CMM that is a runtime derivative. It defines a CMM and explains the steps required to write a CMM. It explains the Solaris runtime derivation mechanism and how to name your CMM and make entries in the OWconfig file to make your CMM known to the system at runtime. It also discusses each of the KCMS classes from which you can derive or extend:
-
-
KcsIO
-
KcsProfile
-
KcsProfileFormat
-
KcsXform
-
KcsStatus
- Subsequent chapters detail how to create class derivatives.
Creating a CMM
- A CMM is defined as:
-
- Color management techniques
- Data structures
- Profiles
- Follow these steps to create a CMM that is a runtime derivative:
-
-
Understand the KCMS framework, its general principles and the SDK "C" interface.
See Chapter 3, "KCMS Framework Operations" for more information.
-
Determine your color management requirements and whether you need to derive from or extend any of the KCMS framework classes to meet those requirements.
Knowing more about the derivable KCMS classes will help you with this decision; see "Derivable Classes."
-
Understand the runtime mechanism for derivatives.
See "Runtime Derivation Mechanism" on page 18.
-
Understand the CMM naming conventions and the OWconfig file. See "Loading CMMs" on page 22.
-
Implement your KCMS framework runtime extensions.
The information in this manual as well as the KCMS CMM Reference Manual will help you understand the foundation library interfaces. You may also find it helpful to use the KCMS Application Developer's Guide SDK manual for information on the KCMS framework API.
-
Test your CMM.
Derivable Classes
- The following sections give helpful information on why you might derive from or extend a particular KCMS class.
KcsIO
- If you have special I/O considerations, you might want to create a KcsIO class derivative. It is a simple I/O protocol that most devices support. For example, this version of KCMS includes an X11 Window System derivative (kcsSUNWIOxwin.so.1) and a Solaris file derivative
-
-
(kcsSUNWIOsolfi.so.1).
- The framework supports file-, memory-, and network-based derivatives. Objects use a static store to read from or write to data; a common type of static store is a file on disk. A static store is a hardware- or platform-independent mechanism for generation and regeneration. Generation is the first time data is read from a static store and an object is instantiated from that data; the data is
- constructed from the saved state. Regeneration, or loading occurs when a derivative brings back all of its state and functionality, after it has been minimized, from its static store. With minimization and regeneration the object is already instantiated. A minimized object contains sufficient information to generate itself from a static store (typically just its UID (unique identifier)).
- See Chapter 4, "KcsIO Derivative," for information on creating a KcsIO class derivative.
KcsProfile
- Derive a new KcsProfile class for characterization and calibration, additional functionality, or new transform derivatives. Usually, this involves overriding one of the update methods to actually produce a new KcsXform. Once the transformation is saved to the static store, the runtime load mechanism deals with it automatically from then on as long as the CMM is installed on the loading system. Since you can supply profiles directly that contain new KcsXform derivatives, the only derivative necessary to supply is the one derived from KcsXform. However, if the profile used to contain these new KcsXform derivatives is the KcsProfile derivative, it overwrites the new KcsXform type with one of its own when calibrated.
- See Chapter 5, "KcsProfile Derivative," for information on creating a KcsProfile class derivative.
KcsProfileFormat
- You can create a KcsProfileFormat class derivative to support an existing profile format, a new profile format, or possibly a set of data that is not an ICC profile (for example, a tag encoded TIFF file). To build a KcsAttributeSet instance within a KcsProfileFormat instance and a set of KcsXform derivatives, enough information in a properly tagged TIFF image might exist.
- The CMM Id and version should be in a known location in the profile header. This is always the case with the ICC profile format; see the ICC specification for this location. Other profile formats must be formatted to conform to this requirement so that the KCMS framework can form the keys to locate the format's runtime loadable module.
- See Chapter 6, "KcsProfileFormat Derivative," for information on creating a KcsProfileFormat class derivative.
KcsXform
- Creating a KcsXform class derivative is the most common derivative since most color management suppliers have their own type of transform technology. Most color technology involves manipulating matrixes and transforms. This class allows you to define a transform and its methods.
- See Chapter 7, "KcsXform Derivative," for information on creating a KcsXform class derivative.
KcsStatus
- The KcsStatus class represents a consistent object-oriented way of returning results from all of the KCMS methods. It allows a representation of error and warning values, error text descriptions, error conversions to and from a KcsStatusId, error comparisons, external mappings through the C API, and message extraction for language localization.
- You do not actually derive from the KcsStatus class; you extend it. You override an error and warning message function to provide your own error and warning messages. It is recommended that you override KcsStatus functions with message extraction for language localization. You are not required to provide your own messages. The KCMS-framework error and warning messages may be sufficient.
- See Chapter 8, "KcsStatus Extension," for information on extending the KcsStatus class.
Runtime Derivation Mechanism
- The KCMS framework uses a model that allows derivation of classes at runtime. This derivation changes and adds to the default functionality in the pre-compiled shared library. The KCMS framework uses the Solaris runtime-loader interface; see the dlopen(3X) and dlsym(3X) man pages for more information. The runtime derivation model has C-based routines that load, unload, initialize, terminate, and allocate at runtime.
Wrapper Functions
- The KCMS framework uses wrapper functions to allocate an object at runtime. Wrapper functions are implemented in C and perform a C++-to-C conversion. The allocation routines return a pointer to the base class object that informs the C++ compiler what is returned, but not the definitions. As in typical C, you can reference symbols in a sharable library because the functions are defined as extern C {}.
- These functions are written in C++ and call new() (or its equivalent alternative). Since the shareable object code has all of the header information from the base class, the derivative is constructed properly and has the same structure as statically-linked code.
External Entry Points
- The KCMS framework uses external entry points to load your derivative as an executable. The symbols are loaded and the derivative is called by the framework to access your derivative's functionality. The types of entry points for a runtime derivative are:
-
- mandatory
- optional
- base-class specific
Mandatory
- Each runtime derivative must supply the following C-based external entry points and variables. In the paragraphs below,"XXXX" refers to the base class identifier from which it is being derived.
-
Note - XXXX can only have the following values: IO, Prof, Pfmt, Xfrm, and Stat.
-
-
KcsDLOpenXXXXCount()
-
extern long KcsDLOpenXXXXCount;
|
-
KcsDLOpenXXXXCount()is the number of times the shareable object was opened; it is equivalent to the number of times the shareable object is being shared. The CMM should not set this variable; it is controlled by the KCMS framework.
-
-
KcsCreateXXXX()
-
KcsXXXX *KcsCreateXXXX(KcsStatus *, XXXX creation args);
|
-
KcsCreateXXXX() is one of possibly many creation entry points. This maps directly to the static createXXXX() methods of the base class from which it is being derived. The arguments following KcsStatus * are specific to the base class and are described in that class chapter. The CMM must support all declared createXXXX() methods; otherwise, applications receive CMM errors from calls to load().
Optional
- Runtime derivatives can supply the following external entry points.
-
-
KcsInitXXXX()
-
KcsStatus KcsInitXXXX(long libMajor, long libMinor,
long *myMajor, long *myMinor);
|
- If you supply KcsInitXXXX(), the KCMS framework calls it when the shareable object is loaded for the first time. This initializes and derives private allocations before any creation method is called. The method checks for minor version numbering; see "Loading CMMs" on page 22 for more information.
-
-
KcsCleanupXXXX()
-
KcsStatus KcsCleanupXXXX();
|
- If you supply KcsCleanupXXXX() the KCMS framework calls it when the shareable object is unloaded for the last time (when KcsDLOpenXXXXCount = 0). This cleans up shareable objects when they are no longer needed.
Base-Class Specific
- Each base class also provides additional necessary and optional entry points. See the chapters describing the KcsProfile, KcsProfileFormat, KcsXform, and KcsStatus classes (Chapter 5 through Chapter 8, respectively), for detailed explanations.
Instantiation
- Instantiate KCMS framework objects or any runtime derivations of that object with the createXXXX(), attach(), and new()methods.
createXXXX()
- Allocate an object with the createXXXX() method. This method combines sharing of the object with runtime derivative support. With chunk set-based objects, this function searches for a match through allocated objects. If it finds a match it attaches to that object and returns its address. If it does not find a match or the object is not chunk set based, it searches for a match through objects in the runtime-loadable object files.
attach()
- Share an object with the attach() method. If an object already exists, it can be shared in memory with this method. You can share the object with other users of that object. Any changes in the object are applied objects that share it. If you share an object, make sure that object does not change while attached to it.
new()
- Get a new object of a specified type or a KCMS framework derivative with the new() method. This allows a runtime derivative to actually override a built-in type after it has been released.
Initialization and Cleanup
- The KcsLoadable class loads a runtime derivative's binaries when a create() method is used. It generates the shared object's configuration file keywords based on class, derivative, and version identifiers. It retrieves the module name and loads the library. See "OWconfig File Structure" on page 24 for further information.
- The KcsLoadable class then locates the KcsDLOpenXXXXCount external entry point. If KcsDLOpenXXXXCount = 0, it locates and loads the KcsInitXXXX() entry point and, if available, calls it. Then the KcsCreateXXXX() entry point is located and loaded. If everything is successful, the create entry point is called.
- When the last of a specific derivative type is deallocated and the KcsCleanupXXXX() entry point is available, it is located, loaded, and called.
Maximizing Extensibility to Runtime Loadability
- To maximize the runtime nature of the KCMS framework, it is recommended that you use the createXXXX() method whenever possible within your CMM derivative. Derivatives statically linked into an application, or included directly in the KCMS framework's shared object libraries (such as, libkcs), can use the correct and latest version of that derivative.
- Note that the KcsStatus class extension is an exception to this recommendation. It passes back a status string rather than a pointer to a derivative, and only two C functions are written.
Loading CMMs
- This section tells you what you need to know to load your CMM. It explains how to name your CMM for each class and how to update the OWconfig file.
CMM Filename Convention
- A module (or CMM) name should follow this convention:
-
kcs<STOCK SYMBOL><CLASS><unique identifier>.so.<version>
|
- The following table describes each field in the CMM filename.
-
Table 2-1
| Filename Field | Description |
| kcs | Color management framework. |
| stock symbol | Short mnemonic used by the stock market. |
| class | Class from which the module is derived. |
| .so | Shared object library. |
| unique identifier | Four-character identifier that distinguishes multiple modules derived from the same class. |
| version | Number compared to the KCS_MAJOR_VERSION number (incremented by SunSoft for every major release). |
-
Note - The version number in the #define and the version number in the module name must match.
- A few KCMS CMM filenames are:
-
-
kcsSUNWIOsolf.so.1...Solaris File CMM
-
kcsSUNWIOxwin.so.1...X11 Window System CMM
-
kcsSUNWStatsolm.so.1..Solaris Message CMM
CMM Makefile
- The CMM must be installed in /usr/openwin/etc/devhandlers.
- A sample makefile in /opt/SUNWddk/kcms/src illustrates how the CMMs are compiled and installed, and how the library names are associated with the modules.
OWconfig File Structure
- The OWconfig library must be included in the CMM linking. It is bundled with Solaris in /usr/openwin/lib/libowconfig.so. The OWconfig library provides routines to access the OWconfig file that gets the name of the CMM you want to dynamically load. You must add the name of your CMM to the OWconfig file to advertise its existence to the KCMS framework.
- A generic OWconfig entry looks like this:
-
class="KCS_IO" name="solf"
kcsLoadableModule="kcsSUNWIOsolf.so.1";
|
- The following table describes each field.
-
Table 2-2 OWconfig
| OWconfig File Entry | Description |
| class | KCS_<class name>. |
| name | Four- or eight-character identifier. |
| kcsLoadableModule | Entire module name. |
KcsIO Example
-
#KcsIO class, Solaris profiles
class="KCS_IO" name="solf"
kcsLoadableModule="KcsSUNWIOsolf.so.1";
#KcsIO class, X11 window system profiles
class="KCS_IO" name="xwin"
kcsLoadableModule="kcsSUNWIOxwin.so.1";
|
- The KcsProfileType enumeration in kcstypes.h contains a type field that is a four-character array described in hexadecimal form as a long. For example:
-
typedef enum {
KcsFileProfile = 0x46696C65, /*File*/
KcsMemoryProfile = 0x4D426C00, /*MBl*/
#ifdef KCS_ON_SOLARIS
KcsWindowProfile = 0x7877696E, /*xwin*/
KcsSolarisProfile = 0x736F6C66, /*solf*/
#else
KcsWindowProfile = 0x57696E64, /*Wind*/
#endif KCS_ON_SOLARIS
KcsProfileTypeEnd = 0x7FFFFFFF,
KcsProfileTypeMax = KcsForceAlign
}KcsProfileType;
|
- The OWconfig library turns the type field back into a string and searches all of the appropriate OWconfig class entries.
KcsProfile Example
-
#KcsProfile Class, Solaris default is KCMS
#Default profile class, CMM Id == Profile Format
class="KCS_Prof" name="dflt"
kcsLoadableModule="kcsEkProfkcms.so.1";
#KCMS profile, CMM Id == Profile Format
class="KCS_Prof" name="KCMS"
kcsLoadableModule="kcsEKProfkcms.so.1";
|
- The key to loading a new version is the CMM Id (bytes 4 through 7 in the ICC profile format). If there is not a match, the default entry dflt is used. You must load the proper CMM Id into the new profile's CMM Id attribute field for recognition of the module. The default loadable module is the Solaris-supplied default.
- This is the base KcsProfile class that can contain transforms (KcsXform class) and a profile format (KcsProfileFormat class). Since the Kodak class is built into the library, this is the mechanism by which the calibration and characterization interface can be extended.
KcsProfileFormat Example
-
#Profile format class, default is ICC
#Default profile format, ICC, default CMM
class="KCS_Pfmt" name="acspdflt"
kcsLoadableModule="kcsEKPfmticc30.so.1";
#ICC profile format, KCMS CMM
class="KCS_Pfmt" name="acspKCMS"
kcsLoadableModule="kcsEKPfmticc30.so.1";
|
- The profile format is determined from the profile type and CMM Id in the ICC profile header. A check is performed to ensure that an ICC profile uses the magic number of the file. If another format is used, the magic number is used to load the module. All profiles should be ICC profile format files with a magic number equal to acsp and must have the ICC header included. The CMM Id is
- used to match the profile format with the correct derivative. If no match is found, the default entry (dflt) is used; therefore, you can use the supplied default profile format class for ICC profiles.
- The name field syntax is: <Profile magic number><CMM Id>
- The OWconfig file entry must match the resulting name. This also gives color management vendors the opportunity to support pre-ICC format profiles, provided they include the ICC header.
KcsXform Example
-
#ICC interpolation table 8 bit, default CMM
class="KCS_Xfrm" name="mft1dflt"
kcsLoadableModule="kcsEKXfrmucp.so.1";
#ICC interpolation table 16 bit, default CMM
class="KCS_Xfrm" name="mft2dflt"
kcsLoadableModule="kcsEKXfrmucp.so.1";
#ICC interpolation table 8 bit, default CMM
class="KCS_Xfrm" name="mft1KCMS"
kcsLoadableModule="kcsEKXfrmucp.so.1";
#ICC interpolation table 16 bit, default CMM
class="KCS_Xfrm" name="mft2KCMS"
kcsLoadableModule="kcsEKXfrmucp.so.1";
#KCMS universal color processor table
class="KCS_Xfrm" name="ucpKCMS"
kcsLoadableModule="kcsEKXfrmucp.so.1";
|
- The name field is a combination of a unique four-character transform identifier that must be registered with the ICC and the CMM Id. The library turns name back into a string and searches all of the appropriate OWconfig class entries.
- Inside an ICC profile, the type of transform is defined by a type identifier that indicates whether it is an 8- or 16-multi function table, indicated by the Signature element of either the Lut8Type (mft1) or Lut16Type (mft2). Default values have been supplied for these cases: mft1dflt and mft2dflt.
KcsStatus Example
-
#Extending error messages
class="KCS_STAT" name-"solm"
kcsLoadableModule="kcsSUNWSTATsolm.so.1";
|
- You define the name field as 4 characters uniquely identifying your set of error and warning messages.
- To add your own error messages supply a single "C" routine that translates your error value into an error string. Also supply a messages.po file for localization purposes. See Chapter 8, "KcsStatus Extension" for detailed information.
- The KcsStatus class will, if an OwnerId variable is set with the status message, dynamically load the matching OwnerId set by the dynamically loaded class. The OwnerID is described in Chapter 8, "KcsStatus Extension."
Updating the OWconfig File
- You can insert and remove configuration entries (class, name, and kcsLoadableModule) in the OWconfig file. The supplied source program OWconfig_sample.c must be edited at the indicated places. Substitute your own unique names where the program comments tell you to "choose a unique name here," for example
-
#define package "SUNWkcsdnd" /* choose a unique name here */
|
- Then compile the with the makefile.owconfig.
-
%make -f makefile.owconfig
|
- Refer to the comments at the beginning of the OWconfig_sample.c program for more information.
Inserting Entries
- To insert configuration entries into the OWconfig file for your new module, run the OWconfig_sample program with the insert option as follows:
-
example% su
example# ./OWconfig_sample -i
|
- The new configuration entries will be appended to the end of the /usr/openwin/server/etc/OWconfig file. For local machine use only, the /etc/openwin/server/etc/OWconfig file will be updated.
Removing Entries
- To remove configuration entries from the OWconfig file, run the OWconfig_sample program with the insert option as follows:
-
example% su
example# ./OWconfig_sample -r
|
Version Numbering
- Once OWconfigGetAttribute() returns the module name, the version number is parsed out of the module name and compared to the global library version number located in kcsos.h to determine if this version can be executed.
-
Note - The major version number in the module name must match the global variable.
|
|