[Gegl-developer] new GEGL samplers: what they are and where they are going

2009-09-17 Thread Nicolas Robidoux

Question about future direction for resamplers:

Would it be better if there was only one sampler tuned for upsampling,
and one tuned for downsampling?

My previous vision for GEGL was that my research group would
contribute TWO resamplers tuned for upsampling and TWO resamplers
tuned for downsampling. The four new samplers would (eventually)
integrate the best of the 16 resamplers programmed by Eric and Adam
for GSoC 2009.  Within each of the two pairs of resamplers, one was to
be interpolatory (and more aliased) and the other would minimally
blur (and be less aliased).

Now: I just figured out how to use the Jacobian matrix information so
that the sampler only add noticeable antialiasing blur when the
operation is performing significant upsampling or downsampling. What
this means for the resamplers tuned for upsampling, for example, is
that we could seamlessly integrate Nohalo and Snohalo in such a way
that the sampler behaves like Nohalo when translating and rotating
(hence is blur free) but behaves increasingly like Snohalo as the
transformation (locally) deviates from being distance preserving
(hence is more anti-aliased), resulting in one single sampler which
would please everyone and their father.

I imagine that a few people would want the added control over the
aliasing vs blur trade-off which having pairs of methods would provide
(also, methods can be faster if they are not jack of all trades).

But I am wondering if for GEGL's target user base an always pretty
good default is preferable to choose your poison.

Comments?

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] new GEGL samplers: what they are and where they are going

2009-08-31 Thread Nicolas Robidoux
, finishing with bilinear
interpolation.

Nohalo level 2 is an unpublished, state of the art method.

Upsize is interpolatory, co-monotone and exact on linears.

It is especially suited for enlarging colour photographs (which
typically are sub-critical, that is, have smallest relevant
details/transitions which are several pixel wide).

Future improvements: Research by Chantal Racette suggests that one
level of subdivision (that is, Nohalo level 1) followed by a variant
of symmetrized MP-quadratic instead of bilinear may yield a better
method than Nohalo level 2.

==
Upsizefast sampler
==

Upsizefast is an implementation of Nohalo level 1, which is described
in

  CPU, SMP and GPU implementations of Nohalo level 1, a fast co-convex
  antialiasing image resampler, by Nicolas Robidoux, Minglun Gong,
  John Cupitt, Adam Turcotte and Kirk Martinez, published in the
  Proceedings of the Canadian Conference on Computer Science 
  Software Engineering, C3S2E 2009, Montreal, Quebec, Canada, May
  19-21, 2009, ACM International Conference Proceedings Series, pages
  185-195.  http://doi.acm.org/10.1145/1557626.1557657

Nohalo level 1 consists of one diagonal straightening subdivision
followed by bilinear interpolation.

Upsizefast is interpolatory, co-monotone and exact on linears.


Upsmooth sampler


Upsmooth is an implementation of (the simplest version of) Snohalo
level 2 (Snohalo = smooth no halo), which consists of Nohalo level
2 preceded by a de-noising and antialiasing smoothing convolution
tuned so that a sharp black on white diagonal line or interface is
straight following the first subdivision.

Snohalo level 2 is an unpublished, state of the art method.

Upsmooth is co-monotone and exact on linears.

Upsmooth is strongly anti-aliasing. It is especially suited for
enlarging text, old school game characters, and heavily
(destructively) compressed images and photographs (jpg with heavy
compression, for example).

Future improvements: It is possible that applying smoothing between
every level instead of only initially, or doing one level of
subdivision and then using a relative of symmetrized MP-quadratic as a
finishing scheme, will yield better results.


Upsmoothfast sampler


Upsmoothfast is an implementation of Snohalo level 1, which consists
of Nohalo level 1 preceded by the antialiasing blur.

Snohalo level 1 is another unpublished, state-of-the-art method.

Upsmoothfast is co-monotone and exact on linears.

=
Downsharp sampler
=

Downsharp is an exact area method which is similar to exact area box
filtering with an averaging rectangle that has sides 1/sqrt(2) of
those of the smallest rectangle (with sides aligned with untransformed
coordinate axes) which contains the approximate inverse image of an
output pixel area (a square centered at the sampling location in
transformed space, with sides, of length one, aligned with the
axes). The inverse image is approximated using the inverse Jacobian
matrix of the transformation. The averaging is done over the minmod
surface which is implicit to the S/Nohalo methods.

The 1/sqrt(2) factor ensures that when the transformation does not
downsample in any direction, the sampler is interpolatory. It also
implies that, of the six downsamplers, it is the one which behaves
most like nearest neighbour (although it is very different from it).

Downsharp is yet another unpublished method.

