diff --git a/source/lib/res/jmemdatasrc.cpp b/source/lib/res/jmemdatasrc.cpp new file mode 100644 index 0000000000..c7589ac0fa --- /dev/null +++ b/source/lib/res/jmemdatasrc.cpp @@ -0,0 +1,186 @@ +#include "precompiled.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * jmemdatasrc.c (adapted from IJG jdatasrc.c) + * + * Copyright (C) 2004, Jan Wassenberg. + * Copyright (C) 1994-1996, Thomas G. Lane. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a single memory buffer. Suspension isn't used. + * + * IMPORTANT: we assume that JOCTET is 8 bits. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for memory input */ +typedef struct +{ + struct jpeg_source_mgr pub; /* public fields */ + + JOCTET* buf; + size_t size; /* total size (bytes) */ + size_t pos; /* offset (bytes) to new data */ +} +MemSrcMgr; + +typedef MemSrcMgr* SrcPtr; + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) init_source(j_decompress_ptr cinfo) +{ +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + */ + +METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo) +{ + SrcPtr src = (SrcPtr)cinfo->src; + static const JOCTET eoi[2] = { 0xFF, JPEG_EOI }; + + /* + * since jpeg_mem_src fills the buffer with everything we've got, + * jpeg is trying to read beyond end of buffer. return a fake EOI marker. + * note: don't modify input buffer: it might be read-only. + */ + + WARNMS(cinfo, JWRN_JPEG_EOF); + + + src->pub.next_input_byte = eoi; + src->pub.bytes_in_buffer = 2; + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + */ + +METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + SrcPtr src = (SrcPtr)cinfo->src; + size_t skip_count = (size_t)num_bytes; + + /* docs say non-positive num_byte skips should be ignored */ + if(num_bytes <= 0) + return; + + /* + * just subtract bytes available in buffer, + * making sure we don't underflow the size_t. + * note: if we skip to or beyond end of buffer, + * bytes_in_buffer = 0 => fill_input_buffer called => abort. + */ + if(skip_count > src->pub.bytes_in_buffer) + skip_count = src->pub.bytes_in_buffer; + + src->pub.bytes_in_buffer -= skip_count; + src->pub.next_input_byte += skip_count; +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) term_source(j_decompress_ptr cinfo) +{ + /* + * no-op (we don't own the buffer and shouldn't, + * to make possible multiple images in a source). + */ +} + + +/* + * Prepare for input from a buffer. + * The caller is responsible for freeing it after finishing decompression. + */ + +GLOBAL(void) jpeg_mem_src(j_decompress_ptr cinfo, void* p, size_t size) +{ + SrcPtr src; + + /* Treat 0-length buffer as fatal error */ + if(size == 0) + ERREXIT(cinfo, JERR_INPUT_EMPTY); + + /* + * The source object is made permanent so that + * a series of JPEG images can be read from the same file + * by calling jpeg_mem_src only before the first one. + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + + /* first time for this JPEG object? */ + if(!cinfo->src) + cinfo->src = (struct jpeg_source_mgr*) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(MemSrcMgr)); + /* (takes care of raising error if out of memory) */ + + src = (SrcPtr)cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* default */ + src->pub.term_source = term_source; + + /* + * fill buffer with everything we have. + * if fill_input_buffer is called, the buffer was overrun. + */ + src->pub.bytes_in_buffer = size; + src->pub.next_input_byte = (JOCTET*)p; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file