-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 So -- I am close to actually getting a generic image api worked out. Here is a not-so-short summary of what I have worked out. I will try to seperate what I have working from what I don't have working. If it is working, it is in CVS. First what is working: there exists an abstraction for the data type of a buffer: GeglBuffer: A GeglBuffer is an abstract type holding a buffer of data with some number of (potentially) dis-continuous banks. A bank element is independ of the concept of pixels or samples. A bank element is a single elemetn of the type stored in the buffer. All elements can be set with the get_element_double and set_element_double calls. There also exists one concrete sub class at the moment, which is designed to contain doubles. Transfer type is an enum describing the data type of a buffer. There exists only one value at the moment TYPE_DOUBLE TransferType gegl_buffer_get_transfer_type(const GeglBuffer* self); gint gegl_buffer_get_num_banks (const GeglBuffer * self); gint gegl_buffer_get_elements_per_bank(const GeglBuffer * self); gpointer * gegl_buffer_get_banks (const GeglBuffer * self); gdouble gegl_buffer_get_element_double(const GeglBuffer* self,gint bank,gint index); void gegl_buffer_set_element_double(GeglBuffer* self,gint bank,gint index,gdouble elem); a factory method for convience. GeglBuffer* gegl_buffer_create(TransferType type, const gchar* first_property_name, ...); GeglNormalizer: This abstract class encasuplates the algorithm needed to convert raw sample data (e.g uchar) to normalized, sample information (e.g. 0.0<=p<=1.0). There exists one concrete sub-class at he moment which takes a single parameter and multiples the raw sample data by that parameter on reading and by the inverse on writing. GeglSampleModel: SampleModel is an abstract class that encasuplates all the information needed to extract samples from buffer elements. A single band contains a single color channel. (e.g. RGB has three bands, Red, green, blue). A sample model also has a width and a height, since that information is almost always needed to figure out how to address the buffer. GeglSampleModel makes to reference to the data type of the buffer it is addressing. GeglSampleModel also contains a set of GeglNormalizers for each channel, which are used by the gegl_sample_model_get_x_normalized fuctions. gint gegl_sample_model_get_num_bands(const GeglSampleModel* self); gint gegl_sample_model_get_width(const GeglSampleModel* self); gint gegl_sample_model_get_height(const GeglSampleModel* self); gdouble* gegl_sample_model_get_pixel_double(const GeglSampleModel* self, ~ gint x, ~ gint y, ~ gdouble* dArray, ~ const GeglBuffer* buffer); void gegl_sample_model_set_pixel_double(const GeglSampleModel* self, ~ gint x, ~ gint y, ~ const gdouble* dArray, ~ GeglBuffer* buffer); gdouble gegl_sample_model_get_sample_double(const GeglSampleModel* self, ~ gint x, ~ gint y, ~ gint band, ~ const GeglBuffer* buffer); void gegl_sample_model_set_sample_double(const GeglSampleModel* self, ~ gint x, ~ gint y, ~ gint band, ~ gdouble sample, ~ GeglBuffer* buffer); gdouble gegl_sample_model_get_sample_normalized(const GeglSampleModel * self, ~ gint x, ~ gint y, ~ gint band, ~ const GeglBuffer* buffer); void gegl_sample_model_set_sample_normalized(const GeglSampleModel * self, ~ gint x, ~ gint y, ~ gint band, ~ gdouble sample, ~ GeglBuffer* buffer); gdouble* gegl_sample_model_get_pixel_normalized(const GeglSampleModel * self, ~ gint x, ~ gint y, ~ gdouble* d_array, ~ const GeglBuffer* buffer); void gegl_sample_model_set_pixel_normalized(const GeglSampleModel* self, ~ gint x, ~ gint y, ~ const gdouble* d_array, ~ GeglBuffer* buffer); //This creates a buffer of type TransferType that is compatible with this sample model. GeglBuffer* gegl_sample_model_create_buffer(const GeglSampleModel* self, ~ TransferType type); //This checks that the layout of the GeglBuffer is compatible with this sample model. gboolean gegl_sample_model_check_buffer(const GeglSampleModel* self, const GeglBuffer* buffer); There is one concrete Sample Model GeglComponentSampleModel: This sample model represents a buffer for which each sample is stored as a single element in the buffer. pixel_stride, scanline_stride, bank_offset, band_index are used to describe the layout of the pixel data in the buffer and are set in the constructor (g_object_new). gint gegl_component_sample_model_get_pixel_stride(const GeglComponentSampleModel* self); gint gegl_component_sample_model_get_scanline_stride(const GeglComponentSampleModel* self); gint gegl_component_sample_model_get_bank_offset(const GeglComponentSampleModel* self, gint bank); gint gegl_component_sample_model_get_band_index(const GeglComponentSampleModel* self, gint band); The rest of this stuff doesn't exist: There is GeglColorModel: GeglColorModel describes how color information is set out in the bands of the a sample model. It allows you to query which channels contain color information (by returning the idicies of the color channels). IT allows you to query the index of the alpha channel, and it allows you to query the indices of the channels which contain lumunosity information. ~ (this is useful because alpha is only supposed to be applied to channels that contain lumonisity information. Thus in Luv, alpha is only multiplied by L and in RGB, all channels contain lumonosity informtion so alpha is applied to all of them). Presumable this classed would be instantiated party by a color space class (which doesn't exist), with the user declaring the existance of alpha. const gint* gegl_color_model_get_color_channels(const GeglSampleModel* self); gint gegl_color_model_get_color_channel(const GeglSampleModel* self, gint idx); gint gegl_color_model_set_color_channel(GeglSampleModel* self, gint index, gboolean is_a_color); gint gegl_color_model_get_num_colors(GeglSampleModel* self); const gint* gegl_color_model_get_lum_channels(const GeglSampleModel* self); const gint* gegl_color_model_set_lum_channel(const GeglSampleModel* self, gint index, gboolean has_lum_info); There is a GeglTile: A gegl tile is essentially a container for a buffer, sample model, and a color model. It should support copy on write. There is a GeglTileIterator. This abstracts the iteration process. It would be instantiated by a GeglTile with a factory method. Here are the pointers from the class structure. GeglObjectClass parent_class; ~ void (*start_lines)(GeglIterator* self); ~ void (*start_bands)(GeglIterator* self); ~ void (*start_pixels)(GeglIterator* self); ~ void (*next_line)(GeglIterator* self); ~ void (*next_band)(GeglIterator* self); ~ void (*next_pixel(GeglIterator* self); ~ gdouble* (*get_colors)(GeglIterator* self,gdouble* pixel); ~ void (*set_colors)(GeglIterator* self, const gdouble* pixel); ~ gdouble (*get_alpha)(GeglIterator* self); ~ gdouble (*set_alpha)(GeglIterator* self,gdouble alpha); ~ gdouble (*get_sample)(GeglIterator* self); ~ gdouble (*set_sample)(GeglIterator* self,gdouble sample); ~ gdouble* (*get_colors_amult)(GeglIterator* self,gdouble* pixel); ~ void (*set_colors_amult)(GeglIterator* self, const gdouble* pixel); ~ gboolean (*finished_lines)(const GeglIterator* self); ~ gboolean (*finished_bands)(const GeglIterator* self); ~ gboolean (*finished_pixels)(const GeglIterator* self); Finally, there is a GeglImage which is responsible for iteracting with the tile cache, and creating tiles on demand. Some notes on usage: The way one would use these class is as such: The most general case would be to use the tile iterator over the tiles of an image. If you wanted to speed up with specialization, you could write a more efficient sample model, or you could access the pixels directly by getting the buffer. Comments?!? IF anyone wants to help me finish this up, I would greatly appreciate it. - -- Dan -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.3 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE/nDsQad4P1+ZAZk0RAsK9AJ9CtDmaKFLwXXaIyEne2p+VUfih2ACeKoYv TnHnhPV4k9QM1YzLJQOMvrk= =AnOB -----END PGP SIGNATURE-----