Downsharp is co-monotone and exact on linears. When upsampling, it is
also interpolatory.

Downsharp is well-suited for producing thumbnails and other
transformations (perspective?) in which large areas become a single
pixel.

Future improvements: Fix things so that downsampling ratios larger
than about 100 are better handled. The simplest way would be to have
the downsamplers use a larger buffer than the current 64x64;
otherwise, use branching and multiple get pointer to input buffer
calls if necessary. And, as mentioned above, possibly get rid of
it.


Downsize sampler


Downsize is like downsharp except that the rectangle always fully
contains the approximate inverse image of a pixel area.

Downsize is yet another unpublished method. It was inspired
somewhat by the PDL::Transform method of Craig DeForest.

Downsize is co-monotone. When upsizing (no rotation or warp), it is
interpolatory and exact on linears.

Downsize is well-suited for producing thumbnails etc.

Future improvements: Like downsharp, better handling of very large
downsampling ratios. It is possible that averaging over the actual
approximate inverse image, or over a related disk or ellipse, give
better results than over the smallest containing rectangle
(programming this well is a non-trivial programming task).

==
Downsmooth sampler
==

Downsmooth is like downsize except that the rectangle is twice
the size required

Re: [Gegl-developer] Abyss color

2009-08-07 Thread Nicolas Robidoux

 What would be the most general way of getting this abyss color to
 gegl-buffer-access.c?

gegl/operations/affine/affine.c

would take care of rotation and scaling and a few other things,
although it probably is still not general enough.

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] use of bitwise arithmetic in GEGL code

2009-08-06 Thread Nicolas Robidoux

Is the use of such tricks discouraged for GEGL (because gfloats could
be doubles at some point?)

We can take the absolute value by setting the sign bit to zero:
// Example 13.24
float f;
*(int*)f = 0x7FFF; // set sign bit to zero

(From http://www.agner.org/optimize/optimizing_cpp.pdf)

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] use of bitwise arithmetic in GEGL code

2009-08-06 Thread Nicolas Robidoux

Ralf Meyer (another Laurentian prof) did some quick and dirty
experimentation with preliminary versions of bit-twiddling minmods and
found that on PowerPC chips it made a big difference. Not on Intel.

Not really surprising: Avoiding branches like the plague is more
relevant to PowerPC/cell than Intel.

In GEGL (production) code? Not sure.

Nicolas Robidoux





___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Passing parameter to sampler from XML file

2009-07-08 Thread Nicolas Robidoux

Suggestion implementing the s/nohalo family and the nohalobox family
without an explicit, visible, parameter:

Would it be possible/desirable to use the current code (which has a
parameter) as some sort of template?

Then, the nohalobox code would produce four independent samplers:

sharperbox - smoothing = 0
sharpbox - smoothing = 1/3.
smoothbox - smoothing = 2/3.
smootherbox - smoothing = 1.

which could be called like, say, linear.

And the s/nohalo code would produce four independent samplers:

sharper - nohalo (nohalo produces the same results as snohalo with smoothing = 
0, just faster)
sharp - snohalo with smoothing = 1/3.
smooth - snohalo with smoothing - 2/3.
smoother - snohalo with smoothing = 1.

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Passing parameter to sampler from XML file

2009-07-08 Thread Nicolas Robidoux

yahvuu writes:
  
  uh, what, me?
  
  i wouldn't want to be bothered with choosing different samplers
  for up/down-scaling.

(I'm surprised. You are always happy with the thumbnails you get?
Result after rotating an image? Maybe I'm too invested in this field
to know what matters and what matters not.)

Peter just gave me more ideas of how it could look in a menu:

bigger (sharp) and bigger (smooth)

and 

smaller (sharp) and smaller (smooth)

The fact that bigger can be used for arbitrary warps (including
downsampling) and smaller can be used for arbitrary warps (including
upsampling) should not confuse anyone. (I think.)

Keep the ideas coming!

Nicolas Robidoux
Laurentian University
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Passing parameter to sampler from XML file

2009-07-08 Thread Nicolas Robidoux

sharpEnlarge and smoothEnlarge

and

sharpShrink and smoothShrink (or sharpReduce and smoothReduce)

?

PS

Let me know if you'd rather I think about all this off list.
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Passing parameter to sampler from XML file

2009-07-08 Thread Nicolas Robidoux

sharpsmall and smoothsmall

and

sharpbig and smoothbig

?

In a scale image menu, the most likely appropriate method could be
chosen automatically (depending on the requested resizing), with an
extra smoothing toggle set by default to off.

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Passing parameter to sampler from XML file

2009-07-07 Thread Nicolas Robidoux

