finalizing the Iterator API
boud at valdyas.org
Wed Jul 7 09:14:23 CEST 2004
On Wednesday 07 July 2004 00:15, Casper Boemann wrote:
> > As for the ".h", here is my opinion :
> > * I don't see the difference between KisPixelIterator and
> > KisPixelRectIterator.
> Well KisPixelIterator is just a super class (oh I forgot that in the class
> definition didn't I)
> Other subclasses besides Rect could be Path or Line, or Extent
> They only visits some pixels. The superclass doesn't really do anything - I
> think it should be abstract.
> And as Boudewijn said up,down.left,right might be nice functions, however
> they don't make sense for a PathIterator. I have had this idea myself, but
> on reflection: when would they really be used.
Edge detection, for instance.
> Another Iterator I just tought of is an affine transformation, used to
> scale, rotate and shear images.
I have a hard time visualizing that, so I'd like to see it... Currently we use
affine transform code I ported from Qt, debugged by Bart, for all this, but we
really need bicubic interpolation scaling, as the current scaling is really
> The prime requirements when defining our pixel representation are:
> 1) it should store only the actual channel data. No configuration data -
> since that would cost too much memory when storing several millions of
:-(. It's a pity, since it would make programming so much easier. But in the
end, I think we have no choice.
> 2) it should allow any combination of int8, int12, int32, float,double,
Fortunately, the colour strategies already have the rudiments of a pixel
description in the ChannelInfo structure. This needs to be extended and
formalized -- here I really put my foot down. I don't want to have to check
the depth of the image every time I consult the ChannelInfo :-).
> 3) copyable without knowing interpretation
> 4) it should either be
> a) truly universal, but that requires configuration info clashing with
> requirement 1
> b) dynamic down-castable to specific imagetypes but that also clashes
> with 1
> c) static down-castable which is what my proposal does.
> Anyway , the GOF (p 91 bottom paragraph)
My offer to provide a copy to people not having that book still stands:
however, not having the paper version handy, can you give the pattern you
> discusses a similar problem, and
> doesn't refer to a usable pattern. It actually alludes that there are none
> except the same solution I propose. Note our problem is even worse because
> we have even more requirements.
Yep. In image manipulation land there are a few solutions that are frequently
* Manual code duplication -- this is what Photoshop does, I believe (because
their 16-bit channel images cannot be manipulated like the 8-bit, but every
release gets a bit better.
* Code generation from a description -- this is gegl. Generate C code for
every image type from a common description.
* Templating -- this is what Vigra does to an amazing extent, and what CImg_
does to a lesser extent.
* Using the maximum precision representation internally, and convert down on
saving. This is what Vips does.
* Using classes and interfaces to abstract everything into polymorphism. This
is what Java2D does, and what OpenEXR seems to do. (Note: ImageJ is a public
domain Java image manipulation app that's plenty fast enough, and it uses
Java2D and some home-grown things. It can be made to work, but perhaps not in
C++. Java is more efficient when it comes down to polymorphism).
So, having overseen the possible solutions, I think we will go with passing a
pointer to bytes (Q_UINT8) to the colour strategies. The colour strategies
can construct, on demand, pixel, colour or channel objects for algorithms to
manipulate. Or algorithms that don't care about how the pixel is laid out
(copy, affine transforms) can copy the Q_UINT8 data directly.
We can then get ultimately rid of QUANTUM, which is an inheritance from the
days Krita used ImageMagick as its core. Howevere, that is another
refactoring step, one which we don't have to take now.
We need the iterators now, so I can continue with selections, and we need to
port the plugins and the affine transform code to use image-type independent
> We could change my proposal to a pointer to an entirely empty class, but
> that is only name calling, and we would still have to static downcast to
> specific subclasses in the colorstrategies.
> The problem with an empty class is that calling sizeof() would be wrong
> (can sizeof be overloaded to give a compile error?). Also an empty class
> that actually contains something seems wrong to me conceptually. For
> example you cannot have an array of these empty classes. The byte array
> seems more correct.
> The benefit of an empty class is that the iterators return a pointer to a
> Pixel class, which may seem more descriptive to the programmer.
> Anyway I'm willing to use an empty class, if the rest of you insist. I do
> however think it gives more complicated and errorprone code, but it is
> definitely doable.
I feel convinced. Although -- see the pseudo-code I mailed in response to
Cyrille's concerns. It seems a bit silly to have to manually ask the colour
strategy to parse the data into a pixel. Maybe we can provide a PixelIterator
that returns the parsed data, for those algorithms that need it that way, and
a PixelDataIterator that returns the pointer, for the algorithms that leave
all the real work to the colour strategy anyway.
> yes it is because of the dynamic layersize I'm working on. It may be
> possible to encode the row,col as a single number but that would just be
> yet another calculation to do for no real benefit. Row and col of a tile
> remain the same when the size of the device changes. tilenum does not as it
> depends on the number of columns (which obviously will no longer be
That's your party: if you need it this way for dynamic layersize, it's
something that must get in. It doesn't affect the users of the iterators.
Boudewijn Rempt | http://www.valdyas.org/fading/index.cgi
More information about the kimageshop