Showing posts with label plugins. Show all posts
Showing posts with label plugins. Show all posts

Thursday, July 23, 2009

Linking tags

Implementing the tag link feature has been easier than I originally thought, but there are some caveats.

lcms2 does support some new features on read/writting profiles. You can use cmsReadTag/cmsWriteTag to read/write lcms objects like LUTs, tone curves and so. You can also use cmsReadRawTag/cmsWriteRawTag to read or write whatever you want, but poor library does not do any checking or understanding on whats going on.

You can also link tags to items created by any of those two methods. So far so good.

But wait, you can also write plug-ins to add more "understood" objects in cmsReadTag/cmsWriteTag and also you can write plug-ins to add new types for those objects.

In addition to all that, there is a brand new structure added as an addedum to ICC spec 4.2, that is the MPE or multi profile elements. This is worth of several comments in this blog. Basically that may make photographers and precission yonkies very happy as it includes *true* floating point numbers, among other things. There is a plug-in type devoted to MPEs. More to come.

So, if you consider all all those acess methods should be consistent, we have a nice mess. The good news are it seems to work, the bad news, we need more testing. But overall I see progress.

Fear not!, maybe I will even accomplish the schedule and realease the whole thing on November.

Monday, July 6, 2009

Tag plug-in

Related with cmsReadTag, here comes one of the easier plug-ins to write: the tag plug-in.

Imagine you are a printer vendor and want to include in your profiles a private tag for storing the ink consumption. So, you register a private tag with ICC, and you get signature "inkc".

Ok, now you want to store this tag as a Lut16Type, so it will be driven by PCS and return one channel giving the relative ink consumption by color.

Writing a plugin in lcms2 will allow cmsReadTag and cmsWriteTag to deal with you new data exactly as any other standard tag.

To do so, you have to fill a cmsPluginTag structure to declare the plugin. This structure is formed by a base, which is common to all plug-ins.

plugin.base.Magic = cmsPluginMagicNumber;
plugin.base.ExpectedVersion = 2.0;
plugin.base.Type = cmsPluginTagSig;


That latter identifies your plug-in as "tag type". Now we need to define the tag signature

plugin.signature = 'inkc';

And some additional info about the type used by your tag:
  • How many instances of the type the tag is going to hold (usually one)
  • in how many different types the tag may come (again, usually one)
  • and then the needed type(s).

plugin.descriptor. ElemCount = 1;
plugin.descriptor. nSupportedTypes = 1;
plugin.descriptor.SupportedTypes[0] = cmsSigLut16Type;

That is all. You can setup the new functionality by calling

cmsPlugin(&plugin);

Advanced tag plug-ins may use polymorphic types, depending on the version of the profile for example. Instead of one type, you can declare several. Then the read tag logic will search for all supported types to find the suitable one. cmsSigLut16Type for v2 and cmsSigLutBtoAType for v4 for example. There is an optional callback function to decide which type to use when writing the tag.


cmsTagTypeSignature DecideType(double ICCVersion, const void *Data);

This plugin is most useful when combined with the tag type plugin, which will be discussed soon.

Friday, July 3, 2009

Plug-ins

One of the main improvements of lcms2 is the plug-in architecture. Plug-ins means you can use the normal API to access customized functionality. Licensing are another compelling reason, you can move all your IP into a proprietary plug-in and still be able to upgrade core revisions in open source. There are 10 types of plug-ins currently supported.
  • Memory management
  • Error management
  • Interpolation
  • Tone curve types
  • Formatters
  • Tag types
  • Tags
  • Rendering intents
  • Multi processing elements
  • Optimizations
I will discuss each type in incoming posts. Plug-ins are declared to lcms by a single function

cmsBool cmsPlugin(void* Plugin);

And the "Plugin" parameter may represent one or several plug-ins, as defined by the plug-in developer. To write plug-ins, there is an additional include file lcms2_plugin.h, which declares functions which are not in the public API but may be useful to this task. For example I/O access, matrix manipulation, and all the types needed to populate the plug-in structures. Those functions begins with "_cms" to denote those are extended functionality and should not be called the application by rather by the plug-in.