Archive

Archive for the ‘OpenGTL’ Category

OpenGTL 0.9.12 and Shiva noise

20 November, 2009 Leave a comment

OpenGTL 0.9.12

Earlier today I made a new release of OpenGTL (download page), version 0.9.12, for that release 23 tasks were completed, the main changes are:

  • Fixing thread safety issues at run time.
  • Progress report.
  • Many new mathematical functions for the Shiva standard library.
  • Replacement of the Shiva kernels random functions.
  • OpenGTL is now compiling and running on Mac OS X.

The first two points are important changes for krita, since the first one meant that with the previous releases we had to use mutex while executing Kernels, preventing to benefit from multi-core. The second one means the user can see something is happening in Krita when a filter is processed.

Random functions in Shiva

This new release also break the Shiva language compared to previous release, I try to prevent that, but since the language is still very young it was bound to happen. In previous releases I quickly introduced a rand() function, because I wanted to write a perlin noise generator. The problem with rand() is that it does not take a seed parameter, meaning that the function use the global seed, meaning that two consecutive call to ther perlin noise generator kernel gives two different results, without any kind of control. For graphics, we need to make sure that the result are reproductible, so now in 0.9.12, the function rand() has been replace by one that takes a seed parameter rand(output int seed).

Such a function is usefull at init time, to construct random structures, like those needed by the perlin noise. But this is not sufficient, we also need a random function that can be used while processing a pixel, and one that would always return the same value for a given pixel and a given seed, for instance to write a salt and pepper noise generator.

The problem of the rand(output int seed) function is that it works by incrementing the seed parameter, so that next time you call it, it gives a different result, so as long as the call are made sequentially it would work fine. But in case of Shiva (or Krita, for that matter), we cannot guarantee that those call will be made sequentially, and it is not possible to keep a value between the computation of two different pixels. Because we might just be interested in generating part of the image, or we might be executing the kernel in a multi-threaded environment. To solve this problem, about six monthes ago, in Krita, we developed an algorithm that takes the pixel coordinate and the seed, and return a pseudo-random number. For 0.9.12, I copied that algorithm in Shiva, giving birth to the second new function for random number generation, which is rand(int x, int y, int seed).

The code for the salt and pepper noise generator is:

kernel Noise
{
  void evaluatePixel(out pixel4 result)
  {
    int x = result.coord.x;
    int y = result.coord.y;
    for(int i = 0; i < 3; ++i)
    {
      result[i] = frand(x, y, 32);
    }
    result.setAlpha( 1.0);
  }
}

The code for the perlin noise generator is slightly more complicated and can be watch in the opengtl mercurial repository.

And the resulting images, salt and pepper noise on the left, and perlin noise on the right:

 

Moiré, when Open Source can be usefull to work

20 October, 2009 1 comment

Sometime I get asked whether what I do in open source is useful for my work. Except for the thing like kalculus that were explicitly written for my work needs, usually the time invested does not pay at all, despite using Krita for scaling or cropping images to put in a paper. But sometime you get the opportunity to accomplish a task in five minutes that would have taken way more time if you had not invest years of development before. Small victory.

Since my thesis deals a lot with computer vision, I wanted to make an introduction to signal and image processing concepts. One of them is the issue of aliasing, which happen when under sampling a signal. And one of the classical artifact caused by sampling is called Moiré. The image below show the result of rescaling a set of concentric circles by three and four (the image were resized up for display):

So my need was to generate those circles. And what better than a programming language made for generating images, such as Shiva ? One can argue that some other tool would have make a better choice. But I was very quick to get to this first version, where I just check if the pixel is inside a white circle or a black one:


kernel ConcentricCircles
{
  const int radius = 3;
  const float4 color1 = { 0.0, 0.0, 0.0, 1.0 };
  const float4 color2 = { 1.0, 1.0, 1.0, 1.0 };
  const float2 center = { IMAGE_WIDTH * 0.5 , IMAGE_HEIGHT * 0.5 };
  void evaluatePixel(out pixel4 result)
  {
    float lf = length(result.coord - center);
    int l = lf;
    if( (l / radius & 1) == 1 )
    {
      result = color1;
    } else {
      result = color2;
    }
  }
}