Nicolas Robidoux writes:
  
  For example, nohalo1 (same result as snohalo1 with smoothing = 0, but
  runs faster) would be sharper, snohalo1 with smoothing = 1 would be
  smoother, and snohalo1 with smoothing = .5 would be halfandhalf,
  or something kind of like that?

If there were only four named presets, I supposed they could be

sharpest, sharp, smooth, smoothest

corresponding to smoothness = 0, 1/3, 2/3 and 1.

with the added bonus that smoothness = 1/3 kind of corresponds to the
Mitchell-Netravali choice of smoothing/interpolation balance.

Øyvind:

Does the above seem like a good choice, or did I change your mind with
my smoothness slider idea (or do you like neither)?

Nicolas Robidoux
Laurentian University
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] API change for samplers to pass inverse Jacobian data to samplers

2009-06-29 Thread Nicolas Robidoux

Martin Nordhotls wrote:
 Personally I don't see the point in duplicating a matrix lib in
 every software, i.e. I question the introduction of GeglMatrix3 in
 the first place, I mean there certainly must be high quality libs
 for matrix operations out there, but that's a different story...

IMHO, when all you are dealing with are 3x3 matrices (which are not
arbitrary 3x3, since they represent affine + perspective
transformations), it is likely that a general purpose matrix library
would be slower. Even more so with 2x2.

So, my vote is actually for not library.

Nicolas Robidoux


___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] API change for samplers to pass inverse Jacobian data to samplers

2009-06-26 Thread Nicolas Robidoux

Adam:

(Ignore if my last email about GeglMatrix3 was off the mark.)

Is it that affine transformations, stored in 3x3 matrices, get
simplified when they are chained?

If so, where is the final overall 3x3 representation?

Hopefully, extracting the linear part from it to compute the inverse
Jacobian could be done there.

Nicolas Robidoux
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] API change for samplers to pass inverse Jacobian data to samplers

2009-06-25 Thread Nicolas Robidoux

Adam Turcotte writes:
 In addition, I will need to expand the OpAffine struct to include an
 additional GeglMatrix3 (call it matrix_inverse or inverse_jacobian?)
 to store this data.

GeglMatrix3?  Is this a 3x3 matrix type?

(Ignore the following if it is not.)

Maybe the matrix created by the create_matrix () method is not really
the plain Jacobian matrix even for affine transformations.

I understand that there are convenient representations of common image
transforms in terms of 3x3 matrices, but I wonder if using a 3x3 to
store either the Jacobian or its inverse just confuses things, at
least for our purposes.

My suggestion: If create_matrix () returns a 3x3, keep the inverse
Jabocian computation out of create_matrix (). 

Because I am far from certain that there would ever be a need to do
matrix operations on the inverse Jacobian, I actually am not even sure
that it is necessary to store it in an explicit matrix type. For
documentation sake? Can anyone foresee a use for the inverse Jacobian
matrix being stored in a 3x3?

Nicolas Robidoux

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] [GSoC] Midterm project evaluations coming up

2009-06-19 Thread Nicolas Robidoux

Adam Turcotte's midterm deliverables:

-- Figure out how to use/adapt/emulate intermediate buffers to store
   intermediate results (kind of like nohalo runs on the GPU:
   intermediate buffer would be like a texture).

-- Figure out how to use/adapt/emulate variable size sampler buffers
   for non-recursive reasonable quality downsampling.

-- Make good progress in implementing the above (hopefully, be done)

nicolas
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] [GSoC] Midterm project evaluations coming up

2009-06-19 Thread Nicolas Robidoux

Argh!

My explanation (RE: Adam's GSoC deliverables) was terrible (Adam just
called me on it).

What I meant:

Somehow allowing a variable footprint (stencil) in (re)samplers. Right
now, the footprint is fixed (from
gegl/gegl/buffer/gegl-sampler-cubic.c):

 GEGL_SAMPLER (self)-context_rect.x = -1;
 GEGL_SAMPLER (self)-context_rect.y = -1;
 GEGL_SAMPLER (self)-context_rect.width = 4;
 GEGL_SAMPLER (self)-context_rect.height = 4;

The RHS's are arbitrary, but I don't think they can be changed at
run-time on a pixel by pixel basis (or even on a run by run basis?).

Hopefully, it makes sense now.

We already have some ideas of how to emulate it.

Nicolas Robidoux
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] [GSoC] Midterm project evaluations coming up

2009-06-16 Thread Nicolas Robidoux

Eric Daoust's GSoC midterm deliverables:

 1) Sped up nohalo level 1 code.

 2) New fast resampling method targeted for downsampling (without
the affine transformation info passed from above, and
without variable size buffers, which will be implemented later
in the SoC). This will be the lower quality (but most likely
very fast) version.

