00001 /* 00002 * jmemsrc.c, based on jdatasrc.c 00003 * 00004 * jdatasrc.c: Copyright (C) 1994-1996, Thomas G. Lane. 00005 */ 00006 00007 /* Provide a data source for libjpeg to read data from memory 00008 * and not from some file (descriptor). 00009 * For Robbie 11 tests 00010 * June 2008, Detlev Droege, droege@uni-koblenz.de 00011 */ 00012 00013 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 00014 #include "jinclude.h" 00015 #include "jpeglib.h" 00016 #include "jerror.h" 00017 00018 00019 /* Expanded data source object for memory input */ 00020 00021 typedef struct { 00022 struct jpeg_source_mgr pub; /* public fields */ 00023 00024 size_t bytesInBuffer; /* source data size */ 00025 JOCTET * buffer; /* start of buffer */ 00026 boolean start_of_file; /* have we gotten any data yet? */ 00027 JOCTET eofBuffer[4]; /* buffer for EOI marker if empty input */ 00028 } mem_source_mgr; 00029 00030 typedef mem_source_mgr * mem_src_ptr; 00031 00032 /* 00033 * Initialize source --- called by jpeg_read_header 00034 * before any data is actually read. 00035 */ 00036 00037 METHODDEF(void) 00038 mem_init_source (j_decompress_ptr cinfo) 00039 { 00040 mem_src_ptr src = (mem_src_ptr) cinfo->src; 00041 00042 /* We reset the empty-input-file flag for each image, 00043 * but we don't clear the input buffer. 00044 * This is correct behavior for reading a series of images from one source. 00045 */ 00046 src->start_of_file = TRUE; 00047 } 00048 00049 METHODDEF(boolean) 00050 mem_fill_input_buffer (j_decompress_ptr cinfo) 00051 { 00052 mem_src_ptr src = (mem_src_ptr) cinfo->src; 00053 size_t nbytes = src->bytesInBuffer; 00054 00055 src->pub.next_input_byte = src->buffer; 00056 if (src->buffer == NULL) { 00057 if (src->start_of_file) /* Treat empty input file as fatal error */ 00058 ERREXIT(cinfo, JERR_INPUT_EMPTY); 00059 WARNMS(cinfo, JWRN_JPEG_EOF); 00060 /* Insert a fake EOI marker */ 00061 src->eofBuffer[0] = (JOCTET) 0xFF; 00062 src->eofBuffer[1] = (JOCTET) JPEG_EOI; 00063 src->buffer = src->eofBuffer; 00064 nbytes = 2; 00065 } 00066 00067 src->pub.bytes_in_buffer = nbytes; 00068 src->start_of_file = FALSE; 00069 00070 return TRUE; 00071 } 00072 00073 METHODDEF(void) 00074 mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes) 00075 { 00076 mem_src_ptr src = (mem_src_ptr) cinfo->src; 00077 00078 /* Quite simple in memory .... 00079 */ 00080 if (num_bytes > 0) { 00081 src->pub.next_input_byte += (size_t) num_bytes; 00082 src->pub.bytes_in_buffer -= (size_t) num_bytes; 00083 } 00084 } 00085 00086 METHODDEF(void) 00087 mem_term_source (j_decompress_ptr cinfo) 00088 { 00089 (void) cinfo; 00090 00091 /* no work necessary here */ 00092 } 00093 00094 /* 00095 * Prepare for input from memory. 00096 * The caller must have already stored the data, and is responsible 00097 * for deallocating the used memory for it after finishing decompression. 00098 */ 00099 00100 GLOBAL(void) 00101 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET * ptr, size_t numBytes) 00102 { 00103 mem_src_ptr src; 00104 00105 /* The source object is made permanent so that a series 00106 * of JPEG images can be read from the same buffer by calling jpeg_memory_src 00107 * only before the first one. 00108 * This makes it unsafe to use this manager and a different source 00109 * manager serially with the same JPEG object. Caveat programmer. 00110 */ 00111 if (cinfo->src == NULL) { /* first time for this JPEG object? */ 00112 cinfo->src = (struct jpeg_source_mgr *) 00113 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 00114 SIZEOF(mem_source_mgr)); 00115 src = (mem_src_ptr) cinfo->src; 00116 src->buffer = ptr; 00117 } 00118 00119 src = (mem_src_ptr) cinfo->src; 00120 src->pub.init_source = mem_init_source; 00121 src->pub.fill_input_buffer = mem_fill_input_buffer; 00122 src->pub.skip_input_data = mem_skip_input_data; 00123 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ 00124 src->pub.term_source = mem_term_source; 00125 src->bytesInBuffer = numBytes; 00126 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ 00127 src->pub.next_input_byte = NULL; /* until buffer loaded */ 00128 }