I then improved that version to get parameters and anti aliasing of the circles, the full Shiva kernel can be found in the shiva collections repository.

Categories: Open Source, OpenGTL

Shiva generator, krita and metaball

24 September, 2009 1 comment

One of the new thing of the upcoming 2.1 release for Krita (among improved stability) is that the OpenGTL library is now even more integrated, which makes it even easier to write cool filters or generators for Krita.

Today, I will speak about generators. Since Krita 2.0, there is a special kind of layers in Krita: generators, it’s like a normal layer, except that the pixel are generated automatically. In 2.0, the only generator available was a plain color generator. In 2.1, you can write your generator using the Shiva language.


kernel Singleball
{
const float radius = 0.1;
const float ringradius = 0.05;
const float ycenter = 0.5;
const float ycenter = 0.5;
const float2 center = { IMAGE_WIDTH * xcenter, IMAGE_HEIGHT * ycenter };
dependent float pxradius, pxringradius;
void evaluateDependents()
{
int image_size = min(IMAGE_WIDTH, IMAGE_HEIGHT);
pxradius = radius * image_size;
pxringradius = ringradius * image_size;
}
void evaluatePixel(out pixel4 result)
{
float2 vec = result.coord - center;
float angle = atan2( vec.x, vec.y);
float r = length(vec);
if(r (pxradius + pxringradius))
{
result = outsidecolor;
} else {
float v = (r - pxradius) / pxringradius;
result = (1.0 - v) * ballcolor + v * outsidecolor;
}
}
region generated()
{
region reg = { 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT};
return reg;
}
}

The value of the input pixel is computed in evaluatePixel, while evaluateDependents is used to initialize some constants.

The actual version of this kernel can be found here, the full version contains configurable options for the center and radius.

Then to use your generator in krita you just need to copy it to ~/.kde/share/apps/krita/shiva/kernels. As you can see, I have made a metaball generators, integrated in krita, with its option widget:

OpenGTL 0.9.8/0.9.9, GTLDesigner 0.9.1, libQtGTL 0.9.0 and shiva-collections 1.0

Today, I made a bunch of releases related to the OpenGTL project. Ranging from the main library, to some utilities and wrapper for Qt applications.

The main library comes with two version one for llvm 2.4 (OpenGTL 0.9.8) and one from llvm 2.5 (OpenGTL 0.9.9), the two main improvements are:

  • a new memory management model, so far each time an object was created it was allocated in memory, and since most objects have a very short life time this was leading to excessive computational time, since putting all objects on the program stack was such a nightmare to manage correctly, I simply started to use a shadow stack with preallocated memory, this is less efficient than using the program stack, but gives massive speed improvement compared to allocating memory through the system
  • a new kernel collection system, the previous system for collection of kernels wasn’t practical to use and required compilation of all kernels at load time, which is very unefficient. The new one was written while doing at the same time integration in a real world application, aka Krita.

libQtGTL is a library that provides wrappers classes and configuration widgets for Kernel for use in Qt applications that want to use kernels, the screenshot below show an exemple of such use in Krita:

From now on, I also start to ship Shiva kernels in an external tarball, in shiva-collections, the goal is to update more often that tarball than I do update the library. It contains the examples that were available previously in OpenGTL tarball, and also some new effects, such as the calleidoscope:

All this is available at OpenGTL’s download page.

OpenGTL 0.9.6/0.9.7

30 November, 2008 2 comments

Since llvm 2.4 has been released a few weeks, and since I have made a lot of improvement in the libraries, it’s about time I make a release of OpenGTL. So a twin release, 0.9.6 for llvm 2.3 and 0.9.7 for llvm 2.4.