(I'll email RE: Adam's deliverables when I have them nailed down.
Adam is currently focusing on the much trickier nohalo level 2 and
buffer issues.)

Nicolas Robidoux
Universite Laurentienne

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] new gegl-sampler code (GSoC): maximum expected downsampling ratio

2009-06-14 Thread Nicolas Robidoux

In case it turns out to be difficult to set the context_rect to be
variable (set on an output pixel by pixel basis--Eric is looking into
this), I'd like to know what I could assume is the largest reasonable
downsampling ratio, meaning that larger downsampling ratios would be
clamped down to this ceiling. Such clamping would allow us to set the
context rectangle to a (reasonably small) fixed value.

More specifically, could I reasonably clamp the downsampling ratio (in
each direction) to one of the following values?

   1.0 (context_rect.width = 4)
   2.7182818284 (context_rect.width = 5)
   7.3890560989 (context_rect.width = 6)
   20.0855369231 (context_rect.width = 7)
   54.5981500331
   148.4131591025
   403.4287934927
   1096.6331584284 
   2980.9579870417 (context_rect.width = 12)

(first and last ones included for the sake of completeness.)

The smaller the maximum, the faster the code will run.

(As the above table makes pretty obvious, the method will be more
suitable for mild downsampling that heavy duty.)

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] alignment of pixels with coordinates

2009-05-28 Thread Nicolas Robidoux

Øyvind Kolås writes:
  ...
  I agree that the convention should be that pixel sampling sites are at
  integer coordinates. I also feel it would be natural to let the extent
  of a pixel be half way towards the neighbour pixel sites, this however
  has the issue of not matching the display GIMP provides when zoomed
  into the image.
  ...
  GEGL might in the future also offer other resamplers for blitting /
  display purposes, the best would of course be if all resamplers could
  be plugged in and interchangeably used for different purposes, at the
  moment the resampling that happens in gegl_node_blit does not use the
  resamplers to do its job for the general cases it probably shouldn't
  either since it needs to be as fast as possible.

Thank you! I finally figured it out:

Image size conventions are actually decoupled from the
pixel-coordinates convention. (Although they often are linked, they
don't need to be.)

The resamplers can all use one convention (center-based physical
coordinates, as you suggest, and as I prefer). But the operations
which call resamplers can have an optional toggle, with defaults
dependent on the called resampler. - I am not totally sure this is
easy to implement, but this would be ideal.

So, an affine operation calling a resampler targeted at downsampling
(e.g. exact area box filtering) would use the image size convention
which corresponds to exact area resampling---that is, the image
sticks out half a pixel from the centers of the boundary pixels
(this is the big image convention)---unless overridden by the user
(note that this is separate, althought related, to the issue of where
the pixel coordinates are).  Likewise, an affine operation calling an
interpolatory resampler (targeted for point transformations) would
use the image convention which is normally associated with it---the
image ends right at the centers of the boundary pixels (the small
image convention).

Nicolas Robidoux
Universite Laurentienne

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] GSoC 2009: implementing multiple quality levels in resamplers

2009-05-28 Thread Nicolas Robidoux

Any suggestions RE: the intelligent way of implementing samplers with
multiple quality levels?

(Note that Adam and Eric may be able to figure this out without your
or my guidance, but in the interest of faster progress I am asking
planning questions here.)

My question will make more sense if I explain things a bit:

The nohalo family of resamplers has levels, which are most easily
understood as quality levels.

Currently, an outdated nohalo level 1 is in the gegl library as
gegl/gegl/buffer/gegl-sampler-sharp.c. (It is correct, but it is much
slower than it has to be.)

Nohalo level 2 is near ready (for VIPS), and by the end of the Summer
we hope to have levels 3 and 4 implemented in GEGL.

Now, these could be associated with quality requests (say, if quality
 .25, use nohalo level 1, if quality  .5 use level 2, etc).

Note, for example, that the footprint (stencil) gets larger as the
quality increases (think of Lanczos methods, for example).

How would you like this to be set up? Are there examples we could
follow?

A related issue:

The upcoming snohalo (snohalo level 1 is ready in VIPS, no progress on
snohalo level 2) also has quality levels (analogous to the nohalo
quality levels). The key aspect is that snohalo has a blur parameter
which, when set to 0, reduces the method to the same level nohalo,
which runs considerably faster (because, among other things, it has a
much smaller footprint). Any suggestion on how to implement this in
GEGL so that a call to snohalo actually return nohalo when blur = 0,
but the codes are kept separate? Or should we simply put the two
together with an if statement which steers internally things toward
nohalo when they should?

