Ian,

Thank you very much for the help. That worked perfectly.

Thanks,
Patrick Reynolds
R & D Engineer
Kitware, Inc.
919 969 6990 x303


On Fri, Jun 19, 2009 at 8:33 AM, Ian Scott <ian.m.scott@student.manchester.ac.uk> wrote:
Patrick Reynolds wrote:
Hi all,

I just wanted to resurrect this thread to see if I really had a bug or if one of you has a solution to this problem.

I'm trying to get the bits of the png image out of the vil_stream_core. With the jpeg format I can omit the imageResource = NULL; line and the vil_stream_core contains the whole bitstream. The png format writes the header only and claims to need to be destroyed (in vil_png.cxx) before the total image is written to the stream. Below is the code snippet that causes the crash:

<code>
vil_image_view<vxl_byte> frame = vil_load( "woo.png" );

vil_stream* imgStream = new vil_stream_core();

 vil_image_resource_sptr imageResource = vil_new_image_resource(
   imgStream, frame.ni <http://frame.ni>(), frame.nj(),

   frame.nplanes() *
   vil_pixel_format_num_components( frame.pixel_format() ),
   vil_pixel_format_component_format( frame.pixel_format() ),
   "png" );

imageResource->put_view( frame, 0, 0 );

If you watch your imgStream past the next code line you can see it being destroyed.
This is because the call to vil_new_image_resource is generally used by vil to transfer ownership of the stream to the image_resource. The image_resource increments the stream's ref_count. When the image_resource is destroyed, the ref_count of the stream falls to zero and the stream is destroyed. This is the ideal behaviour in the normal use case.

However you want the stream to survive, so you need to manage it properly - see below.
imageResource = NULL;

imgStream->tell(); // SEGFAULT

</code>

Any hints would be greatly appreciated.

The following code does not segfault, and should achieve what you need.

int main()
{

 vil_image_view<vxl_byte> frame = vil_load( "woo.png" );

// Keep shared ownership of the stream in this stack frame.
 vil_smart_ptr<vil_stream> imgStream = new vil_stream_core();


  vil_image_resource_sptr imageResource = vil_new_image_resource(
    imgStream.ptr(), frame.ni(), frame.nj(),

    frame.nplanes() *
    vil_pixel_format_num_components( frame.pixel_format() ),
    vil_pixel_format_component_format( frame.pixel_format() ),
    "png" );

// imgStream's ref_count should be at least 2 now.



 imageResource->put_view( frame, 0, 0 );

// Destroy resource so that the image is flushed to the stream.
 imageResource = NULL;

// imgStream's ref_count should be 1, and so it will still exist.
 imgStream->tell();
}
// the destruction of the vil_smart_ptr<vil_stream>, will reduce the stream's ref_count to 0 and destroy the stream.


Ian.