The main changes are:

  • Lot of bug fixes… too many for me to be not lazy to make a list that no one would read… But among other things the conversion between types is done in a much more nicer way.
  • Library support, and start the standard library in OpenShiva
  • Add examples of Shiva kernel
  • Not really a feature but the libraries are now licensed under LGPL version 2 or later (instead of just 2, I hope I won’t live to regret that decision…)

You can download it here or get OpenSuSE package (10.3 or 11.0)

OpenGTL 0.9.5 and Darkroom 1.3

2 September, 2008 1 comment

Today I am making a joint release of OpenGTL and Darkroom, for the main reason that I have made quiet a lot of bug fixes in OpenGTL that are needed to get a fully working Darkroom.

OpenGTL 0.9.5

Among the bug fixes, there are two major changes in this release

  • Start using llvm optimization, there is one thing that OpenGTL does very poorly, it is emitting assembly code, for instance, if you need to access three time a value, it will load it three time from memory… So enabling optimization give a significant boost in execution speed, unfortunately, I haven’t had the time to do some benchmarking, but I have noticed a siginificant improvement in applications (Krita and Darkroom) that use OpenGTL.
  • The second change, which took me longer to do correctly, is that conversion are now handled by the parser and inserted in the AST tree, instead of being assumed to be possible in the parser and triggering asserts in the code generation (previously MyStruct a; int b = 2 + a; would have aborted the program instead of reporting an error to the user). The other benefit of that change is that it makes possible to automatically convert from Shiva’s pixel structure to a vector.

    Before that change, the Blur kernel was looking like this:

    kernel Blur
    {
    void evaluatePixel(image img, out pixel result)
    {
    pixel v1 = img.sampleNearest( result.coord );
    pixel v2 = img.sampleNearest( result.coord - 1.0 );
    pixel v3 = img.sampleNearest( result.coord + 1.0 );
    for(int i = 0; i < 3; ++i)
    {
    result[i] = (v1[i] + v2[i] + v3[i]) / 3;
    }
    }
    }

    And now it is down to:

    kernel Blur
    {
    void evaluatePixel(image img, out pixel result)
    {
    result = ( img.sampleNearest( result.coord ) + img.sampleNearest( result.coord - 1.0 ) + img.sampleNearest( result.coord + 1.0 ) ) / 3.0;
    }
    }

Darkroom 1.3

The two main changes (yes I like to limit myself to the number 2) of Darkroom are:

  • This release introduce a levels widget, if you wonder how it is useful, I suggest reading Unai Garro’s Levels adjust tutorial.

  • Darkroom can now export to jpeg, when I first started Darkroom I considered that the only interesting export format would be Png, only to realize later that if one wants to export to a web gallery, jpeg is better suited
  • Bookmarks (yes that’s a third change, but I only remember about it when I did the screenshots for the levels widget), it’s now possible to save bookmarks of your favorite processing settings

OpenGTL 0.9.3 and 0.9.4 : first release with Shiva

A few days ago, I spoke about OpenShiva, since then I have added quiet a few features, since OpenShiva can now read images, and work with different bit depth than float 32bits, I have also found a lot of bugs that are now fixed (and are covered by automatic tests ! yay !).

Now, there are all the basic features to demonstrate the technology, so it’s about time to make a release. Especially that a new release of llvm has been made early June, and since they make a point to have weird API/ABI breakage at each release: before to create most instructions you would write “new InstructionName(params);” and now it is “InstructionsName::Create(params);” except for a few instructions were the old style is still in use… That said, without llvm, I would have been unable to achieve what I have achieve until now with OpenGTL.

So here comes two releases, 0.9.3 for llvm 2.2 and 0.9.4 for llvm 2.3, they have both the same feautres sets.

Beside a lot of bug fixes, and the early implementation of OpenShiva, OpenCTL has matured a lot, and now most of the standard library is implemented (it remains a very complex function that is underspecified :( and some color conversion functions). And there is also a nice debug system that allows to control output depending on library, file name and function name, which is nice, since OpenGTL, in debug mode, is very noisy (but it’s all needed when debugging).

If you want to have fun, you can download everything here.

Follow

Get every new post delivered to your Inbox.