Thanks (for your patience),

Nicolas Robidoux
Universite Laurentienne






___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-13 Thread Nicolas Robidoux

Hello Utkarsh,

Maybe implementing multi-threading in GEGL would be a good, not yet
taken, project?

(Note that I do not have enough of a broad/detailed view on GEGL to
make this suggestion from a position of authority.)

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-13 Thread Nicolas Robidoux

Dear Utkarsh:

I was talking about CPU multi-threading, that is, using multi-cores,
e.g.

http://www.vips.ecs.soton.ac.uk/index.php?title=Benchmarks#Results_in_detail

And unfortunately, I am swamped, and consequently, I basically can't
help.

I may be wrong, but I am pretty sure that GEGL does not multi-thread
as of now.

Nicolas Robidoux
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-13 Thread Nicolas Robidoux

Utkarsh:

Although clearly the two projects probably should not proceed without
some mutual consultation, I feel that GPU and multi-core involve
fairly seperate programming. For this reason, I would not be overly
concerned that your fixing multi-core (say) would duplicate the GPU
effort.

Clearly, some coordination would be desirable. However, in the nitty
gritty, these are separate projects.

Nicolas Robidoux
Laurentian University
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-12 Thread Nicolas Robidoux

I expect the following items from Øyvind's list to be tackled by Adam
Turcotte and Eric Daoust (both GSoC students which I
mentor). Consequently, if someone is planning to tackle these issues
in the foreseable future, please let everyone know.

