1

If I create a Halide::Buffer by constructing it with a pointer from an STB_Image function call like so:

inline Halide::Buffer<uint8_t> LoadFromFile(const char* filename)
{
    int w, h, d;
    unsigned char* image_data = stbi_load(filename, &w, &h, &d, 0);
    Halide::Buffer buff =  Halide::Buffer(image_data, std::vector<int>{w, h, d});
    return buff;
}

Who is responsible for freeing the underlying buffer? I assumed it would be me since I allocated the memory so I should free it. If I am responsible, where should it be done?

Thanks

  • 1
    What does the documentation say? – Pepijn Kramer Jan 31 '23 at 13:45
  • That's why a good API should have a std::unique_ptr. Now it is indeed unclear from the api if Buffer takes ownership. So what does the documentation say? – Pepijn Kramer Jan 31 '23 at 13:46
  • @user20716902 Being a class does not mean it handles the deallocation of the given `const char *`. By the way, [`Halide::Buffer<>::~Buffer()`](https://halide-lang.org/docs/class_halide_1_1_buffer.html#aa709a312bd3d8841376c4953524969fe) is defaulted (marked as `default`) in the doc. – Fareanor Jan 31 '23 at 13:48
  • in an ideal world returning a raw pointer would be sufficient to signal that it is a nonowning pointer, ie that you are not responsible for the lifetime of the object. In an ideal world you would never have to `delete` on a raw pointer returned from a library function. Though, as Pepjin said, the answer is in the docs, there is no general answer that applies to every raw pointer returned from a function – 463035818_is_not_an_ai Jan 31 '23 at 13:48
  • @Fareanor, I realized when I posted, which is why I already deleted the comment – user20716902 Jan 31 '23 at 13:51
  • @PepijnKramer I wouldn't describe the docs as very clear. I have found references to it being both a shared pointer with ownership or no ownership at all. But seemingly no way to find out how that is set or used – Louis Child Jan 31 '23 at 13:55
  • 1
    You need to free it with `stbi_image_free`. I doubt `Halide::Buffer` does that for you – Ted Lyngmo Jan 31 '23 at 13:59
  • @LouisChild Yes I just had a look, doc is almost non-existent. Not a library I would be confident to use – Pepijn Kramer Jan 31 '23 at 14:04
  • 1
    It ultimately uses [this constructor](https://halide-lang.org/docs/class_halide_1_1_runtime_1_1_buffer.html#a31c020e81707b663ee4761d852222e94), which says "Does not take ownership of the data". – molbdnilo Jan 31 '23 at 14:05
  • 1
    @PepijnKramer while I agree, it's not really my choice unfortunately. I do know that it's supposedly got support from Google and Adobe, so I would hope it's got some level of usefulness. – Louis Child Jan 31 '23 at 14:12
  • 1
    @TedLyngmo thanks, that's what I have ended up doing in the end. – Louis Child Jan 31 '23 at 14:12

1 Answers1

1

Whenever you pass a raw pointer to the Halide::Buffer constructor, it does not take ownership. It's unfortunate that STBI doesn't include a way to load an image to a pre-allocated buffer.


If the Halide image io library meets your needs, you might find it more convenient.

#include <Halide.h>
#include <halide_image_io.h>

// ...

Halide::Buffer<uint8_t> input = Halide::Tools::load_image("images/rgb.png");

Now input owns the image data and will be freed when the destructor is called. The Halide image io library supports the following formats:

  • PNG (via libpng)
  • JPEG (via libjpeg)
  • TIFF
  • Matlab .mat files
Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • For our use case we use a custom data type so it's unlikely that it would work for that, I used STB as a stand in while I was testing Halide's viability because it was a header only library I could just include. What is it about that io library that means the buffer owns it's data? I would assume it has to call one of the Buffer classes constructor eventurally. But from what I could tell they all eventually create a Runtime::Buffer which doesn't own the data passed to it – Louis Child Feb 01 '23 at 18:31