Double tile iterators?
This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Double tile iterators? | Dr William Bland | 04 Jul 13:36 |
Double tile iterators? | David Neary | 04 Jul 14:58 |
Double tile iterators? | Dr William Bland | 04 Jul 15:21 |
Double tile iterators? | Simon Budig | 04 Jul 15:25 |
Double tile iterators? | Daniel Egger | 04 Jul 17:36 |
Double tile iterators? | Simon Budig | 04 Jul 15:31 |
Double tile iterators? | Dr William Bland | 04 Jul 16:48 |
Double tile iterators? | Simon Budig | 04 Jul 19:06 |
Double tile iterators? | Dr William Bland | 05 Jul 12:42 |
Double tile iterators?
Hello all,
I've just started writing my first gimp plugin, so I'm very new at
this. Hope nobody minds my stupid questions ;-)
So what I'm trying to do is make a plugin that selects certain regions of an image (the regions selected will depend on what's in the image). I've already managed to make it so that it can select a pre-defined (i.e. defined in the source) area, but now I need to make that area depend on the contents of the image.
I thought about using some kind of "double tile iterator" to do this, e.g:
gimp_pixel_rgn_init (&image_rgn, image_drawable,
x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
gimp_pixel_rgn_init (&select_rgn, select_drawable,
x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
for (p1 = gimp_pixel_rgns_register (1, &image_rgn),
p2 = gimp_pixel_rgns_register (1, &select_rgn);
(p1 != NULL) && (p2 != NULL);
p1 = gimp_pixel_rgns_process (p1),
p2 = gimp_pixel_rgns_process (p2))
{
/* Interesting stuff goes in here! */
/* Set some of the pixels in select_drawable */
/* depending on the pixels in image_drawable. */
}
but then it occurred to me that the tiles that get iterated over will not necessarily be of the same size for the image_drawable and select_drawable which would cause this loop to go horribly wrong!
Can anyone suggest what the Right Thing to do here is? I know it's possible to look at image_drawable on a pixel-by-pixel basis (rather than tile-by-tile), but from what I've read this will make things *very* slow and obviously I don't want that ;-)
Thanks for any help.
Best wishes,
Bill.
Double tile iterators?
Dr William Bland wrote:
Hello all,
I've just started writing my first gimp plugin, so I'm very new at this. Hope nobody minds my stupid questions ;-)
it occurred to me that the tiles that get iterated over will not necessarily be of the same size for the image_drawable and select_drawable which would cause this loop to go horribly wrong!
Can anyone suggest what the Right Thing to do here is? I know it's possible to look at image_drawable on a pixel-by-pixel basis (rather than tile-by-tile), but from what I've read this will make things *very* slow and obviously I don't want that ;-)
For the moment you have no problems - all tiles are 64x64, and that's hard-coded. It would be nice to have tile sizes modifiable, but that will not happen before 2.0 to the best of my knowledge, and there will be much bigger problems to worry about for plug-ins in that :)
Cheers, Dave.
Double tile iterators?
On Thu, Jul 04, 2002 at 02:58:08PM +0200, David Neary wrote:
For the moment you have no problems - all tiles are 64x64, and that's hard-coded. It would be nice to have tile sizes modifiable, but that will not happen before 2.0 to the best of my knowledge, and there will be much bigger problems to worry about for plug-ins in that :)
Ah! Thanks Dave. I was imagining that the tile size was adjusted dynamically by the gimp in some way to make things as fast as possible. I assumed the size depended at least on the number of bits per pixel in the drawable (e.g. so that tiles all had the same memory requirements rather than the same size). Now I know that's not the case my plug-in will be a lot easier to write. Thanks!
Best wishes, Bill.
Double tile iterators?
David Neary (dneary@wanadoo.fr) wrote:
Dr William Bland wrote:
Hello all,
I've just started writing my first gimp plugin, so I'm very new at this. Hope nobody minds my stupid questions ;-)it occurred to me that the tiles that get iterated over will not necessarily be of the same size for the image_drawable and select_drawable which would cause this loop to go horribly wrong!
Can anyone suggest what the Right Thing to do here is? I know it's possible to look at image_drawable on a pixel-by-pixel basis (rather than tile-by-tile), but from what I've read this will make things *very* slow and obviously I don't want that ;-)
For the moment you have no problems - all tiles are 64x64, and that's hard-coded.
You might run into trouble though, since it is possible to have an offset to a layer, which means, that the tiles do not necessarily match.
However, Some time ago Marc Lehmann destroyed my fears with respect to that. The core cares about this problem and makes sure that the pixel regions are split up in smaller parts where each part is contained in a single tile per drawable.
Bye, Simon
Double tile iterators?
I should have read the code before posting my last message:
Dr William Bland (wjb@abstractnonsense.com) wrote:
I thought about using some kind of "double tile iterator" to do this, e.g:
gimp_pixel_rgn_init (&image_rgn, image_drawable, x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); gimp_pixel_rgn_init (&select_rgn, select_drawable, x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); for (p1 = gimp_pixel_rgns_register (1, &image_rgn), p2 = gimp_pixel_rgns_register (1, &select_rgn); (p1 != NULL) && (p2 != NULL); p1 = gimp_pixel_rgns_process (p1), p2 = gimp_pixel_rgns_process (p2))
this better should be
p1 = gimp_pixel_rgns_register (2, &image_rgn, &select_rgn);
p1 != NULL;
p1 = gimp_pixel_rgns_process (p1)
{
/* Interesting stuff goes in here! */ /* Set some of the pixels in select_drawable */ /* depending on the pixels in image_drawable. */ }
Then the core will care about the stuff I mentioned in the other mail.
Bye, Simon
Double tile iterators?
On Thu, Jul 04, 2002 at 03:31:46PM +0200, Simon Budig wrote:
I should have read the code before posting my last message:
Dr William Bland (wjb@abstractnonsense.com) wrote:
I thought about using some kind of "double tile iterator" to do this, e.g:
gimp_pixel_rgn_init (&image_rgn, image_drawable, x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); gimp_pixel_rgn_init (&select_rgn, select_drawable, x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); for (p1 = gimp_pixel_rgns_register (1, &image_rgn), p2 = gimp_pixel_rgns_register (1, &select_rgn); (p1 != NULL) && (p2 != NULL); p1 = gimp_pixel_rgns_process (p1), p2 = gimp_pixel_rgns_process (p2))
this better should be
p1 = gimp_pixel_rgns_register (2, &image_rgn, &select_rgn); p1 != NULL;
p1 = gimp_pixel_rgns_process (p1){
/* Interesting stuff goes in here! */ /* Set some of the pixels in select_drawable */ /* depending on the pixels in image_drawable. */ }Then the core will care about the stuff I mentioned in the other mail.
Hi Simon,
Thanks! That looks much nicer. Unfortunately I can't get it to
work properly (sorry, like I said, I'm a newbie at this ;-). I now have
the following code:
static void
do_stuff (GimpDrawable *image_drawable, GimpDrawable *select_drawable)
{
GimpPixelRgn image_rgn, select_rgn;
gint x1=0, y1=0, x2=select_drawable->width, y2=select_drawable->height;
guchar *image_data = NULL, *select_data;
gint i;
gint image_bytes = image_drawable->bpp, select_bytes = select_drawable->bpp;
gint size;
gpointer pr;
gimp_pixel_rgn_init (&image_rgn, image_drawable, x1, y1,
(x2 - x1), (y2 - y1), TRUE, TRUE);
gimp_pixel_rgn_init (&select_rgn, select_drawable, x1, y1,
(x2 - x1), (y2 - y1), TRUE, TRUE);
for ( pr = gimp_pixel_rgns_register (2, &select_rgn, &image_rgn);
pr != NULL;
pr = gimp_pixel_rgns_process (pr))
{
size = select_rgn.w * select_rgn.h;
select_data = select_rgn.data;
while (size--)
{
for (i=0; iid, TRUE);
gimp_drawable_update (select_drawable->id, x1, y1, (x2 - x1), (y2 - y1));
}
Note that I'm not yet actually *doing* anything with the data in
image_rgn, only select_rgn. Now if I start gimp, create a blank 256*256
image, select everything and then run my plugin, I get:
http://www.abstractnonsense.com/double.png
which is clearly not right! Some of the pixels are correct, but there is
clearly some random fluff in there as well.
If I change the iterator to a single one, so that it reads
for ( pr = gimp_pixel_rgns_register (1, &select_rgn);
then I get:
http://www.abstractnonsense.com/single.png
which is correct but doesn't help since I will be needing the double
iterator soon.
Any ideas what's going on here? Thanks again for your help.
Best wishes,
Bill.
Double tile iterators?
Am Don, 2002-07-04 um 14.58 schrieb David Neary:
For the moment you have no problems - all tiles are 64x64, and that's hard-coded. It would be nice to have tile sizes modifiable, but that will not happen before 2.0 to the best of my knowledge, and there will be much bigger problems to worry about for plug-ins in that :)
In fact, because it was hardcoded in just places and not in others, I hardcoded it completely to a compiletime constant to avoid some confusion....
Double tile iterators?
Dr William Bland (wjb@abstractnonsense.com) wrote:
Hi Simon,
Thanks! That looks much nicer. Unfortunately I can't get it to work properly (sorry, like I said, I'm a newbie at this ;-). I now have the following code:static void
[...]
{
size = select_rgn.w * select_rgn.h; select_data = select_rgn.data;while (size--) {
for (i=0; i
*select_data++ = 255*(size%2);
}
}
[...]
This is not correct. Please note that the data pointer still points
inside the complete tile. By simply accessing the pixel data linearily
you might leave the region indicated by the pixel region. To do this
properly you have to iterate over the rows separately (select_rgn.w *
select_rgn.bpp bytes) and then add select_rgn.rowstride to the adress
where line starts. Have a look at
http://www.home.unix-ag.org/simon/gimp/guadec2002/gimp-plugin/html/efficientaccess.html
there is a small graphics illustrating this. Sample code is also there.
I hope this helps.
Bye, Simon
Double tile iterators?
On Thu, Jul 04, 2002 at 07:06:36PM +0200, Simon Budig wrote:
This is not correct. Please note that the data pointer still points inside the complete tile. By simply accessing the pixel data linearily you might leave the region indicated by the pixel region. To do this properly you have to iterate over the rows separately (select_rgn.w * select_rgn.bpp bytes) and then add select_rgn.rowstride to the adress where line starts. Have a look at
http://www.home.unix-ag.org/simon/gimp/guadec2002/gimp-plugin/html/efficientaccess.htmlthere is a small graphics illustrating this. Sample code is also there.
Thanks 1e6 for that Simon! This is a very useful resource - so useful in fact that I decided to scrap my existing plug-in and use the example as a new starting point. It's now progressing quite nicely.
Thanks again. Best wishes, Bill.