Øyvind Kolås writes:
  ...
  
  What follows is a blue-sky wishlist of features that should be possible
  to add to the architecture making it and GEGL a powerful base.
  
  - Make the background/empty color configurable (by making the empty
tile's contents configurable).
  - Add abyss policies to be used by resamplers, allowing configuring the
behavior of affine transforms and warping image operations.

I'm not making promises on the following (given that they are not part
of the original GSoC) but they are related to Adam and Eric GSoCs, but
it would make sense to have them have a look at the following (I may
give more programming help with the resampler parts to free them for
what's below):

  - Detect when a tile is set to be a solid block of the background color,
and make the tiled shared with the empty tile.
  - Detect uniformly colored and perhaps other types of tiles and store
them more compactly, perhaps even just compressing tile contents and
share duplicate tiles detected through hashing of their compressed data.

Nicolas Robidoux
Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-12 Thread Nicolas Robidoux

Øyvind Kolås writes:
  I forgot to add one more item to my list of potential/desired
  enhancements of GeglBuffer and that is to make the extent (width and
  heights) of the buffer be updated on demand when tiles are changed,
  allowing automatically growing buffers that are auto-clipped to the
  bounding box of content that differs from the configured background
  color.

Do I gather correctly that this is related to the possible solution
you gave for

http://bugzilla.gnome.org/show_bug.cgi?id=54

namely,

 The bug is manifest because the different interpolation methods have
 different sampling footprints. The resulting image size is computed
 based on the size of the kernel, this is similar in behaviour to the
 gaussian blur which increases the size of the input image as well by
 smearing it out. The upper left corner of the bounding box is stored
 to be in negative coordinats so sampling from 0,0 would yield the
 upper left sample anyways. One way to work around this would be to
 crop the image to the original bounding box.

 Not completely sure if this is a bug or not, I guess it depends on
 what types of behavior we want to support for the edges of
 transformed buffers.

Please let me know if I am completely off track, but there are some
issues which I want to understand if possible (even though you may
have explained it to me already) in order to guide Eric and Adam:

Question 1:

If my memory is good, samplers in GIMP use the center image size
convention, which means that the centers of the boundary pixels creep
in when downsampling, but creep out when upsampling, because what
is kept fixed is the position of the corners of the areas implied by
the boundary pixels, which are half a pixel width out from their
centers.

The most common alternative is the corner convention, which anchors
the positions of the centers of the boundary pixels.

I am omitting discussion the pros and cons for each. (Generally,
center is better for downsampling, and corner is better for
upsampling, so no single convention works best for all situations.)
However, it is my opinion that corner convention is generally
better.

Do you have a preferred implied convention for GEGL? Should it
comply with what is generally the implied convention in GIMP?

This matters, because if the abyss policy is no blending: image goes
to the boundary ignoring the abyss, and the abyss is constant whatever
(0, say, but one of your requested features is that this be
configurable), we need to know where the boundary is.

Question 2:

Do you want resampled image sizes to be enlarged by the size of the
footprint (more specifically, by the size of smallest rectangle which
contains the footprint, since, for example, the footprint of nohalo is
not a rectangle), or do you want the resampled image size to be
cropped, in accordance with the image size convention (in the corner
convention, the image ends right at the center of the boundary pixels,
in the center convention, it ends one half pixel past it).

Prior to our conversations last week, I was sure that cropping should
be done. however, now that I have been exposed to the wonderfulness
of GEGL buffers, I have the impression that the buffer should be
extended by this footprint so that the blending implicit in most
abyss policies be applied not only inside the extent of the original
image, but also outside. A consequence is that the bounding box will
depend on the abyss policy, which is the case now. In other words,
this would be a feature, not a bug.

Question 3:

Because the footprint of the samplers is often asymetrical (for
example, for bicubic, the anchor is the second pixel from the left,
out of the four positions which make up the footprint in the
horizontal direction; this breaks left/right symmetry) the number of
pixels by which the image is extended at the top and left is often not
the same as the number by which it is extended at the bottom and
right. Of course, symmetry is resolved in that extra ones are set to
the background abyss colour (0).

Again, I previously saw this as a bug, which in principle could be
avoided using some logic or cropping. However, at this point, I am
enclined to treat it as a quirky feature which is a side effect of a
sound design decision.

Is this agreed?

--

I hope that I am not making my confusion too manifest here.

Cheers,

Nicolas Robidoux
Universite Laurentienne



___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-12 Thread Nicolas Robidoux

Christopher Montgomery writes:
  ...
  I suspect you are conflating center/corner with 'are we point sampling
  or area sampling the pixel?'.
  ...

I am not.

Although area sampling generally works better with the center
convention, and point sampling works better with the corner
convention, one can use either with either convention. In my mind,
these are related, but separate, issues. I have programmed and used
area sampling methods with either convention, for example.

More about this later.

-

(Thanks for joining the discussion.)

Nicolas Robidoux
Laurentian University




 
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-12 Thread Nicolas Robidoux

Let me try to be a bit more specific, one issue at a time.

--

I agree that, at least at low order (which is all we're doing for
now), abyss policies are independent of whether we are using the
center or corner image conventions, and are also independent of
whether we are implementing an exact area method (like most
implementations of box filtering), or a point resampler (like standard
bicubic).

However, Øyvind expressed a desire to have something implemented in or
for the resamplers which cannot really be done with the usual abyss
policy implementations.

Here is:

Associate a default constant colour with a buffer. What Øyvind would
like (if I understand correctly) is that instead of sampling through
the implied boundary using the resampler as if there was no boundary
(filling in the missing footprint values using the abyss policy), the
resampled values drop dead at the boundary and from then on are
filled (filled, not blended) with the default colour. For example, the
sampler could use the nearest neighbour abyss policy (a.k.a. clamp)
for requested values up to the boundary line, and return the default
colour past it.

Comment: Thinking about this some more, I am starting to think that it
is a bad idea to implement this. (Later.)

Irregardless of whether this is a good or bad idea, the main point is:

Where should the drop dead transition occur:

Aligned with the (center of) the boundary pixels? Or half a pixel
width out (at the boundary of the pixel area associated with boundary
pixels)?

One of my worries is that if one when doing something else than
resizing this will essentially behave like nearest neighbour (from the
outside in), which will be ugly.  So, I am actually starting to
think that drop dead is not such a good idea.

But I'd love to hear opinions on this.

nicolas

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Introduction to GEGL Buffers

2009-05-12 Thread Nicolas Robidoux

Christopher Montgomery writes:
  ...
  Ah, you mean that the implementation is easier, not that the output
  results differ?
  ...

Christopher:

Can we start from scratch? I'm afraid that we may take a long time
explaining to each other exactly what we mean, with the most likely
end result that we agree with each other on the essential (code-wise
consequences). I started the ball rolling being vague, let me see if I
can stop it.

It's not that I don't welcome your input (I actually sought it, and it
is important to me that we align the GEGL resampler team with their
GIMP counterparts), it is just that I am too tired/busy to get into a
I actually mean this, which really is the same although it is
different from what you mean, is that right? Oh! you were talking
about this limited situation but I was talking about the more general
one and things are not the same but you can emulate the other if you
are willing to blah blah blah debate.

It's more important to me to be useful than to be right.

nicolas
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] Documenting gegl

2009-02-19 Thread Nicolas Robidoux

Hello Henrik:

I don't know if this was mentioned before, but the open source VIPS

http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS

although quite different to GEGL, is also somewhat similar.

VIPS handles CMPs well.

Maybe some of VIPS' under the hood parallel machinery would carry
over?

Nicolas Robidoux
Laurentian University/Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] How to get bounding box from inside a sampler

2008-09-19 Thread Nicolas Robidoux

Hello all:

This question will make clear that I don't understand c++.

