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; if (cinfo->src == NULL) { 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; src->pub.term_source = term; src->stream = in; src->pub.bytes_in_buffer = 0; src->pub.next_input_byte = NULL; }
After calling jpeg_create_decompress call the make_stream function.
source share