From 035dcbcd467c49198ec833f4ec2b1ef9afb49c00 Mon Sep 17 00:00:00 2001 From: dhewg Date: Sat, 7 Jan 2012 20:38:28 +0100 Subject: [PATCH] Move jpeg_memory_src() Found another copy in renderer/Cinematic.cpp. Move the newer implementation from renderer/Image_files.cpp in its own file and use the libjpeg v8c license blob (which is where this code comes from). Adapt README too with the v8c license. --- README.txt | 15 +-- neo/CMakeLists.txt | 1 + neo/renderer/Cinematic.cpp | 178 +------------------------------ neo/renderer/Image_files.cpp | 128 +--------------------- neo/renderer/jpeg_memory_src.cpp | 93 ++++++++++++++++ neo/renderer/jpeg_memory_src.h | 24 +++++ 6 files changed, 130 insertions(+), 309 deletions(-) create mode 100644 neo/renderer/jpeg_memory_src.cpp create mode 100644 neo/renderer/jpeg_memory_src.h diff --git a/README.txt b/README.txt index 31c62304..9d767c51 100644 --- a/README.txt +++ b/README.txt @@ -84,7 +84,7 @@ EXCLUDED CODE: The code described below and contained in the Doom 3 GPL Source JPEG library ----------------------------------------------------------------------------- -neo/renderer/jpeg-6/*, renderer/Image_files.cpp +neo/renderer/jpeg_memory_src.* This software is copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. All Rights Reserved except as specified below. @@ -107,11 +107,14 @@ These conditions apply to any software derived from or based on the IJG code, not just to the unmodified library. If you use our work, you ought to acknowledge us. -NOTE: unfortunately the README that came with our copy of the library has -been lost, so the one from release 6b is included instead. There are a few -'glue type' modifications to the library to make it easier to use from -the engine, but otherwise the dependency can be easily cleaned up to a -better release of the library. +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. OggVorbis --------------------------------------------------------------------------- diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index d2720a1b..821a2a50 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -235,6 +235,7 @@ endif() message(STATUS "Building ${CMAKE_BUILD_TYPE} for ${os}.${cpu}") set(src_renderer + renderer/jpeg_memory_src.cpp renderer/Cinematic.cpp renderer/GuiModel.cpp renderer/Image_files.cpp diff --git a/neo/renderer/Cinematic.cpp b/neo/renderer/Cinematic.cpp index 15a274b7..b0dc92f4 100644 --- a/neo/renderer/Cinematic.cpp +++ b/neo/renderer/Cinematic.cpp @@ -28,9 +28,8 @@ If you have questions concerning this license or the applicable additional terms #include "sys/platform.h" -#include - #include "framework/FileSystem.h" +#include "renderer/jpeg_memory_src.h" #include "renderer/tr_local.h" #include "sound/sound.h" @@ -1283,184 +1282,9 @@ void idCinematicLocal::RoQReset() { status = FMV_LOOPED; } - -typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - byte *infile; /* source stream */ - JOCTET * buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ - int memsize; -} my_source_mgr; - -typedef my_source_mgr * my_src_ptr; - -#define INPUT_BUF_SIZE 32768 /* choose an efficiently fread'able size */ - /* jpeg error handling */ struct jpeg_error_mgr jerr; -/* - * 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. - * - * In applications that need to be able to suspend compression due to input - * not being available yet, a FALSE return indicates that no more data can be - * obtained right now, but more may be forthcoming later. In this situation, - * the decompressor will return to its caller (with an indication of the - * number of scanlines it has read, if any). The application should resume - * decompression after it has loaded more data into the input buffer. Note - * that there are substantial restrictions on the use of suspension --- see - * the documentation. - * - * When suspending, the decompressor will back up to a convenient restart point - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point must be rescanned after resumption, so move it to - * the front of the buffer rather than discarding it. - */ - - -static boolean fill_input_buffer( j_decompress_ptr cinfo ) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - int nbytes; - - nbytes = INPUT_BUF_SIZE; - if (nbytes > src->memsize) nbytes = src->memsize; - if (nbytes == 0) { - /* Insert a fake EOI marker */ - src->buffer[0] = (JOCTET) 0xFF; - src->buffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } else { - memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); - src->infile = src->infile + nbytes; - src->memsize = src->memsize - INPUT_BUF_SIZE; - } - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; -} -/* - * Initialize source --- called by jpeg_read_header - * before any data is actually read. - */ - - -static void init_source (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; -} - -/* - * Skip data --- used to skip over a potentially large amount of - * uninteresting data (such as an APPn marker). - * - * Writers of suspendable-input applications must note that skip_input_data - * is not granted the right to give a suspension return. If the skip extends - * beyond the data currently in the buffer, the buffer can be marked empty so - * that the next read will cause a fill_input_buffer call that can suspend. - * Arranging for additional bytes to be discarded before reloading the input - * buffer is the application writer's problem. - */ - -static void -skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - my_src_ptr src = (my_src_ptr) 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) { - src->infile = src->infile + num_bytes; - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - - -/* - * 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. - */ - -static void -term_source (j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - -void -jpeg_memory_src (j_decompress_ptr cinfo, byte *infile, int size) -{ - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - 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(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * sizeof(JOCTET)); - } - - src = (my_src_ptr) 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; /* use default method */ - src->pub.term_source = term_source; - src->infile = infile; - src->memsize = size; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ -} - int JPEGBlit( byte *wStatus, byte *data, int datasize ) { /* This struct contains the JPEG decompression parameters and pointers to diff --git a/neo/renderer/Image_files.cpp b/neo/renderer/Image_files.cpp index 3c445043..c374a9c1 100644 --- a/neo/renderer/Image_files.cpp +++ b/neo/renderer/Image_files.cpp @@ -28,9 +28,7 @@ If you have questions concerning this license or the applicable additional terms #include "sys/platform.h" -#include -#include - +#include "renderer/jpeg_memory_src.h" #include "renderer/tr_local.h" #include "renderer/Image.h" @@ -43,42 +41,6 @@ void R_LoadImage( const char *name, byte **pic, int *width, int *height, bool ma */ -/* - * Include file for users of JPEG library. - * You will need to have included system headers that define at least - * the typedefs FILE and size_t before you can include jpeglib.h. - * (stdio.h is sufficient on ANSI-conforming systems.) - * You may also wish to include "jerror.h". - */ - -extern "C" { - // hooks from jpeg lib to our system - - void jpg_Error( const char *fmt, ... ) { - va_list argptr; - char msg[2048]; - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); - - common->FatalError( "%s", msg ); - } - - void jpg_Printf( const char *fmt, ... ) { - va_list argptr; - char msg[2048]; - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); - - common->Printf( "%s", msg ); - } - -} - - /* ================ R_WriteTGA @@ -787,92 +749,6 @@ static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_T fileSystem->FreeFile( buffer ); } -/* -========================================================= - -JPG LOADING - -Interfaces with the huge libjpeg -========================================================= -*/ - -#ifdef HAVE_JPEG_MEM_SRC -#define j_mem_src jpeg_mem_src -#else -static void init_mem_source(j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - -static boolean fill_mem_input_buffer(j_decompress_ptr cinfo) -{ - static JOCTET mybuffer[4]; - - /* 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 */ - mybuffer[0] = (JOCTET) 0xFF; - mybuffer[1] = (JOCTET) JPEG_EOI; - - 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; - - 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 */ -} - -static void j_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 - /* ============= LoadJPG @@ -948,7 +824,7 @@ static void LoadJPG( const char *filename, unsigned char **pic, int *width, int /* Step 2: specify data source (eg, a file) */ - j_mem_src(&cinfo, fbuffer, len); + jpeg_memory_src(&cinfo, fbuffer, len); /* Step 3: read file parameters with jpeg_read_header() */ diff --git a/neo/renderer/jpeg_memory_src.cpp b/neo/renderer/jpeg_memory_src.cpp new file mode 100644 index 00000000..287badc5 --- /dev/null +++ b/neo/renderer/jpeg_memory_src.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 1994-1996, Thomas G. Lane. + * Modified 2009-2010 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 "sys/platform.h" + +#include "renderer/jpeg_memory_src.h" + +#ifdef HAVE_JPEG_MEM_SRC +void jpeg_memory_src(j_decompress_ptr cinfo, unsigned char *inbuffer, unsigned long insize) { + jpeg_mem_src(cinfo, inbuffer, insize); +} +#else +static void init_mem_source(j_decompress_ptr cinfo) { + /* no work necessary here */ +} + +static boolean fill_mem_input_buffer(j_decompress_ptr cinfo) { + static JOCTET mybuffer[4]; + + /* 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 */ + mybuffer[0] = (JOCTET) 0xFF; + mybuffer[1] = (JOCTET) JPEG_EOI; + + 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; + + 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 jpeg_memory_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 diff --git a/neo/renderer/jpeg_memory_src.h b/neo/renderer/jpeg_memory_src.h new file mode 100644 index 00000000..2e8a58a2 --- /dev/null +++ b/neo/renderer/jpeg_memory_src.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 1994-1996, Thomas G. Lane. + * Modified 2009-2010 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. + */ + +#ifndef __JPEG_MEMORY_SRC_H__ +#define __JPEG_MEMORY_SRC_H__ + +#include +#include + +void jpeg_memory_src(j_decompress_ptr cinfo, unsigned char *inbuffer, unsigned long insize); + +#endif