A new strategy for storing gimp projects is needed when GEGL enters the arena. GEGL will broaden the possiblities available to a gimp project, at gimpcon 2003 there was an agreement that an xml based catalog is a convenient form to express the relationship between the various assets involved in a project.
This page documents a mapping that has proved to work for compositing engine built on gggl.
The compositing model used in the file format is linear lists of image processing operations, similar to the user interfaces usually found in graphics editors with layers.
The start or background image is located at the bottom of a list, this is our image source. Filters and composers can be stacked on top of it. A simple processing list to rescale and save a png image would be represented in xml as:
<xcf> <sink type='null'/> <filter type='scale'> <property name='width' >0.2</property> <property name='height'>0.2</property> </filter> <source type='png'> <property name='resource'>wilber.png</property> </source> </xcf>
Operations accepting two image inputs, composers; like porter duff operations and other layer modes, have an auxiliary child list.
<xcf> <sink type='null'/> <composer type='over'> <property name='x'>0.2</property> <property name='y'>0.2</property> <source type='text'> <property name='string'>hello</property> <property name='font' >courier</property> <property name='size' >90</property> </source> </composer> <filter type='bcontrast'> <property name='brightness'>-0.3</property> <property name='contrast' >1.0</property> </filter> <source type='png'> <property name='resource'>wilber.png</property> </source> </xcf>
Clones similar to symbolic links are possible within the document using the special source of type 'clone', referring to a numbered output id in the same document.
<xcf> <sink type='null'/> <composer type='over'> <property name='x'>0.21</property> <property name='y'>0.21</property> <source type='clone' idref='text'/> </composer> <composer type='over'> <property name='x'>0.2</property> <property name='y'>0.2</property> <filter type='opacity'> <property name='level' >0.4</property> </filter> <filter type='invert'/> <source type='text'> <property name='string'>hello</property> <property name='font' >courier</property> <property name='size' >90</property> <output id='text'/> </source> </composer> <source type='png'> <property name='resource'>wilber.png</property> </source> </xcf>
Free form directed acyclic graphs can also be used as elements in the compositing tree, this allows for multiple inputs to a single node,. clones are also allowed used within the graph, just because it is possible and order doesn't matter within a graph, the image flow in the following example is from top to bottom within the graph.
<!-- need a better graph based example,. perhaps blurring of A and B components in LAB space --> <xcf> <sink type='null'/> <graph> <node name='source'> <!-- implied type nop --> <output id='69'/> </node> <node name='bcontrast'> <input idref='69'/> <property name='brightness'>0.1</property> <property name='contrast'>1.4</property> <output id='42'/> </node> <node name='sink'> <!-- implied type nop --> <input idref='42'/> </node> </graph> <source type='png'> <property name='resource'>wilber.png</property> </source> </xcf>
Oxide uses a very similar structure for it's project files, oxide has the additional notion of sequences, clips, and interpolation of property values, oxide does not (yet) differentiate between different classes of operations, and thus serializes all operations just as "node"
<oxide> <node type='ff_save'> <property name='resource'>output.avi</property> </node'> <sequence> <clip in='0.0' out='250'> <node type='over'> <property name='x'>0.4</property> <property name='y'>0.4</property> <node type='opacity'> <property name='level'> <value time='0.0'>1.0</value> <value time='125.0'>1.0</value> <value time='250.0'>0.0</value> </property> </node> <node type='text'> <property name='string'>hello</property> <output id='42'/> </node> </node> <node type='blank'> <property name='width'>400</property> <property name='height'>300</property> </node> </clip> <clip in='0.0' out='250'> <node type='avi'> <property name='resource'>foo.avi</property> <property name='frame'> <value time='0.0'>0.0</value> <value time='250.0'>250.0</value> </property> </node> </clip> </sequence> </oxide>
perhaps one should consider the top-level xcf document element, to be a source op in itself,. and disregard all the sink ops. Whatever display / file conversion etc. hooks that are inserted on top of the gimp document object,. isn't actually part of the data that the user will interact with.
a way to attach specialized sink ops,. that are just "runtime" debugging is needed, allowing to create layer thumbnails etc.. a naming convention that allows filtering them out to avoid displaying them would be needed,.. an ideal way to do this might be with clones,. since that would seperate the data from the rest of the document..
what is the core op set?,. some opertaions should be considered a core that all implementations needs to have,. e.g. over, crop, png, text(?),
what units to support? for video editing with proxies, like oxide is used for percentages makes most sense, since they are resolution independent and makes it possible to work on a scaled down proxy version,. whilst maintaining project compatibility with the version used for rendering the full version. Pixel precision is needed for composited icons and similar things.
Metadata, in the form of parasites etc. how should they be encoded?
A thumnail is probably natural to have, it would be metadata refering a png|jpg file within the collection.