How to use libjpeg to read jpeg from std :: istream?

libjpeg can read JPEG data from FILE* or the buffer. My data comes from std::istream . I could read the whole std::istream into a buffer for use with libjpeg, but I would prefer libjpeg to read directly from std::istream , if possible. How can I do that?

+4
source share
1 answer

You just need to provide a wrapper around your istream. Define a structure like

 struct JpegStream { jpeg_source_mgr pub; std::istream* stream; byte buffer [4096]; } 

Then you need four methods to work with the stream:

 void init_source (j_decompress_ptr cinfo) { auto src = (JpegStream*)(cinfo->src); src->stream-> // seek to 0 here } boolean fill_buffer (j_decompress_ptr cinfo) { // Read to buffer JpegStream* src = // as above src->pub.next_input_byte = src->buffer; src->pub.bytes_in_buffer = // How many yo could read return eof() ? FALSE : TRUE; } void skip (j_decompress_ptr cinfo, long count) { // Seek by count bytes forward // Make sure you know how much you have cached and subtract that // set bytes_in_buffer and next_input_byte } void term (j_decompress_ptr cinfo) { // Close the stream, can be nop } 

and one way to link them to the JPEG decompression information structure:

 void make_stream (j_decompress_ptr cinfo, std::istream* in) { JpegStream * src; /* The source object and input buffer are made permanent so that a series * of JPEG images can be read from the same file by calling jpeg_stdio_src * only before the first one. (If we discarded the buffer at the end of * one image, we'd likely lose the start of the next one.) * This makes it unsafe to use this manager and a different source * manager serially with the same JPEG object. Caveat programmer. */ if (cinfo->src == NULL) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, POOL_PERMANENT, sizeof(JpegStream)); src = reinterpret_cast<JpegStream*> (cinfo->src); } src = reinterpret_cast<JpegStream*> (cinfo->src); src->pub.init_source = init_source; src->pub.fill_input_buffer = fill_buffer; src->pub.skip_input_data = skip; src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ src->pub.term_source = term; src->stream = in; src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */ } 

After calling jpeg_create_decompress call the make_stream function.

+10
source

All Articles