Suppose that, in the code for, say,
gegl/gegl/buffer/gegl-sampler-cubic.c, I want to use information about
the bounding box of the input data.

More precisely:

I (believe that) I already know that the relevant pixel values start
at indices 0,0. Requested values to the left and above those are
created by the (currently 0,0,0,0) abyss policy.  Which is to say that
0 and 0 are the smallest x and y for which I have real data.

What I want to know is the width and height (in pixels) the area with
valid pixel values.

This is almost the same as:

I want to know the lowest positive indices at which the abyss policy
kicks in.

Which is almost the same as:

What is the index of the rightmost/lowest pixel with real data
associated to it.

--

Once I have this info, I can finish the yafr code.

With thanks,

Nicolas Robidoux
Laurentian University/Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] Speeding up/documenting the gegl code

2008-09-13 Thread Nicolas Robidoux

(Forgive me for preaching, done from the vantage point of a very stubby 
soapbox.)

One thing which I would not mind seeing throughout the gegl code is the 
systematic use of the const keyword.

My understanding is that the const keyword can also be used effectively to 
indicate to the compiler that
it can optimize without worrying about aliasing (of course, if the object is 
not const, the restrict keyword
is the only weapon).

If is also good for documentation, because it allows one (me!) to find out 
easily which arguments can be changed
by a function. (Akin to classical fortran subroutine documentation: declare 
the input arguments first, then 
the arguments which are both input and output, then those which are strictly 
output.

About const correctness:

http://www.cprogramming.com/tutorial/const_correctness.html
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] #defining the restrict keyword

2008-09-13 Thread Nicolas Robidoux

Hello Sven:

Given that the restrict keyword may be defined by default for other compilers 
than gcc (it is in gcc 

http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/Other-Builtins.html

wouldn't the following be better?

#ifndef restrict
#ifndef G_GNUC_RESTRICT
#if defined (__GNUC__)  (__GNUC__ = 4)
#define G_GNUC_RESTRICT __restrict__
#else
#define G_GNUC_RESTRICT
#endif
#define restrict G_GNUC_RESTRICT
#endif
#endif

This appears to work in (the not yet patched in svn) yafr. 

--

Even better:

It appears that autoconf can take care of this in one fell swoop:

http://www.gnu.org/software/libtool/manual/autoconf/C-Compiler.html

See the Macro: AC_C_RESTRICT section.

Nicolas Robidoux
Laurentian University/Universite Laurentienne

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


[Gegl-developer] more benchmarking: restrict vs no restrict

2008-09-13 Thread Nicolas Robidoux

Hello:

I did some quick benchmarks, having to do with qualifying pointers local to 
gegl-sampler-yafr.c and gegl-sampler-linear.c with the restrict keyword.

The upshoot:

Speed wise, this makes not difference.

Comments:

These functions are fairly simple, so it could be that gcc can untangle 
aliasing, since there is not much opportunity for it.

When pointers are dealing with stripes, separating them into different 
pointers may lead to more benefit when using the restrict keyword.

It could be that more globally defined pointers benefit more from the restrict 
keyword.

But I am starting to suspect that const has more likely impact on speed than 
restrict.

Nicolas Robidoux
Laurentian University/Universite Laurentienne
___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Question about the use of C99/gcc built-in math intrinsics within GEGL on gfloats

2008-09-12 Thread Nicolas Robidoux

Hello Sven:

Thanks for your answer. Simplifies my life a lot.

--

There is another C99/gcc built-in with the potential to speed up code a lot: 
the restrict keyword.

See:

http://www.cellperformance.com/mike_acton/2006/05/demystifying_the_restrict_keyw.html

I'll build two versions of the gegl-sampler-yafr code (one of which which I'll 
masquerade as gegl-sampler-cubic so I can run both without recompiling) and run 
careful benchmarks this weekend. One version will stay away from restrict and 
c99 math intrinsics, the other will not (first pass, I may not go as far as 
making explicit calls to fma, although my code is structured in the hope that 
the compiler recognizes fused multiply-adds when appropriate).

I don't quite understand the issues of writing c++ code using c99 features 
(this is why knowing that they are gcc built-ins is useful, provided one knows 
that gcc will be the compiler).

Maybe I'll inspire myself from

http://www.ddj.com/cpp/184401653

Nicolas Robidoux
Laurentian University/Universite Laurentienne

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer


Re: [Gegl-developer] Question about the use of C99/gcc built-in math intrinsics within GEGL on gfloats

2008-09-12 Thread Nicolas Robidoux

I just completed a quick and dirty benchmark comparing the use of 
arithmetic branching using c99/gcc intrinsics within the yafr sampler
code, to using the standard c if then else.

