| /* |
| * jdatasrc.c |
| * |
| * Copyright (C) 1994-1996, Thomas G. Lane. |
| * Modified 2009-2011 by Guido Vollbeding. |
| * This file is part of the Independent JPEG Group's software. |
| * For conditions of distribution and use, see the accompanying README file. |
| * |
| * This file contains decompression data source routines for the case of |
| * reading JPEG data from memory or from a file (or any stdio stream). |
| * While these routines are sufficient for most applications, |
| * some will want to use a different source manager. |
| * IMPORTANT: we assume that fread() will correctly transcribe an array of |
| * JOCTETs from 8-bit-wide elements on external storage. If char is wider |
| * than 8 bits on your machine, you may need to do some tweaking. |
| */ |
| |
| #include "third_party/libjpeg/jpeg.h" |
| |
| #include <jpeglib.h> |
| #include <jerror.h> |
| |
| // jpeg_mem_src is only available since jpeg v8 |
| // Following code are copied from libjpeg v8d jdatasrc.c. |
| #if JPEG_LIB_VERSION < 80 |
| |
| static void init_mem_source(j_decompress_ptr cinfo) |
| { |
| /* no work necessary here */ |
| (void)cinfo; |
| } |
| |
| static boolean fill_mem_input_buffer(j_decompress_ptr cinfo) |
| { |
| static const JOCTET mybuffer[4] = { |
| (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0 |
| }; |
| |
| /* The whole JPEG data is expected to reside in the supplied memory |
| * buffer, so any request for more data beyond the given buffer size |
| * is treated as an error. |
| */ |
| WARNMS(cinfo, JWRN_JPEG_EOF); |
| |
| /* Insert a fake EOI marker */ |
| |
| cinfo->src->next_input_byte = mybuffer; |
| cinfo->src->bytes_in_buffer = 2; |
| |
| return TRUE; |
| } |
| |
| static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) |
| { |
| struct jpeg_source_mgr *src = cinfo->src; |
| |
| /* Just a dumb implementation for now. Could use fseek() except |
| * it doesn't work on pipes. Not clear that being smart is worth |
| * any trouble anyway --- large skips are infrequent. |
| */ |
| if (num_bytes > 0) { |
| while (num_bytes > (long)src->bytes_in_buffer) { |
| num_bytes -= (long)src->bytes_in_buffer; |
| (void)(*src->fill_input_buffer) (cinfo); |
| /* note we assume that fill_input_buffer will never return FALSE, |
| * so suspension need not be handled. |
| */ |
| } |
| src->next_input_byte += (size_t) num_bytes; |
| src->bytes_in_buffer -= (size_t) num_bytes; |
| } |
| } |
| |
| static void term_source(j_decompress_ptr cinfo) |
| { |
| /* no work necessary here */ |
| (void)cinfo; |
| } |
| |
| void jpeg_mem_src(j_decompress_ptr cinfo, |
| unsigned char *inbuffer, unsigned long insize) |
| { |
| struct jpeg_source_mgr *src; |
| |
| if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */ |
| ERREXIT(cinfo, JERR_INPUT_EMPTY); |
| |
| /* The source object is made permanent so that a series of JPEG images |
| * can be read from the same buffer by calling jpeg_mem_src only before |
| * the first one. |
| */ |
| if (cinfo->src == NULL) { /* 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_source_mgr)); |
| } |
| |
| src = cinfo->src; |
| src->init_source = init_mem_source; |
| src->fill_input_buffer = fill_mem_input_buffer; |
| src->skip_input_data = skip_input_data; |
| src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ |
| src->term_source = term_source; |
| src->bytes_in_buffer = (size_t) insize; |
| src->next_input_byte = (JOCTET *) inbuffer; |
| } |
| #endif |