+struct jpeg_stdio_mgr
+{
+ struct jpeg_source_mgr mgr;
+ boolean finished;
+ FILE *file;
+ JOCTET *buffer;
+};
+
+
+/* Size of buffer to read JPEG from file.
+ Not too big, as we want to use alloc_small. */
+#define JPEG_STDIO_BUFFER_SIZE 8192
+
+
+/* Fill input buffer method for JPEG data source manager. Called
+ whenever more data is needed. The data is read from a FILE *. */
+
+static boolean
+our_stdio_fill_input_buffer (cinfo)
+ j_decompress_ptr cinfo;
+{
+ struct jpeg_stdio_mgr *src;
+
+ src = (struct jpeg_stdio_mgr *) cinfo->src;
+ if (!src->finished)
+ {
+ size_t bytes;
+
+ bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
+ if (bytes > 0)
+ src->mgr.bytes_in_buffer = bytes;
+ else
+ {
+ WARNMS (cinfo, JWRN_JPEG_EOF);
+ src->finished = 1;
+ src->buffer[0] = (JOCTET) 0xFF;
+ src->buffer[1] = (JOCTET) JPEG_EOI;
+ src->mgr.bytes_in_buffer = 2;
+ }
+ src->mgr.next_input_byte = src->buffer;
+ }
+
+ return 1;
+}
+
+
+/* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
+ is the JPEG data source manager. */
+
+static void
+our_stdio_skip_input_data (cinfo, num_bytes)
+ j_decompress_ptr cinfo;
+ long num_bytes;
+{
+ struct jpeg_stdio_mgr *src;
+ src = (struct jpeg_stdio_mgr *) cinfo->src;
+
+ while (num_bytes > 0 && !src->finished)
+ {
+ if (num_bytes <= src->mgr.bytes_in_buffer)
+ {
+ src->mgr.bytes_in_buffer -= num_bytes;
+ src->mgr.next_input_byte += num_bytes;
+ break;
+ }
+ else
+ {
+ num_bytes -= src->mgr.bytes_in_buffer;
+ src->mgr.bytes_in_buffer = 0;
+ src->mgr.next_input_byte = NULL;
+
+ our_stdio_fill_input_buffer (cinfo);
+ }
+ }
+}
+
+
+/* Set up the JPEG lib for reading an image from a FILE *.
+ CINFO is the decompression info structure created for
+ reading the image. */
+
+static void
+jpeg_file_src (cinfo, fp)
+ j_decompress_ptr cinfo;
+ FILE *fp;
+{
+ struct jpeg_stdio_mgr *src;
+
+ if (cinfo->src != NULL)
+ src = (struct jpeg_stdio_mgr *) cinfo->src;
+ else
+ {
+ /* First time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof (struct jpeg_stdio_mgr));
+ src = (struct jpeg_stdio_mgr *) cinfo->src;
+ src->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ JPEG_STDIO_BUFFER_SIZE);
+ }
+
+ src->file = fp;
+ src->finished = 0;
+ src->mgr.init_source = our_common_init_source;
+ src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
+ src->mgr.skip_input_data = our_stdio_skip_input_data;
+ src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
+ src->mgr.term_source = our_common_term_source;
+ src->mgr.bytes_in_buffer = 0;
+ src->mgr.next_input_byte = NULL;
+}
+
+