These tests were performed on a Thinkpad t60p with Intel(R) Core(TM)2
CPU T7200 @ 2.00GHz with 2025MiB memory running 2.6.24-19-generic #1
SMP by way of a pretty standard Ubuntu 8.04.

Warning: There seems to be something wrong with math.h with the
current version of gcc, as suggested by some recent bug postings. For
example, according to the gcc documentation, I should not have to
prefix fminf with __builtin_. Consequently, it could be that the
benchmark results will soon be made irrelevant.

Second warning: If my memory is good, Intel chips have a good and fast
implementation of the ? : branching construct (having to do with
selecting which register to copy into another), as well as good branch
prediction. My code without intrinsics is structured to take advantage
of this.

Third warning: I have not optimized looking at the assembler output of
gcc, and have done no optimization of the arithmetic branching
version of the code. In particular, I have not used fmaf, even though
my code is peppered with opportunity to use it (this may not be a big
deal: apparently, gcc attempts to spot opportunities to use fused
multiply-add).

--
quick description of the test:
--

I ran a bunch of consecutive scalings (times 20) of a digital
photograph with initial dimensions 200x133, driving the gegl scale
through an xml file analogous to the ones in gegl/docs/gallery,
alternating between the with branching and arithmetic branching
with intrinsics versions, and throwing in four scalings with the gegl
stock linear.

-
Differences between the two versions of the code:
-

16 code segments resembling the following (note the ?: this the
version with branching):

  const gfloat prem_squared = prem * prem_;
  const gfloat deux_squared = deux * deux_;
  const gfloat troi_squared = troi * troi_;
  const gfloat prem_times_deux = prem * deux;
  const gfloat deux_times_troi = deux * troi;
  const gfloat deux_squared_minus_prem_squared = deux_squared - prem_squared;
  const gfloat troi_squared_minus_deux_squared = troi_squared - deux_squared;
  const gfloat prem_vs_deux =
deux_squared_minus_prem_squared  (gfloat) 0. ? prem : deux;
  const gfloat deux_vs_troi=
troi_squared_minus_deux_squared  (gfloat) 0. ? deux: troi;
  const gfloat my__up =
prem_times_deux  (gfloat) 0. ? prem_vs_deux : (gfloat) 0.;
  const gfloat my_dow =
deux_times_troi (gfloat) 0. ? deux_vs_troi : (gfloat) 0.;

were replaced by (this is the version with arithmetic branching):

  const gfloat abs_prem = fabsf( prem );
  const gfloat abs_deux = fabsf( deux );
  const gfloat abs_troi = fabsf( troi );
  const gfloat prem_vs_deux = __builtin_fminf( abs_prem, abs_deux );
  const gfloat deux_vs_troi = __builtin_fminf( abs_deux, abs_troi );
  const gfloat sign_prem = copysignf( prem, (gfloat) 1. );
  const gfloat sign_deux = copysignf( deux, (gfloat) 1. );
  const gfloat sign_troi = copysignf( troi, (gfloat) 1. );
  const gfloat my__up =
( sign_prem * sign_deux + (gfloat) 1. ) * prem_vs_deux;
  const gfloat my_dow =
( sign_deux * sign_troi + (gfloat) 1. ) * prem_deux_0_vs_troi;

Basically, what the code snippets does is this:

If prem and deux have the same sign, put the smallest one (in absolute
value) in my__up. Otherwise, set my__up to zero. Do likewise with
deux, troi and my_dow. The above two code snippets represent the best
ways of performing this that I could figure.

===
Overall conclusion:
===

Arithmetic branching (without other improvements) does not appear to
be worth the trouble.


Average timings:


stock gegl linear scale:

47.50 = ( 47.474 + 47.581 + 47.345 + 47.595 ) / 4

gegl yafr with ? branching and no use of intrinsics:

52.58 = 
( 52.422 + 52.479 + 52.748 + 52.501 + 52.680 + 52.623 + 52.537 +
52.518 + 52.576 + 52.487 + 52.542 + 52.485 + 52.645 + 52.810 + 52.667
+ 52.554 ) / 16

gegl yafr performing arithmetic branching with fabsf, copysignf and fminf:

52.70 = ( 52.568 + 52.447 + 52.763 + 52.524 + 52.772 + 52.652 + 52.524
+ 52.765 + 52.596 + 52.850 + 52.733 + 52.799 + 52.627 + 52.897 +
52.871 + 52.866 ) / 16

As you can see, the ? version is slightly faster overall. Probably
not in a significant way, but this certainly does not suggest that
this is worth the hassle.

Nicolas Robidoux
Laurentian University/Universite Laurentienne

___
Gegl-developer mailing list
Gegl-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer