Crash when calling Gdk::Drawable::draw_pixbuf

View: New views
9 Messages — Rating Filter:   Alert me  

Crash when calling Gdk::Drawable::draw_pixbuf

by Falk Schilling :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I have a question belonging to a conversion from Gtk::Image to Gdk::Image.

First at all, I have created an UI via Glade that contains some
(Gtk::)Image widgets. Then I am loading an input image into one of those
widgets. I also have some nifty resizing buttons that read the
Gdk::Pixbuf from that image, scale(_simple) that and redisplay it on the
widget. Until here I have absolutely no problems, that works quite well.

But now I want to read in an (empty/white) image, draw a simple pixel to
position (x,y) and redisplay the modified image.

To achieve this, I am currently doing the following:
• have the following member variables (m_pixbuf, m_gc, m_dim are
initialized and work properly, m_drawable and m_gdk_image are NULL ):

Glib::RefPtr<Gdk::GC> m_gc;
Glib::RefPtr<Gdk::Drawable> m_drawable;
Glib::RefPtr<Gdk::Image> m_gdk_image;
Glib::RefPtr<Gdk::Pixbuf> m_pixbuf;
rdcnnsim::Dimension m_dim;

/* rdcnnsim::Dimension
 * simple class that contains width and height as integers
 */

• take the Gdk::Pixbuf of the Gtk::Image and call:

m_drawable->draw_pixbuf(m_gc,
                        m_pixbuf,
                        0,0,
                        0,0,
                        m_dim.get_width(),
                        m_dim.get_height(),
                        Gdk::RGB_DITHER_NONE,
                        0,0);

At this point I am getting an extraordinary annoying segfault when
starting the application.

The next step would be (if I get that error away) to use the
Gdk::Drawable::get_image() member for creating an Gdk::Image.

Unfortunately I have no idea anymore where else to look, so I ask you
for some help. That whole thing is used for a student research project
and the submission date is getting closer every hour I spent with bug
searching.

Thanks in advance!

Greetings,
Falk Schilling
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Mark Roberts-10 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear Falk!

> • have the following member variables (m_pixbuf, m_gc, m_dim are
> initialized and work properly, m_drawable and m_gdk_image are NULL ):
>
> Glib::RefPtr<Gdk::GC> m_gc;
> Glib::RefPtr<Gdk::Drawable> m_drawable;
> Glib::RefPtr<Gdk::Image> m_gdk_image;
> Glib::RefPtr<Gdk::Pixbuf> m_pixbuf;
> rdcnnsim::Dimension m_dim;
>
> /* rdcnnsim::Dimension
> * simple class that contains width and height as integers
> */
>
> • take the Gdk::Pixbuf of the Gtk::Image and call:
>
> m_drawable->draw_pixbuf(m_gc,
>        m_pixbuf,
>        0,0,
> 0,0,
> m_dim.get_width(),
> m_dim.get_height(),
> Gdk::RGB_DITHER_NONE,
> 0,0);
You just said that m_drawable was NULL...

> At this point I am getting an extraordinary annoying segfault when
> starting the application.

All the best,
Mark Roberts
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Falk Schilling :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear Mark,

of course you’re right, accessing a method of a non-existing object is a
very suboptimal idea… ^^

But nevertheless, if I do the following, I still get a segmentation
fault when calling Gdk::Drawable::draw_pixbuf().

m_drawable = Gdk::Drawable::create();

Maybe I have somewhere overlooked something in the documentation, but I
assume that this is the right way to instantiate an Gdk::Drawable object.

Greetings,
Falk Schilling


P.S.: Sorry Mark, I unfortunately replied your mail to your personal
account, but it was intended to let the list also take part at the
discussion.


Mark Roberts schrieb:

> Dear Falk!
>
>> • have the following member variables (m_pixbuf, m_gc, m_dim are
>> initialized and work properly, m_drawable and m_gdk_image are NULL ):
>>
>> Glib::RefPtr<Gdk::GC> m_gc;
>> Glib::RefPtr<Gdk::Drawable> m_drawable;
>> Glib::RefPtr<Gdk::Image> m_gdk_image;
>> Glib::RefPtr<Gdk::Pixbuf> m_pixbuf;
>> rdcnnsim::Dimension m_dim;
>>
>> /* rdcnnsim::Dimension
>> * simple class that contains width and height as integers
>> */
>>
>> • take the Gdk::Pixbuf of the Gtk::Image and call:
>>
>> m_drawable->draw_pixbuf(m_gc,
>>                 m_pixbuf,
>>                 0,0,
>>             0,0,
>>             m_dim.get_width(),
>>             m_dim.get_height(),
>>             Gdk::RGB_DITHER_NONE,
>>             0,0);
>
> You just said that m_drawable was NULL...
>
>> At this point I am getting an extraordinary annoying segfault when
>> starting the application.
>
> All the best,
> Mark Roberts

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Daniel Elstner :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Am Freitag, den 19.06.2009, 23:54 +0200 schrieb Falk Schilling:
> Dear Mark,
>
> of course you’re right, accessing a method of a non-existing object is a
> very suboptimal idea… ^^
>
> But nevertheless, if I do the following, I still get a segmentation
> fault when calling Gdk::Drawable::draw_pixbuf().
>
> m_drawable = Gdk::Drawable::create();

That looks odd.  If that create() method does indeed exist, I have no
idea what it would possibly do.  Gdk::Drawable is an abstract base
class. :-)

> Maybe I have somewhere overlooked something in the documentation, but I
> assume that this is the right way to instantiate an Gdk::Drawable object.

I'm surprised that it is possible at all.  You want to instantiate a
Gdk::Pixmap, Gdk::Bitmap or Gdk::Window object, I think.

Also, are you sure Gdk::Image is really what you want to use?  This
stuff all maps directly to X11 primitives...

--Daniel


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Falk Schilling :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hallo Daniel,

thanks for your reply.

Daniel Elstner schrieb:
>> m_drawable = Gdk::Drawable::create();
>
> That looks odd.  If that create() method does indeed exist, I have no
> idea what it would possibly do.  Gdk::Drawable is an abstract base
> class. :-)

Well, that explains a few things, e.g. some missing constructor methods
for Gdk::Drawable (compared with other classes). Since this class method
returns a Glib::RefPtr<Gdk::Drawable> I assumed that this is the way of
creating objects. The documentation unfortunately lacks some information
at this point, what this is used for.

>> Maybe I have somewhere overlooked something in the documentation, but I
>> assume that this is the right way to instantiate an Gdk::Drawable object.
>
> I'm surprised that it is possible at all.  You want to instantiate a
> Gdk::Pixmap, Gdk::Bitmap or Gdk::Window object, I think.
>
> Also, are you sure Gdk::Image is really what you want to use?  This
> stuff all maps directly to X11 primitives...

Well, I don’t want to use Cairo for just drawing simple pixels. I indeed
don’t need stuff like arcs, lines or whatever else; I want to read
pixels out of an image, process the values and write the result into
another image. Purely and simple pixel operations.

Ok, you suggest to take Gdk::Pixmap for this stuff. Well, how do I
convert the Gdk::Pixbuf into a Gdk::Pixmap?

Greetings,
Falk Schilling
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Falk Schilling :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Ok, I now tried to cope with Gdk::Pixmap. I now use the following code
in the constructor of my derived Gtk::Window.

m_imgcol is an object of my ImageCollection class, that contains
pointers to rdcnnsim::Image* (derivate of Gtk::Image), accessible via
the image(m,n)-method (an analog approach is used for Gdk::Pixbuf and
now Gdk::Pixmap, except that I use Glib::RefPtr<> for the members there).


for ( int i=0 ; i < static_cast<int>(RDCNNS_NUMBER); i++)
   for ( int j=0; j< static_cast<int>(IMAGES_NUMBER); j++)
        {
          rdcnn_enum_t m = static_cast<rdcnn_enum_t>(i);
          name_t n = static_cast<name_t>(j);
               
          if ( !(m == TARGET && n == INPUT) )
            {
              m_refGlade->get_widget_derived(
                                             glade_widget_names[m][n],
                                             m_imgcol.image(m,n)
                                             );
              m_imgcol.image(m,n)->load(EMPTY_IMAGE.c_str());
              m_imgcol.pixmap(m,n) =
                Gdk::Pixmap::create(m_imgcol.image(m,n)->get_window(),
                                    m_dim.get_width(),
                                    m_dim.get_height(),
                                    m_imgcol.image(m,n)->get_window()
                                    ->get_depth());
               
                //m_colormap = this->get_default_colormap();
               
              m_imgcol.pixbuf(m,n)
                = m_imgcol.image(m,n)->get_pixbuf();
             }
}


The problem is, that now Gdk::Pixmap::create causes the segfault. I
know, that this is a very bad solution, because I use the complete
(derived) Gtk:Image as Drawable, although I only want to modify its
Pixbuf, but that was just a try whether it works or not.

Greetings,
Falk



Falk Schilling schrieb:

> Hallo Daniel,
>
> thanks for your reply.
>
> Daniel Elstner schrieb:
>>> m_drawable = Gdk::Drawable::create();
>> That looks odd.  If that create() method does indeed exist, I have no
>> idea what it would possibly do.  Gdk::Drawable is an abstract base
>> class. :-)
>
> Well, that explains a few things, e.g. some missing constructor methods
> for Gdk::Drawable (compared with other classes). Since this class method
> returns a Glib::RefPtr<Gdk::Drawable> I assumed that this is the way of
> creating objects. The documentation unfortunately lacks some information
> at this point, what this is used for.
>
>>> Maybe I have somewhere overlooked something in the documentation, but I
>>> assume that this is the right way to instantiate an Gdk::Drawable object.
>> I'm surprised that it is possible at all.  You want to instantiate a
>> Gdk::Pixmap, Gdk::Bitmap or Gdk::Window object, I think.
>>
>> Also, are you sure Gdk::Image is really what you want to use?  This
>> stuff all maps directly to X11 primitives...
>
> Well, I don’t want to use Cairo for just drawing simple pixels. I indeed
> don’t need stuff like arcs, lines or whatever else; I want to read
> pixels out of an image, process the values and write the result into
> another image. Purely and simple pixel operations.
>
> Ok, you suggest to take Gdk::Pixmap for this stuff. Well, how do I
> convert the Gdk::Pixbuf into a Gdk::Pixmap?
>
> Greetings,
> Falk Schilling
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list@...
> http://mail.gnome.org/mailman/listinfo/gtkmm-list

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Daniel Elstner :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Am Samstag, den 20.06.2009, 11:48 +0200 schrieb Falk Schilling:
[...]

>    {
>      m_refGlade->get_widget_derived(
>     glade_widget_names[m][n],
>     m_imgcol.image(m,n)
>     );
>      m_imgcol.image(m,n)->load(EMPTY_IMAGE.c_str());
>      m_imgcol.pixmap(m,n) =
> Gdk::Pixmap::create(m_imgcol.image(m,n)->get_window(),
>    m_dim.get_width(),
>    m_dim.get_height(),
>    m_imgcol.image(m,n)->get_window()
>    ->get_depth());
[...]
> The problem is, that now Gdk::Pixmap::create causes the segfault.

Most likely because the Gtk::Image widget isn't realized yet at this
point, which means its Gdk::Window doesn't exist yet.

> I
> know, that this is a very bad solution, because I use the complete
> (derived) Gtk:Image as Drawable,

I don't see where you do that. It wouldn't work anyway. (Gtk::Image is
*not* a Gdk::Drawable).

> although I only want to modify its
> Pixbuf, but that was just a try whether it works or not.

Gtk::Image is a widget that can display some image. It does not by
itself maintain the image data. Modifying its Gdk::Pixbuf means just
assigning a new one.

> > Well, that explains a few things, e.g. some missing constructor methods
> > for Gdk::Drawable (compared with other classes). Since this class method
> > returns a Glib::RefPtr<Gdk::Drawable> I assumed that this is the way of
> > creating objects. The documentation unfortunately lacks some information
> > at this point, what this is used for.

Well, I had a look and it's indeed there.  There cannot possibly be any
documentation because it is useless and doesn't work.  It seems to have
been added by accident.  Congratulations, you are the first person to
notice this, even though it must have been around for about a
decade. :-)

> >> Also, are you sure Gdk::Image is really what you want to use?  This
> >> stuff all maps directly to X11 primitives...
> >
> > Well, I don’t want to use Cairo for just drawing simple pixels. I indeed
> > don’t need stuff like arcs, lines or whatever else; I want to read
> > pixels out of an image, process the values and write the result into
> > another image. Purely and simple pixel operations.

You've got it completely the wrong way around.  Cairo does simple
client-side drawing.  Using Gdk::Drawable means you are communicating
with the X server.  Gdk::Image is client-side, but still comes with all
the Xlib complexity like visuals and color maps and what not.

If you really only want to work with pixels, you can just access
Gdk::Pixbuf directly. From the top of my head:

    // Assume we have an RGB pixbuf with 8 bits per component
    g_assert(pixbuf->get_colorspace() == Gdk::COLORSPACE_RGB);
    g_assert(pixbuf->get_bits_per_sample() == 8);

    guint8 *const pixel = pixbuf->get_pixels()
                        + row * pixbuf->get_rowstride()
                        + col * pixbuf->get_n_channels();
    pixel[0] = red;
    pixel[1] = green;
    pixel[2] = blue;

I think there was a libart or something to encapsulate this, but it's
rarely used these days.  From my point of view, either you are drawing
at a high level and use Cairo, or you want to deal with raw pixel data
in which case setting single pixels in isolation would be unacceptably
slow, so you would work on the buffer as a whole.

> > Ok, you suggest to take Gdk::Pixmap for this stuff. Well, how do I
> > convert the Gdk::Pixbuf into a Gdk::Pixmap?

No, I didn't suggest to use Gdk::Pixmap.  Well, maybe I suggested it,
but I certainly don't recommend it. :-)  What I meant was that
Gdk::Pixmap would be a Gdk::Drawable which you can instantiate.  In
other words, it would work, but still be a bad idea for what you are
doing.

Generally, I think you need to step back for a moment and think things
over.  Your current attempt makes it look way more complicated than it
actually is.

--Daniel


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Falk Schilling :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Daniel Elstner schrieb:
> Most likely because the Gtk::Image widget isn't realized yet at this
> point, which means its Gdk::Window doesn't exist yet.

Ok, that sounds pretty reasonable.

>> I
>> know, that this is a very bad solution, because I use the complete
>> (derived) Gtk:Image as Drawable,
>
> I don't see where you do that. It wouldn't work anyway. (Gtk::Image is
> *not* a Gdk::Drawable).

Ok, my description was at that point of writing very bad. If it was that
easy, I surely didn’t want to convert the Pixbuf into a Drawable before…
What I meant, but unfortunately didn’t say: I just want to manipulate
the loaded image, not the stuff around. But that’s not really relevant
at this point.

>> although I only want to modify its
>> Pixbuf, but that was just a try whether it works or not.
>
> Gtk::Image is a widget that can display some image. It does not by
> itself maintain the image data. Modifying its Gdk::Pixbuf means just
> assigning a new one.

Understood.

> Well, I had a look and it's indeed there.  There cannot possibly be any
> documentation because it is useless and doesn't work.  It seems to have
> been added by accident.  Congratulations, you are the first person to
> notice this, even though it must have been around for about a
> decade. :-)

Oh, what honour. :)

> You've got it completely the wrong way around.  Cairo does simple
> client-side drawing.  Using Gdk::Drawable means you are communicating
> with the X server.  Gdk::Image is client-side, but still comes with all
> the Xlib complexity like visuals and color maps and what not.
>
> If you really only want to work with pixels, you can just access
> Gdk::Pixbuf directly. From the top of my head:
>
>     // Assume we have an RGB pixbuf with 8 bits per component
>     g_assert(pixbuf->get_colorspace() == Gdk::COLORSPACE_RGB);
>     g_assert(pixbuf->get_bits_per_sample() == 8);
>
>     guint8 *const pixel = pixbuf->get_pixels()
>                         + row * pixbuf->get_rowstride()
>                         + col * pixbuf->get_n_channels();
>     pixel[0] = red;
>     pixel[1] = green;
>     pixel[2] = blue;
>
> I think there was a libart or something to encapsulate this, but it's
> rarely used these days.  From my point of view, either you are drawing
> at a high level and use Cairo, or you want to deal with raw pixel data
> in which case setting single pixels in isolation would be unacceptably
> slow, so you would work on the buffer as a whole.

Thank you for this clarification. My whole experience with GTKMM/GTK+
relates to only a few weeks, so I am far away from understandig the
whole complexity of all part libraries.

>>> Ok, you suggest to take Gdk::Pixmap for this stuff. Well, how do I
>>> convert the Gdk::Pixbuf into a Gdk::Pixmap?
>
> No, I didn't suggest to use Gdk::Pixmap.  Well, maybe I suggested it,
> but I certainly don't recommend it. :-)  What I meant was that
> Gdk::Pixmap would be a Gdk::Drawable which you can instantiate.  In
> other words, it would work, but still be a bad idea for what you are
> doing.
>
> Generally, I think you need to step back for a moment and think things
> over.  Your current attempt makes it look way more complicated than it
> actually is.

Well, you offered me some new ideas that I will have to think about.
With the present approach I won’t get much success, so a restructuration
is probably a nice idea.

Thank you very much for your help!

Greetings,
Falk
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Crash when calling Gdk::Drawable::draw_pixbuf

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, 20 Jun 2009 13:33:12 +0200
Falk Schilling <falk.schilling@...> wrote:
[snip]
> Thank you for this clarification. My whole experience with GTKMM/GTK+
> relates to only a few weeks, so I am far away from understandig the
> whole complexity of all part libraries.

This will explain how the image data in Gdk::Pixbuf/GdkPixbuf is set
out:
http://library.gnome.org/devel/gdk-pixbuf/stable/gdk-pixbuf-gdk-pixbuf.html#image-data

Note that, unlike cairo image surfaces, the alpha value (if any) of the
pixel data in Gdk::Pixbuf is lossless and not premultiplied, so you
need to do a conversion were you to want to convert between the two
(cairo uses premultiplied alpha and the RGB pixel data is stored
differently, in 32 bit integers). Cairo is more efficient in
interfacing with the Xserver because of its pixel layout, and in
compositing. Gdk::Pixbuf is usually easier to manipulate on the client
side at the pixel level.

Chris

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list