
Christian Henning wrote:
Well, have a look at read_rows(). ?Say one of the jpeg_read_scalines() calls fails and calls the error handler. ?I think that:
- The dtor for buffer will not be called because you have longjump()d out of its scope.
Agreed. I wonder how I can fix that. I cannot really move buffer into class scope since I don't know the buffer's value type. This type depends on the current pixel type.
You can probably just declare the buffer before you call setjmp(). However, I only have an intuitive idea of what happens. It really needs someone who actually understands this stuff (i.e. the spec) to look at it. For example, the GNU libc manual says: "When you perform a non-local exit, accessible objects generally retain whatever values they had at the time longjmp was called. The exception is that the values of automatic variables local to the function containing the setjmp call that have been changed since the call to setjmp are indeterminate, unless you have declared them volatile" That seems to suggest that buffer becomes undefined. In a sense this doesn't matter since it will be destroyed when you throw, as long as it is undefined in a way that doesn't cause its dtor to crash or leak.
(As I think I suggested before, to me personally it would be more useful to have a set of wrappers for these libraries that only deal with these C++-ification issues, rather than the full gil integration that you're offering. ?For example the whole issue with memory usage where you're saying that "memory is cheap, everyone has gigabytes these days" just doesn't apply to the digital photo frames and mobile phones that I'm dealing with. ?So in order to get anything useful from this, I would love to decouple this 'library wrapping' from the gil aspect.)
When you C++-tified libjpeg for instance, in what container would you store the data? You probably would use a template parameter to give the user the option.
No; if I were doing this, I'd first wrap libjpeg to hide all its nasty warts like this error handling, increase the type safety, and other "thin" changes - as above. class ReadJpegFile { public: struct JpegDecodingError: std::exception {}; typedef uint8_t sample_t; ReadJpegFile(std::string fn); ~ReadJpegFile(); size_t read_scanlines(size_t n_lines, sample_t* data); .... }; Concerns about e.g. containers would come in the next layer.
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top. Phil.