diff options
author | Tim Angus <tim@ngus.net> | 2009-10-03 11:58:50 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:15:34 +0000 |
commit | ac3e5586cd56657ff1b6f5f64af7e1d7c76b410d (patch) | |
tree | b245f2cbd4e7491b948aea5c7c080be61307c950 | |
parent | dc3819f1e99d8159bdb0ea1da26506b00fe78e62 (diff) |
* Merge ioq3-r1458
-rw-r--r-- | Makefile | 28 | ||||
-rwxr-xr-x | make-macosx-ub.sh | 24 | ||||
-rw-r--r-- | src/client/cl_cin.c | 1 | ||||
-rw-r--r-- | src/client/cl_input.c | 3 | ||||
-rw-r--r-- | src/client/cl_keys.c | 1 | ||||
-rw-r--r-- | src/client/cl_main.c | 4 | ||||
-rw-r--r-- | src/client/cl_scrn.c | 5 | ||||
-rw-r--r-- | src/client/client.h | 3 | ||||
-rw-r--r-- | src/client/snd_dma.c | 1 | ||||
-rw-r--r-- | src/client/snd_openal.c | 25 | ||||
-rw-r--r-- | src/jpeg-6b/README (renamed from src/jpeg-6/README) | 0 | ||||
-rw-r--r-- | src/jpeg-6b/ioq3-changes.diff | 916 | ||||
-rw-r--r-- | src/jpeg-6b/jcapimin.c (renamed from src/jpeg-6/jcapimin.c) | 80 | ||||
-rw-r--r-- | src/jpeg-6b/jcapistd.c (renamed from src/jpeg-6/jcapistd.c) | 8 | ||||
-rw-r--r-- | src/jpeg-6b/jccoefct.c (renamed from src/jpeg-6/jccoefct.c) | 27 | ||||
-rw-r--r-- | src/jpeg-6b/jccolor.c (renamed from src/jpeg-6/jccolor.c) | 18 | ||||
-rw-r--r-- | src/jpeg-6b/jcdctmgr.c (renamed from src/jpeg-6/jcdctmgr.c) | 113 | ||||
-rw-r--r-- | src/jpeg-6b/jchuff.c (renamed from src/jpeg-6/jchuff.c) | 181 | ||||
-rw-r--r-- | src/jpeg-6b/jchuff.h (renamed from src/jpeg-6/jchuff.h) | 23 | ||||
-rw-r--r-- | src/jpeg-6b/jcinit.c (renamed from src/jpeg-6/jcinit.c) | 6 | ||||
-rw-r--r-- | src/jpeg-6b/jcmainct.c (renamed from src/jpeg-6/jcmainct.c) | 58 | ||||
-rw-r--r-- | src/jpeg-6b/jcmarker.c (renamed from src/jpeg-6/jcmarker.c) | 133 | ||||
-rw-r--r-- | src/jpeg-6b/jcmaster.c (renamed from src/jpeg-6/jcmaster.c) | 32 | ||||
-rw-r--r-- | src/jpeg-6b/jcomapi.c (renamed from src/jpeg-6/jcomapi.c) | 24 | ||||
-rw-r--r-- | src/jpeg-6b/jconfig.h (renamed from src/jpeg-6/jconfig.h) | 0 | ||||
-rw-r--r-- | src/jpeg-6b/jcparam.c (renamed from src/jpeg-6/jcparam.c) | 115 | ||||
-rw-r--r-- | src/jpeg-6b/jcphuff.c (renamed from src/jpeg-6/jcphuff.c) | 82 | ||||
-rw-r--r-- | src/jpeg-6b/jcprepct.c (renamed from src/jpeg-6/jcprepct.c) | 45 | ||||
-rw-r--r-- | src/jpeg-6b/jcsample.c (renamed from src/jpeg-6/jcsample.c) | 22 | ||||
-rw-r--r-- | src/jpeg-6b/jctrans.c (renamed from src/jpeg-6/jctrans.c) | 39 | ||||
-rw-r--r-- | src/jpeg-6b/jdapimin.c (renamed from src/jpeg-6/jdapimin.c) | 57 | ||||
-rw-r--r-- | src/jpeg-6b/jdapistd.c (renamed from src/jpeg-6/jdapistd.c) | 16 | ||||
-rw-r--r-- | src/jpeg-6b/jdatadst.c (renamed from src/jpeg-6/jdatadst.c) | 10 | ||||
-rw-r--r-- | src/jpeg-6b/jdatasrc.c (renamed from src/jpeg-6/jdatasrc.c) | 21 | ||||
-rw-r--r-- | src/jpeg-6b/jdcoefct.c (renamed from src/jpeg-6/jdcoefct.c) | 65 | ||||
-rw-r--r-- | src/jpeg-6b/jdcolor.c (renamed from src/jpeg-6/jdcolor.c) | 45 | ||||
-rw-r--r-- | src/jpeg-6b/jdct.h (renamed from src/jpeg-6/jdct.h) | 20 | ||||
-rw-r--r-- | src/jpeg-6b/jddctmgr.c (renamed from src/jpeg-6/jddctmgr.c) | 17 | ||||
-rw-r--r-- | src/jpeg-6b/jdhuff.c (renamed from src/jpeg-6/jdhuff.c) | 399 | ||||
-rw-r--r-- | src/jpeg-6b/jdhuff.h (renamed from src/jpeg-6/jdhuff.h) | 47 | ||||
-rw-r--r-- | src/jpeg-6b/jdinput.c (renamed from src/jpeg-6/jdinput.c) | 22 | ||||
-rw-r--r-- | src/jpeg-6b/jdmainct.c (renamed from src/jpeg-6/jdmainct.c) | 34 | ||||
-rw-r--r-- | src/jpeg-6b/jdmarker.c (renamed from src/jpeg-6/jdmarker.c) | 626 | ||||
-rw-r--r-- | src/jpeg-6b/jdmaster.c (renamed from src/jpeg-6/jdmaster.c) | 22 | ||||
-rw-r--r-- | src/jpeg-6b/jdmerge.c (renamed from src/jpeg-6/jdmerge.c) | 16 | ||||
-rw-r--r-- | src/jpeg-6b/jdphuff.c (renamed from src/jpeg-6/jdphuff.c) | 362 | ||||
-rw-r--r-- | src/jpeg-6b/jdpostct.c (renamed from src/jpeg-6/jdpostct.c) | 18 | ||||
-rw-r--r-- | src/jpeg-6b/jdsample.c (renamed from src/jpeg-6/jdsample.c) | 22 | ||||
-rw-r--r-- | src/jpeg-6b/jdtrans.c (renamed from src/jpeg-6/jdtrans.c) | 75 | ||||
-rw-r--r-- | src/jpeg-6b/jerror.c (renamed from src/jpeg-6/jerror.c) | 38 | ||||
-rw-r--r-- | src/jpeg-6b/jerror.h (renamed from src/jpeg-6/jerror.h) | 28 | ||||
-rw-r--r-- | src/jpeg-6b/jfdctflt.c (renamed from src/jpeg-6/jfdctflt.c) | 4 | ||||
-rw-r--r-- | src/jpeg-6b/jfdctfst.c (renamed from src/jpeg-6/jfdctfst.c) | 4 | ||||
-rw-r--r-- | src/jpeg-6b/jfdctint.c (renamed from src/jpeg-6/jfdctint.c) | 4 | ||||
-rw-r--r-- | src/jpeg-6b/jidctflt.c (renamed from src/jpeg-6/jidctflt.c) | 11 | ||||
-rw-r--r-- | src/jpeg-6b/jidctfst.c (renamed from src/jpeg-6/jidctfst.c) | 15 | ||||
-rw-r--r-- | src/jpeg-6b/jidctint.c (renamed from src/jpeg-6/jidctint.c) | 15 | ||||
-rw-r--r-- | src/jpeg-6b/jidctred.c (renamed from src/jpeg-6/jidctred.c) | 23 | ||||
-rw-r--r-- | src/jpeg-6b/jinclude.h (renamed from src/jpeg-6/jinclude.h) | 2 | ||||
-rw-r--r-- | src/jpeg-6b/jload.c (renamed from src/jpeg-6/jload.c) | 0 | ||||
-rw-r--r-- | src/jpeg-6b/jmemansi.c (renamed from src/jpeg-6/jmemansi.c) | 24 | ||||
-rw-r--r-- | src/jpeg-6b/jmemdos.c (renamed from src/jpeg-6/jmemdos.c) | 68 | ||||
-rw-r--r-- | src/jpeg-6b/jmemmgr.c (renamed from src/jpeg-6/jmemmgr.c) | 37 | ||||
-rw-r--r-- | src/jpeg-6b/jmemname.c (renamed from src/jpeg-6/jmemname.c) | 33 | ||||
-rw-r--r-- | src/jpeg-6b/jmemnobs.c (renamed from src/jpeg-6/jmemnobs.c) | 20 | ||||
-rw-r--r-- | src/jpeg-6b/jmemsys.h (renamed from src/jpeg-6/jmemsys.h) | 50 | ||||
-rw-r--r-- | src/jpeg-6b/jmorecfg.h (renamed from src/jpeg-6/jmorecfg.h) | 49 | ||||
-rw-r--r-- | src/jpeg-6b/jpegint.h (renamed from src/jpeg-6/jpegint.h) | 102 | ||||
-rw-r--r-- | src/jpeg-6b/jpeglib.h (renamed from src/jpeg-6/jpeglib.h) | 247 | ||||
-rw-r--r-- | src/jpeg-6b/jpegtran.c (renamed from src/jpeg-6/jpegtran.c) | 162 | ||||
-rw-r--r-- | src/jpeg-6b/jquant1.c (renamed from src/jpeg-6/jquant1.c) | 36 | ||||
-rw-r--r-- | src/jpeg-6b/jquant2.c (renamed from src/jpeg-6/jquant2.c) | 38 | ||||
-rw-r--r-- | src/jpeg-6b/jutils.c (renamed from src/jpeg-6/jutils.c) | 16 | ||||
-rw-r--r-- | src/jpeg-6b/jversion.h (renamed from src/jpeg-6/jversion.h) | 6 | ||||
-rw-r--r-- | src/null/null_client.c | 3 | ||||
-rw-r--r-- | src/null/null_input.c | 4 | ||||
-rw-r--r-- | src/null/null_snddma.c | 3 | ||||
-rw-r--r-- | src/qcommon/common.c | 26 | ||||
-rw-r--r-- | src/qcommon/files.c | 21 | ||||
-rw-r--r-- | src/qcommon/msg.c | 2 | ||||
-rw-r--r-- | src/qcommon/net_ip.c | 93 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 3 | ||||
-rw-r--r-- | src/qcommon/unzip.c | 3 | ||||
-rw-r--r-- | src/qcommon/vm_interpreted.c | 16 | ||||
-rw-r--r-- | src/qcommon/vm_x86.c | 172 | ||||
-rw-r--r-- | src/qcommon/vm_x86_64.c | 2 | ||||
-rw-r--r-- | src/renderer/tr_backend.c | 8 | ||||
-rw-r--r-- | src/renderer/tr_bsp.c | 2 | ||||
-rw-r--r-- | src/renderer/tr_font.c | 2 | ||||
-rw-r--r-- | src/renderer/tr_image.c | 8 | ||||
-rw-r--r-- | src/renderer/tr_image_jpg.c | 2 | ||||
-rw-r--r-- | src/renderer/tr_local.h | 2 | ||||
-rw-r--r-- | src/renderer/tr_scene.c | 3 | ||||
-rw-r--r-- | src/renderer/tr_shader.c | 9 | ||||
-rw-r--r-- | src/sdl/sdl_glimp.c | 77 | ||||
-rw-r--r-- | src/sdl/sdl_input.c | 287 | ||||
-rw-r--r-- | src/sys/sys_loadlib.h | 11 | ||||
-rw-r--r-- | src/sys/sys_local.h | 3 | ||||
-rw-r--r-- | src/sys/sys_main.c | 59 | ||||
-rw-r--r-- | src/sys/sys_unix.c | 32 | ||||
-rw-r--r-- | src/sys/sys_win32.c | 70 |
101 files changed, 4008 insertions, 1858 deletions
@@ -35,6 +35,9 @@ endif ifndef BUILD_GAME_QVM BUILD_GAME_QVM = endif +ifndef BUILD_MISSIONPACK + BUILD_MISSIONPACK= +endif ifneq ($(PLATFORM),darwin) BUILD_CLIENT_SMP = 0 @@ -154,7 +157,7 @@ GDIR=$(MOUNT_DIR)/game CGDIR=$(MOUNT_DIR)/cgame NDIR=$(MOUNT_DIR)/null UIDIR=$(MOUNT_DIR)/ui -JPDIR=$(MOUNT_DIR)/jpeg-6 +JPDIR=$(MOUNT_DIR)/jpeg-6b SPEEXDIR=$(MOUNT_DIR)/libspeex Q3ASMDIR=$(MOUNT_DIR)/tools/asm LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg @@ -188,6 +191,13 @@ ifeq ($(wildcard .svn),.svn) VERSION:=$(VERSION)_SVN$(SVN_REV) USE_SVN=1 endif +else +ifeq ($(wildcard .git/svn/.metadata),.git/svn/.metadata) + SVN_REV=$(shell LANG=C git-svn info | awk '$$1 == "Revision:" {print $$2; exit 0}') + ifneq ($(SVN_REV),) + VERSION:=$(VERSION)_SVN$(SVN_REV) + endif +endif endif @@ -411,8 +421,10 @@ ifeq ($(PLATFORM),mingw32) BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \ -DUSE_ICON - # Require Windows XP or later - BASE_CFLAGS += -DWINVER=0x501 + # In the absence of wspiapi.h, require Windows XP or later + ifeq ($(shell test -e $(CMDIR)/wspiapi.h; echo $$?),1) + BASE_CFLAGS += -DWINVER=0x501 + endif ifeq ($(USE_OPENAL),1) BASE_CFLAGS += -DUSE_OPENAL @@ -1174,18 +1186,17 @@ Q3OBJ = \ \ $(B)/client/jcapimin.o \ $(B)/client/jcapistd.o \ - $(B)/client/jchuff.o \ - $(B)/client/jcinit.o \ $(B)/client/jccoefct.o \ $(B)/client/jccolor.o \ - $(B)/client/jfdctflt.o \ $(B)/client/jcdctmgr.o \ - $(B)/client/jcphuff.o \ + $(B)/client/jchuff.o \ + $(B)/client/jcinit.o \ $(B)/client/jcmainct.o \ $(B)/client/jcmarker.o \ $(B)/client/jcmaster.o \ $(B)/client/jcomapi.o \ $(B)/client/jcparam.o \ + $(B)/client/jcphuff.o \ $(B)/client/jcprepct.o \ $(B)/client/jcsample.o \ $(B)/client/jdapimin.o \ @@ -1203,6 +1214,7 @@ Q3OBJ = \ $(B)/client/jdsample.o \ $(B)/client/jdtrans.o \ $(B)/client/jerror.o \ + $(B)/client/jfdctflt.o \ $(B)/client/jidctflt.o \ $(B)/client/jmemmgr.o \ $(B)/client/jmemnobs.o \ @@ -1253,6 +1265,7 @@ ifeq ($(ARCH),x86) $(B)/client/snapvectora.o endif +ifeq ($(USE_VOIP),1) ifeq ($(USE_INTERNAL_SPEEX),1) Q3OBJ += \ $(B)/client/bits.o \ @@ -1296,6 +1309,7 @@ Q3OBJ += \ $(B)/client/vq.o \ $(B)/client/window.o endif +endif ifeq ($(HAVE_VM_COMPILED),true) diff --git a/make-macosx-ub.sh b/make-macosx-ub.sh index 4f1a26af..3317bf6d 100755 --- a/make-macosx-ub.sh +++ b/make-macosx-ub.sh @@ -6,7 +6,6 @@ PKGINFO=APPLTREM ICNS=misc/Tremulous.icns DESTDIR=build/release-darwin-ub BASEDIR=base -Q3_VERSION=`grep '^VERSION=' Makefile | sed -e 's/.*=\(.*\)/\1/'` BIN_OBJ=" build/release-darwin-ppc/tremulous.ppc @@ -24,10 +23,15 @@ BASE_OBJ=" build/release-darwin-ppc/$BASEDIR/gameppc.dylib build/release-darwin-x86/$BASEDIR/gamex86.dylib " + +cd `dirname $0` if [ ! -f Makefile ]; then echo "This script must be run from the Tremulous build directory"; + exit 1 fi +Q3_VERSION=`grep '^VERSION=' Makefile | sed -e 's/.*=\(.*\)/\1/'` + # We only care if we're >= 10.4, not if we're specifically Tiger. # "8" is the Darwin major kernel version. #TIGERHOST=`uname -r | grep ^8.` @@ -114,6 +118,15 @@ if [ -d /Developer/SDKs/MacOSX10.2.8.sdk ] && [ -x /usr/bin/gcc-3.3 ] && [ $TIGE -Wl,-syslibroot,/Developer/SDKs/MacOSX10.2.8.sdk,-m" fi +if [ -z $PPC_CLIENT_SDK ] || [ -z $PPC_SERVER_SDK ] || [ -z $X86_SDK ]; then + echo "\ +ERROR: This script is for building a Universal Binary. You cannot build + for a different architecture unless you have the proper Mac OS X SDKs + installed. If you just want to to compile for your own system run + 'make' instead of this script." + exit 1 +fi + echo "Building PPC Dedicated Server against \"$PPC_SERVER_SDK\"" echo "Building PPC Client against \"$PPC_CLIENT_SDK\"" echo "Building X86 Client/Dedicated Server against \"$X86_SDK\"" @@ -126,15 +139,6 @@ WARNING: in order to build a binary with maximum compatibility you must MacOSX10.2.8, MacOSX10.3.9, and MacOSX10.4u SDKs installed from the Xcode install disk Packages folder." fi - -if [ -z $PPC_CLIENT_SDK ] || [ -z $PPC_SERVER_SDK ] || [ -z $X86_SDK ]; then - echo "\ -ERROR: This script is for building a Universal Binary. You cannot build - for a different architecture unless you have the proper Mac OS X SDKs - installed. If you just want to to compile for your own system run - 'make' instead of this script." - exit 1 -fi sleep 3 if [ ! -d $DESTDIR ]; then diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c index bf8501f1..1443937c 100644 --- a/src/client/cl_cin.c +++ b/src/client/cl_cin.c @@ -136,7 +136,6 @@ static int currentHandle = -1; static int CL_handle = -1; extern int s_soundtime; // sample PAIRS -extern int s_paintedtime; // sample PAIRS void CIN_CloseAllVideos(void) { diff --git a/src/client/cl_input.c b/src/client/cl_input.c index 30352aa3..cb95ce8c 100644 --- a/src/client/cl_input.c +++ b/src/client/cl_input.c @@ -454,8 +454,7 @@ void CL_MouseMove( usercmd_t *cmd ) { cl.mouseDy[cl.mouseIndex] = 0; rate = sqrt( mx * mx + my * my ) / (float)frame_msec; - accelSensitivity = ( cl_sensitivity->value * - cl_platformSensitivity->value ) + rate * cl_mouseAccel->value; + accelSensitivity = cl_sensitivity->value + rate * cl_mouseAccel->value; // scale by FOV accelSensitivity *= cl.cgameSensitivity; diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c index 7c982c4b..8b9dcf4d 100644 --- a/src/client/cl_keys.c +++ b/src/client/cl_keys.c @@ -1116,7 +1116,6 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) { { if (keys[K_ALT].down) { -// Key_ClearStates(); // Thilo: why should we clear the key states here? Cvar_SetValue( "r_fullscreen", !Cvar_VariableIntegerValue( "r_fullscreen" ) ); return; diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 444b877d..0bba97d0 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -72,7 +72,6 @@ cvar_t *cl_forceavidemo; cvar_t *cl_freelook; cvar_t *cl_sensitivity; -cvar_t *cl_platformSensitivity; cvar_t *cl_mouseAccel; cvar_t *cl_showMouseRate; @@ -2974,7 +2973,6 @@ void CL_Init( void ) { cl_run = Cvar_Get ("cl_run", "1", CVAR_ARCHIVE); cl_sensitivity = Cvar_Get ("sensitivity", "5", CVAR_ARCHIVE); - cl_platformSensitivity = Cvar_Get ("cl_platformSensitivity", "1.0", CVAR_ROM); cl_mouseAccel = Cvar_Get ("cl_mouseAccel", "0", CVAR_ARCHIVE); cl_freelook = Cvar_Get( "cl_freelook", "1", CVAR_ARCHIVE ); @@ -3126,7 +3124,7 @@ void CL_Shutdown( void ) { Com_Printf( "----- CL_Shutdown -----\n" ); if ( recursive ) { - printf ("recursive shutdown\n"); + Com_Printf( "WARNING: Recursive shutdown\n" ); return; } recursive = qtrue; diff --git a/src/client/cl_scrn.c b/src/client/cl_scrn.c index cf89fb9d..c44950f2 100644 --- a/src/client/cl_scrn.c +++ b/src/client/cl_scrn.c @@ -321,9 +321,13 @@ int SCR_GetBigStringWidth( const char *str ) { //=============================================================================== + +#ifdef USE_VOIP /* ================= SCR_DrawVoipMeter + +FIXME: inherited from ioq3, move to cgame/ui ================= */ void SCR_DrawVoipMeter( void ) { @@ -357,6 +361,7 @@ void SCR_DrawVoipMeter( void ) { sprintf( string, "VoIP: [%s]", buffer ); SCR_DrawStringExt( 320 - strlen( string ) * 4, 10, 8, string, g_color_table[7], qtrue, qfalse ); } +#endif diff --git a/src/client/client.h b/src/client/client.h index a3cbadfb..d7f430cb 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -376,7 +376,6 @@ extern cvar_t *cl_run; extern cvar_t *cl_anglespeedkey; extern cvar_t *cl_sensitivity; -extern cvar_t *cl_platformSensitivity; extern cvar_t *cl_freelook; extern cvar_t *cl_mouseAccel; @@ -491,8 +490,6 @@ void CL_VerifyCode( void ); float CL_KeyState (kbutton_t *key); char *Key_KeynumToString (int keynum); -int Key_GetCatcher( void ); -void Key_SetCatcher( int catcher ); // // cl_parse.c diff --git a/src/client/snd_dma.c b/src/client/snd_dma.c index d9fea8d4..a418733a 100644 --- a/src/client/snd_dma.c +++ b/src/client/snd_dma.c @@ -39,7 +39,6 @@ void S_SoundList_f(void); void S_Music_f(void); void S_Update_( void ); -void S_UpdateBackgroundTrack( void ); void S_Base_StopAllSounds(void); void S_Base_StopBackgroundTrack( void ); diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c index 5fad0a45..5421a7a0 100644 --- a/src/client/snd_openal.c +++ b/src/client/snd_openal.c @@ -1992,7 +1992,7 @@ qboolean S_AL_Init( soundInterface_t *si ) // New console variables s_alPrecache = Cvar_Get( "s_alPrecache", "1", CVAR_ARCHIVE ); - s_alGain = Cvar_Get( "s_alGain", "0.4", CVAR_ARCHIVE ); + s_alGain = Cvar_Get( "s_alGain", "1.0", CVAR_ARCHIVE ); s_alSources = Cvar_Get( "s_alSources", "96", CVAR_ARCHIVE ); s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE ); s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE ); @@ -2095,22 +2095,33 @@ qboolean S_AL_Init( soundInterface_t *si ) // !!! FIXME: add support for capture device enumeration. // !!! FIXME: add some better error reporting. s_alCapture = Cvar_Get( "s_alCapture", "1", CVAR_ARCHIVE | CVAR_LATCH ); - if (!s_alCapture->integer) { + if (!s_alCapture->integer) + { Com_Printf("OpenAL capture support disabled by user ('+set s_alCapture 1' to enable)\n"); + } #if USE_MUMBLE - } else if (cl_useMumble->integer) { + else if (cl_useMumble->integer) + { Com_Printf("OpenAL capture support disabled for Mumble support\n"); + } #endif - } else { + else + { +#ifdef MACOS_X // !!! FIXME: Apple has a 1.1-compliant OpenAL, which includes // !!! FIXME: capture support, but they don't list it in the // !!! FIXME: extension string. We need to check the version string, // !!! FIXME: then the extension string, but that's too much trouble, // !!! FIXME: so we'll just check the function pointer for now. - //if (qalcIsExtensionPresent(NULL, "ALC_EXT_capture")) { - if (qalcCaptureOpenDevice == NULL) { + if (qalcCaptureOpenDevice == NULL) +#else + if (!qalcIsExtensionPresent(NULL, "ALC_EXT_capture")) +#endif + { Com_Printf("No ALC_EXT_capture support, can't record audio.\n"); - } else { + } + else + { // !!! FIXME: 8000Hz is what Speex narrowband mode needs, but we // !!! FIXME: should probably open the capture device after // !!! FIXME: initializing Speex so we can change to wideband diff --git a/src/jpeg-6/README b/src/jpeg-6b/README index 86cc2066..86cc2066 100644 --- a/src/jpeg-6/README +++ b/src/jpeg-6b/README diff --git a/src/jpeg-6b/ioq3-changes.diff b/src/jpeg-6b/ioq3-changes.diff new file mode 100644 index 00000000..1ce424bc --- /dev/null +++ b/src/jpeg-6b/ioq3-changes.diff @@ -0,0 +1,916 @@ +diff -u -w /home/tma/sources/jpeg-6b/jcdctmgr.c ./jcdctmgr.c +--- /home/tma/sources/jpeg-6b/jcdctmgr.c 1996-01-13 19:15:12.000000000 +0000 ++++ ./jcdctmgr.c 2008-08-22 00:07:09.000000000 +0100 +@@ -57,7 +57,6 @@ + int ci, qtblno, i; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; +- DCTELEM * dtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { +@@ -168,6 +167,8 @@ + } + + ++/* code/jpeg-6b/jcdctmgr.c:184: warning: ‘forward_DCT’ defined but not used */ ++#if 0 + /* + * Perform forward DCT on one or more blocks of a component. + * +@@ -262,6 +263,7 @@ + } + } + } ++#endif + + + #ifdef DCT_FLOAT_SUPPORTED +diff -u -w /home/tma/sources/jpeg-6b/jcmainct.c ./jcmainct.c +--- /home/tma/sources/jpeg-6b/jcmainct.c 1996-01-06 23:24:59.000000000 +0000 ++++ ./jcmainct.c 2008-08-22 00:10:21.000000000 +0100 +@@ -68,32 +68,32 @@ + METHODDEF(void) + start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + +- main->cur_iMCU_row = 0; /* initialize counters */ +- main->rowgroup_ctr = 0; +- main->suspended = FALSE; +- main->pass_mode = pass_mode; /* save mode for use by process_data */ ++ jmain->cur_iMCU_row = 0; /* initialize counters */ ++ jmain->rowgroup_ctr = 0; ++ jmain->suspended = FALSE; ++ jmain->pass_mode = pass_mode; /* save mode for use by process_data */ + + switch (pass_mode) { + case JBUF_PASS_THRU: + #ifdef FULL_MAIN_BUFFER_SUPPORTED +- if (main->whole_image[0] != NULL) ++ if (jmain->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + #endif +- main->pub.process_data = process_data_simple_main; ++ jmain->pub.process_data = process_data_simple_main; + break; + #ifdef FULL_MAIN_BUFFER_SUPPORTED + case JBUF_SAVE_SOURCE: + case JBUF_CRANK_DEST: + case JBUF_SAVE_AND_PASS: +- if (main->whole_image[0] == NULL) ++ if (jmain->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +- main->pub.process_data = process_data_buffer_main; ++ jmain->pub.process_data = process_data_buffer_main; + break; + #endif + default: +@@ -114,46 +114,46 @@ + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + +- while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { +- /* Read input data if we haven't filled the main buffer yet */ +- if (main->rowgroup_ctr < DCTSIZE) ++ while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { ++ /* Read input data if we haven't filled the jmain buffer yet */ ++ if (jmain->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, +- main->buffer, &main->rowgroup_ctr, ++ jmain->buffer, &jmain->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + + /* If we don't have a full iMCU row buffered, return to application for + * more data. Note that preprocessor will always pad to fill the iMCU row + * at the bottom of the image. + */ +- if (main->rowgroup_ctr != DCTSIZE) ++ if (jmain->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ +- if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { ++ if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ +- if (! main->suspended) { ++ if (! jmain->suspended) { + (*in_row_ctr)--; +- main->suspended = TRUE; ++ jmain->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous +- * call suspended; then mark the main buffer empty. ++ * call suspended; then mark the jmain buffer empty. + */ +- if (main->suspended) { ++ if (jmain->suspended) { + (*in_row_ctr)++; +- main->suspended = FALSE; ++ jmain->suspended = FALSE; + } +- main->rowgroup_ctr = 0; +- main->cur_iMCU_row++; ++ jmain->rowgroup_ctr = 0; ++ jmain->cur_iMCU_row++; + } + } + +@@ -170,25 +170,25 @@ + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; +- boolean writing = (main->pass_mode != JBUF_CRANK_DEST); ++ boolean writing = (jmain->pass_mode != JBUF_CRANK_DEST); + +- while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { ++ while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ +- if (main->rowgroup_ctr == 0) { ++ if (jmain->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { +- main->buffer[ci] = (*cinfo->mem->access_virt_sarray) +- ((j_common_ptr) cinfo, main->whole_image[ci], +- main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), ++ jmain->buffer[ci] = (*cinfo->mem->access_virt_sarray) ++ ((j_common_ptr) cinfo, jmain->whole_image[ci], ++ jmain->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + } + /* In a read pass, pretend we just read some source data. */ + if (! writing) { + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; +- main->rowgroup_ctr = DCTSIZE; ++ jmain->rowgroup_ctr = DCTSIZE; + } + } + +@@ -197,40 +197,40 @@ + if (writing) { + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, +- main->buffer, &main->rowgroup_ctr, ++ jmain->buffer, &jmain->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ +- if (main->rowgroup_ctr < DCTSIZE) ++ if (jmain->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ +- if (main->pass_mode != JBUF_SAVE_SOURCE) { +- if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { ++ if (jmain->pass_mode != JBUF_SAVE_SOURCE) { ++ if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ +- if (! main->suspended) { ++ if (! jmain->suspended) { + (*in_row_ctr)--; +- main->suspended = TRUE; ++ jmain->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous +- * call suspended; then mark the main buffer empty. ++ * call suspended; then mark the jmain buffer empty. + */ +- if (main->suspended) { ++ if (jmain->suspended) { + (*in_row_ctr)++; +- main->suspended = FALSE; ++ jmain->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ +- main->rowgroup_ctr = 0; +- main->cur_iMCU_row++; ++ jmain->rowgroup_ctr = 0; ++ jmain->cur_iMCU_row++; + } + } + +@@ -238,21 +238,21 @@ + + + /* +- * Initialize main buffer controller. ++ * Initialize jmain buffer controller. + */ + + GLOBAL(void) + jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) + { +- my_main_ptr main; ++ my_main_ptr jmain; + int ci; + jpeg_component_info *compptr; + +- main = (my_main_ptr) ++ jmain = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); +- cinfo->main = (struct jpeg_c_main_controller *) main; +- main->pub.start_pass = start_pass_main; ++ cinfo->main = (struct jpeg_c_main_controller *) jmain; ++ jmain->pub.start_pass = start_pass_main; + + /* We don't need to create a buffer in raw-data mode. */ + if (cinfo->raw_data_in) +@@ -267,7 +267,7 @@ + /* Note we pad the bottom to a multiple of the iMCU height */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { +- main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) ++ jmain->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, +@@ -279,12 +279,12 @@ + #endif + } else { + #ifdef FULL_MAIN_BUFFER_SUPPORTED +- main->whole_image[0] = NULL; /* flag for no virtual arrays */ ++ jmain->whole_image[0] = NULL; /* flag for no virtual arrays */ + #endif + /* Allocate a strip buffer for each component */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { +- main->buffer[ci] = (*cinfo->mem->alloc_sarray) ++ jmain->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); +diff -u -w /home/tma/sources/jpeg-6b/jdatasrc.c ./jdatasrc.c +--- /home/tma/sources/jpeg-6b/jdatasrc.c 1996-01-06 23:26:42.000000000 +0000 ++++ ./jdatasrc.c 2008-08-22 00:00:59.000000000 +0100 +@@ -19,13 +19,17 @@ + #include "jpeglib.h" + #include "jerror.h" + ++#ifndef MIN ++#define MIN(a, b) ((a)<(b)?(a):(b)) ++#endif + + /* Expanded data source object for stdio input */ + + typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + +- FILE * infile; /* source stream */ ++ unsigned char *inbuf; /* source stream */ ++ size_t inbufbytes; + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ + } my_source_mgr; +@@ -90,18 +94,19 @@ + fill_input_buffer (j_decompress_ptr cinfo) + { + my_src_ptr src = (my_src_ptr) cinfo->src; +- size_t nbytes; +- +- nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); ++ size_t nbytes = MIN(src->inbufbytes, INPUT_BUF_SIZE); + + if (nbytes <= 0) { +- if (src->start_of_file) /* Treat empty input file as fatal error */ +- ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; ++ } else { ++ memcpy( src->buffer, src->inbuf, nbytes); ++ ++ src->inbuf += nbytes; ++ src->inbufbytes -= nbytes; + } + + src->pub.next_input_byte = src->buffer; +@@ -179,7 +184,7 @@ + */ + + GLOBAL(void) +-jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) ++jpeg_mem_src (j_decompress_ptr cinfo, unsigned char *inbuf, size_t size) + { + my_src_ptr src; + +@@ -206,7 +211,8 @@ + 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->inbuf = inbuf; ++ src->inbufbytes = size; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ + } +diff -u -w /home/tma/sources/jpeg-6b/jdmainct.c ./jdmainct.c +--- /home/tma/sources/jpeg-6b/jdmainct.c 1996-01-06 23:27:17.000000000 +0000 ++++ ./jdmainct.c 2008-08-22 00:13:48.000000000 +0100 +@@ -159,7 +159,7 @@ + * This is done only once, not once per pass. + */ + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + int ci, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; +@@ -168,10 +168,10 @@ + /* Get top-level space for component array pointers. + * We alloc both arrays with one call to save a few cycles. + */ +- main->xbuffer[0] = (JSAMPIMAGE) ++ jmain->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); +- main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; ++ jmain->xbuffer[1] = jmain->xbuffer[0] + cinfo->num_components; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { +@@ -184,9 +184,9 @@ + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf += rgroup; /* want one row group at negative offsets */ +- main->xbuffer[0][ci] = xbuf; ++ jmain->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); +- main->xbuffer[1][ci] = xbuf; ++ jmain->xbuffer[1][ci] = xbuf; + } + } + +@@ -194,13 +194,13 @@ + LOCAL(void) + make_funny_pointers (j_decompress_ptr cinfo) + /* Create the funny pointer lists discussed in the comments above. +- * The actual workspace is already allocated (in main->buffer), ++ * The actual workspace is already allocated (in jmain->buffer), + * and the space for the pointer lists is allocated too. + * This routine just fills in the curiously ordered lists. + * This will be repeated at the beginning of each pass. + */ + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; +@@ -210,10 +210,10 @@ + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ +- xbuf0 = main->xbuffer[0][ci]; +- xbuf1 = main->xbuffer[1][ci]; ++ xbuf0 = jmain->xbuffer[0][ci]; ++ xbuf1 = jmain->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ +- buf = main->buffer[ci]; ++ buf = jmain->buffer[ci]; + for (i = 0; i < rgroup * (M + 2); i++) { + xbuf0[i] = xbuf1[i] = buf[i]; + } +@@ -240,7 +240,7 @@ + * This changes the pointer list state from top-of-image to the normal state. + */ + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; +@@ -250,8 +250,8 @@ + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ +- xbuf0 = main->xbuffer[0][ci]; +- xbuf1 = main->xbuffer[1][ci]; ++ xbuf0 = jmain->xbuffer[0][ci]; ++ xbuf1 = jmain->xbuffer[1][ci]; + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; + xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; +@@ -269,7 +269,7 @@ + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + int ci, i, rgroup, iMCUheight, rows_left; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; +@@ -286,12 +286,12 @@ + * so we need only do it once. + */ + if (ci == 0) { +- main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); ++ jmain->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + } + /* Duplicate the last real sample row rgroup*2 times; this pads out the + * last partial rowgroup and ensures at least one full rowgroup of context. + */ +- xbuf = main->xbuffer[main->whichptr][ci]; ++ xbuf = jmain->xbuffer[jmain->whichptr][ci]; + for (i = 0; i < rgroup * 2; i++) { + xbuf[rows_left + i] = xbuf[rows_left-1]; + } +@@ -306,27 +306,27 @@ + METHODDEF(void) + start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { +- main->pub.process_data = process_data_context_main; ++ jmain->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ +- main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ +- main->context_state = CTX_PREPARE_FOR_IMCU; +- main->iMCU_row_ctr = 0; ++ jmain->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ ++ jmain->context_state = CTX_PREPARE_FOR_IMCU; ++ jmain->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ +- main->pub.process_data = process_data_simple_main; ++ jmain->pub.process_data = process_data_simple_main; + } +- main->buffer_full = FALSE; /* Mark buffer empty */ +- main->rowgroup_ctr = 0; ++ jmain->buffer_full = FALSE; /* Mark buffer empty */ ++ jmain->rowgroup_ctr = 0; + break; + #ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ +- main->pub.process_data = process_data_crank_post; ++ jmain->pub.process_data = process_data_crank_post; + break; + #endif + default: +@@ -346,14 +346,14 @@ + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + +- /* Read input data if we haven't filled the main buffer yet */ +- if (! main->buffer_full) { +- if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) ++ /* Read input data if we haven't filled the jmain buffer yet */ ++ if (! jmain->buffer_full) { ++ if (! (*cinfo->coef->decompress_data) (cinfo, jmain->buffer)) + return; /* suspension forced, can do nothing more */ +- main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ ++ jmain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + } + + /* There are always min_DCT_scaled_size row groups in an iMCU row. */ +@@ -364,14 +364,14 @@ + */ + + /* Feed the postprocessor */ +- (*cinfo->post->post_process_data) (cinfo, main->buffer, +- &main->rowgroup_ctr, rowgroups_avail, ++ (*cinfo->post->post_process_data) (cinfo, jmain->buffer, ++ &jmain->rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ +- if (main->rowgroup_ctr >= rowgroups_avail) { +- main->buffer_full = FALSE; +- main->rowgroup_ctr = 0; ++ if (jmain->rowgroup_ctr >= rowgroups_avail) { ++ jmain->buffer_full = FALSE; ++ jmain->rowgroup_ctr = 0; + } + } + +@@ -386,15 +386,15 @@ + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) + { +- my_main_ptr main = (my_main_ptr) cinfo->main; ++ my_main_ptr jmain = (my_main_ptr) cinfo->main; + +- /* Read input data if we haven't filled the main buffer yet */ +- if (! main->buffer_full) { ++ /* Read input data if we haven't filled the jmain buffer yet */ ++ if (! jmain->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, +- main->xbuffer[main->whichptr])) ++ jmain->xbuffer[jmain->whichptr])) + return; /* suspension forced, can do nothing more */ +- main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ +- main->iMCU_row_ctr++; /* count rows received */ ++ jmain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ ++ jmain->iMCU_row_ctr++; /* count rows received */ + } + + /* Postprocessor typically will not swallow all the input data it is handed +@@ -402,47 +402,47 @@ + * to exit and restart. This switch lets us keep track of how far we got. + * Note that each case falls through to the next on successful completion. + */ +- switch (main->context_state) { ++ switch (jmain->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ +- (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], +- &main->rowgroup_ctr, main->rowgroups_avail, ++ (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr], ++ &jmain->rowgroup_ctr, jmain->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); +- if (main->rowgroup_ctr < main->rowgroups_avail) ++ if (jmain->rowgroup_ctr < jmain->rowgroups_avail) + return; /* Need to suspend */ +- main->context_state = CTX_PREPARE_FOR_IMCU; ++ jmain->context_state = CTX_PREPARE_FOR_IMCU; + if (*out_row_ctr >= out_rows_avail) + return; /* Postprocessor exactly filled output buf */ + /*FALLTHROUGH*/ + case CTX_PREPARE_FOR_IMCU: + /* Prepare to process first M-1 row groups of this iMCU row */ +- main->rowgroup_ctr = 0; +- main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); ++ jmain->rowgroup_ctr = 0; ++ jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + /* Check for bottom of image: if so, tweak pointers to "duplicate" + * the last sample row, and adjust rowgroups_avail to ignore padding rows. + */ +- if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) ++ if (jmain->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); +- main->context_state = CTX_PROCESS_IMCU; ++ jmain->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ +- (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], +- &main->rowgroup_ctr, main->rowgroups_avail, ++ (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr], ++ &jmain->rowgroup_ctr, jmain->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); +- if (main->rowgroup_ctr < main->rowgroups_avail) ++ if (jmain->rowgroup_ctr < jmain->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ +- if (main->iMCU_row_ctr == 1) ++ if (jmain->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ +- main->whichptr ^= 1; /* 0=>1 or 1=>0 */ +- main->buffer_full = FALSE; ++ jmain->whichptr ^= 1; /* 0=>1 or 1=>0 */ ++ jmain->buffer_full = FALSE; + /* Still need to process last row group of this iMCU row, */ + /* which is saved at index M+1 of the other xbuffer */ +- main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); +- main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); +- main->context_state = CTX_POSTPONED_ROW; ++ jmain->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); ++ jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); ++ jmain->context_state = CTX_POSTPONED_ROW; + } + } + +@@ -469,21 +469,21 @@ + + + /* +- * Initialize main buffer controller. ++ * Initialize jmain buffer controller. + */ + + GLOBAL(void) + jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) + { +- my_main_ptr main; ++ my_main_ptr jmain; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + +- main = (my_main_ptr) ++ jmain = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); +- cinfo->main = (struct jpeg_d_main_controller *) main; +- main->pub.start_pass = start_pass_main; ++ cinfo->main = (struct jpeg_d_main_controller *) jmain; ++ jmain->pub.start_pass = start_pass_main; + + if (need_full_buffer) /* shouldn't happen */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +@@ -504,7 +504,7 @@ + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ +- main->buffer[ci] = (*cinfo->mem->alloc_sarray) ++ jmain->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); +diff -u -w /home/tma/sources/jpeg-6b/jerror.c ./jerror.c +--- /home/tma/sources/jpeg-6b/jerror.c 1998-02-22 01:03:15.000000000 +0000 ++++ ./jerror.c 2008-08-21 23:58:36.000000000 +0100 +@@ -18,6 +18,8 @@ + * These routines are used by both the compression and decompression code. + */ + ++#include "../renderer/tr_local.h" ++ + /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ + #include "jinclude.h" + #include "jpeglib.h" +@@ -69,13 +71,15 @@ + METHODDEF(void) + error_exit (j_common_ptr cinfo) + { +- /* Always display the message */ +- (*cinfo->err->output_message) (cinfo); ++ char buffer[JMSG_LENGTH_MAX]; ++ ++ /* Create the message */ ++ (*cinfo->err->format_message) (cinfo, buffer); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + +- exit(EXIT_FAILURE); ++ ri.Error( ERR_FATAL, "%s\n", buffer ); + } + + +@@ -108,7 +112,7 @@ + MB_OK | MB_ICONERROR); + #else + /* Send it to stderr, adding a newline */ +- fprintf(stderr, "%s\n", buffer); ++ ri.Printf(PRINT_ALL, "%s\n", buffer); + #endif + } + +diff -u -w /home/tma/sources/jpeg-6b/jinclude.h ./jinclude.h +--- /home/tma/sources/jpeg-6b/jinclude.h 1994-04-01 21:29:31.000000000 +0100 ++++ ./jinclude.h 2008-08-21 23:58:36.000000000 +0100 +@@ -15,9 +15,34 @@ + */ + + ++#ifdef _MSC_VER ++ ++#pragma warning(disable : 4018) // signed/unsigned mismatch ++#pragma warning(disable : 4032) ++#pragma warning(disable : 4051) ++#pragma warning(disable : 4057) // slightly different base types ++#pragma warning(disable : 4100) // unreferenced formal parameter ++#pragma warning(disable : 4115) ++#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence ++#pragma warning(disable : 4127) // conditional expression is constant ++#pragma warning(disable : 4136) ++#pragma warning(disable : 4152) // nonstandard extension, function/data pointer conversion in expression ++#pragma warning(disable : 4201) ++#pragma warning(disable : 4214) ++#pragma warning(disable : 4244) ++#pragma warning(disable : 4305) // truncation from const double to float ++#pragma warning(disable : 4310) // cast truncates constant value ++#pragma warning(disable: 4505) // unreferenced local function has been removed ++#pragma warning(disable : 4514) ++#pragma warning(disable : 4702) // unreachable code ++#pragma warning(disable : 4711) // selected for automatic inline expansion ++#pragma warning(disable : 4220) // varargs matches remaining parameters ++#pragma warning(disable : 4761) // integral size mismatch ++#endif ++ + /* Include auto-config file to find out which system include files we need. */ + +-#include "jconfig.h" /* auto configuration options */ ++#include "../jpeg-6b/jconfig.h" /* auto configuration options */ + #define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + + /* +diff -u -w /home/tma/sources/jpeg-6b/jmemnobs.c ./jmemnobs.c +--- /home/tma/sources/jpeg-6b/jmemnobs.c 1996-01-06 23:31:18.000000000 +0000 ++++ ./jmemnobs.c 2008-08-21 23:58:36.000000000 +0100 +@@ -8,39 +8,35 @@ + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space +- * can be obtained from malloc(). ++ * can be obtained from ri.Malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + ++#include "../renderer/tr_local.h" ++ + #define JPEG_INTERNALS + #include "jinclude.h" + #include "jpeglib.h" + #include "jmemsys.h" /* import the system-dependent declarations */ + +-#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */ +-extern void * malloc JPP((size_t size)); +-extern void free JPP((void *ptr)); +-#endif +- +- + /* + * Memory allocation and freeing are controlled by the regular library +- * routines malloc() and free(). ++ * routines ri.Malloc() and ri.Free(). + */ + + GLOBAL(void *) + jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) + { +- return (void *) malloc(sizeofobject); ++ return (void *) ri.Malloc(sizeofobject); + } + + GLOBAL(void) + jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) + { +- free(object); ++ ri.Free(object); + } + + +@@ -54,13 +50,13 @@ + GLOBAL(void FAR *) + jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) + { +- return (void FAR *) malloc(sizeofobject); ++ return (void FAR *) ri.Malloc(sizeofobject); + } + + GLOBAL(void) + jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) + { +- free(object); ++ ri.Free(object); + } + + +diff -u -w /home/tma/sources/jpeg-6b/jmorecfg.h ./jmorecfg.h +--- /home/tma/sources/jpeg-6b/jmorecfg.h 1997-08-10 00:58:56.000000000 +0100 ++++ ./jmorecfg.h 2008-08-21 23:58:36.000000000 +0100 +@@ -157,7 +157,8 @@ + + /* INT32 must hold at least signed 32-bit values. */ + +-#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ ++/* MinGW basetsd.h defines INT32 - don't redefine it */ ++#if !(defined __MINGW32__ && defined _BASETSD_H) + typedef long INT32; + #endif + +@@ -210,8 +211,10 @@ + */ + + #ifdef NEED_FAR_POINTERS ++#undef FAR + #define FAR far + #else ++#undef FAR + #define FAR + #endif + +@@ -223,9 +226,7 @@ + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +-#ifndef HAVE_BOOLEAN +-typedef int boolean; +-#endif ++typedef unsigned char boolean; + #ifndef FALSE /* in case these macros already exist */ + #define FALSE 0 /* values of boolean */ + #endif +@@ -260,8 +261,8 @@ + + /* Capability options common to encoder and decoder: */ + +-#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +-#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ ++#undef DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ ++#undef DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ + #define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + + /* Encoder capability options: */ +@@ -283,15 +284,15 @@ + /* Decoder capability options: */ + + #undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +-#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +-#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +-#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +-#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +-#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ ++#undef D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ ++#undef D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ ++#undef SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ ++#undef BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ ++#undef IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ + #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +-#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +-#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +-#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ ++#undef UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ ++#undef QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ ++#undef QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + + /* more capability options later, no doubt */ + +@@ -314,7 +315,7 @@ + #define RGB_RED 0 /* Offset of Red in an RGB scanline element */ + #define RGB_GREEN 1 /* Offset of Green */ + #define RGB_BLUE 2 /* Offset of Blue */ +-#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ ++#define RGB_PIXELSIZE 4 /* JSAMPLEs per RGB scanline element */ + + + /* Definitions for speed-related optimizations. */ +diff -u -w /home/tma/sources/jpeg-6b/jpeglib.h ./jpeglib.h +--- /home/tma/sources/jpeg-6b/jpeglib.h 1998-02-21 19:48:14.000000000 +0000 ++++ ./jpeglib.h 2008-08-22 00:01:58.000000000 +0100 +@@ -21,9 +21,9 @@ + */ + + #ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +-#include "jconfig.h" /* widely used configuration options */ ++#include "../jpeg-6b/jconfig.h" /* widely used configuration options */ + #endif +-#include "jmorecfg.h" /* seldom changed options */ ++#include "../jpeg-6b/jmorecfg.h" /* seldom changed options */ + + + /* Version ID for the JPEG library. +@@ -835,7 +835,7 @@ + #define jpeg_destroy_compress jDestCompress + #define jpeg_destroy_decompress jDestDecompress + #define jpeg_stdio_dest jStdDest +-#define jpeg_stdio_src jStdSrc ++#define jpeg_mem_src jMemSrc + #define jpeg_set_defaults jSetDefaults + #define jpeg_set_colorspace jSetColorspace + #define jpeg_default_colorspace jDefColorspace +@@ -908,7 +908,7 @@ + /* Standard data source and destination managers: stdio streams. */ + /* Caller is responsible for opening the file before and closing after. */ + EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +-EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); ++EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, unsigned char *inbuf, size_t size)); + + /* Default parameter setup for compression */ + EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +@@ -1089,8 +1089,8 @@ + */ + + #ifdef JPEG_INTERNALS +-#include "jpegint.h" /* fetch private declarations */ +-#include "jerror.h" /* fetch error codes too */ ++#include "../jpeg-6b/jpegint.h" /* fetch private declarations */ ++#include "../jpeg-6b/jerror.h" /* fetch error codes too */ + #endif + + #endif /* JPEGLIB_H */ diff --git a/src/jpeg-6/jcapimin.c b/src/jpeg-6b/jcapimin.c index 1cd9736d..54fb8c58 100644 --- a/src/jpeg-6/jcapimin.c +++ b/src/jpeg-6b/jcapimin.c @@ -1,7 +1,7 @@ /* * jcapimin.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,18 +26,31 @@ * The error manager must already be set up (in case memory manager fails). */ -GLOBAL void -jpeg_create_compress (j_compress_ptr cinfo) +GLOBAL(void) +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) { int i; - /* For debugging purposes, zero the whole master structure. - * But error manager pointer is already there, so save and restore it. + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_compress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. */ { struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); cinfo->err = err; + cinfo->client_data = client_data; } cinfo->is_decompressor = FALSE; @@ -58,6 +71,8 @@ jpeg_create_compress (j_compress_ptr cinfo) cinfo->ac_huff_tbl_ptrs[i] = NULL; } + cinfo->script_space = NULL; + cinfo->input_gamma = 1.0; /* in case application forgets */ /* OK, I'm ready */ @@ -69,7 +84,7 @@ jpeg_create_compress (j_compress_ptr cinfo) * Destruction of a JPEG compression object */ -GLOBAL void +GLOBAL(void) jpeg_destroy_compress (j_compress_ptr cinfo) { jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ @@ -81,7 +96,7 @@ jpeg_destroy_compress (j_compress_ptr cinfo) * but don't destroy the object itself. */ -GLOBAL void +GLOBAL(void) jpeg_abort_compress (j_compress_ptr cinfo) { jpeg_abort((j_common_ptr) cinfo); /* use common routine */ @@ -100,7 +115,7 @@ jpeg_abort_compress (j_compress_ptr cinfo) * jcparam.o would be linked whether the application used it or not. */ -GLOBAL void +GLOBAL(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) { int i; @@ -128,7 +143,7 @@ jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) * work including most of the actual output. */ -GLOBAL void +GLOBAL(void) jpeg_finish_compress (j_compress_ptr cinfo) { JDIMENSION iMCU_row; @@ -173,17 +188,44 @@ jpeg_finish_compress (j_compress_ptr cinfo) * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). */ -GLOBAL void +GLOBAL(void) jpeg_write_marker (j_compress_ptr cinfo, int marker, const JOCTET *dataptr, unsigned int datalen) { + JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val)); + + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); + write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ + while (datalen--) { + (*write_marker_byte) (cinfo, *dataptr); + dataptr++; + } +} + +/* Same, but piecemeal. */ + +GLOBAL(void) +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +{ if (cinfo->next_scanline != 0 || (cinfo->global_state != CSTATE_SCANNING && cinfo->global_state != CSTATE_RAW_OK && cinfo->global_state != CSTATE_WRCOEFS)) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - (*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen); + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); +} + +GLOBAL(void) +jpeg_write_m_byte (j_compress_ptr cinfo, int val) +{ + (*cinfo->marker->write_marker_byte) (cinfo, val); } @@ -208,7 +250,7 @@ jpeg_write_marker (j_compress_ptr cinfo, int marker, * will not re-emit the tables unless it is passed write_all_tables=TRUE. */ -GLOBAL void +GLOBAL(void) jpeg_write_tables (j_compress_ptr cinfo) { if (cinfo->global_state != CSTATE_START) @@ -223,6 +265,16 @@ jpeg_write_tables (j_compress_ptr cinfo) (*cinfo->marker->write_tables_only) (cinfo); /* And clean up. */ (*cinfo->dest->term_destination) (cinfo); - /* We can use jpeg_abort to release memory. */ - jpeg_abort((j_common_ptr) cinfo); + /* + * In library releases up through v6a, we called jpeg_abort() here to free + * any working memory allocated by the destination manager and marker + * writer. Some applications had a problem with that: they allocated space + * of their own from the library memory manager, and didn't want it to go + * away during write_tables. So now we do nothing. This will cause a + * memory leak if an app calls write_tables repeatedly without doing a full + * compression cycle or otherwise resetting the JPEG object. However, that + * seems less bad than unexpectedly freeing memory in the normal case. + * An app that prefers the old behavior can call jpeg_abort for itself after + * each call to jpeg_write_tables(). + */ } diff --git a/src/jpeg-6/jcapistd.c b/src/jpeg-6b/jcapistd.c index b99e560b..c0320b1b 100644 --- a/src/jpeg-6/jcapistd.c +++ b/src/jpeg-6b/jcapistd.c @@ -1,7 +1,7 @@ /* * jcapistd.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -34,7 +34,7 @@ * wrong thing. */ -GLOBAL void +GLOBAL(void) jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) { if (cinfo->global_state != CSTATE_START) @@ -73,7 +73,7 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) * when using a multiple-scanline buffer. */ -GLOBAL JDIMENSION +GLOBAL(JDIMENSION) jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines) { @@ -116,7 +116,7 @@ jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, * Processes exactly one iMCU row per call, unless suspended. */ -GLOBAL JDIMENSION +GLOBAL(JDIMENSION) jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, JDIMENSION num_lines) { diff --git a/src/jpeg-6/jccoefct.c b/src/jpeg-6b/jccoefct.c index ea3169b8..1963ddb6 100644 --- a/src/jpeg-6/jccoefct.c +++ b/src/jpeg-6b/jccoefct.c @@ -1,7 +1,7 @@ /* * jccoefct.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -58,17 +58,17 @@ typedef my_coef_controller * my_coef_ptr; /* Forward declarations */ -METHODDEF boolean compress_data +METHODDEF(boolean) compress_data JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); #ifdef FULL_COEF_BUFFER_SUPPORTED -METHODDEF boolean compress_first_pass +METHODDEF(boolean) compress_first_pass JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); -METHODDEF boolean compress_output +METHODDEF(boolean) compress_output JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); #endif -LOCAL void +LOCAL(void) start_iMCU_row (j_compress_ptr cinfo) /* Reset within-iMCU-row counters for a new row */ { @@ -96,7 +96,7 @@ start_iMCU_row (j_compress_ptr cinfo) * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -135,11 +135,11 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) * per call, ie, v_samp_factor block rows for each component in the image. * Returns TRUE if the iMCU row is completed, FALSE if suspended. * - * NB: input_buf contains a plane for each component in image. - * For single pass, this is the same as the components in the scan. + * NB: input_buf contains a plane for each component in image, + * which we index according to the component's SOF position. */ -METHODDEF boolean +METHODDEF(boolean) compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -175,7 +175,8 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) if (coef->iMCU_row_num < last_iMCU_row || yoffset+yindex < compptr->last_row_height) { (*cinfo->fdct->forward_DCT) (cinfo, compptr, - input_buf[ci], coef->MCU_buffer[blkn], + input_buf[compptr->component_index], + coef->MCU_buffer[blkn], ypos, xpos, (JDIMENSION) blockcnt); if (blockcnt < compptr->MCU_width) { /* Create some dummy blocks at the right edge of the image. */ @@ -240,7 +241,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * at the scan-dependent variables (MCU dimensions, etc). */ -METHODDEF boolean +METHODDEF(boolean) compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -336,7 +337,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * NB: input_buf is ignored; it is likely to be a NULL pointer. */ -METHODDEF boolean +METHODDEF(boolean) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -400,7 +401,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * Initialize coefficient buffer controller. */ -GLOBAL void +GLOBAL(void) jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) { my_coef_ptr coef; diff --git a/src/jpeg-6/jccolor.c b/src/jpeg-6b/jccolor.c index 67079118..0a8a4b5d 100644 --- a/src/jpeg-6/jccolor.c +++ b/src/jpeg-6b/jccolor.c @@ -1,7 +1,7 @@ /* * jccolor.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -82,7 +82,7 @@ typedef my_color_converter * my_cconvert_ptr; * Initialize for RGB->YCC colorspace conversion. */ -METHODDEF void +METHODDEF(void) rgb_ycc_start (j_compress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; @@ -126,7 +126,7 @@ rgb_ycc_start (j_compress_ptr cinfo) * offset required on that side. */ -METHODDEF void +METHODDEF(void) rgb_ycc_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) @@ -182,7 +182,7 @@ rgb_ycc_convert (j_compress_ptr cinfo, * We assume rgb_ycc_start has been called (we only use the Y tables). */ -METHODDEF void +METHODDEF(void) rgb_gray_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) @@ -221,7 +221,7 @@ rgb_gray_convert (j_compress_ptr cinfo, * We assume rgb_ycc_start has been called. */ -METHODDEF void +METHODDEF(void) cmyk_ycck_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) @@ -276,7 +276,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo, * The source can be either plain grayscale or YCbCr (since Y == gray). */ -METHODDEF void +METHODDEF(void) grayscale_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) @@ -305,7 +305,7 @@ grayscale_convert (j_compress_ptr cinfo, * We assume input_components == num_components. */ -METHODDEF void +METHODDEF(void) null_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) @@ -337,7 +337,7 @@ null_convert (j_compress_ptr cinfo, * Empty method for start_pass. */ -METHODDEF void +METHODDEF(void) null_method (j_compress_ptr cinfo) { /* no work needed */ @@ -348,7 +348,7 @@ null_method (j_compress_ptr cinfo) * Module initialization routine for input colorspace conversion. */ -GLOBAL void +GLOBAL(void) jinit_color_converter (j_compress_ptr cinfo) { my_cconvert_ptr cconvert; diff --git a/src/jpeg-6/jcdctmgr.c b/src/jpeg-6b/jcdctmgr.c index debba72b..94d5cda4 100644 --- a/src/jpeg-6/jcdctmgr.c +++ b/src/jpeg-6b/jcdctmgr.c @@ -1,7 +1,7 @@ /* * jcdctmgr.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -27,8 +27,7 @@ typedef struct { /* The actual post-DCT divisors --- not identical to the quant table * entries, because of scaling (especially for an unnormalized DCT). - * Each table is given in normal array order; note that this must - * be converted from the zigzag order of the quantization tables. + * Each table is given in normal array order. */ DCTELEM * divisors[NUM_QUANT_TBLS]; @@ -51,16 +50,13 @@ typedef my_fdct_controller * my_fdct_ptr; * first scan. Hence all components should be examined here. */ -METHODDEF void +METHODDEF(void) start_pass_fdctmgr (j_compress_ptr cinfo) { my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; int ci, qtblno, i; jpeg_component_info *compptr; JQUANT_TBL * qtbl; -#ifdef DCT_ISLOW_SUPPORTED - DCTELEM * dtbl; -#endif for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { @@ -85,7 +81,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } dtbl = fdct->divisors[qtblno]; for (i = 0; i < DCTSIZE2; i++) { - dtbl[i] = ((DCTELEM) qtbl->quantval[jpeg_zigzag_order[i]]) << 3; + dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; } break; #endif @@ -100,7 +96,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) */ #define CONST_BITS 14 static const INT16 aanscales[DCTSIZE2] = { - /* precomputed values scaled up by 14 bits: in natural order */ + /* precomputed values scaled up by 14 bits */ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, @@ -120,7 +116,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) dtbl = fdct->divisors[qtblno]; for (i = 0; i < DCTSIZE2; i++) { dtbl[i] = (DCTELEM) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], (INT32) aanscales[i]), CONST_BITS-3); } @@ -155,7 +151,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) for (row = 0; row < DCTSIZE; row++) { for (col = 0; col < DCTSIZE; col++) { fdtbl[i] = (FAST_FLOAT) - (1.0 / (((double) qtbl->quantval[jpeg_zigzag_order[i]] * + (1.0 / (((double) qtbl->quantval[i] * aanscalefactor[row] * aanscalefactor[col] * 8.0))); i++; } @@ -171,6 +167,8 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } +/* code/jpeg-6b/jcdctmgr.c:184: warning: ‘forward_DCT’ defined but not used */ +#if 0 /* * Perform forward DCT on one or more blocks of a component. * @@ -179,9 +177,98 @@ start_pass_fdctmgr (j_compress_ptr cinfo) * blocks. The quantized coefficients are returned in coef_blocks[]. */ +METHODDEF(void) +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for integer DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + forward_DCT_method_ptr do_dct = fdct->do_dct; + DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register DCTELEM *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register DCTELEM temp, qval; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ +#ifdef FAST_DIVIDE +#define DIVIDE_BY(a,b) a /= b +#else +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#endif + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; + } + } + } +} +#endif + + #ifdef DCT_FLOAT_SUPPORTED -METHODDEF void +METHODDEF(void) forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JDIMENSION start_row, JDIMENSION start_col, @@ -256,7 +343,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, * Initialize FDCT manager. */ -GLOBAL void +GLOBAL(void) jinit_forward_dct (j_compress_ptr cinfo) { my_fdct_ptr fdct; diff --git a/src/jpeg-6/jchuff.c b/src/jpeg-6b/jchuff.c index 59f7865c..f2352505 100644 --- a/src/jpeg-6/jchuff.c +++ b/src/jpeg-6b/jchuff.c @@ -1,7 +1,7 @@ /* * jchuff.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -86,13 +86,13 @@ typedef struct { /* Forward declarations */ -METHODDEF boolean encode_mcu_huff JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_huff JPP((j_compress_ptr cinfo)); +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); #ifdef ENTROPY_OPT_SUPPORTED -METHODDEF boolean encode_mcu_gather JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo)); +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); #endif @@ -102,7 +102,7 @@ METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo)); * just count the Huffman symbols used and generate Huffman code tables. */ -METHODDEF void +METHODDEF(void) start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -125,16 +125,14 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) compptr = cinfo->cur_comp_info[ci]; dctbl = compptr->dc_tbl_no; actbl = compptr->ac_tbl_no; - /* Make sure requested tables are present */ - /* (In gather mode, tables need not be allocated yet) */ - if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || - (cinfo->dc_huff_tbl_ptrs[dctbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); - if (actbl < 0 || actbl >= NUM_HUFF_TBLS || - (cinfo->ac_huff_tbl_ptrs[actbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); if (gather_statistics) { #ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); /* Allocate and zero the statistics tables */ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ if (entropy->dc_count_ptrs[dctbl] == NULL) @@ -151,9 +149,9 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) } else { /* Compute derived values for Huffman tables */ /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, & entropy->dc_derived_tbls[dctbl]); - jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, & entropy->ac_derived_tbls[actbl]); } /* Initialize DC predictions to 0 */ @@ -172,19 +170,34 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) /* * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * * Note this is also used by jcphuff.c. */ -GLOBAL void -jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, +GLOBAL(void) +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, c_derived_tbl ** pdtbl) { + JHUFF_TBL *htbl; c_derived_tbl *dtbl; - int p, i, l, lastp, si; + int p, i, l, lastp, si, maxsymbol; char huffsize[257]; unsigned int huffcode[257]; unsigned int code; + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + /* Allocate a workspace if we haven't already done so. */ if (*pdtbl == NULL) *pdtbl = (c_derived_tbl *) @@ -193,19 +206,21 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, dtbl = *pdtbl; /* Figure C.1: make table of Huffman code length for each symbol */ - /* Note that this is in code-length order. */ p = 0; for (l = 1; l <= 16; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++) + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) huffsize[p++] = (char) l; } huffsize[p] = 0; lastp = p; /* Figure C.2: generate the codes themselves */ - /* Note that this is in code-length order. */ - + /* We also validate that the counts represent a legal Huffman code tree. */ + code = 0; si = huffsize[0]; p = 0; @@ -214,6 +229,11 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, huffcode[p++] = code; code++; } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); code <<= 1; si++; } @@ -221,14 +241,25 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, /* Figure C.3: generate encoding tables */ /* These are code and size indexed by symbol value */ - /* Set any codeless symbols to have code length 0; - * this allows emit_bits to detect any attempt to emit such symbols. + /* Set all codeless symbols to have code length 0; + * this lets us detect duplicate VAL entries here, and later + * allows emit_bits to detect any attempt to emit such symbols. */ MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); + /* This is also a convenient place to check for out-of-range + * and duplicated VAL entries. We allow 0..255 for AC symbols + * but only 0..15 for DC. (We could constrain them further + * based on data depth and mode, but this seems enough.) + */ + maxsymbol = isDC ? 15 : 255; + for (p = 0; p < lastp; p++) { - dtbl->ehufco[htbl->huffval[p]] = huffcode[p]; - dtbl->ehufsi[htbl->huffval[p]] = huffsize[p]; + i = htbl->huffval[p]; + if (i < 0 || i > maxsymbol || dtbl->ehufsi[i]) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + dtbl->ehufco[i] = huffcode[p]; + dtbl->ehufsi[i] = huffsize[p]; } } @@ -243,7 +274,7 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, { action; } } -LOCAL boolean +LOCAL(boolean) dump_buffer (working_state * state) /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ { @@ -267,7 +298,7 @@ dump_buffer (working_state * state) */ INLINE -LOCAL boolean +LOCAL(boolean) emit_bits (working_state * state, unsigned int code, int size) /* Emit some bits; return TRUE if successful, FALSE if must suspend */ { @@ -305,7 +336,7 @@ emit_bits (working_state * state, unsigned int code, int size) } -LOCAL boolean +LOCAL(boolean) flush_bits (working_state * state) { if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ @@ -318,7 +349,7 @@ flush_bits (working_state * state) /* Encode a single block's worth of coefficients */ -LOCAL boolean +LOCAL(boolean) encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) { @@ -343,6 +374,11 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, nbits++; temp >>= 1; } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); /* Emit the Huffman-coded symbol for the number of bits */ if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) @@ -380,6 +416,9 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1)) nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); /* Emit Huffman symbol for run length / number of bits */ i = (r << 4) + nbits; @@ -408,7 +447,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, * Emit a restart marker & resynchronize predictions. */ -LOCAL boolean +LOCAL(boolean) emit_restart (working_state * state, int restart_num) { int ci; @@ -433,7 +472,7 @@ emit_restart (working_state * state, int restart_num) * Encode and output one MCU's worth of Huffman-compressed coefficients. */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -490,7 +529,7 @@ encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * Finish up at the end of a Huffman-compressed scan. */ -METHODDEF void +METHODDEF(void) finish_pass_huff (j_compress_ptr cinfo) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -516,19 +555,12 @@ finish_pass_huff (j_compress_ptr cinfo) /* * Huffman coding optimization. * - * This actually is optimization, in the sense that we find the best possible - * Huffman table(s) for the given data. We first scan the supplied data and - * count the number of uses of each symbol that is to be Huffman-coded. - * (This process must agree with the code above.) Then we build an - * optimal Huffman coding tree for the observed counts. - * - * The JPEG standard requires Huffman codes to be no more than 16 bits long. - * If some symbols have a very small but nonzero probability, the Huffman tree - * must be adjusted to meet the code length restriction. We currently use - * the adjustment method suggested in the JPEG spec. This method is *not* - * optimal; it may not choose the best possible limited-length code. But - * since the symbols involved are infrequently used, it's not clear that - * going to extra trouble is worthwhile. + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. */ #ifdef ENTROPY_OPT_SUPPORTED @@ -536,8 +568,8 @@ finish_pass_huff (j_compress_ptr cinfo) /* Process a single block's worth of coefficients */ -LOCAL void -htest_one_block (JCOEFPTR block, int last_dc_val, +LOCAL(void) +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, long dc_counts[], long ac_counts[]) { register int temp; @@ -556,6 +588,11 @@ htest_one_block (JCOEFPTR block, int last_dc_val, nbits++; temp >>= 1; } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count the Huffman symbol for the number of bits */ dc_counts[nbits]++; @@ -582,6 +619,9 @@ htest_one_block (JCOEFPTR block, int last_dc_val, nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1)) nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count Huffman symbol for run length / number of bits */ ac_counts[(r << 4) + nbits]++; @@ -601,7 +641,7 @@ htest_one_block (JCOEFPTR block, int last_dc_val, * No data is actually output, so no suspension return is possible. */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -623,7 +663,7 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { ci = cinfo->MCU_membership[blkn]; compptr = cinfo->cur_comp_info[ci]; - htest_one_block(MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], entropy->dc_count_ptrs[compptr->dc_tbl_no], entropy->ac_count_ptrs[compptr->ac_tbl_no]); entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; @@ -634,11 +674,34 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* - * Generate the optimal coding for the given counts, fill htbl. + * Generate the best Huffman code table for the given counts, fill htbl. * Note this is also used by jcphuff.c. + * + * The JPEG standard requires that no symbol be assigned a codeword of all + * one bits (so that padding bits added at the end of a compressed segment + * can't look like a valid code). Because of the canonical ordering of + * codewords, this just means that there must be an unused slot in the + * longest codeword length category. Section K.2 of the JPEG spec suggests + * reserving such a slot by pretending that symbol 256 is a valid symbol + * with count 1. In theory that's not optimal; giving it count zero but + * including it in the symbol set anyway should give a better Huffman code. + * But the theoretically better code actually seems to come out worse in + * practice, because it produces more all-ones bytes (which incur stuffed + * zero bytes in the final file). In any case the difference is tiny. + * + * The JPEG standard requires Huffman codes to be no more than 16 bits long. + * If some symbols have a very small but nonzero probability, the Huffman tree + * must be adjusted to meet the code length restriction. We currently use + * the adjustment method suggested in JPEG section K.2. This method is *not* + * optimal; it may not choose the best possible limited-length code. But + * typically only very-low-frequency symbols will be given less-than-optimal + * lengths, so the code is almost optimal. Experimental comparisons against + * an optimal limited-length-code algorithm indicate that the difference is + * microscopic --- usually less than a hundredth of a percent of total size. + * So the extra complexity of an optimal algorithm doesn't seem worthwhile. */ -GLOBAL void +GLOBAL(void) jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) { #define MAX_CLEN 32 /* assumed maximum initial code length */ @@ -656,10 +719,10 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) for (i = 0; i < 257; i++) others[i] = -1; /* init links to empty */ - freq[256] = 1; /* make sure there is a nonzero count */ + freq[256] = 1; /* make sure 256 has a nonzero count */ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees * that no real symbol is given code-value of all ones, because 256 - * will be placed in the largest codeword category. + * will be placed last in the largest codeword category. */ /* Huffman's basic algorithm to assign optimal code lengths to symbols */ @@ -779,7 +842,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) * Finish up a statistics-gathering pass and create the new Huffman tables. */ -METHODDEF void +METHODDEF(void) finish_pass_gather (j_compress_ptr cinfo) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -824,7 +887,7 @@ finish_pass_gather (j_compress_ptr cinfo) * Module initialization routine for Huffman entropy encoding. */ -GLOBAL void +GLOBAL(void) jinit_huff_encoder (j_compress_ptr cinfo) { huff_entropy_ptr entropy; diff --git a/src/jpeg-6/jchuff.h b/src/jpeg-6b/jchuff.h index f43d571d..a9599fc1 100644 --- a/src/jpeg-6/jchuff.h +++ b/src/jpeg-6b/jchuff.h @@ -1,7 +1,7 @@ /* * jchuff.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -10,6 +10,18 @@ * progressive encoder (jcphuff.c). No other modules need to see these. */ +/* The legal range of a DCT coefficient is + * -1024 .. +1023 for 8-bit data; + * -16384 .. +16383 for 12-bit data. + * Hence the magnitude should always fit in 10 or 14 bits respectively. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MAX_COEF_BITS 10 +#else +#define MAX_COEF_BITS 14 +#endif + /* Derived data constructed for each Huffman table */ typedef struct { @@ -26,9 +38,10 @@ typedef struct { #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Expand a Huffman table definition into the derived format */ -EXTERN void jpeg_make_c_derived_tbl JPP((j_compress_ptr cinfo, - JHUFF_TBL * htbl, c_derived_tbl ** pdtbl)); +EXTERN(void) jpeg_make_c_derived_tbl + JPP((j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl)); /* Generate an optimal table definition given the specified counts */ -EXTERN void jpeg_gen_optimal_table JPP((j_compress_ptr cinfo, - JHUFF_TBL * htbl, long freq[])); +EXTERN(void) jpeg_gen_optimal_table + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/src/jpeg-6/jcinit.c b/src/jpeg-6b/jcinit.c index 2cc82b25..5efffe33 100644 --- a/src/jpeg-6/jcinit.c +++ b/src/jpeg-6b/jcinit.c @@ -1,7 +1,7 @@ /* * jcinit.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,7 +26,7 @@ * which modules will be used and give them appropriate initialization calls. */ -GLOBAL void +GLOBAL(void) jinit_compress_master (j_compress_ptr cinfo) { /* Initialize master control (includes parameter checking/processing) */ @@ -56,7 +56,7 @@ jinit_compress_master (j_compress_ptr cinfo) /* Need a full-image coefficient buffer in any multi-pass mode. */ jinit_c_coef_controller(cinfo, - (cinfo->num_scans > 1 || cinfo->optimize_coding)); + (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding)); jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); jinit_marker_writer(cinfo); diff --git a/src/jpeg-6/jcmainct.c b/src/jpeg-6b/jcmainct.c index aa8ba9b5..03a61a7e 100644 --- a/src/jpeg-6/jcmainct.c +++ b/src/jpeg-6b/jcmainct.c @@ -1,7 +1,7 @@ /* * jcmainct.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -51,11 +51,11 @@ typedef my_main_controller * my_main_ptr; /* Forward declarations */ -METHODDEF void process_data_simple_main +METHODDEF(void) process_data_simple_main JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); #ifdef FULL_MAIN_BUFFER_SUPPORTED -METHODDEF void process_data_buffer_main +METHODDEF(void) process_data_buffer_main JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); #endif @@ -65,7 +65,7 @@ METHODDEF void process_data_buffer_main * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { my_main_ptr jmain = (my_main_ptr) cinfo->main; @@ -109,7 +109,7 @@ start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) * where we have only a strip buffer. */ -METHODDEF void +METHODDEF(void) process_data_simple_main (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail) @@ -117,7 +117,7 @@ process_data_simple_main (j_compress_ptr cinfo, my_main_ptr jmain = (my_main_ptr) cinfo->main; while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { - /* Read input data if we haven't filled the main buffer yet */ + /* Read input data if we haven't filled the jmain buffer yet */ if (jmain->rowgroup_ctr < DCTSIZE) (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr, in_rows_avail, @@ -146,7 +146,7 @@ process_data_simple_main (j_compress_ptr cinfo, return; } /* We did finish the row. Undo our little suspension hack if a previous - * call suspended; then mark the main buffer empty. + * call suspended; then mark the jmain buffer empty. */ if (jmain->suspended) { (*in_row_ctr)++; @@ -165,30 +165,30 @@ process_data_simple_main (j_compress_ptr cinfo, * This routine handles all of the modes that use a full-size buffer. */ -METHODDEF void +METHODDEF(void) process_data_buffer_main (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail) { - my_main_ptr main = (my_main_ptr) cinfo->main; + my_main_ptr jmain = (my_main_ptr) cinfo->main; int ci; jpeg_component_info *compptr; - boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + boolean writing = (jmain->pass_mode != JBUF_CRANK_DEST); - while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { /* Realign the virtual buffers if at the start of an iMCU row. */ - if (main->rowgroup_ctr == 0) { + if (jmain->rowgroup_ctr == 0) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - main->buffer[ci] = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, main->whole_image[ci], - main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + jmain->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, jmain->whole_image[ci], + jmain->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); } /* In a read pass, pretend we just read some source data. */ if (! writing) { *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; - main->rowgroup_ctr = DCTSIZE; + jmain->rowgroup_ctr = DCTSIZE; } } @@ -197,40 +197,40 @@ process_data_buffer_main (j_compress_ptr cinfo, if (writing) { (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr, in_rows_avail, - main->buffer, &main->rowgroup_ctr, + jmain->buffer, &jmain->rowgroup_ctr, (JDIMENSION) DCTSIZE); /* Return to application if we need more data to fill the iMCU row. */ - if (main->rowgroup_ctr < DCTSIZE) + if (jmain->rowgroup_ctr < DCTSIZE) return; } /* Emit data, unless this is a sink-only pass. */ - if (main->pass_mode != JBUF_SAVE_SOURCE) { - if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + if (jmain->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { /* If compressor did not consume the whole row, then we must need to * suspend processing and return to the application. In this situation * we pretend we didn't yet consume the last input row; otherwise, if * it happened to be the last row of the image, the application would * think we were done. */ - if (! main->suspended) { + if (! jmain->suspended) { (*in_row_ctr)--; - main->suspended = TRUE; + jmain->suspended = TRUE; } return; } /* We did finish the row. Undo our little suspension hack if a previous - * call suspended; then mark the main buffer empty. + * call suspended; then mark the jmain buffer empty. */ - if (main->suspended) { + if (jmain->suspended) { (*in_row_ctr)++; - main->suspended = FALSE; + jmain->suspended = FALSE; } } /* If get here, we are done with this iMCU row. Mark buffer empty. */ - main->rowgroup_ctr = 0; - main->cur_iMCU_row++; + jmain->rowgroup_ctr = 0; + jmain->cur_iMCU_row++; } } @@ -238,10 +238,10 @@ process_data_buffer_main (j_compress_ptr cinfo, /* - * Initialize main buffer controller. + * Initialize jmain buffer controller. */ -GLOBAL void +GLOBAL(void) jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) { my_main_ptr jmain; diff --git a/src/jpeg-6/jcmarker.c b/src/jpeg-6b/jcmarker.c index f4d290b9..3d1e6c6d 100644 --- a/src/jpeg-6/jcmarker.c +++ b/src/jpeg-6b/jcmarker.c @@ -1,7 +1,7 @@ /* * jcmarker.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -81,6 +81,17 @@ typedef enum { /* JPEG marker codes */ } JPEG_MARKER; +/* Private state */ + +typedef struct { + struct jpeg_marker_writer pub; /* public fields */ + + unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */ +} my_marker_writer; + +typedef my_marker_writer * my_marker_ptr; + + /* * Basic output routines. * @@ -93,7 +104,7 @@ typedef enum { /* JPEG marker codes */ * points where markers will be written. */ -LOCAL void +LOCAL(void) emit_byte (j_compress_ptr cinfo, int val) /* Emit a byte */ { @@ -107,7 +118,7 @@ emit_byte (j_compress_ptr cinfo, int val) } -LOCAL void +LOCAL(void) emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) /* Emit a marker code */ { @@ -116,7 +127,7 @@ emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) } -LOCAL void +LOCAL(void) emit_2bytes (j_compress_ptr cinfo, int value) /* Emit a 2-byte integer; these are always MSB first in JPEG files */ { @@ -129,7 +140,7 @@ emit_2bytes (j_compress_ptr cinfo, int value) * Routines to write specific marker types. */ -LOCAL int +LOCAL(int) emit_dqt (j_compress_ptr cinfo, int index) /* Emit a DQT marker */ /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ @@ -155,9 +166,11 @@ emit_dqt (j_compress_ptr cinfo, int index) emit_byte(cinfo, index + (prec<<4)); for (i = 0; i < DCTSIZE2; i++) { + /* The table entries must be emitted in zigzag order. */ + unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; if (prec) - emit_byte(cinfo, qtbl->quantval[i] >> 8); - emit_byte(cinfo, qtbl->quantval[i] & 0xFF); + emit_byte(cinfo, (int) (qval >> 8)); + emit_byte(cinfo, (int) (qval & 0xFF)); } qtbl->sent_table = TRUE; @@ -167,7 +180,7 @@ emit_dqt (j_compress_ptr cinfo, int index) } -LOCAL void +LOCAL(void) emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) /* Emit a DHT marker */ { @@ -205,7 +218,7 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) } -LOCAL void +LOCAL(void) emit_dac (j_compress_ptr cinfo) /* Emit a DAC marker */ /* Since the useful info is so small, we want to emit all the tables in */ @@ -248,7 +261,7 @@ emit_dac (j_compress_ptr cinfo) } -LOCAL void +LOCAL(void) emit_dri (j_compress_ptr cinfo) /* Emit a DRI marker */ { @@ -260,7 +273,7 @@ emit_dri (j_compress_ptr cinfo) } -LOCAL void +LOCAL(void) emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) /* Emit a SOF marker */ { @@ -291,7 +304,7 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) } -LOCAL void +LOCAL(void) emit_sos (j_compress_ptr cinfo) /* Emit a SOS marker */ { @@ -332,7 +345,7 @@ emit_sos (j_compress_ptr cinfo) } -LOCAL void +LOCAL(void) emit_jfif_app0 (j_compress_ptr cinfo) /* Emit a JFIF-compliant APP0 marker */ { @@ -340,7 +353,7 @@ emit_jfif_app0 (j_compress_ptr cinfo) * Length of APP0 block (2 bytes) * Block ID (4 bytes - ASCII "JFIF") * Zero byte (1 byte to terminate the ID string) - * Version Major, Minor (2 bytes - 0x01, 0x01) + * Version Major, Minor (2 bytes - major first) * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) * Xdpu (2 bytes - dots per unit horizontal) * Ydpu (2 bytes - dots per unit vertical) @@ -357,11 +370,8 @@ emit_jfif_app0 (j_compress_ptr cinfo) emit_byte(cinfo, 0x49); emit_byte(cinfo, 0x46); emit_byte(cinfo, 0); - /* We currently emit version code 1.01 since we use no 1.02 features. - * This may avoid complaints from some older decoders. - */ - emit_byte(cinfo, 1); /* Major version */ - emit_byte(cinfo, 1); /* Minor version */ + emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */ + emit_byte(cinfo, cinfo->JFIF_minor_version); emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ emit_2bytes(cinfo, (int) cinfo->X_density); emit_2bytes(cinfo, (int) cinfo->Y_density); @@ -370,7 +380,7 @@ emit_jfif_app0 (j_compress_ptr cinfo) } -LOCAL void +LOCAL(void) emit_adobe_app14 (j_compress_ptr cinfo) /* Emit an Adobe APP14 marker */ { @@ -417,28 +427,30 @@ emit_adobe_app14 (j_compress_ptr cinfo) /* - * This routine is exported for possible use by applications. - * The intended use is to emit COM or APPn markers after calling - * jpeg_start_compress() and before the first jpeg_write_scanlines() call - * (hence, after write_file_header but before write_frame_header). + * These routines allow writing an arbitrary marker with parameters. + * The only intended use is to emit COM or APPn markers after calling + * write_file_header and before calling write_frame_header. * Other uses are not guaranteed to produce desirable results. + * Counting the parameter bytes properly is the caller's responsibility. */ -METHODDEF void -write_any_marker (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen) -/* Emit an arbitrary marker with parameters */ +METHODDEF(void) +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +/* Emit an arbitrary marker header */ { - if (datalen <= (unsigned int) 65533) { /* safety check */ - emit_marker(cinfo, (JPEG_MARKER) marker); - - emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ + if (datalen > (unsigned int) 65533) /* safety check */ + ERREXIT(cinfo, JERR_BAD_LENGTH); - while (datalen--) { - emit_byte(cinfo, *dataptr); - dataptr++; - } - } + emit_marker(cinfo, (JPEG_MARKER) marker); + + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ +} + +METHODDEF(void) +write_marker_byte (j_compress_ptr cinfo, int val) +/* Emit one byte of marker parameters following write_marker_header */ +{ + emit_byte(cinfo, val); } @@ -453,11 +465,16 @@ write_any_marker (j_compress_ptr cinfo, int marker, * jpeg_start_compress returns. */ -METHODDEF void +METHODDEF(void) write_file_header (j_compress_ptr cinfo) { + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + emit_marker(cinfo, M_SOI); /* first the SOI */ + /* SOI is defined to reset restart interval to 0 */ + marker->last_restart_interval = 0; + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ emit_jfif_app0(cinfo); if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ @@ -473,7 +490,7 @@ write_file_header (j_compress_ptr cinfo) * try to error-check the quant table numbers as soon as they see the SOF. */ -METHODDEF void +METHODDEF(void) write_frame_header (j_compress_ptr cinfo) { int ci, prec; @@ -530,9 +547,10 @@ write_frame_header (j_compress_ptr cinfo) * Compressed data will be written following the SOS. */ -METHODDEF void +METHODDEF(void) write_scan_header (j_compress_ptr cinfo) { + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; int i; jpeg_component_info *compptr; @@ -565,11 +583,12 @@ write_scan_header (j_compress_ptr cinfo) } /* Emit DRI if required --- note that DRI value could change for each scan. - * If it doesn't, a tiny amount of space is wasted in multiple-scan files. - * We assume DRI will never be nonzero for one scan and zero for a later one. + * We avoid wasting space with unnecessary DRIs, however. */ - if (cinfo->restart_interval) + if (cinfo->restart_interval != marker->last_restart_interval) { emit_dri(cinfo); + marker->last_restart_interval = cinfo->restart_interval; + } emit_sos(cinfo); } @@ -579,7 +598,7 @@ write_scan_header (j_compress_ptr cinfo) * Write datastream trailer. */ -METHODDEF void +METHODDEF(void) write_file_trailer (j_compress_ptr cinfo) { emit_marker(cinfo, M_EOI); @@ -593,7 +612,7 @@ write_file_trailer (j_compress_ptr cinfo) * emitted. Note that all tables will be marked sent_table = TRUE at exit. */ -METHODDEF void +METHODDEF(void) write_tables_only (j_compress_ptr cinfo) { int i; @@ -622,18 +641,24 @@ write_tables_only (j_compress_ptr cinfo) * Initialize the marker writer module. */ -GLOBAL void +GLOBAL(void) jinit_marker_writer (j_compress_ptr cinfo) { + my_marker_ptr marker; + /* Create the subobject */ - cinfo->marker = (struct jpeg_marker_writer *) + marker = (my_marker_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(struct jpeg_marker_writer)); + SIZEOF(my_marker_writer)); + cinfo->marker = (struct jpeg_marker_writer *) marker; /* Initialize method pointers */ - cinfo->marker->write_any_marker = write_any_marker; - cinfo->marker->write_file_header = write_file_header; - cinfo->marker->write_frame_header = write_frame_header; - cinfo->marker->write_scan_header = write_scan_header; - cinfo->marker->write_file_trailer = write_file_trailer; - cinfo->marker->write_tables_only = write_tables_only; + marker->pub.write_file_header = write_file_header; + marker->pub.write_frame_header = write_frame_header; + marker->pub.write_scan_header = write_scan_header; + marker->pub.write_file_trailer = write_file_trailer; + marker->pub.write_tables_only = write_tables_only; + marker->pub.write_marker_header = write_marker_header; + marker->pub.write_marker_byte = write_marker_byte; + /* Initialize private state */ + marker->last_restart_interval = 0; } diff --git a/src/jpeg-6/jcmaster.c b/src/jpeg-6b/jcmaster.c index 84494e62..aab4020b 100644 --- a/src/jpeg-6/jcmaster.c +++ b/src/jpeg-6b/jcmaster.c @@ -1,7 +1,7 @@ /* * jcmaster.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -42,7 +42,7 @@ typedef my_comp_master * my_master_ptr; * Support routines that do various essential calculations. */ -LOCAL void +LOCAL(void) initial_setup (j_compress_ptr cinfo) /* Do computations that are needed before master selection phase */ { @@ -126,7 +126,7 @@ initial_setup (j_compress_ptr cinfo) #ifdef C_MULTISCAN_FILES_SUPPORTED -LOCAL void +LOCAL(void) validate_script (j_compress_ptr cinfo) /* Verify that the scan script in cinfo->scan_info[] is valid; also * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. @@ -185,8 +185,20 @@ validate_script (j_compress_ptr cinfo) Al = scanptr->Al; if (cinfo->progressive_mode) { #ifdef C_PROGRESSIVE_SUPPORTED + /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + * seems wrong: the upper bound ought to depend on data precision. + * Perhaps they really meant 0..N+1 for N-bit precision. + * Here we allow 0..10 for 8-bit data; Al larger than 10 results in + * out-of-range reconstructed DC values during the first DC scan, + * which might cause problems for some decoders. + */ +#if BITS_IN_JSAMPLE == 8 +#define MAX_AH_AL 10 +#else +#define MAX_AH_AL 13 +#endif if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || - Ah < 0 || Ah > 13 || Al < 0 || Al > 13) + Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL) ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); if (Ss == 0) { if (Se != 0) /* DC and AC together not OK */ @@ -251,7 +263,7 @@ validate_script (j_compress_ptr cinfo) #endif /* C_MULTISCAN_FILES_SUPPORTED */ -LOCAL void +LOCAL(void) select_scan_parameters (j_compress_ptr cinfo) /* Set up the scan parameters for the current scan */ { @@ -292,7 +304,7 @@ select_scan_parameters (j_compress_ptr cinfo) } -LOCAL void +LOCAL(void) per_scan_setup (j_compress_ptr cinfo) /* Do computations that are needed before processing a JPEG scan */ /* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ @@ -385,7 +397,7 @@ per_scan_setup (j_compress_ptr cinfo) * required. */ -METHODDEF void +METHODDEF(void) prepare_for_pass (j_compress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -473,7 +485,7 @@ prepare_for_pass (j_compress_ptr cinfo) * In multi-pass processing, this routine is not used. */ -METHODDEF void +METHODDEF(void) pass_startup (j_compress_ptr cinfo) { cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ @@ -487,7 +499,7 @@ pass_startup (j_compress_ptr cinfo) * Finish up at end of pass. */ -METHODDEF void +METHODDEF(void) finish_pass_master (j_compress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -527,7 +539,7 @@ finish_pass_master (j_compress_ptr cinfo) * Initialize master compression control. */ -GLOBAL void +GLOBAL(void) jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) { my_master_ptr master; diff --git a/src/jpeg-6/jcomapi.c b/src/jpeg-6b/jcomapi.c index c10903f0..9b1fa756 100644 --- a/src/jpeg-6/jcomapi.c +++ b/src/jpeg-6b/jcomapi.c @@ -1,7 +1,7 @@ /* * jcomapi.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -25,11 +25,15 @@ * responsibility. */ -GLOBAL void +GLOBAL(void) jpeg_abort (j_common_ptr cinfo) { int pool; + /* Do nothing if called on a not-initialized or destroyed JPEG object. */ + if (cinfo->mem == NULL) + return; + /* Releasing pools in reverse order might help avoid fragmentation * with some (brain-damaged) malloc libraries. */ @@ -38,7 +42,15 @@ jpeg_abort (j_common_ptr cinfo) } /* Reset overall state for possible reuse of object */ - cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START); + if (cinfo->is_decompressor) { + cinfo->global_state = DSTATE_START; + /* Try to keep application from accessing now-deleted marker list. + * A bit kludgy to do it here, but this is the most central place. + */ + ((j_decompress_ptr) cinfo)->marker_list = NULL; + } else { + cinfo->global_state = CSTATE_START; + } } @@ -53,7 +65,7 @@ jpeg_abort (j_common_ptr cinfo) * responsibility. */ -GLOBAL void +GLOBAL(void) jpeg_destroy (j_common_ptr cinfo) { /* We need only tell the memory manager to release everything. */ @@ -70,7 +82,7 @@ jpeg_destroy (j_common_ptr cinfo) * (Would jutils.c be a more reasonable place to put these?) */ -GLOBAL JQUANT_TBL * +GLOBAL(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo) { JQUANT_TBL *tbl; @@ -82,7 +94,7 @@ jpeg_alloc_quant_table (j_common_ptr cinfo) } -GLOBAL JHUFF_TBL * +GLOBAL(JHUFF_TBL *) jpeg_alloc_huff_table (j_common_ptr cinfo) { JHUFF_TBL *tbl; diff --git a/src/jpeg-6/jconfig.h b/src/jpeg-6b/jconfig.h index 361586ee..361586ee 100644 --- a/src/jpeg-6/jconfig.h +++ b/src/jpeg-6b/jconfig.h diff --git a/src/jpeg-6/jcparam.c b/src/jpeg-6b/jcparam.c index 29862d36..6fc48f53 100644 --- a/src/jpeg-6/jcparam.c +++ b/src/jpeg-6b/jcparam.c @@ -1,7 +1,7 @@ /* * jcparam.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -19,7 +19,7 @@ * Quantization table setup routines */ -GLOBAL void +GLOBAL(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, const unsigned int *basic_table, int scale_factor, boolean force_baseline) @@ -29,7 +29,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, * are limited to 1..255 for JPEG baseline compatibility. */ { - JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + JQUANT_TBL ** qtblptr; int i; long temp; @@ -37,6 +37,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, if (cinfo->global_state != CSTATE_START) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl); + + qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + if (*qtblptr == NULL) *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); @@ -55,7 +60,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, } -GLOBAL void +GLOBAL(void) jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, boolean force_baseline) /* Set or change the 'quality' (quantization) setting, using default tables @@ -64,31 +69,30 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, * applications that insist on a linear percentage scaling. */ { - /* This is the sample quantization table given in the JPEG spec section K.1, - * but expressed in zigzag order (as are all of our quant. tables). + /* These are the sample quantization tables given in JPEG spec section K.1. * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { - 16, 11, 12, 14, 12, 10, 16, 14, - 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, - 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, - 87, 69, 55, 56, 80, 109, 81, 87, - 95, 98, 103, 104, 103, 62, 77, 113, - 121, 112, 100, 120, 92, 101, 103, 99 - }; + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { - 17, 18, 18, 24, 21, 24, 47, 26, - 26, 47, 99, 66, 56, 66, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 - }; + }; /* Set up two quantization tables using the specified scaling */ jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, @@ -98,7 +102,7 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, } -GLOBAL int +GLOBAL(int) jpeg_quality_scaling (int quality) /* Convert a user-specified quality rating to a percentage scaling factor * for an underlying quantization table, using our recommended scaling curve. @@ -111,8 +115,8 @@ jpeg_quality_scaling (int quality) /* The basic table is used as-is (scaling 100) for a quality of 50. * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; - * note that at Q=100 the scaling is 0, which will cause j_add_quant_table - * to make all the table entries 1 (hence, no quantization loss). + * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + * to make all the table entries 1 (hence, minimum quantization loss). * Qualities 1..50 are converted to scaling percentage 5000/Q. */ if (quality < 50) @@ -124,7 +128,7 @@ jpeg_quality_scaling (int quality) } -GLOBAL void +GLOBAL(void) jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) /* Set or change the 'quality' (quantization) setting, using default tables. * This is the standard quality-adjusting entry point for typical user @@ -144,23 +148,37 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) * Huffman table setup routines */ -LOCAL void +LOCAL(void) add_huff_table (j_compress_ptr cinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) /* Define a Huffman table */ { + int nsymbols, len; + if (*htblptr == NULL) *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - + + /* Copy the number-of-symbols-of-each-code-length counts */ MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); - MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval)); + + /* Validate the counts. We do this here mainly so we can copy the right + * number of symbols from the val[] array, without risking marching off + * the end of memory. jchuff.c will do a more thorough test later. + */ + nsymbols = 0; + for (len = 1; len <= 16; len++) + nsymbols += bits[len]; + if (nsymbols < 1 || nsymbols > 256) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8)); /* Initialize sent_table FALSE so table will be written to JPEG file. */ (*htblptr)->sent_table = FALSE; } -LOCAL void +LOCAL(void) std_huff_tables (j_compress_ptr cinfo) /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* IMPORTANT: these are only valid for 8-bit data precision! */ @@ -246,7 +264,7 @@ std_huff_tables (j_compress_ptr cinfo) * your code will still work (they'll be set to reasonable defaults). */ -GLOBAL void +GLOBAL(void) jpeg_set_defaults (j_compress_ptr cinfo) { int i; @@ -314,7 +332,15 @@ jpeg_set_defaults (j_compress_ptr cinfo) /* Fill in default JFIF marker parameters. Note that whether the marker * will actually be written is determined by jpeg_set_colorspace. + * + * By default, the library emits JFIF version code 1.01. + * An application that wants to emit JFIF 1.02 extension markers should set + * JFIF_minor_version to 2. We could probably get away with just defaulting + * to 1.02, but there may still be some decoders in use that will complain + * about that; saying 1.01 should minimize compatibility problems. */ + cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ + cinfo->JFIF_minor_version = 1; cinfo->density_unit = 0; /* Pixel size is unknown by default */ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->Y_density = 1; @@ -329,7 +355,7 @@ jpeg_set_defaults (j_compress_ptr cinfo) * Select an appropriate JPEG colorspace for in_color_space. */ -GLOBAL void +GLOBAL(void) jpeg_default_colorspace (j_compress_ptr cinfo) { switch (cinfo->in_color_space) { @@ -361,7 +387,7 @@ jpeg_default_colorspace (j_compress_ptr cinfo) * Set the JPEG colorspace, and choose colorspace-dependent default values. */ -GLOBAL void +GLOBAL(void) jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) { jpeg_component_info * compptr; @@ -445,7 +471,7 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) #ifdef C_PROGRESSIVE_SUPPORTED -LOCAL jpeg_scan_info * +LOCAL(jpeg_scan_info *) fill_a_scan (jpeg_scan_info * scanptr, int ci, int Ss, int Se, int Ah, int Al) /* Support routine: generate one scan for specified component */ @@ -460,7 +486,7 @@ fill_a_scan (jpeg_scan_info * scanptr, int ci, return scanptr; } -LOCAL jpeg_scan_info * +LOCAL(jpeg_scan_info *) fill_scans (jpeg_scan_info * scanptr, int ncomps, int Ss, int Se, int Ah, int Al) /* Support routine: generate one scan for each component */ @@ -479,7 +505,7 @@ fill_scans (jpeg_scan_info * scanptr, int ncomps, return scanptr; } -LOCAL jpeg_scan_info * +LOCAL(jpeg_scan_info *) fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) /* Support routine: generate interleaved DC scan if possible, else N scans */ { @@ -507,7 +533,7 @@ fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) * cinfo->num_components and cinfo->jpeg_color_space must be correct. */ -GLOBAL void +GLOBAL(void) jpeg_simple_progression (j_compress_ptr cinfo) { int ncomps = cinfo->num_components; @@ -530,11 +556,20 @@ jpeg_simple_progression (j_compress_ptr cinfo) nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ } - /* Allocate space for script. */ - /* We use permanent pool just in case application re-uses script. */ - scanptr = (jpeg_scan_info *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - nscans * SIZEOF(jpeg_scan_info)); + /* Allocate space for script. + * We need to put it in the permanent pool in case the application performs + * multiple compressions without changing the settings. To avoid a memory + * leak if jpeg_simple_progression is called repeatedly for the same JPEG + * object, we try to re-use previously allocated space, and we allocate + * enough space to handle YCbCr even if initially asked for grayscale. + */ + if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) { + cinfo->script_space_size = MAX(nscans, 10); + cinfo->script_space = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + } + scanptr = cinfo->script_space; cinfo->scan_info = scanptr; cinfo->num_scans = nscans; diff --git a/src/jpeg-6/jcphuff.c b/src/jpeg-6b/jcphuff.c index 922c17c6..07f9178b 100644 --- a/src/jpeg-6/jcphuff.c +++ b/src/jpeg-6b/jcphuff.c @@ -1,7 +1,7 @@ /* * jcphuff.c * - * Copyright (C) 1995, Thomas G. Lane. + * Copyright (C) 1995-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -86,23 +86,23 @@ typedef phuff_entropy_encoder * phuff_entropy_ptr; #endif /* Forward declarations */ -METHODDEF boolean encode_mcu_DC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_AC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_DC_refine JPP((j_compress_ptr cinfo, +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo, JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_AC_refine JPP((j_compress_ptr cinfo, +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo, JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_phuff JPP((j_compress_ptr cinfo)); -METHODDEF void finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo)); +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); /* * Initialize for a Huffman-compressed scan using progressive JPEG. */ -METHODDEF void +METHODDEF(void) start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -147,22 +147,19 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) compptr = cinfo->cur_comp_info[ci]; /* Initialize DC predictions to 0 */ entropy->last_dc_val[ci] = 0; - /* Make sure requested tables are present */ - /* (In gather mode, tables need not be allocated yet) */ + /* Get table index */ if (is_DC_band) { if (cinfo->Ah != 0) /* DC refinement needs no table */ continue; tbl = compptr->dc_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - (cinfo->dc_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); } else { entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - (cinfo->ac_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); } if (gather_statistics) { + /* Check for invalid table index */ + /* (make_c_derived_tbl does this in the other path) */ + if (tbl < 0 || tbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); /* Allocate and zero the statistics tables */ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ if (entropy->count_ptrs[tbl] == NULL) @@ -171,14 +168,10 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) 257 * SIZEOF(long)); MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); } else { - /* Compute derived values for Huffman tables */ + /* Compute derived values for Huffman table */ /* We may do this more than once for a table, but it's not expensive */ - if (is_DC_band) - jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); - else - jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + & entropy->derived_tbls[tbl]); } } @@ -208,7 +201,7 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) dump_buffer(entropy); } -LOCAL void +LOCAL(void) dump_buffer (phuff_entropy_ptr entropy) /* Empty the output buffer; we do not support suspension in this module. */ { @@ -231,7 +224,7 @@ dump_buffer (phuff_entropy_ptr entropy) */ INLINE -LOCAL void +LOCAL(void) emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) /* Emit some bits, unless we are in gather mode */ { @@ -270,7 +263,7 @@ emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) } -LOCAL void +LOCAL(void) flush_bits (phuff_entropy_ptr entropy) { emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ @@ -284,7 +277,7 @@ flush_bits (phuff_entropy_ptr entropy) */ INLINE -LOCAL void +LOCAL(void) emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) { if (entropy->gather_statistics) @@ -300,7 +293,7 @@ emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) * Emit bits from a correction bit buffer. */ -LOCAL void +LOCAL(void) emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, unsigned int nbits) { @@ -319,7 +312,7 @@ emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, * Emit any pending EOBRUN symbol. */ -LOCAL void +LOCAL(void) emit_eobrun (phuff_entropy_ptr entropy) { register int temp, nbits; @@ -329,6 +322,9 @@ emit_eobrun (phuff_entropy_ptr entropy) nbits = 0; while ((temp >>= 1)) nbits++; + /* safety check: shouldn't happen given limited correction-bit buffer */ + if (nbits > 14) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); if (nbits) @@ -347,7 +343,7 @@ emit_eobrun (phuff_entropy_ptr entropy) * Emit a restart marker & resynchronize predictions. */ -LOCAL void +LOCAL(void) emit_restart (phuff_entropy_ptr entropy, int restart_num) { int ci; @@ -377,7 +373,7 @@ emit_restart (phuff_entropy_ptr entropy, int restart_num) * or first pass of successive approximation). */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -427,6 +423,11 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) nbits++; temp >>= 1; } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit the Huffman-coded symbol for the number of bits */ emit_symbol(entropy, compptr->dc_tbl_no, nbits); @@ -459,7 +460,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * or first pass of successive approximation). */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -523,6 +524,9 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1)) nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit Huffman symbol for run length / number of bits */ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); @@ -563,7 +567,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * is not very clear on the point. */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -610,7 +614,7 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * MCU encoding for AC successive approximation refinement scan. */ -METHODDEF boolean +METHODDEF(boolean) encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -738,7 +742,7 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * Finish up at the end of a Huffman-compressed progressive scan. */ -METHODDEF void +METHODDEF(void) finish_pass_phuff (j_compress_ptr cinfo) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -759,7 +763,7 @@ finish_pass_phuff (j_compress_ptr cinfo) * Finish up a statistics-gathering pass and create the new Huffman tables. */ -METHODDEF void +METHODDEF(void) finish_pass_gather_phuff (j_compress_ptr cinfo) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -806,7 +810,7 @@ finish_pass_gather_phuff (j_compress_ptr cinfo) * Module initialization routine for progressive Huffman entropy encoding. */ -GLOBAL void +GLOBAL(void) jinit_phuff_encoder (j_compress_ptr cinfo) { phuff_entropy_ptr entropy; diff --git a/src/jpeg-6/jcprepct.c b/src/jpeg-6b/jcprepct.c index 7e609462..fa93333d 100644 --- a/src/jpeg-6/jcprepct.c +++ b/src/jpeg-6b/jcprepct.c @@ -1,7 +1,7 @@ /* * jcprepct.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -74,7 +74,7 @@ typedef my_prep_controller * my_prep_ptr; * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; @@ -102,7 +102,7 @@ start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) * by duplicating the bottom row. */ -LOCAL void +LOCAL(void) expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows, int output_rows) { @@ -124,7 +124,7 @@ expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, * input rows. */ -METHODDEF void +METHODDEF(void) pre_process_data (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail, @@ -191,7 +191,7 @@ pre_process_data (j_compress_ptr cinfo, * Process some data in the context case. */ -METHODDEF void +METHODDEF(void) pre_process_context (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail, @@ -202,7 +202,6 @@ pre_process_context (j_compress_ptr cinfo, int numrows, ci; int buf_height = cinfo->max_v_samp_factor * 3; JDIMENSION inrows; - jpeg_component_info * compptr; while (*out_row_group_ctr < out_row_groups_avail) { if (*in_row_ctr < in_rows_avail) { @@ -232,15 +231,14 @@ pre_process_context (j_compress_ptr cinfo, /* Return for more data, unless we are at the bottom of the image. */ if (prep->rows_to_go != 0) break; - } - /* If at bottom of image, pad to fill the conversion buffer. */ - if (prep->rows_to_go == 0 && - prep->next_buf_row < prep->next_buf_stop) { - for (ci = 0; ci < cinfo->num_components; ci++) { - expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, - prep->next_buf_row, prep->next_buf_stop); + /* When at bottom of image, pad to fill the conversion buffer. */ + if (prep->next_buf_row < prep->next_buf_stop) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; } - prep->next_buf_row = prep->next_buf_stop; } /* If we've gotten enough data, downsample a row group. */ if (prep->next_buf_row == prep->next_buf_stop) { @@ -257,21 +255,6 @@ pre_process_context (j_compress_ptr cinfo, prep->next_buf_row = 0; prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; } - /* If at bottom of image, pad the output to a full iMCU height. - * Note we assume the caller is providing a one-iMCU-height output buffer! - */ - if (prep->rows_to_go == 0 && - *out_row_group_ctr < out_row_groups_avail) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - expand_bottom_edge(output_buf[ci], - compptr->width_in_blocks * DCTSIZE, - (int) (*out_row_group_ctr * compptr->v_samp_factor), - (int) (out_row_groups_avail * compptr->v_samp_factor)); - } - *out_row_group_ctr = out_row_groups_avail; - break; /* can exit outer loop without test */ - } } } @@ -280,7 +263,7 @@ pre_process_context (j_compress_ptr cinfo, * Create the wrapped-around downsampling input buffer needed for context mode. */ -LOCAL void +LOCAL(void) create_context_buffer (j_compress_ptr cinfo) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; @@ -328,7 +311,7 @@ create_context_buffer (j_compress_ptr cinfo) * Initialize preprocessing controller. */ -GLOBAL void +GLOBAL(void) jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) { my_prep_ptr prep; diff --git a/src/jpeg-6/jcsample.c b/src/jpeg-6b/jcsample.c index bf0fb46b..212ec875 100644 --- a/src/jpeg-6/jcsample.c +++ b/src/jpeg-6b/jcsample.c @@ -1,7 +1,7 @@ /* * jcsample.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -71,7 +71,7 @@ typedef my_downsampler * my_downsample_ptr; * Initialize for a downsampling pass. */ -METHODDEF void +METHODDEF(void) start_pass_downsample (j_compress_ptr cinfo) { /* no work for now */ @@ -83,7 +83,7 @@ start_pass_downsample (j_compress_ptr cinfo) * by duplicating the rightmost samples. */ -LOCAL void +LOCAL(void) expand_right_edge (JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols, JDIMENSION output_cols) { @@ -110,7 +110,7 @@ expand_right_edge (JSAMPARRAY image_data, int num_rows, * In this version we simply downsample each component independently. */ -METHODDEF void +METHODDEF(void) sep_downsample (j_compress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_index, JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) @@ -136,7 +136,7 @@ sep_downsample (j_compress_ptr cinfo, * Note that this version is not actually used for customary sampling ratios. */ -METHODDEF void +METHODDEF(void) int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -183,7 +183,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, * without smoothing. */ -METHODDEF void +METHODDEF(void) fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -208,7 +208,7 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, * alternate pixel locations (a simple ordered dither pattern). */ -METHODDEF void +METHODDEF(void) h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -245,7 +245,7 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, * without smoothing. */ -METHODDEF void +METHODDEF(void) h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -288,7 +288,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, * with smoothing. One row of context is required. */ -METHODDEF void +METHODDEF(void) h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -388,7 +388,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, * with smoothing. One row of context is required. */ -METHODDEF void +METHODDEF(void) fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, JSAMPARRAY input_data, JSAMPARRAY output_data) { @@ -460,7 +460,7 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, * Note that we must select a routine for each component. */ -GLOBAL void +GLOBAL(void) jinit_downsampler (j_compress_ptr cinfo) { my_downsample_ptr downsample; diff --git a/src/jpeg-6/jctrans.c b/src/jpeg-6b/jctrans.c index 8fc53b19..0e6d7076 100644 --- a/src/jpeg-6/jctrans.c +++ b/src/jpeg-6b/jctrans.c @@ -1,7 +1,7 @@ /* * jctrans.c * - * Copyright (C) 1995, Thomas G. Lane. + * Copyright (C) 1995-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -16,9 +16,9 @@ /* Forward declarations */ -LOCAL void transencode_master_selection +LOCAL(void) transencode_master_selection JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); -LOCAL void transencode_coef_controller +LOCAL(void) transencode_coef_controller JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); @@ -34,7 +34,7 @@ LOCAL void transencode_coef_controller * typically will be realized during this routine and filled afterwards. */ -GLOBAL void +GLOBAL(void) jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { if (cinfo->global_state != CSTATE_START) @@ -59,7 +59,7 @@ jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) * scan script and Huffman optimization) are left in their default states. */ -GLOBAL void +GLOBAL(void) jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, j_compress_ptr dstinfo) { @@ -129,6 +129,23 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, * instead we rely on jpeg_set_colorspace to have made a suitable choice. */ } + /* Also copy JFIF version and resolution information, if available. + * Strictly speaking this isn't "critical" info, but it's nearly + * always appropriate to copy it if available. In particular, + * if the application chooses to copy JFIF 1.02 extension markers from + * the source file, we need to copy the version to make sure we don't + * emit a file that has 1.02 extensions but a claimed version of 1.01. + * We will *not*, however, copy version info from mislabeled "2.01" files. + */ + if (srcinfo->saw_JFIF_marker) { + if (srcinfo->JFIF_major_version == 1) { + dstinfo->JFIF_major_version = srcinfo->JFIF_major_version; + dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version; + } + dstinfo->density_unit = srcinfo->density_unit; + dstinfo->X_density = srcinfo->X_density; + dstinfo->Y_density = srcinfo->Y_density; + } } @@ -137,7 +154,7 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, * This substitutes for jcinit.c's initialization of the full compressor. */ -LOCAL void +LOCAL(void) transencode_master_selection (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { @@ -170,7 +187,7 @@ transencode_master_selection (j_compress_ptr cinfo, /* We can now tell the memory manager to allocate virtual arrays. */ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - /* Write the datastream header (SOI) immediately. + /* Write the datastream header (SOI, JFIF) immediately. * Frame and scan headers are postponed till later. * This lets application insert special markers after the SOI. */ @@ -206,7 +223,7 @@ typedef struct { typedef my_coef_controller * my_coef_ptr; -LOCAL void +LOCAL(void) start_iMCU_row (j_compress_ptr cinfo) /* Reset within-iMCU-row counters for a new row */ { @@ -234,7 +251,7 @@ start_iMCU_row (j_compress_ptr cinfo) * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -257,7 +274,7 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) * NB: input_buf is ignored; it is likely to be a NULL pointer. */ -METHODDEF boolean +METHODDEF(boolean) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -342,7 +359,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * with unitheight at least v_samp_factor. */ -LOCAL void +LOCAL(void) transencode_coef_controller (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { diff --git a/src/jpeg-6/jdapimin.c b/src/jpeg-6b/jdapimin.c index d5681876..cadb59fc 100644 --- a/src/jpeg-6/jdapimin.c +++ b/src/jpeg-6b/jdapimin.c @@ -1,7 +1,7 @@ /* * jdapimin.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,18 +26,31 @@ * The error manager must already be set up (in case memory manager fails). */ -GLOBAL void -jpeg_create_decompress (j_decompress_ptr cinfo) +GLOBAL(void) +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) { int i; - /* For debugging purposes, zero the whole master structure. - * But error manager pointer is already there, so save and restore it. + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_decompress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. */ { struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); cinfo->err = err; + cinfo->client_data = client_data; } cinfo->is_decompressor = TRUE; @@ -59,6 +72,7 @@ jpeg_create_decompress (j_decompress_ptr cinfo) /* Initialize marker processor so application can override methods * for COM, APPn markers before calling jpeg_read_header. */ + cinfo->marker_list = NULL; jinit_marker_reader(cinfo); /* And initialize the overall input controller. */ @@ -73,7 +87,7 @@ jpeg_create_decompress (j_decompress_ptr cinfo) * Destruction of a JPEG decompression object */ -GLOBAL void +GLOBAL(void) jpeg_destroy_decompress (j_decompress_ptr cinfo) { jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ @@ -85,7 +99,7 @@ jpeg_destroy_decompress (j_decompress_ptr cinfo) * but don't destroy the object itself. */ -GLOBAL void +GLOBAL(void) jpeg_abort_decompress (j_decompress_ptr cinfo) { jpeg_abort((j_common_ptr) cinfo); /* use common routine */ @@ -93,27 +107,10 @@ jpeg_abort_decompress (j_decompress_ptr cinfo) /* - * Install a special processing method for COM or APPn markers. - */ - -GLOBAL void -jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine) -{ - if (marker_code == JPEG_COM) - cinfo->marker->process_COM = routine; - else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15) - cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine; - else - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); -} - - -/* * Set default decompression parameters. */ -LOCAL void +LOCAL(void) default_decompress_parms (j_decompress_ptr cinfo) { /* Guess the input colorspace, and set output colorspace accordingly. */ @@ -240,7 +237,7 @@ default_decompress_parms (j_decompress_ptr cinfo) * extra error checking. */ -GLOBAL int +GLOBAL(int) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) { int retcode; @@ -286,7 +283,7 @@ jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) * method. */ -GLOBAL int +GLOBAL(int) jpeg_consume_input (j_decompress_ptr cinfo) { int retcode = JPEG_SUSPENDED; @@ -333,7 +330,7 @@ jpeg_consume_input (j_decompress_ptr cinfo) * Have we finished reading the input file? */ -GLOBAL boolean +GLOBAL(boolean) jpeg_input_complete (j_decompress_ptr cinfo) { /* Check for valid jpeg object */ @@ -348,7 +345,7 @@ jpeg_input_complete (j_decompress_ptr cinfo) * Is there more than one scan? */ -GLOBAL boolean +GLOBAL(boolean) jpeg_has_multiple_scans (j_decompress_ptr cinfo) { /* Only valid after jpeg_read_header completes */ @@ -368,7 +365,7 @@ jpeg_has_multiple_scans (j_decompress_ptr cinfo) * a suspending data source is used. */ -GLOBAL boolean +GLOBAL(boolean) jpeg_finish_decompress (j_decompress_ptr cinfo) { if ((cinfo->global_state == DSTATE_SCANNING || diff --git a/src/jpeg-6/jdapistd.c b/src/jpeg-6b/jdapistd.c index e36f25c2..c8e3fa0c 100644 --- a/src/jpeg-6/jdapistd.c +++ b/src/jpeg-6b/jdapistd.c @@ -1,7 +1,7 @@ /* * jdapistd.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -20,7 +20,7 @@ /* Forward declarations */ -LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); /* @@ -34,7 +34,7 @@ LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); * a suspending data source is used. */ -GLOBAL boolean +GLOBAL(boolean) jpeg_start_decompress (j_decompress_ptr cinfo) { if (cinfo->global_state == DSTATE_READY) { @@ -91,7 +91,7 @@ jpeg_start_decompress (j_decompress_ptr cinfo) * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. */ -LOCAL boolean +LOCAL(boolean) output_pass_setup (j_decompress_ptr cinfo) { if (cinfo->global_state != DSTATE_PRESCAN) { @@ -148,7 +148,7 @@ output_pass_setup (j_decompress_ptr cinfo) * an oversize buffer (max_lines > scanlines remaining) is not an error. */ -GLOBAL JDIMENSION +GLOBAL(JDIMENSION) jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION max_lines) { @@ -181,7 +181,7 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, * Processes exactly one iMCU row per call, unless suspended. */ -GLOBAL JDIMENSION +GLOBAL(JDIMENSION) jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, JDIMENSION max_lines) { @@ -224,7 +224,7 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, * Initialize for an output pass in buffered-image mode. */ -GLOBAL boolean +GLOBAL(boolean) jpeg_start_output (j_decompress_ptr cinfo, int scan_number) { if (cinfo->global_state != DSTATE_BUFIMAGE && @@ -249,7 +249,7 @@ jpeg_start_output (j_decompress_ptr cinfo, int scan_number) * a suspending data source is used. */ -GLOBAL boolean +GLOBAL(boolean) jpeg_finish_output (j_decompress_ptr cinfo) { if ((cinfo->global_state == DSTATE_SCANNING || diff --git a/src/jpeg-6/jdatadst.c b/src/jpeg-6b/jdatadst.c index 08c4dafd..a8f6fb0e 100644 --- a/src/jpeg-6/jdatadst.c +++ b/src/jpeg-6b/jdatadst.c @@ -1,7 +1,7 @@ /* * jdatadst.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -39,7 +39,7 @@ typedef my_destination_mgr * my_dest_ptr; * before any data is actually written. */ -METHODDEF void +METHODDEF(void) init_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; @@ -77,7 +77,7 @@ init_destination (j_compress_ptr cinfo) * write it out when emptying the buffer externally. */ -METHODDEF boolean +METHODDEF(boolean) empty_output_buffer (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; @@ -102,7 +102,7 @@ empty_output_buffer (j_compress_ptr cinfo) * for error exit. */ -METHODDEF void +METHODDEF(void) term_destination (j_compress_ptr cinfo) { my_dest_ptr dest = (my_dest_ptr) cinfo->dest; @@ -126,7 +126,7 @@ term_destination (j_compress_ptr cinfo) * for closing it after finishing compression. */ -GLOBAL void +GLOBAL(void) jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) { my_dest_ptr dest; diff --git a/src/jpeg-6/jdatasrc.c b/src/jpeg-6b/jdatasrc.c index b19d8854..795f65ed 100644 --- a/src/jpeg-6/jdatasrc.c +++ b/src/jpeg-6b/jdatasrc.c @@ -1,7 +1,7 @@ /* * jdatasrc.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -14,7 +14,6 @@ * than 8 bits on your machine, you may need to do some tweaking. */ - /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ #include "jinclude.h" #include "jpeglib.h" @@ -24,7 +23,6 @@ #define MIN(a, b) ((a)<(b)?(a):(b)) #endif - /* Expanded data source object for stdio input */ typedef struct { @@ -46,7 +44,7 @@ typedef my_source_mgr * my_src_ptr; * before any data is actually read. */ -METHODDEF void +METHODDEF(void) init_source (j_decompress_ptr cinfo) { my_src_ptr src = (my_src_ptr) cinfo->src; @@ -92,22 +90,19 @@ init_source (j_decompress_ptr cinfo) * the front of the buffer rather than discarding it. */ -METHODDEF boolean +METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { my_src_ptr src = (my_src_ptr) cinfo->src; size_t nbytes = MIN(src->inbufbytes, INPUT_BUF_SIZE); - if(!nbytes) - { + if (nbytes <= 0) { WARNMS(cinfo, JWRN_JPEG_EOF); /* Insert a fake EOI marker */ src->buffer[0] = (JOCTET) 0xFF; src->buffer[1] = (JOCTET) JPEG_EOI; nbytes = 2; - } - else - { + } else { memcpy( src->buffer, src->inbuf, nbytes); src->inbuf += nbytes; @@ -134,7 +129,7 @@ fill_input_buffer (j_decompress_ptr cinfo) * buffer is the application writer's problem. */ -METHODDEF void +METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) { my_src_ptr src = (my_src_ptr) cinfo->src; @@ -175,7 +170,7 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes) * for error exit. */ -METHODDEF void +METHODDEF(void) term_source (j_decompress_ptr cinfo) { /* no work necessary here */ @@ -188,7 +183,7 @@ term_source (j_decompress_ptr cinfo) * for closing it after finishing decompression. */ -GLOBAL void +GLOBAL(void) jpeg_mem_src (j_decompress_ptr cinfo, unsigned char *inbuf, size_t size) { my_src_ptr src; diff --git a/src/jpeg-6/jdcoefct.c b/src/jpeg-6b/jdcoefct.c index ba153f5b..4938d20f 100644 --- a/src/jpeg-6/jdcoefct.c +++ b/src/jpeg-6b/jdcoefct.c @@ -1,7 +1,7 @@ /* * jdcoefct.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -62,20 +62,20 @@ typedef struct { typedef my_coef_controller * my_coef_ptr; /* Forward declarations */ -METHODDEF int decompress_onepass +METHODDEF(int) decompress_onepass JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); #ifdef D_MULTISCAN_FILES_SUPPORTED -METHODDEF int decompress_data +METHODDEF(int) decompress_data JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); #endif #ifdef BLOCK_SMOOTHING_SUPPORTED -LOCAL boolean smoothing_ok JPP((j_decompress_ptr cinfo)); -METHODDEF int decompress_smooth_data +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo)); +METHODDEF(int) decompress_smooth_data JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); #endif -LOCAL void +LOCAL(void) start_iMCU_row (j_decompress_ptr cinfo) /* Reset within-iMCU-row counters for a new row (input side) */ { @@ -103,7 +103,7 @@ start_iMCU_row (j_decompress_ptr cinfo) * Initialize for an input processing pass. */ -METHODDEF void +METHODDEF(void) start_input_pass (j_decompress_ptr cinfo) { cinfo->input_iMCU_row = 0; @@ -115,7 +115,7 @@ start_input_pass (j_decompress_ptr cinfo) * Initialize for an output processing pass. */ -METHODDEF void +METHODDEF(void) start_output_pass (j_decompress_ptr cinfo) { #ifdef BLOCK_SMOOTHING_SUPPORTED @@ -139,11 +139,11 @@ start_output_pass (j_decompress_ptr cinfo) * Input and output must run in lockstep since we have only a one-MCU buffer. * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. * - * NB: output_buf contains a plane for each component in image. - * For single pass, this is the same as the components in the scan. + * NB: output_buf contains a plane for each component in image, + * which we index according to the component's SOF position. */ -METHODDEF int +METHODDEF(int) decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -186,7 +186,8 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width : compptr->last_col_width; - output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size; + output_ptr = output_buf[compptr->component_index] + + yoffset * compptr->DCT_scaled_size; start_col = MCU_col_num * compptr->MCU_sample_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (cinfo->input_iMCU_row < last_iMCU_row || @@ -223,7 +224,7 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) * Dummy consume-input routine for single-pass operation. */ -METHODDEF int +METHODDEF(int) dummy_consume_data (j_decompress_ptr cinfo) { return JPEG_SUSPENDED; /* Always indicate nothing was done */ @@ -239,7 +240,7 @@ dummy_consume_data (j_decompress_ptr cinfo) * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. */ -METHODDEF int +METHODDEF(int) consume_data (j_decompress_ptr cinfo) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -310,7 +311,7 @@ consume_data (j_decompress_ptr cinfo) * NB: output_buf contains a plane for each component in image. */ -METHODDEF int +METHODDEF(int) decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -385,6 +386,13 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) * the coefficients it can estimate are not yet known to full precision. */ +/* Natural-order array positions of the first 5 zigzag-order coefficients */ +#define Q01_POS 1 +#define Q10_POS 8 +#define Q20_POS 16 +#define Q11_POS 9 +#define Q02_POS 2 + /* * Determine whether block smoothing is applicable and safe. * We also latch the current states of the coef_bits[] entries for the @@ -393,7 +401,7 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) * more accurately than they really are. */ -LOCAL boolean +LOCAL(boolean) smoothing_ok (j_decompress_ptr cinfo) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -421,10 +429,13 @@ smoothing_ok (j_decompress_ptr cinfo) if ((qtable = compptr->quant_table) == NULL) return FALSE; /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ - for (coefi = 0; coefi <= 5; coefi++) { - if (qtable->quantval[coefi] == 0) - return FALSE; - } + if (qtable->quantval[0] == 0 || + qtable->quantval[Q01_POS] == 0 || + qtable->quantval[Q10_POS] == 0 || + qtable->quantval[Q20_POS] == 0 || + qtable->quantval[Q11_POS] == 0 || + qtable->quantval[Q02_POS] == 0) + return FALSE; /* DC values must be at least partly known for all components. */ coef_bits = cinfo->coef_bits[ci]; if (coef_bits[0] < 0) @@ -446,7 +457,7 @@ smoothing_ok (j_decompress_ptr cinfo) * Variant of decompress_data for use when doing block smoothing. */ -METHODDEF int +METHODDEF(int) decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { my_coef_ptr coef = (my_coef_ptr) cinfo->coef; @@ -521,11 +532,11 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); quanttbl = compptr->quant_table; Q00 = quanttbl->quantval[0]; - Q01 = quanttbl->quantval[1]; - Q10 = quanttbl->quantval[2]; - Q20 = quanttbl->quantval[3]; - Q11 = quanttbl->quantval[4]; - Q02 = quanttbl->quantval[5]; + Q01 = quanttbl->quantval[Q01_POS]; + Q10 = quanttbl->quantval[Q10_POS]; + Q20 = quanttbl->quantval[Q20_POS]; + Q11 = quanttbl->quantval[Q11_POS]; + Q02 = quanttbl->quantval[Q02_POS]; inverse_DCT = cinfo->idct->inverse_DCT[ci]; output_ptr = output_buf[ci]; /* Loop over all DCT blocks to be processed. */ @@ -661,7 +672,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) * Initialize coefficient buffer controller. */ -GLOBAL void +GLOBAL(void) jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { my_coef_ptr coef; diff --git a/src/jpeg-6/jdcolor.c b/src/jpeg-6b/jdcolor.c index b2bdf6ee..6c04dfe8 100644 --- a/src/jpeg-6/jdcolor.c +++ b/src/jpeg-6b/jdcolor.c @@ -1,7 +1,7 @@ /* * jdcolor.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -66,7 +66,7 @@ typedef my_color_deconverter * my_cconvert_ptr; * Initialize tables for YCC->RGB colorspace conversion. */ -LOCAL void +LOCAL(void) build_ycc_rgb_table (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; @@ -116,7 +116,7 @@ build_ycc_rgb_table (j_decompress_ptr cinfo) * offset required on that side. */ -METHODDEF void +METHODDEF(void) ycc_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) @@ -165,7 +165,7 @@ ycc_rgb_convert (j_decompress_ptr cinfo, * converting from separate-planes to interleaved representation. */ -METHODDEF void +METHODDEF(void) null_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) @@ -197,7 +197,7 @@ null_convert (j_decompress_ptr cinfo, * we just copy the Y (luminance) component and ignore chrominance. */ -METHODDEF void +METHODDEF(void) grayscale_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) @@ -208,13 +208,40 @@ grayscale_convert (j_decompress_ptr cinfo, /* + * Convert grayscale to RGB: just duplicate the graylevel three times. + * This is provided to support applications that don't want to cope + * with grayscale as a separate case. + */ + +METHODDEF(void) +gray_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr = input_buf[0][input_row++]; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/* * Adobe-style YCCK->CMYK conversion. * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same * conversion as above, while passing K (black) unchanged. * We assume build_ycc_rgb_table has been called. */ -METHODDEF void +METHODDEF(void) ycck_cmyk_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) @@ -262,7 +289,7 @@ ycck_cmyk_convert (j_decompress_ptr cinfo, * Empty method for start_pass. */ -METHODDEF void +METHODDEF(void) start_pass_dcolor (j_decompress_ptr cinfo) { /* no work needed */ @@ -273,7 +300,7 @@ start_pass_dcolor (j_decompress_ptr cinfo) * Module initialization routine for output colorspace conversion. */ -GLOBAL void +GLOBAL(void) jinit_color_deconverter (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert; @@ -333,6 +360,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo) if (cinfo->jpeg_color_space == JCS_YCbCr) { cconvert->pub.color_convert = ycc_rgb_convert; build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { + cconvert->pub.color_convert = gray_rgb_convert; } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { cconvert->pub.color_convert = null_convert; } else diff --git a/src/jpeg-6/jdct.h b/src/jpeg-6b/jdct.h index 3ce790bc..04192a26 100644 --- a/src/jpeg-6/jdct.h +++ b/src/jpeg-6b/jdct.h @@ -1,7 +1,7 @@ /* * jdct.h * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -94,26 +94,26 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ /* Extern declarations for the forward and inverse DCT routines. */ -EXTERN void jpeg_fdct_islow JPP((DCTELEM * data)); -EXTERN void jpeg_fdct_ifast JPP((DCTELEM * data)); -EXTERN void jpeg_fdct_float JPP((FAST_FLOAT * data)); +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); -EXTERN void jpeg_idct_islow +EXTERN(void) jpeg_idct_islow JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_ifast +EXTERN(void) jpeg_idct_ifast JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_float +EXTERN(void) jpeg_idct_float JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_4x4 +EXTERN(void) jpeg_idct_4x4 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_2x2 +EXTERN(void) jpeg_idct_2x2 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_1x1 +EXTERN(void) jpeg_idct_1x1 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); diff --git a/src/jpeg-6/jddctmgr.c b/src/jpeg-6b/jddctmgr.c index 71215f19..bbf8d0e9 100644 --- a/src/jpeg-6/jddctmgr.c +++ b/src/jpeg-6b/jddctmgr.c @@ -1,7 +1,7 @@ /* * jddctmgr.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -85,7 +85,7 @@ typedef union { * a matching multiplier table. */ -METHODDEF void +METHODDEF(void) start_pass (j_decompress_ptr cinfo) { my_idct_ptr idct = (my_idct_ptr) cinfo->idct; @@ -161,11 +161,11 @@ start_pass (j_decompress_ptr cinfo) case JDCT_ISLOW: { /* For LL&M IDCT method, multipliers are equal to raw quantization - * coefficients, but are stored in natural order as ints. + * coefficients, but are stored as ints to ensure access efficiency. */ ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; for (i = 0; i < DCTSIZE2; i++) { - ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]]; + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; } } break; @@ -178,7 +178,7 @@ start_pass (j_decompress_ptr cinfo) * scalefactor[0] = 1 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 * For integer operation, the multiplier table is to be scaled by - * IFAST_SCALE_BITS. The multipliers are stored in natural order. + * IFAST_SCALE_BITS. */ IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; #define CONST_BITS 14 @@ -197,7 +197,7 @@ start_pass (j_decompress_ptr cinfo) for (i = 0; i < DCTSIZE2; i++) { ifmtbl[i] = (IFAST_MULT_TYPE) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], (INT32) aanscales[i]), CONST_BITS-IFAST_SCALE_BITS); } @@ -211,7 +211,6 @@ start_pass (j_decompress_ptr cinfo) * coefficients scaled by scalefactor[row]*scalefactor[col], where * scalefactor[0] = 1 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * The multipliers are stored in natural order. */ FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; int row, col; @@ -224,7 +223,7 @@ start_pass (j_decompress_ptr cinfo) for (row = 0; row < DCTSIZE; row++) { for (col = 0; col < DCTSIZE; col++) { fmtbl[i] = (FLOAT_MULT_TYPE) - ((double) qtbl->quantval[jpeg_zigzag_order[i]] * + ((double) qtbl->quantval[i] * aanscalefactor[row] * aanscalefactor[col]); i++; } @@ -244,7 +243,7 @@ start_pass (j_decompress_ptr cinfo) * Initialize IDCT manager. */ -GLOBAL void +GLOBAL(void) jinit_inverse_dct (j_decompress_ptr cinfo) { my_idct_ptr idct; diff --git a/src/jpeg-6/jdhuff.c b/src/jpeg-6b/jdhuff.c index 95174b17..b5ba39f7 100644 --- a/src/jpeg-6/jdhuff.c +++ b/src/jpeg-6b/jdhuff.c @@ -1,7 +1,7 @@ /* * jdhuff.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -64,6 +64,15 @@ typedef struct { /* Pointers to derived tables (these workspaces have image lifespan) */ d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcu: */ + + /* Pointers to derived tables to be used for each block within an MCU */ + d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + /* Whether we care about the DC and AC coefficient values for each block */ + boolean dc_needed[D_MAX_BLOCKS_IN_MCU]; + boolean ac_needed[D_MAX_BLOCKS_IN_MCU]; } huff_entropy_decoder; typedef huff_entropy_decoder * huff_entropy_ptr; @@ -73,11 +82,11 @@ typedef huff_entropy_decoder * huff_entropy_ptr; * Initialize for a Huffman-compressed scan. */ -METHODDEF void +METHODDEF(void) start_pass_huff_decoder (j_decompress_ptr cinfo) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; + int ci, blkn, dctbl, actbl; jpeg_component_info * compptr; /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. @@ -92,27 +101,37 @@ start_pass_huff_decoder (j_decompress_ptr cinfo) compptr = cinfo->cur_comp_info[ci]; dctbl = compptr->dc_tbl_no; actbl = compptr->ac_tbl_no; - /* Make sure requested tables are present */ - if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || - cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); - if (actbl < 0 || actbl >= NUM_HUFF_TBLS || - cinfo->ac_huff_tbl_ptrs[actbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); /* Compute derived values for Huffman tables */ /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, & entropy->dc_derived_tbls[dctbl]); - jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, & entropy->ac_derived_tbls[actbl]); /* Initialize DC predictions to 0 */ entropy->saved.last_dc_val[ci] = 0; } + /* Precalculate decoding info for each block in an MCU of this scan */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + /* Precalculate which table to use for each block */ + entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Decide whether we really care about the coefficient values */ + if (compptr->component_needed) { + entropy->dc_needed[blkn] = TRUE; + /* we don't need the ACs if producing a 1/8th-size image */ + entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1); + } else { + entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; + } + } + /* Initialize bitread state variables */ entropy->bitstate.bits_left = 0; entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->bitstate.printed_eod = FALSE; + entropy->pub.insufficient_data = FALSE; /* Initialize restart counter */ entropy->restarts_to_go = cinfo->restart_interval; @@ -121,20 +140,35 @@ start_pass_huff_decoder (j_decompress_ptr cinfo) /* * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * * Note this is also used by jdphuff.c. */ -GLOBAL void -jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, +GLOBAL(void) +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, d_derived_tbl ** pdtbl) { + JHUFF_TBL *htbl; d_derived_tbl *dtbl; - int p, i, l, si; + int p, i, l, si, numsymbols; int lookbits, ctr; char huffsize[257]; unsigned int huffcode[257]; unsigned int code; + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + /* Allocate a workspace if we haven't already done so. */ if (*pdtbl == NULL) *pdtbl = (d_derived_tbl *) @@ -144,17 +178,20 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, dtbl->pub = htbl; /* fill in back link */ /* Figure C.1: make table of Huffman code length for each symbol */ - /* Note that this is in code-length order. */ p = 0; for (l = 1; l <= 16; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++) + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) huffsize[p++] = (char) l; } huffsize[p] = 0; + numsymbols = p; /* Figure C.2: generate the codes themselves */ - /* Note that this is in code-length order. */ + /* We also validate that the counts represent a legal Huffman code tree. */ code = 0; si = huffsize[0]; @@ -164,6 +201,11 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, huffcode[p++] = code; code++; } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); code <<= 1; si++; } @@ -173,8 +215,10 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, p = 0; for (l = 1; l <= 16; l++) { if (htbl->bits[l]) { - dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */ - dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */ + /* valoffset[l] = huffval[] index of 1st symbol of code length l, + * minus the minimum code of length l + */ + dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p]; p += htbl->bits[l]; dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ } else { @@ -205,6 +249,20 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, } } } + + /* Validate symbols as being reasonable. + * For AC tables, we make no check, but accept all byte values 0..255. + * For DC tables, we require the symbols to be in range 0..15. + * (Tighter bounds could be applied depending on the data depth and mode, + * but this is sufficient to ensure safe decoding.) + */ + if (isDC) { + for (i = 0; i < numsymbols; i++) { + int sym = htbl->huffval[i]; + if (sym < 0 || sym > 15) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + } + } } @@ -230,7 +288,7 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, #endif -GLOBAL boolean +GLOBAL(boolean) jpeg_fill_bit_buffer (bitread_working_state * state, register bit_buf_type get_buffer, register int bits_left, int nbits) @@ -239,68 +297,86 @@ jpeg_fill_bit_buffer (bitread_working_state * state, /* Copy heavily used state fields into locals (hopefully registers) */ register const JOCTET * next_input_byte = state->next_input_byte; register size_t bytes_in_buffer = state->bytes_in_buffer; - register int c; + j_decompress_ptr cinfo = state->cinfo; /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ /* (It is assumed that no request will be for more than that many bits.) */ - - while (bits_left < MIN_GET_BITS) { - /* Attempt to read a byte */ - if (state->unread_marker != 0) - goto no_more_data; /* can't advance past a marker */ - - if (bytes_in_buffer == 0) { - if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) - return FALSE; - next_input_byte = state->cinfo->src->next_input_byte; - bytes_in_buffer = state->cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - - /* If it's 0xFF, check and discard stuffed zero byte */ - if (c == 0xFF) { - do { - if (bytes_in_buffer == 0) { - if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) - return FALSE; - next_input_byte = state->cinfo->src->next_input_byte; - bytes_in_buffer = state->cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - } while (c == 0xFF); - - if (c == 0) { - /* Found FF/00, which represents an FF data byte */ - c = 0xFF; - } else { - /* Oops, it's actually a marker indicating end of compressed data. */ - /* Better put it back for use later */ - state->unread_marker = c; - - no_more_data: - /* There should be enough bits still left in the data segment; */ - /* if so, just break out of the outer while loop. */ - if (bits_left >= nbits) - break; - /* Uh-oh. Report corrupted data to user and stuff zeroes into - * the data stream, so that we can produce some kind of image. - * Note that this code will be repeated for each byte demanded - * for the rest of the segment. We use a nonvolatile flag to ensure - * that only one warning message appears. + /* We fail to do so only if we hit a marker or are forced to suspend. */ + + if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ + while (bits_left < MIN_GET_BITS) { + register int c; + + /* Attempt to read a byte */ + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + + /* If it's 0xFF, check and discard stuffed zero byte */ + if (c == 0xFF) { + /* Loop here to discard any padding FF's on terminating marker, + * so that we can save a valid unread_marker value. NOTE: we will + * accept multiple FF's followed by a 0 as meaning a single FF data + * byte. This data pattern is not valid according to the standard. */ - if (! *(state->printed_eod_ptr)) { - WARNMS(state->cinfo, JWRN_HIT_MARKER); - *(state->printed_eod_ptr) = TRUE; + do { + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + } while (c == 0xFF); + + if (c == 0) { + /* Found FF/00, which represents an FF data byte */ + c = 0xFF; + } else { + /* Oops, it's actually a marker indicating end of compressed data. + * Save the marker code for later use. + * Fine point: it might appear that we should save the marker into + * bitread working state, not straight into permanent state. But + * once we have hit a marker, we cannot need to suspend within the + * current MCU, because we will read no more bytes from the data + * source. So it is OK to update permanent state right away. + */ + cinfo->unread_marker = c; + /* See if we need to insert some fake zero bits. */ + goto no_more_bytes; } - c = 0; /* insert a zero byte into bit buffer */ } - } - /* OK, load c into get_buffer */ - get_buffer = (get_buffer << 8) | c; - bits_left += 8; + /* OK, load c into get_buffer */ + get_buffer = (get_buffer << 8) | c; + bits_left += 8; + } /* end while */ + } else { + no_more_bytes: + /* We get here if we've read the marker that terminates the compressed + * data segment. There should be enough bits in the buffer register + * to satisfy the request; if so, no problem. + */ + if (nbits > bits_left) { + /* Uh-oh. Report corrupted data to user and stuff zeroes into + * the data stream, so that we can produce some kind of image. + * We use a nonvolatile flag to ensure that only one warning message + * appears per data segment. + */ + if (! cinfo->entropy->insufficient_data) { + WARNMS(cinfo, JWRN_HIT_MARKER); + cinfo->entropy->insufficient_data = TRUE; + } + /* Fill the buffer with zero bits */ + get_buffer <<= MIN_GET_BITS - bits_left; + bits_left = MIN_GET_BITS; + } } /* Unload the local registers */ @@ -318,7 +394,7 @@ jpeg_fill_bit_buffer (bitread_working_state * state, * See jdhuff.h for info about usage. */ -GLOBAL int +GLOBAL(int) jpeg_huff_decode (bitread_working_state * state, register bit_buf_type get_buffer, register int bits_left, d_derived_tbl * htbl, int min_bits) @@ -353,8 +429,7 @@ jpeg_huff_decode (bitread_working_state * state, return 0; /* fake a zero as the safest result */ } - return htbl->pub->huffval[ htbl->valptr[l] + - ((int) (code - htbl->mincode[l])) ]; + return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; } @@ -389,7 +464,7 @@ static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ * Returns FALSE if must suspend. */ -LOCAL boolean +LOCAL(boolean) process_restart (j_decompress_ptr cinfo) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; @@ -411,8 +486,13 @@ process_restart (j_decompress_ptr cinfo) /* Reset restart counter */ entropy->restarts_to_go = cinfo->restart_interval; - /* Next segment can get another out-of-data warning */ - entropy->bitstate.printed_eod = FALSE; + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; return TRUE; } @@ -433,18 +513,13 @@ process_restart (j_decompress_ptr cinfo) * this module, since we'll just re-assign them on the next call.) */ -METHODDEF boolean +METHODDEF(boolean) decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - register int s, k, r; - int blkn, ci; - JBLOCKROW block; + int blkn; BITREAD_STATE_VARS; savable_state state; - d_derived_tbl * dctbl; - d_derived_tbl * actbl; - jpeg_component_info * compptr; /* Process restart marker if needed; may have to suspend */ if (cinfo->restart_interval) { @@ -453,95 +528,97 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) return FALSE; } - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { - /* Outer loop handles each block in the MCU */ + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no]; - actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Outer loop handles each block in the MCU */ - /* Decode a single block's worth of coefficients */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + JBLOCKROW block = MCU_data[blkn]; + d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; + d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; + register int s, k, r; - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } + /* Decode a single block's worth of coefficients */ - /* Shortcut if component's values are not interesting */ - if (! compptr->component_needed) - goto skip_ACs; + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } - /* Convert DC difference to actual value, update last_dc_val */ - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ - (*block)[0] = (JCOEF) s; + if (entropy->dc_needed[blkn]) { + /* Convert DC difference to actual value, update last_dc_val */ + int ci = cinfo->MCU_membership[blkn]; + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + } - /* Do we need to decode the AC coefficients for this component? */ - if (compptr->DCT_scaled_size > 1) { + if (entropy->ac_needed[blkn]) { - /* Section F.2.2.2: decode the AC coefficients */ - /* Since zeroes are skipped, output area must be cleared beforehand */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); - r = s >> 4; - s &= 15; + r = s >> 4; + s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Output coefficient in natural (dezigzagged) order. - * Note: the extra entries in jpeg_natural_order[] will save us - * if k >= DCTSIZE2, which could happen if the data is corrupted. - */ - (*block)[jpeg_natural_order[k]] = (JCOEF) s; - } else { - if (r != 15) - break; - k += 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } } - } - } else { -skip_ACs: + } else { - /* Section F.2.2.2: decode the AC coefficients */ - /* In this path we just discard the values */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); - r = s >> 4; - s &= 15; + r = s >> 4; + s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } else { - if (r != 15) - break; - k += 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } } - } + } } - } - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } /* Account for restart interval (no-op if not using restarts) */ entropy->restarts_to_go--; @@ -554,7 +631,7 @@ skip_ACs: * Module initialization routine for Huffman entropy decoding. */ -GLOBAL void +GLOBAL(void) jinit_huff_decoder (j_decompress_ptr cinfo) { huff_entropy_ptr entropy; diff --git a/src/jpeg-6/jdhuff.h b/src/jpeg-6b/jdhuff.h index d67fc3b8..ae19b6ca 100644 --- a/src/jpeg-6/jdhuff.h +++ b/src/jpeg-6b/jdhuff.h @@ -1,7 +1,7 @@ /* * jdhuff.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -25,10 +25,13 @@ typedef struct { /* Basic tables: (element [0] of each array is unused) */ - INT32 mincode[17]; /* smallest code of length k */ INT32 maxcode[18]; /* largest code of length k (-1 if none) */ /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ - int valptr[17]; /* huffval[] index of 1st symbol of length k */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + /* valoffset[k] = huffval[] index of 1st symbol of code length k, less + * the smallest code of length k; so given a code of length k, the + * corresponding symbol is huffval[code + valoffset[k]] + */ /* Link to public Huffman table (needed only in jpeg_huff_decode) */ JHUFF_TBL *pub; @@ -43,8 +46,9 @@ typedef struct { } d_derived_tbl; /* Expand a Huffman table definition into the derived format */ -EXTERN void jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo, - JHUFF_TBL * htbl, d_derived_tbl ** pdtbl)); +EXTERN(void) jpeg_make_d_derived_tbl + JPP((j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl)); /* @@ -70,51 +74,46 @@ typedef INT32 bit_buf_type; /* type of bit-extraction buffer */ /* If long is > 32 bits on your machine, and shifting/masking longs is * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE - * appropriately should be a win. Unfortunately we can't do this with - * something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * appropriately should be a win. Unfortunately we can't define the size + * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) * because not all machines measure sizeof in 8-bit bytes. */ typedef struct { /* Bitreading state saved across MCUs */ bit_buf_type get_buffer; /* current bit-extraction buffer */ int bits_left; /* # of unused bits in it */ - boolean printed_eod; /* flag to suppress multiple warning msgs */ } bitread_perm_state; typedef struct { /* Bitreading working state within an MCU */ - /* current data source state */ + /* Current data source location */ + /* We need a copy, rather than munging the original, in case of suspension */ const JOCTET * next_input_byte; /* => next byte to read from source */ size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ - int unread_marker; /* nonzero if we have hit a marker */ - /* bit input buffer --- note these values are kept in register variables, + /* Bit input buffer --- note these values are kept in register variables, * not in this struct, inside the inner loops. */ bit_buf_type get_buffer; /* current bit-extraction buffer */ int bits_left; /* # of unused bits in it */ - /* pointers needed by jpeg_fill_bit_buffer */ + /* Pointer needed by jpeg_fill_bit_buffer. */ j_decompress_ptr cinfo; /* back link to decompress master record */ - boolean * printed_eod_ptr; /* => flag in permanent state */ } bitread_working_state; /* Macros to declare and load/save bitread local variables. */ #define BITREAD_STATE_VARS \ register bit_buf_type get_buffer; \ register int bits_left; \ - bitread_working_state br_state = {0} + bitread_working_state br_state #define BITREAD_LOAD_STATE(cinfop,permstate) \ br_state.cinfo = cinfop; \ br_state.next_input_byte = cinfop->src->next_input_byte; \ br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ - br_state.unread_marker = cinfop->unread_marker; \ get_buffer = permstate.get_buffer; \ - bits_left = permstate.bits_left; \ - br_state.printed_eod_ptr = & permstate.printed_eod + bits_left = permstate.bits_left; #define BITREAD_SAVE_STATE(cinfop,permstate) \ cinfop->src->next_input_byte = br_state.next_input_byte; \ cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ - cinfop->unread_marker = br_state.unread_marker; \ permstate.get_buffer = get_buffer; \ permstate.bits_left = bits_left @@ -152,9 +151,9 @@ typedef struct { /* Bitreading working state within an MCU */ (bits_left -= (nbits)) /* Load up the bit buffer to a depth of at least nbits */ -EXTERN boolean jpeg_fill_bit_buffer JPP((bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - int nbits)); +EXTERN(boolean) jpeg_fill_bit_buffer + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); /* @@ -197,6 +196,6 @@ slowlabel: \ } /* Out-of-line case for Huffman code fetching */ -EXTERN int jpeg_huff_decode JPP((bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - d_derived_tbl * htbl, int min_bits)); +EXTERN(int) jpeg_huff_decode + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); diff --git a/src/jpeg-6/jdinput.c b/src/jpeg-6b/jdinput.c index 3061a17b..0c2ac8f1 100644 --- a/src/jpeg-6/jdinput.c +++ b/src/jpeg-6b/jdinput.c @@ -1,7 +1,7 @@ /* * jdinput.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -28,14 +28,14 @@ typedef my_input_controller * my_inputctl_ptr; /* Forward declarations */ -METHODDEF int consume_markers JPP((j_decompress_ptr cinfo)); +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo)); /* * Routines to calculate various quantities related to the size of the image. */ -LOCAL void +LOCAL(void) initial_setup (j_decompress_ptr cinfo) /* Called once, when first SOS marker is reached */ { @@ -117,7 +117,7 @@ initial_setup (j_decompress_ptr cinfo) } -LOCAL void +LOCAL(void) per_scan_setup (j_decompress_ptr cinfo) /* Do computations that are needed before processing a JPEG scan */ /* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ @@ -216,7 +216,7 @@ per_scan_setup (j_decompress_ptr cinfo) * not at the current Q-table slots. */ -LOCAL void +LOCAL(void) latch_quant_tables (j_decompress_ptr cinfo) { int ci, qtblno; @@ -250,7 +250,7 @@ latch_quant_tables (j_decompress_ptr cinfo) * Subsequent calls come from consume_markers, below. */ -METHODDEF void +METHODDEF(void) start_input_pass (j_decompress_ptr cinfo) { per_scan_setup(cinfo); @@ -267,7 +267,7 @@ start_input_pass (j_decompress_ptr cinfo) * the expected data of the scan. */ -METHODDEF void +METHODDEF(void) finish_input_pass (j_decompress_ptr cinfo) { cinfo->inputctl->consume_input = consume_markers; @@ -284,7 +284,7 @@ finish_input_pass (j_decompress_ptr cinfo) * we are reading a compressed data segment or inter-segment markers. */ -METHODDEF int +METHODDEF(int) consume_markers (j_decompress_ptr cinfo) { my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; @@ -301,7 +301,7 @@ consume_markers (j_decompress_ptr cinfo) initial_setup(cinfo); inputctl->inheaders = FALSE; /* Note: start_input_pass must be called by jdmaster.c - * before any more input can be consumed. jdapi.c is + * before any more input can be consumed. jdapimin.c is * responsible for enforcing this sequencing. */ } else { /* 2nd or later SOS marker */ @@ -335,7 +335,7 @@ consume_markers (j_decompress_ptr cinfo) * Reset state to begin a fresh datastream. */ -METHODDEF void +METHODDEF(void) reset_input_controller (j_decompress_ptr cinfo) { my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; @@ -357,7 +357,7 @@ reset_input_controller (j_decompress_ptr cinfo) * This is called only once, when the decompression object is created. */ -GLOBAL void +GLOBAL(void) jinit_input_controller (j_decompress_ptr cinfo) { my_inputctl_ptr inputctl; diff --git a/src/jpeg-6/jdmainct.c b/src/jpeg-6b/jdmainct.c index e50a4717..2f265336 100644 --- a/src/jpeg-6/jdmainct.c +++ b/src/jpeg-6b/jdmainct.c @@ -1,7 +1,7 @@ /* * jdmainct.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -140,20 +140,20 @@ typedef my_main_controller * my_main_ptr; /* Forward declarations */ -METHODDEF void process_data_simple_main +METHODDEF(void) process_data_simple_main JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -METHODDEF void process_data_context_main +METHODDEF(void) process_data_context_main JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); #ifdef QUANT_2PASS_SUPPORTED -METHODDEF void process_data_crank_post +METHODDEF(void) process_data_crank_post JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); #endif -LOCAL void +LOCAL(void) alloc_funny_pointers (j_decompress_ptr cinfo) /* Allocate space for the funny pointer lists. * This is done only once, not once per pass. @@ -191,10 +191,10 @@ alloc_funny_pointers (j_decompress_ptr cinfo) } -LOCAL void +LOCAL(void) make_funny_pointers (j_decompress_ptr cinfo) /* Create the funny pointer lists discussed in the comments above. - * The actual workspace is already allocated (in main->buffer), + * The actual workspace is already allocated (in jmain->buffer), * and the space for the pointer lists is allocated too. * This routine just fills in the curiously ordered lists. * This will be repeated at the beginning of each pass. @@ -234,7 +234,7 @@ make_funny_pointers (j_decompress_ptr cinfo) } -LOCAL void +LOCAL(void) set_wraparound_pointers (j_decompress_ptr cinfo) /* Set up the "wraparound" pointers at top and bottom of the pointer lists. * This changes the pointer list state from top-of-image to the normal state. @@ -262,7 +262,7 @@ set_wraparound_pointers (j_decompress_ptr cinfo) } -LOCAL void +LOCAL(void) set_bottom_pointers (j_decompress_ptr cinfo) /* Change the pointer lists to duplicate the last sample row at the bottom * of the image. whichptr indicates which xbuffer holds the final iMCU row. @@ -303,7 +303,7 @@ set_bottom_pointers (j_decompress_ptr cinfo) * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) { my_main_ptr jmain = (my_main_ptr) cinfo->main; @@ -341,7 +341,7 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) * This handles the simple case where no context is required. */ -METHODDEF void +METHODDEF(void) process_data_simple_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) @@ -349,7 +349,7 @@ process_data_simple_main (j_decompress_ptr cinfo, my_main_ptr jmain = (my_main_ptr) cinfo->main; JDIMENSION rowgroups_avail; - /* Read input data if we haven't filled the main buffer yet */ + /* Read input data if we haven't filled the jmain buffer yet */ if (! jmain->buffer_full) { if (! (*cinfo->coef->decompress_data) (cinfo, jmain->buffer)) return; /* suspension forced, can do nothing more */ @@ -381,14 +381,14 @@ process_data_simple_main (j_decompress_ptr cinfo, * This handles the case where context rows must be provided. */ -METHODDEF void +METHODDEF(void) process_data_context_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { my_main_ptr jmain = (my_main_ptr) cinfo->main; - /* Read input data if we haven't filled the main buffer yet */ + /* Read input data if we haven't filled the jmain buffer yet */ if (! jmain->buffer_full) { if (! (*cinfo->coef->decompress_data) (cinfo, jmain->xbuffer[jmain->whichptr])) @@ -455,7 +455,7 @@ process_data_context_main (j_decompress_ptr cinfo, #ifdef QUANT_2PASS_SUPPORTED -METHODDEF void +METHODDEF(void) process_data_crank_post (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) @@ -469,10 +469,10 @@ process_data_crank_post (j_decompress_ptr cinfo, /* - * Initialize main buffer controller. + * Initialize jmain buffer controller. */ -GLOBAL void +GLOBAL(void) jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { my_main_ptr jmain; diff --git a/src/jpeg-6/jdmarker.c b/src/jpeg-6b/jdmarker.c index 80e5f783..f4cca8cc 100644 --- a/src/jpeg-6/jdmarker.c +++ b/src/jpeg-6b/jdmarker.c @@ -1,7 +1,7 @@ /* * jdmarker.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -85,6 +85,28 @@ typedef enum { /* JPEG marker codes */ } JPEG_MARKER; +/* Private state */ + +typedef struct { + struct jpeg_marker_reader pub; /* public fields */ + + /* Application-overridable marker processing methods */ + jpeg_marker_parser_method process_COM; + jpeg_marker_parser_method process_APPn[16]; + + /* Limit on marker data length to save for each marker type */ + unsigned int length_limit_COM; + unsigned int length_limit_APPn[16]; + + /* Status of COM/APPn marker saving */ + jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ + unsigned int bytes_read; /* data bytes read so far in marker */ + /* Note: cur_marker is not linked into marker_list until it's all read. */ +} my_marker_reader; + +typedef my_marker_reader * my_marker_ptr; + + /* * Macros for fetching data from the data source module. * @@ -104,7 +126,7 @@ typedef enum { /* JPEG marker codes */ ( datasrc->next_input_byte = next_input_byte, \ datasrc->bytes_in_buffer = bytes_in_buffer ) -/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */ +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ #define INPUT_RELOAD(cinfo) \ ( next_input_byte = datasrc->next_input_byte, \ bytes_in_buffer = datasrc->bytes_in_buffer ) @@ -118,14 +140,14 @@ typedef enum { /* JPEG marker codes */ if (! (*datasrc->fill_input_buffer) (cinfo)) \ { action; } \ INPUT_RELOAD(cinfo); \ - } \ - bytes_in_buffer-- + } /* Read a byte into variable V. * If must suspend, take the specified action (typically "return FALSE"). */ #define INPUT_BYTE(cinfo,V,action) \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ V = GETJOCTET(*next_input_byte++); ) /* As above, but read two bytes interpreted as an unsigned 16-bit integer. @@ -133,8 +155,10 @@ typedef enum { /* JPEG marker codes */ */ #define INPUT_2BYTES(cinfo,V,action) \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ V += GETJOCTET(*next_input_byte++); ) @@ -150,11 +174,18 @@ typedef enum { /* JPEG marker codes */ * marker parameters; restart point has not been moved. Same routine * will be called again after application supplies more input data. * - * This approach to suspension assumes that all of a marker's parameters can - * fit into a single input bufferload. This should hold for "normal" - * markers. Some COM/APPn markers might have large parameter segments, - * but we use skip_input_data to get past those, and thereby put the problem - * on the source manager's shoulders. + * This approach to suspension assumes that all of a marker's parameters + * can fit into a single input bufferload. This should hold for "normal" + * markers. Some COM/APPn markers might have large parameter segments + * that might not fit. If we are simply dropping such a marker, we use + * skip_input_data to get past it, and thereby put the problem on the + * source manager's shoulders. If we are saving the marker's contents + * into memory, we use a slightly different convention: when forced to + * suspend, the marker processor updates the restart point to the end of + * what it's consumed (ie, the end of the buffer) before returning FALSE. + * On resumption, cinfo->unread_marker still contains the marker code, + * but the data source will point to the next chunk of marker data. + * The marker processor must retain internal state to deal with this. * * Note that we don't bother to avoid duplicate trace messages if a * suspension occurs within marker parameters. Other side effects @@ -162,7 +193,7 @@ typedef enum { /* JPEG marker codes */ */ -LOCAL boolean +LOCAL(boolean) get_soi (j_decompress_ptr cinfo) /* Process an SOI marker */ { @@ -188,7 +219,9 @@ get_soi (j_decompress_ptr cinfo) cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ cinfo->saw_JFIF_marker = FALSE; - cinfo->density_unit = 0; /* set default JFIF APP0 values */ + cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; cinfo->X_density = 1; cinfo->Y_density = 1; cinfo->saw_Adobe_marker = FALSE; @@ -200,7 +233,7 @@ get_soi (j_decompress_ptr cinfo) } -LOCAL boolean +LOCAL(boolean) get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) /* Process a SOFn marker */ { @@ -264,7 +297,7 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) } -LOCAL boolean +LOCAL(boolean) get_sos (j_decompress_ptr cinfo) /* Process a SOS marker */ { @@ -280,11 +313,11 @@ get_sos (j_decompress_ptr cinfo) INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + TRACEMS1(cinfo, 1, JTRC_SOS, n); + if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) ERREXIT(cinfo, JERR_BAD_LENGTH); - TRACEMS1(cinfo, 1, JTRC_SOS, n); - cinfo->comps_in_scan = n; /* Collect the component-spec parameters */ @@ -334,113 +367,9 @@ get_sos (j_decompress_ptr cinfo) } -METHODDEF boolean -get_app0 (j_decompress_ptr cinfo) -/* Process an APP0 marker */ -{ -#define JFIF_LEN 14 - INT32 length; - UINT8 b[JFIF_LEN]; - int buffp; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - /* See if a JFIF APP0 marker is present */ - - if (length >= JFIF_LEN) { - for (buffp = 0; buffp < JFIF_LEN; buffp++) - INPUT_BYTE(cinfo, b[buffp], return FALSE); - length -= JFIF_LEN; - - if (b[0]==0x4A && b[1]==0x46 && b[2]==0x49 && b[3]==0x46 && b[4]==0) { - /* Found JFIF APP0 marker: check version */ - /* Major version must be 1, anything else signals an incompatible change. - * We used to treat this as an error, but now it's a nonfatal warning, - * because some bozo at Hijaak couldn't read the spec. - * Minor version should be 0..2, but process anyway if newer. - */ - if (b[5] != 1) - WARNMS2(cinfo, JWRN_JFIF_MAJOR, b[5], b[6]); - else if (b[6] > 2) - TRACEMS2(cinfo, 1, JTRC_JFIF_MINOR, b[5], b[6]); - /* Save info */ - cinfo->saw_JFIF_marker = TRUE; - cinfo->density_unit = b[7]; - cinfo->X_density = (b[8] << 8) + b[9]; - cinfo->Y_density = (b[10] << 8) + b[11]; - TRACEMS3(cinfo, 1, JTRC_JFIF, - cinfo->X_density, cinfo->Y_density, cinfo->density_unit); - if (b[12] | b[13]) - TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, b[12], b[13]); - if (length != ((INT32) b[12] * (INT32) b[13] * (INT32) 3)) - TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) length); - } else { - /* Start of APP0 does not match "JFIF" */ - TRACEMS1(cinfo, 1, JTRC_APP0, (int) length + JFIF_LEN); - } - } else { - /* Too short to be JFIF marker */ - TRACEMS1(cinfo, 1, JTRC_APP0, (int) length); - } - - INPUT_SYNC(cinfo); - if (length > 0) /* skip any remaining data -- could be lots */ - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -METHODDEF boolean -get_app14 (j_decompress_ptr cinfo) -/* Process an APP14 marker */ -{ -#define ADOBE_LEN 12 - INT32 length; - UINT8 b[ADOBE_LEN]; - int buffp; - unsigned int version, flags0, flags1, transform; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; +#ifdef D_ARITH_CODING_SUPPORTED - /* See if an Adobe APP14 marker is present */ - - if (length >= ADOBE_LEN) { - for (buffp = 0; buffp < ADOBE_LEN; buffp++) - INPUT_BYTE(cinfo, b[buffp], return FALSE); - length -= ADOBE_LEN; - - if (b[0]==0x41 && b[1]==0x64 && b[2]==0x6F && b[3]==0x62 && b[4]==0x65) { - /* Found Adobe APP14 marker */ - version = (b[5] << 8) + b[6]; - flags0 = (b[7] << 8) + b[8]; - flags1 = (b[9] << 8) + b[10]; - transform = b[11]; - TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); - cinfo->saw_Adobe_marker = TRUE; - cinfo->Adobe_transform = (UINT8) transform; - } else { - /* Start of APP14 does not match "Adobe" */ - TRACEMS1(cinfo, 1, JTRC_APP14, (int) length + ADOBE_LEN); - } - } else { - /* Too short to be Adobe marker */ - TRACEMS1(cinfo, 1, JTRC_APP14, (int) length); - } - - INPUT_SYNC(cinfo); - if (length > 0) /* skip any remaining data -- could be lots */ - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -LOCAL boolean +LOCAL(boolean) get_dac (j_decompress_ptr cinfo) /* Process a DAC marker */ { @@ -472,12 +401,21 @@ get_dac (j_decompress_ptr cinfo) } } + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + INPUT_SYNC(cinfo); return TRUE; } +#else /* ! D_ARITH_CODING_SUPPORTED */ + +#define get_dac(cinfo) skip_variable(cinfo) -LOCAL boolean +#endif /* D_ARITH_CODING_SUPPORTED */ + + +LOCAL(boolean) get_dht (j_decompress_ptr cinfo) /* Process a DHT marker */ { @@ -491,7 +429,7 @@ get_dht (j_decompress_ptr cinfo) INPUT_2BYTES(cinfo, length, return FALSE); length -= 2; - while (length > 0) { + while (length > 16) { INPUT_BYTE(cinfo, index, return FALSE); TRACEMS1(cinfo, 1, JTRC_DHT, index); @@ -512,8 +450,11 @@ get_dht (j_decompress_ptr cinfo) bits[9], bits[10], bits[11], bits[12], bits[13], bits[14], bits[15], bits[16]); + /* Here we just do minimal validation of the counts to avoid walking + * off the end of our table space. jdhuff.c will check more carefully. + */ if (count > 256 || ((INT32) count) > length) - ERREXIT(cinfo, JERR_DHT_COUNTS); + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); for (i = 0; i < count; i++) INPUT_BYTE(cinfo, huffval[i], return FALSE); @@ -537,12 +478,15 @@ get_dht (j_decompress_ptr cinfo) MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); } + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + INPUT_SYNC(cinfo); return TRUE; } -LOCAL boolean +LOCAL(boolean) get_dqt (j_decompress_ptr cinfo) /* Process a DQT marker */ { @@ -574,27 +518,33 @@ get_dqt (j_decompress_ptr cinfo) INPUT_2BYTES(cinfo, tmp, return FALSE); else INPUT_BYTE(cinfo, tmp, return FALSE); - quant_ptr->quantval[i] = (UINT16) tmp; + /* We convert the zigzag-order table to natural array order. */ + quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; } - for (i = 0; i < DCTSIZE2; i += 8) { - TRACEMS8(cinfo, 2, JTRC_QUANTVALS, - quant_ptr->quantval[i ], quant_ptr->quantval[i+1], - quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], - quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], - quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + if (cinfo->err->trace_level >= 2) { + for (i = 0; i < DCTSIZE2; i += 8) { + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + } } length -= DCTSIZE2+1; if (prec) length -= DCTSIZE2; } + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + INPUT_SYNC(cinfo); return TRUE; } -LOCAL boolean +LOCAL(boolean) get_dri (j_decompress_ptr cinfo) /* Process a DRI marker */ { @@ -618,7 +568,280 @@ get_dri (j_decompress_ptr cinfo) } -METHODDEF boolean +/* + * Routines for processing APPn and COM markers. + * These are either saved in memory or discarded, per application request. + * APP0 and APP14 are specially checked to see if they are + * JFIF and Adobe markers, respectively. + */ + +#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ +#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ +#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ + + +LOCAL(void) +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP0. + * Take appropriate action if it is a JFIF marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + INT32 totallen = (INT32) datalen + remaining; + + if (datalen >= APP0_DATA_LEN && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x49 && + GETJOCTET(data[3]) == 0x46 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF APP0 marker: save info */ + cinfo->saw_JFIF_marker = TRUE; + cinfo->JFIF_major_version = GETJOCTET(data[5]); + cinfo->JFIF_minor_version = GETJOCTET(data[6]); + cinfo->density_unit = GETJOCTET(data[7]); + cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); + cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); + /* Check version. + * Major version must be 1, anything else signals an incompatible change. + * (We used to treat this as an error, but now it's a nonfatal warning, + * because some bozo at Hijaak couldn't read the spec.) + * Minor version should be 0..2, but process anyway if newer. + */ + if (cinfo->JFIF_major_version != 1) + WARNMS2(cinfo, JWRN_JFIF_MAJOR, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version); + /* Generate trace messages */ + TRACEMS5(cinfo, 1, JTRC_JFIF, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + /* Validate thumbnail dimensions and issue appropriate messages */ + if (GETJOCTET(data[12]) | GETJOCTET(data[13])) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + totallen -= APP0_DATA_LEN; + if (totallen != + ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) + TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); + } else if (datalen >= 6 && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x58 && + GETJOCTET(data[3]) == 0x58 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF "JFXX" extension APP0 marker */ + /* The library doesn't actually do anything with these, + * but we try to produce a helpful trace message. + */ + switch (GETJOCTET(data[5])) { + case 0x10: + TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen); + break; + case 0x11: + TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen); + break; + case 0x13: + TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen); + break; + default: + TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), (int) totallen); + break; + } + } else { + /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen); + } +} + + +LOCAL(void) +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP14. + * Take appropriate action if it is an Adobe marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + unsigned int version, flags0, flags1, transform; + + if (datalen >= APP14_DATA_LEN && + GETJOCTET(data[0]) == 0x41 && + GETJOCTET(data[1]) == 0x64 && + GETJOCTET(data[2]) == 0x6F && + GETJOCTET(data[3]) == 0x62 && + GETJOCTET(data[4]) == 0x65) { + /* Found Adobe APP14 marker */ + version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); + flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); + flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); + transform = GETJOCTET(data[11]); + TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); + cinfo->saw_Adobe_marker = TRUE; + cinfo->Adobe_transform = (UINT8) transform; + } else { + /* Start of APP14 does not match "Adobe", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining)); + } +} + + +METHODDEF(boolean) +get_interesting_appn (j_decompress_ptr cinfo) +/* Process an APP0 or APP14 marker without saving it */ +{ + INT32 length; + JOCTET b[APPN_DATA_LEN]; + unsigned int i, numtoread; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* get the interesting part of the marker data */ + if (length >= APPN_DATA_LEN) + numtoread = APPN_DATA_LEN; + else if (length > 0) + numtoread = (unsigned int) length; + else + numtoread = 0; + for (i = 0; i < numtoread; i++) + INPUT_BYTE(cinfo, b[i], return FALSE); + length -= numtoread; + + /* process it */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + case M_APP14: + examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + default: + /* can't get here unless jpeg_save_markers chooses wrong processor */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +#ifdef SAVE_MARKERS_SUPPORTED + +METHODDEF(boolean) +save_marker (j_decompress_ptr cinfo) +/* Save an APPn or COM marker into the marker list */ +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + jpeg_saved_marker_ptr cur_marker = marker->cur_marker; + unsigned int bytes_read, data_length; + JOCTET FAR * data; + INT32 length = 0; + INPUT_VARS(cinfo); + + if (cur_marker == NULL) { + /* begin reading a marker */ + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + if (length >= 0) { /* watch out for bogus length word */ + /* figure out how much we want to save */ + unsigned int limit; + if (cinfo->unread_marker == (int) M_COM) + limit = marker->length_limit_COM; + else + limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; + if ((unsigned int) length < limit) + limit = (unsigned int) length; + /* allocate and initialize the marker item */ + cur_marker = (jpeg_saved_marker_ptr) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_struct) + limit); + cur_marker->next = NULL; + cur_marker->marker = (UINT8) cinfo->unread_marker; + cur_marker->original_length = (unsigned int) length; + cur_marker->data_length = limit; + /* data area is just beyond the jpeg_marker_struct */ + data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1); + marker->cur_marker = cur_marker; + marker->bytes_read = 0; + bytes_read = 0; + data_length = limit; + } else { + /* deal with bogus length word */ + bytes_read = data_length = 0; + data = NULL; + } + } else { + /* resume reading a marker */ + bytes_read = marker->bytes_read; + data_length = cur_marker->data_length; + data = cur_marker->data + bytes_read; + } + + while (bytes_read < data_length) { + INPUT_SYNC(cinfo); /* move the restart point to here */ + marker->bytes_read = bytes_read; + /* If there's not at least one byte in buffer, suspend */ + MAKE_BYTE_AVAIL(cinfo, return FALSE); + /* Copy bytes with reasonable rapidity */ + while (bytes_read < data_length && bytes_in_buffer > 0) { + *data++ = *next_input_byte++; + bytes_in_buffer--; + bytes_read++; + } + } + + /* Done reading what we want to read */ + if (cur_marker != NULL) { /* will be NULL if bogus length word */ + /* Add new marker to end of list */ + if (cinfo->marker_list == NULL) { + cinfo->marker_list = cur_marker; + } else { + jpeg_saved_marker_ptr prev = cinfo->marker_list; + while (prev->next != NULL) + prev = prev->next; + prev->next = cur_marker; + } + /* Reset pointer & calc remaining data length */ + data = cur_marker->data; + length = cur_marker->original_length - data_length; + } + /* Reset to initial state for next marker */ + marker->cur_marker = NULL; + + /* Process the marker if interesting; else just make a generic trace msg */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, data, data_length, length); + break; + case M_APP14: + examine_app14(cinfo, data, data_length, length); + break; + default: + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, + (int) (data_length + length)); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +METHODDEF(boolean) skip_variable (j_decompress_ptr cinfo) /* Skip over an unknown or uninteresting variable-length marker */ { @@ -626,11 +849,13 @@ skip_variable (j_decompress_ptr cinfo) INPUT_VARS(cinfo); INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); INPUT_SYNC(cinfo); /* do before skip_input_data */ - (*cinfo->src->skip_input_data) (cinfo, (long) length - 2L); + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); return TRUE; } @@ -645,7 +870,7 @@ skip_variable (j_decompress_ptr cinfo) * but it will never be 0 or FF. */ -LOCAL boolean +LOCAL(boolean) next_marker (j_decompress_ptr cinfo) { int c; @@ -692,7 +917,7 @@ next_marker (j_decompress_ptr cinfo) } -LOCAL boolean +LOCAL(boolean) first_marker (j_decompress_ptr cinfo) /* Like next_marker, but used to obtain the initial SOI marker. */ /* For this marker, we do not allow preceding garbage or fill; otherwise, @@ -723,7 +948,7 @@ first_marker (j_decompress_ptr cinfo) * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. */ -METHODDEF int +METHODDEF(int) read_markers (j_decompress_ptr cinfo) { /* Outer loop repeats once for each marker. */ @@ -830,12 +1055,13 @@ read_markers (j_decompress_ptr cinfo) case M_APP13: case M_APP14: case M_APP15: - if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo)) + if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ + cinfo->unread_marker - (int) M_APP0]) (cinfo)) return JPEG_SUSPENDED; break; case M_COM: - if (! (*cinfo->marker->process_COM) (cinfo)) + if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) return JPEG_SUSPENDED; break; @@ -883,7 +1109,7 @@ read_markers (j_decompress_ptr cinfo) * it holds a marker which the decoder will be unable to read past. */ -METHODDEF boolean +METHODDEF(boolean) read_restart_marker (j_decompress_ptr cinfo) { /* Obtain a marker unless we already did. */ @@ -896,7 +1122,7 @@ read_restart_marker (j_decompress_ptr cinfo) if (cinfo->unread_marker == ((int) M_RST0 + cinfo->marker->next_restart_num)) { /* Normal case --- swallow the marker and let entropy decoder continue */ - TRACEMS1(cinfo, 2, JTRC_RST, cinfo->marker->next_restart_num); + TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); cinfo->unread_marker = 0; } else { /* Uh-oh, the restart markers have been messed up. */ @@ -962,7 +1188,7 @@ read_restart_marker (j_decompress_ptr cinfo) * any other marker would have to be bogus data in that case. */ -GLOBAL boolean +GLOBAL(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) { int marker = cinfo->unread_marker; @@ -1012,15 +1238,18 @@ jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) * Reset marker processing state to begin a fresh datastream. */ -METHODDEF void +METHODDEF(void) reset_marker_reader (j_decompress_ptr cinfo) { + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + cinfo->comp_info = NULL; /* until allocated by get_sof */ cinfo->input_scan_number = 0; /* no SOS seen yet */ cinfo->unread_marker = 0; /* no pending marker */ - cinfo->marker->saw_SOI = FALSE; /* set internal state too */ - cinfo->marker->saw_SOF = FALSE; - cinfo->marker->discarded_bytes = 0; + marker->pub.saw_SOI = FALSE; /* set internal state too */ + marker->pub.saw_SOF = FALSE; + marker->pub.discarded_bytes = 0; + marker->cur_marker = NULL; } @@ -1029,24 +1258,103 @@ reset_marker_reader (j_decompress_ptr cinfo) * This is called only once, when the decompression object is created. */ -GLOBAL void +GLOBAL(void) jinit_marker_reader (j_decompress_ptr cinfo) { + my_marker_ptr marker; int i; /* Create subobject in permanent pool */ - cinfo->marker = (struct jpeg_marker_reader *) + marker = (my_marker_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(struct jpeg_marker_reader)); - /* Initialize method pointers */ - cinfo->marker->reset_marker_reader = reset_marker_reader; - cinfo->marker->read_markers = read_markers; - cinfo->marker->read_restart_marker = read_restart_marker; - cinfo->marker->process_COM = skip_variable; - for (i = 0; i < 16; i++) - cinfo->marker->process_APPn[i] = skip_variable; - cinfo->marker->process_APPn[0] = get_app0; - cinfo->marker->process_APPn[14] = get_app14; + SIZEOF(my_marker_reader)); + cinfo->marker = (struct jpeg_marker_reader *) marker; + /* Initialize public method pointers */ + marker->pub.reset_marker_reader = reset_marker_reader; + marker->pub.read_markers = read_markers; + marker->pub.read_restart_marker = read_restart_marker; + /* Initialize COM/APPn processing. + * By default, we examine and then discard APP0 and APP14, + * but simply discard COM and all other APPn. + */ + marker->process_COM = skip_variable; + marker->length_limit_COM = 0; + for (i = 0; i < 16; i++) { + marker->process_APPn[i] = skip_variable; + marker->length_limit_APPn[i] = 0; + } + marker->process_APPn[0] = get_interesting_appn; + marker->process_APPn[14] = get_interesting_appn; /* Reset marker processing state */ reset_marker_reader(cinfo); } + + +/* + * Control saving of COM and APPn markers into marker_list. + */ + +#ifdef SAVE_MARKERS_SUPPORTED + +GLOBAL(void) +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + long maxlength; + jpeg_marker_parser_method processor; + + /* Length limit mustn't be larger than what we can allocate + * (should only be a concern in a 16-bit environment). + */ + maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct); + if (((long) length_limit) > maxlength) + length_limit = (unsigned int) maxlength; + + /* Choose processor routine to use. + * APP0/APP14 have special requirements. + */ + if (length_limit) { + processor = save_marker; + /* If saving APP0/APP14, save at least enough for our internal use. */ + if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN) + length_limit = APP0_DATA_LEN; + else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN) + length_limit = APP14_DATA_LEN; + } else { + processor = skip_variable; + /* If discarding APP0/APP14, use our regular on-the-fly processor. */ + if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14) + processor = get_interesting_appn; + } + + if (marker_code == (int) M_COM) { + marker->process_COM = processor; + marker->length_limit_COM = length_limit; + } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) { + marker->process_APPn[marker_code - (int) M_APP0] = processor; + marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit; + } else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +/* + * Install a special processing method for COM or APPn markers. + */ + +GLOBAL(void) +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + if (marker_code == (int) M_COM) + marker->process_COM = routine; + else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) + marker->process_APPn[marker_code - (int) M_APP0] = routine; + else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} diff --git a/src/jpeg-6/jdmaster.c b/src/jpeg-6b/jdmaster.c index 18e08809..2802c5b7 100644 --- a/src/jpeg-6/jdmaster.c +++ b/src/jpeg-6b/jdmaster.c @@ -1,7 +1,7 @@ /* * jdmaster.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -40,7 +40,7 @@ typedef my_decomp_master * my_master_ptr; * CRUCIAL: this must match the actual capabilities of jdmerge.c! */ -LOCAL boolean +LOCAL(boolean) use_merged_upsample (j_decompress_ptr cinfo) { #ifdef UPSAMPLE_MERGING_SUPPORTED @@ -80,11 +80,11 @@ use_merged_upsample (j_decompress_ptr cinfo) * Also note that it may be called before the master module is initialized! */ -GLOBAL void +GLOBAL(void) jpeg_calc_output_dimensions (j_decompress_ptr cinfo) /* Do computations that are needed before master selection phase */ { -#if 0 // JDC: commented out to remove warning +#ifdef IDCT_SCALING_SUPPORTED int ci; jpeg_component_info *compptr; #endif @@ -244,7 +244,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) * enough and used often enough to justify this. */ -LOCAL void +LOCAL(void) prepare_range_limit_table (j_decompress_ptr cinfo) /* Allocate and fill in the sample_range_limit table */ { @@ -284,7 +284,7 @@ prepare_range_limit_table (j_decompress_ptr cinfo) * settings. */ -LOCAL void +LOCAL(void) master_selection (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -431,10 +431,10 @@ master_selection (j_decompress_ptr cinfo) * modules will be active during this pass and give them appropriate * start_pass calls. We also set is_dummy_pass to indicate whether this * is a "real" output pass or a dummy pass for color quantization. - * (In the latter case, jdapi.c will crank the pass to completion.) + * (In the latter case, jdapistd.c will crank the pass to completion.) */ -METHODDEF void +METHODDEF(void) prepare_for_output_pass (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -494,7 +494,7 @@ prepare_for_output_pass (j_decompress_ptr cinfo) * Finish up at end of an output pass. */ -METHODDEF void +METHODDEF(void) finish_output_pass (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -511,7 +511,7 @@ finish_output_pass (j_decompress_ptr cinfo) * Switch to a new external colormap between output passes. */ -GLOBAL void +GLOBAL(void) jpeg_new_colormap (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; @@ -539,7 +539,7 @@ jpeg_new_colormap (j_decompress_ptr cinfo) * This is performed at the start of jpeg_start_decompress. */ -GLOBAL void +GLOBAL(void) jinit_master_decompress (j_decompress_ptr cinfo) { my_master_ptr master; diff --git a/src/jpeg-6/jdmerge.c b/src/jpeg-6b/jdmerge.c index 95585fb8..37444468 100644 --- a/src/jpeg-6/jdmerge.c +++ b/src/jpeg-6b/jdmerge.c @@ -1,7 +1,7 @@ /* * jdmerge.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -79,7 +79,7 @@ typedef my_upsampler * my_upsample_ptr; * This is taken directly from jdcolor.c; see that file for more info. */ -LOCAL void +LOCAL(void) build_ycc_rgb_table (j_decompress_ptr cinfo) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; @@ -122,7 +122,7 @@ build_ycc_rgb_table (j_decompress_ptr cinfo) * Initialize for an upsampling pass. */ -METHODDEF void +METHODDEF(void) start_pass_merged_upsample (j_decompress_ptr cinfo) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; @@ -140,7 +140,7 @@ start_pass_merged_upsample (j_decompress_ptr cinfo) * The control routine just handles the row buffering considerations. */ -METHODDEF void +METHODDEF(void) merged_2v_upsample (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -189,7 +189,7 @@ merged_2v_upsample (j_decompress_ptr cinfo, } -METHODDEF void +METHODDEF(void) merged_1v_upsample (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -222,7 +222,7 @@ merged_1v_upsample (j_decompress_ptr cinfo, * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. */ -METHODDEF void +METHODDEF(void) h2v1_merged_upsample (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf) @@ -284,7 +284,7 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. */ -METHODDEF void +METHODDEF(void) h2v2_merged_upsample (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf) @@ -366,7 +366,7 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, * of this module; no safety checks are made here. */ -GLOBAL void +GLOBAL(void) jinit_merged_upsampler (j_decompress_ptr cinfo) { my_upsample_ptr upsample; diff --git a/src/jpeg-6/jdphuff.c b/src/jpeg-6b/jdphuff.c index 025bfd80..22678099 100644 --- a/src/jpeg-6/jdphuff.c +++ b/src/jpeg-6b/jdphuff.c @@ -1,7 +1,7 @@ /* * jdphuff.c * - * Copyright (C) 1995, Thomas G. Lane. + * Copyright (C) 1995-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -74,21 +74,21 @@ typedef struct { typedef phuff_entropy_decoder * phuff_entropy_ptr; /* Forward declarations */ -METHODDEF boolean decode_mcu_DC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_AC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo, JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo, JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); /* * Initialize for a Huffman-compressed scan. */ -METHODDEF void +METHODDEF(void) start_pass_phuff_decoder (j_decompress_ptr cinfo) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -119,6 +119,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) } if (cinfo->Al > 13) /* need not check for < 0 */ bad = TRUE; + /* Arguably the maximum Al value should be less than 13 for 8-bit precision, + * but the spec doesn't say so, and we try to be liberal about what we + * accept. Note: large Al values could result in out-of-range DC + * coefficients during early scans, leading to bizarre displays due to + * overflows in the IDCT math. But we won't crash. + */ if (bad) ERREXIT4(cinfo, JERR_BAD_PROGRESSION, cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); @@ -160,18 +166,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) if (is_DC_band) { if (cinfo->Ah == 0) { /* DC refinement needs no table */ tbl = compptr->dc_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - cinfo->dc_huff_tbl_ptrs[tbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); - jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, & entropy->derived_tbls[tbl]); } } else { tbl = compptr->ac_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - cinfo->ac_huff_tbl_ptrs[tbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); - jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, & entropy->derived_tbls[tbl]); /* remember the single active table */ entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; @@ -183,7 +183,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) /* Initialize bitread state variables */ entropy->bitstate.bits_left = 0; entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->bitstate.printed_eod = FALSE; + entropy->pub.insufficient_data = FALSE; /* Initialize private state variables */ entropy->saved.EOBRUN = 0; @@ -224,7 +224,7 @@ static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ * Returns FALSE if must suspend. */ -LOCAL boolean +LOCAL(boolean) process_restart (j_decompress_ptr cinfo) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -248,8 +248,13 @@ process_restart (j_decompress_ptr cinfo) /* Reset restart counter */ entropy->restarts_to_go = cinfo->restart_interval; - /* Next segment can get another out-of-data warning */ - entropy->bitstate.printed_eod = FALSE; + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; return TRUE; } @@ -277,7 +282,7 @@ process_restart (j_decompress_ptr cinfo) * or first pass of successive approximation). */ -METHODDEF boolean +METHODDEF(boolean) decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -297,39 +302,45 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) return FALSE; } - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { - /* Outer loop handles each block in the MCU */ + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + + /* Decode a single block's worth of coefficients */ - /* Decode a single block's worth of coefficients */ + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, tbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, tbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ + (*block)[0] = (JCOEF) (s << Al); } - /* Convert DC difference to actual value, update last_dc_val */ - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */ - (*block)[0] = (JCOEF) (s << Al); + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); } - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - /* Account for restart interval (no-op if not using restarts) */ entropy->restarts_to_go--; @@ -342,7 +353,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) * or first pass of successive approximation). */ -METHODDEF boolean +METHODDEF(boolean) decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -361,53 +372,59 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) return FALSE; } - /* Load up working state. - * We can avoid loading/saving bitread state if in an EOB run. + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. */ - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ - - /* There is always only one block per MCU */ - - if (EOBRUN > 0) /* if it's a band of zeroes... */ - EOBRUN--; /* ...process it now (we do nothing) */ - else { - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; + if (! entropy->pub.insufficient_data) { - for (k = cinfo->Ss; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, return FALSE, label2); - r = s >> 4; - s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Scale and output coefficient in natural (dezigzagged) order */ - (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); - } else { - if (r == 15) { /* ZRL */ - k += 15; /* skip 15 zeroes in band */ - } else { /* EOBr, run length is 2^r + appended bits */ - EOBRUN = 1 << r; - if (r) { /* EOBr, r > 0 */ - CHECK_BIT_BUFFER(br_state, r, return FALSE); - r = GET_BITS(r); - EOBRUN += r; - } - EOBRUN--; /* this band is processed at this moment */ - break; /* force end-of-band */ + /* Load up working state. + * We can avoid loading/saving bitread state if in an EOB run. + */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ + else { + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + for (k = cinfo->Ss; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } } } + + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); } - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + /* Completed MCU, so update state */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ } - /* Completed MCU, so update state */ - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ - /* Account for restart interval (no-op if not using restarts) */ entropy->restarts_to_go--; @@ -421,7 +438,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) * is not very clear on the point. */ -METHODDEF boolean +METHODDEF(boolean) decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -437,6 +454,10 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) return FALSE; } + /* Not worth the cycles to check insufficient_data here, + * since we will not change the data anyway if we read zeroes. + */ + /* Load up working state */ BITREAD_LOAD_STATE(cinfo,entropy->bitstate); @@ -466,7 +487,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) * MCU decoding for AC successive approximation refinement scan. */ -METHODDEF boolean +METHODDEF(boolean) decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; @@ -489,55 +510,93 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) return FALSE; } - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ - - /* There is always only one block per MCU */ - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; - - /* If we are forced to suspend, we must undo the assignments to any newly - * nonzero coefficients in the block, because otherwise we'd get confused - * next time about which coefficients were already nonzero. - * But we need not undo addition of bits to already-nonzero coefficients; - * instead, we can test the current bit position to see if we already did it. + /* If we've run out of data, don't modify the MCU. */ - num_newnz = 0; + if (! entropy->pub.insufficient_data) { - /* initialize coefficient loop counter to start of band */ - k = cinfo->Ss; + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ - if (EOBRUN == 0) { - for (; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, goto undoit, label3); - r = s >> 4; - s &= 15; - if (s) { - if (s != 1) /* size of new coef should always be 1 */ - WARNMS(cinfo, JWRN_HUFF_BAD_CODE); - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) - s = p1; /* newly nonzero coef is positive */ - else - s = m1; /* newly nonzero coef is negative */ - } else { - if (r != 15) { - EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ - if (r) { - CHECK_BIT_BUFFER(br_state, r, goto undoit); - r = GET_BITS(r); - EOBRUN += r; + /* There is always only one block per MCU */ + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + /* If we are forced to suspend, we must undo the assignments to any newly + * nonzero coefficients in the block, because otherwise we'd get confused + * next time about which coefficients were already nonzero. + * But we need not undo addition of bits to already-nonzero coefficients; + * instead, we can test the current bit to see if we already did it. + */ + num_newnz = 0; + + /* initialize coefficient loop counter to start of band */ + k = cinfo->Ss; + + if (EOBRUN == 0) { + for (; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ } - break; /* rest of block is handled by EOB logic */ + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; } - /* note s = 0 for processing ZRL */ } - /* Advance over already-nonzero coefs and r still-zero coefs, - * appending correction bits to the nonzeroes. A correction bit is 1 + } + + if (EOBRUN > 0) { + /* Scan any remaining coefficient positions after the end-of-band + * (the last newly nonzero coefficient, if any). Append a correction + * bit to each already-nonzero coefficient. A correction bit is 1 * if the absolute value of the coefficient must be increased. */ - do { + for (; k <= Se; k++) { thiscoef = *block + jpeg_natural_order[k]; if (*thiscoef != 0) { CHECK_BIT_BUFFER(br_state, 1, goto undoit); @@ -549,50 +608,17 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) *thiscoef += m1; } } - } else { - if (--r < 0) - break; /* reached target zero coefficient */ } - k++; - } while (k <= Se); - if (s) { - int pos = jpeg_natural_order[k]; - /* Output newly nonzero coefficient */ - (*block)[pos] = (JCOEF) s; - /* Remember its position in case we have to suspend */ - newnz_pos[num_newnz++] = pos; } + /* Count one block completed in EOB run */ + EOBRUN--; } - } - if (EOBRUN > 0) { - /* Scan any remaining coefficient positions after the end-of-band - * (the last newly nonzero coefficient, if any). Append a correction - * bit to each already-nonzero coefficient. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - for (; k <= Se; k++) { - thiscoef = *block + jpeg_natural_order[k]; - if (*thiscoef != 0) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } - } - /* Count one block completed in EOB run */ - EOBRUN--; + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ } - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ - /* Account for restart interval (no-op if not using restarts) */ entropy->restarts_to_go--; @@ -611,7 +637,7 @@ undoit: * Module initialization routine for progressive Huffman entropy decoding. */ -GLOBAL void +GLOBAL(void) jinit_phuff_decoder (j_decompress_ptr cinfo) { phuff_entropy_ptr entropy; diff --git a/src/jpeg-6/jdpostct.c b/src/jpeg-6b/jdpostct.c index f6120023..571563d7 100644 --- a/src/jpeg-6/jdpostct.c +++ b/src/jpeg-6b/jdpostct.c @@ -1,7 +1,7 @@ /* * jdpostct.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -43,20 +43,20 @@ typedef my_post_controller * my_post_ptr; /* Forward declarations */ -METHODDEF void post_process_1pass +METHODDEF(void) post_process_1pass JPP((j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); #ifdef QUANT_2PASS_SUPPORTED -METHODDEF void post_process_prepass +METHODDEF(void) post_process_prepass JPP((j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -METHODDEF void post_process_2pass +METHODDEF(void) post_process_2pass JPP((j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -69,7 +69,7 @@ METHODDEF void post_process_2pass * Initialize for a processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) { my_post_ptr post = (my_post_ptr) cinfo->post; @@ -122,7 +122,7 @@ start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) * This is used for color precision reduction as well as one-pass quantization. */ -METHODDEF void +METHODDEF(void) post_process_1pass (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -154,7 +154,7 @@ post_process_1pass (j_decompress_ptr cinfo, * Process some data in the first pass of 2-pass quantization. */ -METHODDEF void +METHODDEF(void) post_process_prepass (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -198,7 +198,7 @@ post_process_prepass (j_decompress_ptr cinfo, * Process some data in the second pass of 2-pass quantization. */ -METHODDEF void +METHODDEF(void) post_process_2pass (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -246,7 +246,7 @@ post_process_2pass (j_decompress_ptr cinfo, * Initialize postprocessing controller. */ -GLOBAL void +GLOBAL(void) jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { my_post_ptr post; diff --git a/src/jpeg-6/jdsample.c b/src/jpeg-6b/jdsample.c index 661e198d..80ffefb2 100644 --- a/src/jpeg-6/jdsample.c +++ b/src/jpeg-6b/jdsample.c @@ -1,7 +1,7 @@ /* * jdsample.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -65,7 +65,7 @@ typedef my_upsampler * my_upsample_ptr; * Initialize for an upsampling pass. */ -METHODDEF void +METHODDEF(void) start_pass_upsample (j_decompress_ptr cinfo) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; @@ -85,7 +85,7 @@ start_pass_upsample (j_decompress_ptr cinfo) * color conversion a row at a time. */ -METHODDEF void +METHODDEF(void) sep_upsample (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, @@ -153,7 +153,7 @@ sep_upsample (j_decompress_ptr cinfo, * "consumed" until we are done color converting and emitting it. */ -METHODDEF void +METHODDEF(void) fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -166,7 +166,7 @@ fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * These components will not be referenced by color conversion. */ -METHODDEF void +METHODDEF(void) noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -185,7 +185,7 @@ noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * you would be well advised to improve this code. */ -METHODDEF void +METHODDEF(void) int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -229,7 +229,7 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * It's still a box filter. */ -METHODDEF void +METHODDEF(void) h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -257,7 +257,7 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * It's still a box filter. */ -METHODDEF void +METHODDEF(void) h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -300,7 +300,7 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * alternate pixel locations (a simple ordered dither pattern). */ -METHODDEF void +METHODDEF(void) h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -341,7 +341,7 @@ h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * context from the main buffer controller (see initialization code). */ -METHODDEF void +METHODDEF(void) h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { @@ -395,7 +395,7 @@ h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, * Module initialization routine for upsampling. */ -GLOBAL void +GLOBAL(void) jinit_upsampler (j_decompress_ptr cinfo) { my_upsample_ptr upsample; diff --git a/src/jpeg-6/jdtrans.c b/src/jpeg-6b/jdtrans.c index 5c14adc6..6c0ab715 100644 --- a/src/jpeg-6/jdtrans.c +++ b/src/jpeg-6b/jdtrans.c @@ -1,7 +1,7 @@ /* * jdtrans.c * - * Copyright (C) 1995, Thomas G. Lane. + * Copyright (C) 1995-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -16,7 +16,7 @@ /* Forward declarations */ -LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo)); /* @@ -30,43 +30,61 @@ LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); * To release the memory occupied by the virtual arrays, call * jpeg_finish_decompress() when done with the data. * + * An alternative usage is to simply obtain access to the coefficient arrays + * during a buffered-image-mode decompression operation. This is allowed + * after any jpeg_finish_output() call. The arrays can be accessed until + * jpeg_finish_decompress() is called. (Note that any call to the library + * may reposition the arrays, so don't rely on access_virt_barray() results + * to stay valid across library calls.) + * * Returns NULL if suspended. This case need be checked only if * a suspending data source is used. */ -GLOBAL jvirt_barray_ptr * +GLOBAL(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo) { if (cinfo->global_state == DSTATE_READY) { /* First call: initialize active modules */ transdecode_master_selection(cinfo); cinfo->global_state = DSTATE_RDCOEFS; - } else if (cinfo->global_state != DSTATE_RDCOEFS) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Absorb whole file into the coef buffer */ - for (;;) { - int retcode; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - /* Absorb some more input */ - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_SUSPENDED) - return NULL; - if (retcode == JPEG_REACHED_EOI) - break; - /* Advance progress counter if appropriate */ - if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* startup underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + if (cinfo->global_state == DSTATE_RDCOEFS) { + /* Absorb whole file into the coef buffer */ + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return NULL; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } } } + /* Set state so that jpeg_finish_decompress does the right thing */ + cinfo->global_state = DSTATE_STOPPING; } - /* Set state so that jpeg_finish_decompress does the right thing */ - cinfo->global_state = DSTATE_STOPPING; - return cinfo->coef->coef_arrays; + /* At this point we should be in state DSTATE_STOPPING if being used + * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + * to the coefficients during a full buffered-image-mode decompression. + */ + if ((cinfo->global_state == DSTATE_STOPPING || + cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { + return cinfo->coef->coef_arrays; + } + /* Oops, improper usage */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return NULL; /* keep compiler happy */ } @@ -75,9 +93,12 @@ jpeg_read_coefficients (j_decompress_ptr cinfo) * This substitutes for jdmaster.c's initialization of the full decompressor. */ -LOCAL void +LOCAL(void) transdecode_master_selection (j_decompress_ptr cinfo) { + /* This is effectively a buffered-image operation. */ + cinfo->buffered_image = TRUE; + /* Entropy decoding: either Huffman or arithmetic coding. */ if (cinfo->arith_code) { ERREXIT(cinfo, JERR_ARITH_NOTIMPL); diff --git a/src/jpeg-6/jerror.c b/src/jpeg-6b/jerror.c index 026e2d11..9df35d69 100644 --- a/src/jpeg-6/jerror.c +++ b/src/jpeg-6b/jerror.c @@ -1,7 +1,7 @@ /* * jerror.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -10,6 +10,11 @@ * stderr is the right thing to do. Many applications will want to replace * some or all of these routines. * + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, + * you get a Windows-specific hack to display error messages in a dialog box. + * It ain't much, but it beats dropping error messages into the bit bucket, + * which is what happens to output to stderr under most Windows C compilers. + * * These routines are used by both the compression and decompression code. */ @@ -21,6 +26,10 @@ #include "jversion.h" #include "jerror.h" +#ifdef USE_WINDOWS_MESSAGEBOX +#include <windows.h> +#endif + #ifndef EXIT_FAILURE /* define exit() codes if not provided */ #define EXIT_FAILURE 1 #endif @@ -59,7 +68,7 @@ const char * const jpeg_std_message_table[] = { * or jpeg_destroy) at some point. */ -METHODDEF void +METHODDEF(void) error_exit (j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; @@ -78,9 +87,18 @@ error_exit (j_common_ptr cinfo) * Actual output of an error or trace message. * Applications may override this method to send JPEG messages somewhere * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. */ -METHODDEF void +METHODDEF(void) output_message (j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; @@ -88,8 +106,14 @@ output_message (j_common_ptr cinfo) /* Create the message */ (*cinfo->err->format_message) (cinfo, buffer); +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else /* Send it to stderr, adding a newline */ ri.Printf(PRINT_ALL, "%s\n", buffer); +#endif } @@ -104,7 +128,7 @@ output_message (j_common_ptr cinfo) * or change the policy about which messages to display. */ -METHODDEF void +METHODDEF(void) emit_message (j_common_ptr cinfo, int msg_level) { struct jpeg_error_mgr * err = cinfo->err; @@ -133,7 +157,7 @@ emit_message (j_common_ptr cinfo, int msg_level) * Few applications should need to override this method. */ -METHODDEF void +METHODDEF(void) format_message (j_common_ptr cinfo, char * buffer) { struct jpeg_error_mgr * err = cinfo->err; @@ -188,7 +212,7 @@ format_message (j_common_ptr cinfo, char * buffer) * this method if it has additional error processing state. */ -METHODDEF void +METHODDEF(void) reset_error_mgr (j_common_ptr cinfo) { cinfo->err->num_warnings = 0; @@ -207,7 +231,7 @@ reset_error_mgr (j_common_ptr cinfo) * after which the application may override some of the methods. */ -GLOBAL struct jpeg_error_mgr * +GLOBAL(struct jpeg_error_mgr *) jpeg_std_error (struct jpeg_error_mgr * err) { err->error_exit = error_exit; diff --git a/src/jpeg-6/jerror.h b/src/jpeg-6b/jerror.h index bf60e7ec..fc2fffea 100644 --- a/src/jpeg-6/jerror.h +++ b/src/jpeg-6b/jerror.h @@ -1,7 +1,7 @@ /* * jerror.h * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -45,10 +45,14 @@ JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") @@ -59,6 +63,8 @@ JMESSAGE(JERR_BAD_PROG_SCRIPT, JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") @@ -67,7 +73,6 @@ JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") -JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts") JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") @@ -130,12 +135,13 @@ JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") JMESSAGE(JTRC_EOI, "End Of Image") JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") -JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d %d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, "Warning: thumbnail image size does not match data length %u") -JMESSAGE(JTRC_JFIF_MINOR, "Unknown JFIF minor revision number %d.%02d") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") -JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") @@ -153,6 +159,12 @@ JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") JMESSAGE(JTRC_UNKNOWN_IDS, "Unrecognized component IDs %d %d %d, assuming YCbCr") JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") @@ -259,6 +271,12 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ (cinfo)->err->msg_code = (code); \ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) #define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ diff --git a/src/jpeg-6/jfdctflt.c b/src/jpeg-6b/jfdctflt.c index 21371eb8..79d7a007 100644 --- a/src/jpeg-6/jfdctflt.c +++ b/src/jpeg-6b/jfdctflt.c @@ -1,7 +1,7 @@ /* * jfdctflt.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -55,7 +55,7 @@ * Perform the forward DCT on one block of samples. */ -GLOBAL void +GLOBAL(void) jpeg_fdct_float (FAST_FLOAT * data) { FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; diff --git a/src/jpeg-6/jfdctfst.c b/src/jpeg-6b/jfdctfst.c index a52d7b73..ccb378a3 100644 --- a/src/jpeg-6/jfdctfst.c +++ b/src/jpeg-6b/jfdctfst.c @@ -1,7 +1,7 @@ /* * jfdctfst.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -110,7 +110,7 @@ * Perform the forward DCT on one block of samples. */ -GLOBAL void +GLOBAL(void) jpeg_fdct_ifast (DCTELEM * data) { DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; diff --git a/src/jpeg-6/jfdctint.c b/src/jpeg-6b/jfdctint.c index 7df04330..0a78b64a 100644 --- a/src/jpeg-6/jfdctint.c +++ b/src/jpeg-6b/jfdctint.c @@ -1,7 +1,7 @@ /* * jfdctint.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -136,7 +136,7 @@ * Perform the forward DCT on one block of samples. */ -GLOBAL void +GLOBAL(void) jpeg_fdct_islow (DCTELEM * data) { INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; diff --git a/src/jpeg-6/jidctflt.c b/src/jpeg-6b/jidctflt.c index 847919ee..0188ce3d 100644 --- a/src/jpeg-6/jidctflt.c +++ b/src/jpeg-6b/jidctflt.c @@ -1,7 +1,7 @@ /* * jidctflt.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -64,7 +64,7 @@ * Perform dequantization and inverse DCT on one block of coefficients. */ -GLOBAL void +GLOBAL(void) jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) @@ -96,9 +96,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, * column DCT calculations can be simplified this way. */ - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); diff --git a/src/jpeg-6/jidctfst.c b/src/jpeg-6b/jidctfst.c index 5736817e..dba4216f 100644 --- a/src/jpeg-6/jidctfst.c +++ b/src/jpeg-6b/jidctfst.c @@ -1,7 +1,7 @@ /* * jidctfst.c * - * Copyright (C) 1994-1995, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -164,7 +164,7 @@ * Perform dequantization and inverse DCT on one block of coefficients. */ -GLOBAL void +GLOBAL(void) jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) @@ -197,9 +197,10 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, * column DCT calculations can be simplified this way. */ - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); @@ -289,8 +290,8 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, */ #ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) & RANGE_MASK]; diff --git a/src/jpeg-6/jidctint.c b/src/jpeg-6b/jidctint.c index f25b08de..a72b3207 100644 --- a/src/jpeg-6/jidctint.c +++ b/src/jpeg-6b/jidctint.c @@ -1,7 +1,7 @@ /* * jidctint.c * - * Copyright (C) 1991-1994, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -144,7 +144,7 @@ * Perform dequantization and inverse DCT on one block of coefficients. */ -GLOBAL void +GLOBAL(void) jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) @@ -178,9 +178,10 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, * column DCT calculations can be simplified this way. */ - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -284,8 +285,8 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, */ #ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) & RANGE_MASK]; diff --git a/src/jpeg-6/jidctred.c b/src/jpeg-6b/jidctred.c index 019c339c..421f3c7c 100644 --- a/src/jpeg-6/jidctred.c +++ b/src/jpeg-6b/jidctred.c @@ -1,7 +1,7 @@ /* * jidctred.c * - * Copyright (C) 1994, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -114,7 +114,7 @@ * producing a reduced-size 4x4 output block. */ -GLOBAL void +GLOBAL(void) jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) @@ -139,8 +139,9 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* Don't bother to process column 4, because second pass won't use it */ if (ctr == DCTSIZE-4) continue; - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) { + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && + inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { /* AC terms all zero; we need not examine term 4 for 4x4 output */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -198,8 +199,8 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* It's not clear whether a zero row test is worthwhile here ... */ #ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) & RANGE_MASK]; @@ -266,7 +267,7 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, * producing a reduced-size 2x2 output block. */ -GLOBAL void +GLOBAL(void) jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) @@ -290,8 +291,8 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* Don't bother to process columns 2,4,6 */ if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) continue; - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) { + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -331,7 +332,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* It's not clear whether a zero row test is worthwhile here ... */ #ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) { + if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) & RANGE_MASK]; @@ -374,7 +375,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, * producing a reduced-size 1x1 output block. */ -GLOBAL void +GLOBAL(void) jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col) diff --git a/src/jpeg-6/jinclude.h b/src/jpeg-6b/jinclude.h index aede8ec9..1c5515cd 100644 --- a/src/jpeg-6/jinclude.h +++ b/src/jpeg-6b/jinclude.h @@ -42,7 +42,7 @@ /* Include auto-config file to find out which system include files we need. */ -#include "../jpeg-6/jconfig.h" /* auto configuration options */ +#include "../jpeg-6b/jconfig.h" /* auto configuration options */ #define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ /* diff --git a/src/jpeg-6/jload.c b/src/jpeg-6b/jload.c index 29e750b3..29e750b3 100644 --- a/src/jpeg-6/jload.c +++ b/src/jpeg-6b/jload.c diff --git a/src/jpeg-6/jmemansi.c b/src/jpeg-6b/jmemansi.c index 70010f96..2d93e496 100644 --- a/src/jpeg-6/jmemansi.c +++ b/src/jpeg-6b/jmemansi.c @@ -1,7 +1,7 @@ /* * jmemansi.c * - * Copyright (C) 1992-1994, Thomas G. Lane. + * Copyright (C) 1992-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -32,13 +32,13 @@ extern void free JPP((void *ptr)); * routines malloc() and free(). */ -GLOBAL void * +GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) { return (void *) malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) { free(object); @@ -52,13 +52,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) * you probably won't be able to process useful-size images in only 64KB. */ -GLOBAL void FAR * +GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) { return (void FAR *) malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) { free(object); @@ -77,7 +77,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) #define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ #endif -GLOBAL long +GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) { @@ -93,7 +93,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, */ -METHODDEF void +METHODDEF(void) read_backing_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -106,7 +106,7 @@ read_backing_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) write_backing_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -119,7 +119,7 @@ write_backing_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) close_backing_store (j_common_ptr cinfo, backing_store_ptr info) { fclose(info->temp_file); @@ -137,7 +137,7 @@ close_backing_store (j_common_ptr cinfo, backing_store_ptr info) * indeed, we can't even find out the actual name of the temp file. */ -GLOBAL void +GLOBAL(void) jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -154,13 +154,13 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, * cleanup required. */ -GLOBAL long +GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) { return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ } -GLOBAL void +GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) { /* no work */ diff --git a/src/jpeg-6/jmemdos.c b/src/jpeg-6b/jmemdos.c index 4db8ec57..60b45c69 100644 --- a/src/jpeg-6/jmemdos.c +++ b/src/jpeg-6b/jmemdos.c @@ -1,7 +1,7 @@ /* * jmemdos.c * - * Copyright (C) 1992-1994, Thomas G. Lane. + * Copyright (C) 1992-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -77,6 +77,10 @@ extern char * getenv JPP((const char * name)); #define READ_BINARY "rb" #endif +#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */ + You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */ +#endif + #if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ #endif @@ -85,7 +89,7 @@ extern char * getenv JPP((const char * name)); /* * Declarations for assembly-language support routines (see jmemdosa.asm). * - * The functions are declared "far" as are all pointer arguments; + * The functions are declared "far" as are all their pointer arguments; * this ensures the assembly source code will work regardless of the * compiler memory model. We assume "short" is 16 bits, "long" is 32. */ @@ -100,17 +104,17 @@ typedef struct { /* registers for calling EMS driver */ void far * ds_si; } EMScontext; -EXTERN short far jdos_open JPP((short far * handle, char far * filename)); -EXTERN short far jdos_close JPP((short handle)); -EXTERN short far jdos_seek JPP((short handle, long offset)); -EXTERN short far jdos_read JPP((short handle, void far * buffer, +extern short far jdos_open JPP((short far * handle, char far * filename)); +extern short far jdos_close JPP((short handle)); +extern short far jdos_seek JPP((short handle, long offset)); +extern short far jdos_read JPP((short handle, void far * buffer, unsigned short count)); -EXTERN short far jdos_write JPP((short handle, void far * buffer, +extern short far jdos_write JPP((short handle, void far * buffer, unsigned short count)); -EXTERN void far jxms_getdriver JPP((XMSDRIVER far *)); -EXTERN void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); -EXTERN short far jems_available JPP((void)); -EXTERN void far jems_calldriver JPP((EMScontext far *)); +extern void far jxms_getdriver JPP((XMSDRIVER far *)); +extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); +extern short far jems_available JPP((void)); +extern void far jems_calldriver JPP((EMScontext far *)); /* @@ -120,7 +124,7 @@ EXTERN void far jems_calldriver JPP((EMScontext far *)); static int next_file_num; /* to distinguish among several temp files */ -LOCAL void +LOCAL(void) select_file_name (char * fname) { const char * env; @@ -158,13 +162,13 @@ select_file_name (char * fname) * routines malloc() and free(). */ -GLOBAL void * +GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) { return (void *) malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) { free(object); @@ -175,13 +179,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) * "Large" objects are allocated in far memory, if possible */ -GLOBAL void FAR * +GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) { return (void FAR *) far_malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) { far_free(object); @@ -200,7 +204,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) #define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ #endif -GLOBAL long +GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) { @@ -235,7 +239,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, */ -METHODDEF void +METHODDEF(void) read_file_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -251,7 +255,7 @@ read_file_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) write_file_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -267,7 +271,7 @@ write_file_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) close_file_store (j_common_ptr cinfo, backing_store_ptr info) { jdos_close(info->handle.file_handle); /* close the file */ @@ -280,7 +284,7 @@ close_file_store (j_common_ptr cinfo, backing_store_ptr info) } -LOCAL boolean +LOCAL(boolean) open_file_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -325,7 +329,7 @@ typedef struct { /* XMS move specification structure */ #define ODD(X) (((X) & 1L) != 0) -METHODDEF void +METHODDEF(void) read_xms_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -358,7 +362,7 @@ read_xms_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) write_xms_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -393,7 +397,7 @@ write_xms_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) close_xms_store (j_common_ptr cinfo, backing_store_ptr info) { XMScontext ctx; @@ -406,7 +410,7 @@ close_xms_store (j_common_ptr cinfo, backing_store_ptr info) } -LOCAL boolean +LOCAL(boolean) open_xms_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -483,7 +487,7 @@ typedef union { /* EMS move specification structure */ #define LOBYTE(W) ((W) & 0xFF) -METHODDEF void +METHODDEF(void) read_ems_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -508,7 +512,7 @@ read_ems_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) write_ems_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -533,7 +537,7 @@ write_ems_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) close_ems_store (j_common_ptr cinfo, backing_store_ptr info) { EMScontext ctx; @@ -546,7 +550,7 @@ close_ems_store (j_common_ptr cinfo, backing_store_ptr info) } -LOCAL boolean +LOCAL(boolean) open_ems_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -591,7 +595,7 @@ open_ems_store (j_common_ptr cinfo, backing_store_ptr info, * Initial opening of a backing-store object. */ -GLOBAL void +GLOBAL(void) jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -615,14 +619,14 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, * cleanup required. */ -GLOBAL long +GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) { next_file_num = 0; /* initialize temp file name generator */ return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ } -GLOBAL void +GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) { /* Microsoft C, at least in v6.00A, will not successfully reclaim freed diff --git a/src/jpeg-6/jmemmgr.c b/src/jpeg-6b/jmemmgr.c index dc3e1c76..d801b322 100644 --- a/src/jpeg-6/jmemmgr.c +++ b/src/jpeg-6b/jmemmgr.c @@ -1,7 +1,7 @@ /* * jmemmgr.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -182,7 +182,7 @@ struct jvirt_barray_control { #ifdef MEM_STATS /* optional extra stuff for statistics */ -LOCAL void +LOCAL(void) print_mem_stats (j_common_ptr cinfo, int pool_id) { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -213,7 +213,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id) #endif /* MEM_STATS */ -LOCAL void +LOCAL(void) out_of_memory (j_common_ptr cinfo, int which) /* Report an out-of-memory error and stop execution */ /* If we compiled MEM_STATS support, report alloc requests before dying */ @@ -253,7 +253,7 @@ static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = #define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ -METHODDEF void * +METHODDEF(void *) alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* Allocate a "small" object */ { @@ -338,7 +338,7 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) * deliberately bunch rows together to ensure a large request size. */ -METHODDEF void FAR * +METHODDEF(void FAR *) alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* Allocate a "large" object */ { @@ -391,7 +391,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) * a virtual array. */ -METHODDEF JSAMPARRAY +METHODDEF(JSAMPARRAY) alloc_sarray (j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow, JDIMENSION numrows) /* Allocate a 2-D sample array */ @@ -439,7 +439,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id, * This is essentially the same as the code for sample arrays, above. */ -METHODDEF JBLOCKARRAY +METHODDEF(JBLOCKARRAY) alloc_barray (j_common_ptr cinfo, int pool_id, JDIMENSION blocksperrow, JDIMENSION numrows) /* Allocate a 2-D coefficient-block array */ @@ -519,7 +519,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id, */ -METHODDEF jvirt_sarray_ptr +METHODDEF(jvirt_sarray_ptr) request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION samplesperrow, JDIMENSION numrows, JDIMENSION maxaccess) @@ -549,7 +549,7 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, } -METHODDEF jvirt_barray_ptr +METHODDEF(jvirt_barray_ptr) request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION maxaccess) @@ -579,7 +579,7 @@ request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, } -METHODDEF void +METHODDEF(void) realize_virt_arrays (j_common_ptr cinfo) /* Allocate the in-memory buffers for any unrealized virtual arrays */ { @@ -686,7 +686,7 @@ realize_virt_arrays (j_common_ptr cinfo) } -LOCAL void +LOCAL(void) do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) /* Do backing store read or write of a virtual sample array */ { @@ -719,7 +719,7 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) } -LOCAL void +LOCAL(void) do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) /* Do backing store read or write of a virtual coefficient-block array */ { @@ -752,7 +752,7 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) } -METHODDEF JSAMPARRAY +METHODDEF(JSAMPARRAY) access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable) @@ -837,7 +837,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, } -METHODDEF JBLOCKARRAY +METHODDEF(JBLOCKARRAY) access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable) @@ -926,7 +926,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, * Release all objects belonging to a specified pool. */ -METHODDEF void +METHODDEF(void) free_pool (j_common_ptr cinfo, int pool_id) { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -998,7 +998,7 @@ free_pool (j_common_ptr cinfo, int pool_id) * Note that this cannot be called unless cinfo->mem is non-NULL. */ -METHODDEF void +METHODDEF(void) self_destruct (j_common_ptr cinfo) { int pool; @@ -1024,7 +1024,7 @@ self_destruct (j_common_ptr cinfo) * When this is called, only the error manager pointer is valid in cinfo! */ -GLOBAL void +GLOBAL(void) jinit_memory_mgr (j_common_ptr cinfo) { my_mem_ptr mem; @@ -1076,6 +1076,9 @@ jinit_memory_mgr (j_common_ptr cinfo) mem->pub.free_pool = free_pool; mem->pub.self_destruct = self_destruct; + /* Make MAX_ALLOC_CHUNK accessible to other modules */ + mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK; + /* Initialize working state */ mem->pub.max_memory_to_use = max_to_use; diff --git a/src/jpeg-6/jmemname.c b/src/jpeg-6b/jmemname.c index ba826fbb..ed96dee1 100644 --- a/src/jpeg-6/jmemname.c +++ b/src/jpeg-6b/jmemname.c @@ -1,7 +1,7 @@ /* * jmemname.c * - * Copyright (C) 1992-1994, Thomas G. Lane. + * Copyright (C) 1992-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -30,9 +30,14 @@ extern void free JPP((void *ptr)); #define READ_BINARY "r" #define RW_BINARY "w+" #else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define RW_BINARY "w+b", "ctx=stm" +#else /* standard ANSI-compliant case */ #define READ_BINARY "rb" #define RW_BINARY "w+b" #endif +#endif /* @@ -86,7 +91,7 @@ extern int errno; #endif -LOCAL void +LOCAL(void) select_file_name (char * fname) { FILE * tfile; @@ -117,7 +122,7 @@ select_file_name (char * fname) #define TEMP_FILE_NAME "%sJPG%dXXXXXX" #endif -LOCAL void +LOCAL(void) select_file_name (char * fname) { next_file_num++; /* advance counter */ @@ -134,13 +139,13 @@ select_file_name (char * fname) * routines malloc() and free(). */ -GLOBAL void * +GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) { return (void *) malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) { free(object); @@ -154,13 +159,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) * you probably won't be able to process useful-size images in only 64KB. */ -GLOBAL void FAR * +GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) { return (void FAR *) malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) { free(object); @@ -179,7 +184,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) #define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ #endif -GLOBAL long +GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) { @@ -195,7 +200,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, */ -METHODDEF void +METHODDEF(void) read_backing_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -208,7 +213,7 @@ read_backing_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) write_backing_store (j_common_ptr cinfo, backing_store_ptr info, void FAR * buffer_address, long file_offset, long byte_count) @@ -221,7 +226,7 @@ write_backing_store (j_common_ptr cinfo, backing_store_ptr info, } -METHODDEF void +METHODDEF(void) close_backing_store (j_common_ptr cinfo, backing_store_ptr info) { fclose(info->temp_file); /* close the file */ @@ -238,7 +243,7 @@ close_backing_store (j_common_ptr cinfo, backing_store_ptr info) * Initial opening of a backing-store object. */ -GLOBAL void +GLOBAL(void) jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -257,14 +262,14 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, * cleanup required. */ -GLOBAL long +GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) { next_file_num = 0; /* initialize temp file name generator */ return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ } -GLOBAL void +GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) { /* no work */ diff --git a/src/jpeg-6/jmemnobs.c b/src/jpeg-6b/jmemnobs.c index 87533a19..cbd60814 100644 --- a/src/jpeg-6/jmemnobs.c +++ b/src/jpeg-6b/jmemnobs.c @@ -1,7 +1,7 @@ /* * jmemnobs.c * - * Copyright (C) 1992-1994, Thomas G. Lane. + * Copyright (C) 1992-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -23,17 +23,17 @@ #include "jmemsys.h" /* import the system-dependent declarations */ /* - * Memory allocation and ri.Freeing are controlled by the regular library + * Memory allocation and freeing are controlled by the regular library * routines ri.Malloc() and ri.Free(). */ -GLOBAL void * +GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) { return (void *) ri.Malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) { ri.Free(object); @@ -47,13 +47,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) * you probably won't be able to process useful-size images in only 64KB. */ -GLOBAL void FAR * +GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) { return (void FAR *) ri.Malloc(sizeofobject); } -GLOBAL void +GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) { ri.Free(object); @@ -65,7 +65,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) * Here we always say, "we got all you want bud!" */ -GLOBAL long +GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) { @@ -79,7 +79,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, * this should never be called and we can just error out. */ -GLOBAL void +GLOBAL(void) jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { @@ -92,13 +92,13 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, * cleanup required. Here, there isn't any. */ -GLOBAL long +GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) { return 0; /* just set max_memory_to_use to 0 */ } -GLOBAL void +GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) { /* no work */ diff --git a/src/jpeg-6/jmemsys.h b/src/jpeg-6b/jmemsys.h index 033d29a7..6c3c6d34 100644 --- a/src/jpeg-6/jmemsys.h +++ b/src/jpeg-6b/jmemsys.h @@ -1,7 +1,7 @@ /* * jmemsys.h * - * Copyright (C) 1992-1994, Thomas G. Lane. + * Copyright (C) 1992-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -14,7 +14,8 @@ * in the IJG distribution. You may need to modify it if you write a * custom memory manager. If system-dependent changes are needed in * this file, the best method is to #ifdef them based on a configuration - * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR. + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. */ @@ -43,9 +44,9 @@ * On an 80x86 machine using small-data memory model, these manage near heap. */ -EXTERN void * jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); -EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object, - size_t sizeofobject)); +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); /* * These two functions are used to allocate and release large chunks of @@ -56,9 +57,10 @@ EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object, * in case a different allocation strategy is desirable for large chunks. */ -EXTERN void FAR * jpeg_get_large JPP((j_common_ptr cinfo,size_t sizeofobject)); -EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, - size_t sizeofobject)); +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, + size_t sizeofobject)); +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); /* * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may @@ -98,10 +100,10 @@ EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, * Conversely, zero may be returned to always use the minimum amount of memory. */ -EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo, - long min_bytes_needed, - long max_bytes_needed, - long already_allocated)); +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); /* @@ -113,6 +115,7 @@ EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo, #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + #ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ typedef unsigned short XMSH; /* type of extended-memory handles */ @@ -126,6 +129,11 @@ typedef union { #endif /* USE_MSDOS_MEMMGR */ +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#include <Files.h> +#endif /* USE_MAC_MEMMGR */ + + typedef struct backing_store_struct * backing_store_ptr; typedef struct backing_store_struct { @@ -147,12 +155,20 @@ typedef struct backing_store_struct { handle_union handle; /* reference to backing-store storage object */ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ #else +#ifdef USE_MAC_MEMMGR + /* For the Mac manager (jmemmac.c), we need: */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else /* For a typical implementation with temp files, we need: */ FILE * temp_file; /* stdio reference to temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ #endif +#endif } backing_store_info; + /* * Initial opening of a backing-store object. This must fill in the * read/write/close pointers in the object. The read/write routines @@ -161,9 +177,9 @@ typedef struct backing_store_struct { * just take an error exit.) */ -EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, - backing_store_ptr info, - long total_bytes_needed)); +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); /* @@ -178,5 +194,5 @@ EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, * all opened backing-store objects have been closed. */ -EXTERN long jpeg_mem_init JPP((j_common_ptr cinfo)); -EXTERN void jpeg_mem_term JPP((j_common_ptr cinfo)); +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/src/jpeg-6/jmorecfg.h b/src/jpeg-6b/jmorecfg.h index 4cae5a4f..f8020071 100644 --- a/src/jpeg-6/jmorecfg.h +++ b/src/jpeg-6b/jmorecfg.h @@ -1,7 +1,7 @@ /* * jmorecfg.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -149,6 +149,12 @@ typedef unsigned short UINT16; typedef unsigned int UINT16; #endif /* HAVE_UNSIGNED_SHORT */ +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + /* INT32 must hold at least signed 32-bit values. */ /* MinGW basetsd.h defines INT32 - don't redefine it */ @@ -156,12 +162,6 @@ typedef unsigned int UINT16; typedef long INT32; #endif -/* INT16 must hold at least the values -32768..32767. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ -typedef short INT16; -#endif - /* Datatype used for image dimensions. The JPEG standard only supports * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore * "unsigned int" is sufficient on all machines. However, if you need to @@ -174,16 +174,34 @@ typedef unsigned int JDIMENSION; #define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ -/* These defines are used in all function definitions and extern declarations. - * You could modify them if you need to change function linkage conventions. +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. * Another application is to make all functions global for use with debuggers * or code profilers that require it. */ -#define METHODDEF static /* a function called through method pointers */ -#define LOCAL static /* a function used only in its module */ -#define GLOBAL /* a function referenced thru EXTERNs */ -#define EXTERN extern /* a reference to a GLOBAL function */ +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif /* Here is the pseudo-keyword for declaring pointers that must be "far" @@ -208,9 +226,7 @@ typedef unsigned int JDIMENSION; * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. */ -//#ifndef HAVE_BOOLEAN -//typedef int boolean; -//#endif +typedef unsigned char boolean; #ifndef FALSE /* in case these macros already exist */ #define FALSE 0 /* values of boolean */ #endif @@ -270,6 +286,7 @@ typedef unsigned int JDIMENSION; #undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #undef D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ #undef D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#undef SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ #undef BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ #undef IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ diff --git a/src/jpeg-6/jpegint.h b/src/jpeg-6b/jpegint.h index ab5bee2c..95b00d40 100644 --- a/src/jpeg-6/jpegint.h +++ b/src/jpeg-6b/jpegint.h @@ -1,7 +1,7 @@ /* * jpegint.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -118,15 +118,16 @@ struct jpeg_entropy_encoder { /* Marker writing */ struct jpeg_marker_writer { - /* write_any_marker is exported for use by applications */ - /* Probably only COM and APPn markers should be written */ - JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen)); JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, + unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); }; @@ -194,9 +195,6 @@ struct jpeg_marker_reader { JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); /* Read a restart marker --- exported for use by entropy decoder only */ jpeg_marker_parser_method read_restart_marker; - /* Application-overridable marker processing methods */ - jpeg_marker_parser_method process_COM; - jpeg_marker_parser_method process_APPn[16]; /* State of marker reader --- nominally internal, but applications * supplying COM or APPn handlers might like to know the state. @@ -212,6 +210,10 @@ struct jpeg_entropy_decoder { JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean insufficient_data; /* set TRUE after emitting warning */ }; /* Inverse DCT (also performs dequantization) */ @@ -329,53 +331,55 @@ struct jpeg_color_quantizer { /* Compression module initialization routines */ -EXTERN void jinit_compress_master JPP((j_compress_ptr cinfo)); -EXTERN void jinit_c_master_control JPP((j_compress_ptr cinfo, - boolean transcode_only)); -EXTERN void jinit_c_main_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_c_prep_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_c_coef_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_color_converter JPP((j_compress_ptr cinfo)); -EXTERN void jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN void jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN void jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN void jinit_phuff_encoder JPP((j_compress_ptr cinfo)); -EXTERN void jinit_marker_writer JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, + boolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); /* Decompression module initialization routines */ -EXTERN void jinit_master_decompress JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_d_main_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_d_coef_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_d_post_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_input_controller JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_inverse_dct JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_upsampler JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_color_deconverter JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); /* Memory manager initialization */ -EXTERN void jinit_memory_mgr JPP((j_common_ptr cinfo)); +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); /* Utility routines in jutils.c */ -EXTERN long jdiv_round_up JPP((long a, long b)); -EXTERN long jround_up JPP((long a, long b)); -EXTERN void jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols)); -EXTERN void jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks)); -EXTERN void jzero_far JPP((void FAR * target, size_t bytestozero)); +EXTERN(long) jdiv_round_up JPP((long a, long b)); +EXTERN(long) jround_up JPP((long a, long b)); +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); /* Constant tables in jutils.c */ +#if 0 /* This table is not actually needed in v6a */ extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +#endif extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ /* Suppress undefined-structure complaints if necessary. */ diff --git a/src/jpeg-6/jpeglib.h b/src/jpeg-6b/jpeglib.h index a0e9e27a..8ff305d2 100644 --- a/src/jpeg-6/jpeglib.h +++ b/src/jpeg-6b/jpeglib.h @@ -1,7 +1,7 @@ /* * jpeglib.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -13,7 +13,6 @@ #ifndef JPEGLIB_H #define JPEGLIB_H -typedef unsigned char boolean; /* * First we include the configuration files that record how this * installation of the JPEG library is set up. jconfig.h can be @@ -22,16 +21,16 @@ typedef unsigned char boolean; */ #ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ -#include "../jpeg-6/jconfig.h" /* widely used configuration options */ +#include "../jpeg-6b/jconfig.h" /* widely used configuration options */ #endif -#include "../jpeg-6/jmorecfg.h" /* seldom changed options */ +#include "../jpeg-6b/jmorecfg.h" /* seldom changed options */ /* Version ID for the JPEG library. * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". */ -#define JPEG_LIB_VERSION 60 /* Version 6 */ +#define JPEG_LIB_VERSION 62 /* Version 6b */ /* Various constants determining the sizes of things. @@ -59,18 +58,6 @@ typedef unsigned char boolean; #endif -/* This macro is used to declare a "method", that is, a function pointer. - * We want to supply prototype parameters if the compiler can cope. - * Note that the arglist parameter must be parenthesized! - */ - -#ifdef HAVE_PROTOTYPES -#define JMETHOD(type,methodname,arglist) type (*methodname) arglist -#else -#define JMETHOD(type,methodname,arglist) type (*methodname) () -#endif - - /* Data structures for images (arrays of samples and of DCT coefficients). * On 80x86 machines, the image arrays are too big for near pointers, * but the pointer arrays can fit in near memory. @@ -94,8 +81,9 @@ typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ /* DCT coefficient quantization tables. */ typedef struct { - /* This field directly represents the contents of a JPEG DQT marker. - * Note: the values are always given in zigzag order. + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. */ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ /* This field is used only during compression. It's initialized FALSE when @@ -182,7 +170,7 @@ typedef struct { /* Saved quantization table for component; NULL if none yet saved. * See jdinput.c comments about the need for this information. - * This field is not currently used by the compressor. + * This field is currently used only for decompression. */ JQUANT_TBL * quant_table; @@ -200,6 +188,18 @@ typedef struct { int Ah, Al; /* progressive JPEG successive approx. parms */ } jpeg_scan_info; +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; /* Known color spaces. */ @@ -242,8 +242,9 @@ typedef enum { struct jpeg_error_mgr * err; /* Error handler module */\ struct jpeg_memory_mgr * mem; /* Memory manager module */\ struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ - boolean is_decompressor; /* so common code can tell which is which */\ - int global_state /* for checking call sequence validity */ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ /* Routines that are to be used by both halves of the library are declared * to receive a pointer to this structure. There are no actual instances of @@ -334,6 +335,8 @@ struct jpeg_compress_struct { /* Parameters controlling emission of special markers. */ boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; /* These three values are not used by the JPEG code, merely copied */ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ @@ -398,6 +401,8 @@ struct jpeg_compress_struct { struct jpeg_downsampler * downsample; struct jpeg_forward_dct * fdct; struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; }; @@ -543,7 +548,9 @@ struct jpeg_decompress_struct { * the JPEG library. */ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ - /* Data copied from JFIF marker: */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; UINT8 density_unit; /* JFIF code for pixel size units */ UINT16 X_density; /* Horizontal pixel density */ UINT16 Y_density; /* Vertical pixel density */ @@ -552,6 +559,12 @@ struct jpeg_decompress_struct { boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + /* Remaining fields are known throughout decompressor, but generally * should not be touched by a surrounding application. */ @@ -784,6 +797,9 @@ struct jpeg_memory_mgr { * after creating the JPEG object. */ long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; }; @@ -814,12 +830,12 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); #ifdef NEED_SHORT_EXTERNAL_NAMES #define jpeg_std_error jStdError -#define jpeg_create_compress jCreaCompress -#define jpeg_create_decompress jCreaDecompress +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress #define jpeg_destroy_compress jDestCompress #define jpeg_destroy_decompress jDestDecompress #define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc +#define jpeg_mem_src jMemSrc #define jpeg_set_defaults jSetDefaults #define jpeg_set_colorspace jSetColorspace #define jpeg_default_colorspace jDefColorspace @@ -836,6 +852,8 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); #define jpeg_finish_compress jFinCompress #define jpeg_write_raw_data jWrtRawData #define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte #define jpeg_write_tables jWrtTables #define jpeg_read_header jReadHeader #define jpeg_start_decompress jStrtDecompress @@ -849,6 +867,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); #define jpeg_new_colormap jNewCMap #define jpeg_consume_input jConsumeInput #define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers #define jpeg_set_marker_processor jSetMarker #define jpeg_read_coefficients jReadCoefs #define jpeg_write_coefficients jWrtCoefs @@ -862,65 +881,86 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); /* Default error-management setup */ -EXTERN struct jpeg_error_mgr *jpeg_std_error JPP((struct jpeg_error_mgr *err)); - -/* Initialization and destruction of JPEG compression objects */ -/* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx */ -EXTERN void jpeg_create_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_create_decompress JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_destroy_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); /* Standard data source and destination managers: stdio streams. */ /* Caller is responsible for opening the file before and closing after. */ -EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN void jpeg_mem_src JPP((j_decompress_ptr cinfo, unsigned char *buffer, size_t size)); +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, unsigned char *inbuf, size_t size)); /* Default parameter setup for compression */ -EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); /* Compression parameter setup aids */ -EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); -EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); -EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); -EXTERN void jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); -EXTERN int jpeg_quality_scaling JPP((int quality)); -EXTERN void jpeg_simple_progression JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); -EXTERN JQUANT_TBL * jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); -EXTERN JHUFF_TBL * jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); /* Main entry points for compression */ -EXTERN void jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); -EXTERN JDIMENSION jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); -EXTERN void jpeg_finish_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); /* Replaces jpeg_write_scanlines when writing raw downsampled data. */ -EXTERN JDIMENSION jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); /* Write a special marker. See libjpeg.doc concerning safe usage. */ -EXTERN void jpeg_write_marker JPP((j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen)); +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); /* Alternate compression function: just write an abbreviated table file */ -EXTERN void jpeg_write_tables JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); /* Decompression startup: read start of JPEG datastream to see what's there */ -EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); /* Return value is one of: */ #define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ #define JPEG_HEADER_OK 1 /* Found valid image datastream */ @@ -932,25 +972,25 @@ EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo, */ /* Main entry points for decompression */ -EXTERN boolean jpeg_start_decompress JPP((j_decompress_ptr cinfo)); -EXTERN JDIMENSION jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); -EXTERN boolean jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); /* Replaces jpeg_read_scanlines when reading raw downsampled data. */ -EXTERN JDIMENSION jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); /* Additional entry points for buffered-image mode. */ -EXTERN boolean jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); -EXTERN boolean jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); -EXTERN boolean jpeg_finish_output JPP((j_decompress_ptr cinfo)); -EXTERN boolean jpeg_input_complete JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_new_colormap JPP((j_decompress_ptr cinfo)); -EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); /* Return value is one of: */ /* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ #define JPEG_REACHED_SOS 1 /* Reached start of new scan */ @@ -959,19 +999,24 @@ EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo)); #define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ /* Precalculate output dimensions for current decompression parameters. */ -EXTERN void jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); /* Install a special processing method for COM or APPn markers. */ -EXTERN void jpeg_set_marker_processor JPP((j_decompress_ptr cinfo, - int marker_code, - jpeg_marker_parser_method routine)); +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); /* Read or write raw DCT coefficients --- useful for lossless transcoding. */ -EXTERN jvirt_barray_ptr * jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); -EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); /* If you choose to abort compression or decompression before completing * jpeg_finish_(de)compress, then you need to clean up to release memory, @@ -979,18 +1024,18 @@ EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, * if you're done with the JPEG object, but if you want to clean it up and * reuse it, call this: */ -EXTERN void jpeg_abort_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); /* Generic versions of jpeg_abort and jpeg_destroy that work on either * flavor of JPEG object. These may be more convenient in some places. */ -EXTERN void jpeg_abort JPP((j_common_ptr cinfo)); -EXTERN void jpeg_destroy JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); /* Default restart-marker-resync procedure for use by data source modules */ -EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); /* These marker codes are exported since applications and data source modules @@ -1044,8 +1089,8 @@ struct jpeg_color_quantizer { long dummy; }; */ #ifdef JPEG_INTERNALS -#include "../jpeg-6/jpegint.h" /* fetch private declarations */ -#include "../jpeg-6/jerror.h" /* fetch error codes too */ +#include "../jpeg-6b/jpegint.h" /* fetch private declarations */ +#include "../jpeg-6b/jerror.h" /* fetch error codes too */ #endif #endif /* JPEGLIB_H */ diff --git a/src/jpeg-6/jpegtran.c b/src/jpeg-6b/jpegtran.c index f602c6b9..20ef111b 100644 --- a/src/jpeg-6/jpegtran.c +++ b/src/jpeg-6b/jpegtran.c @@ -1,21 +1,24 @@ /* * jpegtran.c * - * Copyright (C) 1995, Thomas G. Lane. + * Copyright (C) 1995-1997, Thomas G. Lane. * 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 a command-line user interface for JPEG transcoding. * It is very similar to cjpeg.c, but provides lossless transcoding between - * different JPEG file formats. + * different JPEG file formats. It also provides some lossless and sort-of- + * lossless transformations of JPEG data. */ #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "transupp.h" /* Support routines for jpegtran */ #include "jversion.h" /* for version message */ #ifdef USE_CCOMMAND /* command-line reader for Macintosh */ #ifdef __MWERKS__ -#include <SIOUX.h> /* Metrowerks declares it here */ +#include <SIOUX.h> /* Metrowerks needs this */ +#include <console.h> /* ... and this */ #endif #ifdef THINK_C #include <console.h> /* Think declares it here */ @@ -34,9 +37,11 @@ static const char * progname; /* program name for error messages */ static char * outfilename; /* for -outfile switch */ +static JCOPY_OPTION copyoption; /* -copy switch */ +static jpeg_transform_info transformoption; /* image transformation options */ -LOCAL void +LOCAL(void) usage (void) /* complain about bad command line */ { @@ -48,12 +53,24 @@ usage (void) #endif fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -copy none Copy no extra markers from source file\n"); + fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); + fprintf(stderr, " -copy all Copy all extra markers\n"); #ifdef ENTROPY_OPT_SUPPORTED fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); #endif #ifdef C_PROGRESSIVE_SUPPORTED fprintf(stderr, " -progressive Create progressive JPEG file\n"); #endif +#if TRANSFORMS_SUPPORTED + fprintf(stderr, "Switches for modifying the image:\n"); + fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n"); + fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n"); + fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n"); + fprintf(stderr, " -transpose Transpose image\n"); + fprintf(stderr, " -transverse Transverse transpose image\n"); + fprintf(stderr, " -trim Drop non-transformable edge blocks\n"); +#endif /* TRANSFORMS_SUPPORTED */ fprintf(stderr, "Switches for advanced users:\n"); fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); @@ -70,7 +87,30 @@ usage (void) } -LOCAL int +LOCAL(void) +select_transform (JXFORM_CODE transform) +/* Silly little routine to detect multiple transform options, + * which we can't handle. + */ +{ +#if TRANSFORMS_SUPPORTED + if (transformoption.transform == JXFORM_NONE || + transformoption.transform == transform) { + transformoption.transform = transform; + } else { + fprintf(stderr, "%s: can only do one image transformation at a time\n", + progname); + usage(); + } +#else + fprintf(stderr, "%s: sorry, image transformation was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif +} + + +LOCAL(int) parse_switches (j_compress_ptr cinfo, int argc, char **argv, int last_file_arg_seen, boolean for_real) /* Parse optional switches. @@ -90,6 +130,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, /* Set up default JPEG parameters. */ simple_progressive = FALSE; outfilename = NULL; + copyoption = JCOPYOPT_DEFAULT; + transformoption.transform = JXFORM_NONE; + transformoption.trim = FALSE; + transformoption.force_grayscale = FALSE; cinfo->err->trace_level = 0; /* Scan command line options, adjust parameters */ @@ -116,6 +160,19 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, exit(EXIT_FAILURE); #endif + } else if (keymatch(arg, "copy", 1)) { + /* Select which extra markers to copy. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "none", 1)) { + copyoption = JCOPYOPT_NONE; + } else if (keymatch(argv[argn], "comments", 1)) { + copyoption = JCOPYOPT_COMMENTS; + } else if (keymatch(argv[argn], "all", 1)) { + copyoption = JCOPYOPT_ALL; + } else + usage(); + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { /* Enable debug printouts. */ /* On first -d, print version identification */ @@ -128,6 +185,25 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, } cinfo->err->trace_level++; + } else if (keymatch(arg, "flip", 1)) { + /* Mirror left-right or top-bottom. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "horizontal", 1)) + select_transform(JXFORM_FLIP_H); + else if (keymatch(argv[argn], "vertical", 1)) + select_transform(JXFORM_FLIP_V); + else + usage(); + + } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) { + /* Force to grayscale. */ +#if TRANSFORMS_SUPPORTED + transformoption.force_grayscale = TRUE; +#else + select_transform(JXFORM_NONE); /* force an error */ +#endif + } else if (keymatch(arg, "maxmemory", 3)) { /* Maximum memory in Kb (or Mb with 'm'). */ long lval; @@ -187,7 +263,20 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, /* restart_interval will be computed during startup */ } - } else if (keymatch(arg, "scans", 2)) { + } else if (keymatch(arg, "rotate", 2)) { + /* Rotate 90, 180, or 270 degrees (measured clockwise). */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "90", 2)) + select_transform(JXFORM_ROT_90); + else if (keymatch(argv[argn], "180", 3)) + select_transform(JXFORM_ROT_180); + else if (keymatch(argv[argn], "270", 3)) + select_transform(JXFORM_ROT_270); + else + usage(); + + } else if (keymatch(arg, "scans", 1)) { /* Set scan script. */ #ifdef C_MULTISCAN_FILES_SUPPORTED if (++argn >= argc) /* advance to next argument */ @@ -200,6 +289,18 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, exit(EXIT_FAILURE); #endif + } else if (keymatch(arg, "transpose", 1)) { + /* Transpose (across UL-to-LR axis). */ + select_transform(JXFORM_TRANSPOSE); + + } else if (keymatch(arg, "transverse", 6)) { + /* Transverse transpose (across UR-to-LL axis). */ + select_transform(JXFORM_TRANSVERSE); + + } else if (keymatch(arg, "trim", 3)) { + /* Trim off any partial edge MCUs that the transform can't handle. */ + transformoption.trim = TRUE; + } else { usage(); /* bogus switch */ } @@ -229,7 +330,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, * The main program. */ -GLOBAL int +int main (int argc, char **argv) { struct jpeg_decompress_struct srcinfo; @@ -238,7 +339,8 @@ main (int argc, char **argv) #ifdef PROGRESS_REPORT struct cdjpeg_progress_mgr progress; #endif - jvirt_barray_ptr * coef_arrays; + jvirt_barray_ptr * src_coef_arrays; + jvirt_barray_ptr * dst_coef_arrays; int file_index; FILE * input_file; FILE * output_file; @@ -268,12 +370,15 @@ main (int argc, char **argv) /* Scan command line to find file names. * It is convenient to use just one switch-parsing routine, but the switch - * values read here are ignored; we will rescan the switches after opening - * the input file. + * values read here are mostly ignored; we will rescan the switches after + * opening the input file. Also note that most of the switches affect the + * destination JPEG object, so we parse into that and then copy over what + * needs to affects the source too. */ file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); jsrcerr.trace_level = jdsterr.trace_level; + srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; #ifdef TWO_FILE_COMMANDLINE /* Must have either -outfile switch or explicit output file name */ @@ -328,25 +433,54 @@ main (int argc, char **argv) /* Specify data source for decompression */ jpeg_stdio_src(&srcinfo, input_file); + /* Enable saving of extra markers that we want to copy */ + jcopy_markers_setup(&srcinfo, copyoption); + /* Read file header */ (void) jpeg_read_header(&srcinfo, TRUE); + /* Any space needed by a transform option must be requested before + * jpeg_read_coefficients so that memory allocation will be done right. + */ +#if TRANSFORMS_SUPPORTED + jtransform_request_workspace(&srcinfo, &transformoption); +#endif + /* Read source file as DCT coefficients */ - coef_arrays = jpeg_read_coefficients(&srcinfo); + src_coef_arrays = jpeg_read_coefficients(&srcinfo); /* Initialize destination compression parameters from source values */ jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + /* Adjust destination parameters if required by transform options; + * also find out which set of coefficient arrays will hold the output. + */ +#if TRANSFORMS_SUPPORTED + dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#else + dst_coef_arrays = src_coef_arrays; +#endif + /* Adjust default compression parameters by re-parsing the options */ file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); /* Specify data destination for compression */ jpeg_stdio_dest(&dstinfo, output_file); - /* Start compressor */ - jpeg_write_coefficients(&dstinfo, coef_arrays); + /* Start compressor (note no image data is actually written here) */ + jpeg_write_coefficients(&dstinfo, dst_coef_arrays); - /* ought to copy source comments here... */ + /* Copy to the output file any extra markers that we want to preserve */ + jcopy_markers_execute(&srcinfo, &dstinfo, copyoption); + + /* Execute image transformation, if any */ +#if TRANSFORMS_SUPPORTED + jtransform_execute_transformation(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#endif /* Finish compression and release memory */ jpeg_finish_compress(&dstinfo); diff --git a/src/jpeg-6/jquant1.c b/src/jpeg-6b/jquant1.c index 035e79a8..b2f96aa1 100644 --- a/src/jpeg-6/jquant1.c +++ b/src/jpeg-6b/jquant1.c @@ -1,7 +1,7 @@ /* * jquant1.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -182,7 +182,7 @@ typedef my_cquantizer * my_cquantize_ptr; */ -LOCAL int +LOCAL(int) select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) /* Determine allocation of desired colors to components, */ /* and fill in Ncolors[] array to indicate choice. */ @@ -241,7 +241,7 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) } -LOCAL int +LOCAL(int) output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) /* Return j'th output value, where j will range from 0 to maxj */ /* The output values must fall in 0..MAXJSAMPLE in increasing order */ @@ -255,7 +255,7 @@ output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) } -LOCAL int +LOCAL(int) largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) /* Return largest input value that should map to j'th output value */ /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ @@ -269,7 +269,7 @@ largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) * Create the colormap. */ -LOCAL void +LOCAL(void) create_colormap (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -329,7 +329,7 @@ create_colormap (j_decompress_ptr cinfo) * Create the color index table. */ -LOCAL void +LOCAL(void) create_colorindex (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -392,7 +392,7 @@ create_colorindex (j_decompress_ptr cinfo) * distinct output values. */ -LOCAL ODITHER_MATRIX_PTR +LOCAL(ODITHER_MATRIX_PTR) make_odither_array (j_decompress_ptr cinfo, int ncolors) { ODITHER_MATRIX_PTR odither; @@ -428,7 +428,7 @@ make_odither_array (j_decompress_ptr cinfo, int ncolors) * share a dither table. */ -LOCAL void +LOCAL(void) create_odither_tables (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -455,7 +455,7 @@ create_odither_tables (j_decompress_ptr cinfo) * Map some rows of pixels to the output colormapped representation. */ -METHODDEF void +METHODDEF(void) color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* General case, no dithering */ @@ -483,7 +483,7 @@ color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, } -METHODDEF void +METHODDEF(void) color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* Fast path for out_color_components==3, no dithering */ @@ -511,7 +511,7 @@ color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, } -METHODDEF void +METHODDEF(void) quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* General case, with ordered dithering */ @@ -561,7 +561,7 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, } -METHODDEF void +METHODDEF(void) quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* Fast path for out_color_components==3, with ordered dithering */ @@ -606,7 +606,7 @@ quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, } -METHODDEF void +METHODDEF(void) quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* General case, with Floyd-Steinberg dithering */ @@ -718,7 +718,7 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, * Allocate workspace for Floyd-Steinberg errors. */ -LOCAL void +LOCAL(void) alloc_fs_workspace (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -737,7 +737,7 @@ alloc_fs_workspace (j_decompress_ptr cinfo) * Initialize for one-pass color quantization. */ -METHODDEF void +METHODDEF(void) start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -794,7 +794,7 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) * Finish up at the end of the pass. */ -METHODDEF void +METHODDEF(void) finish_pass_1_quant (j_decompress_ptr cinfo) { /* no work in 1-pass case */ @@ -806,7 +806,7 @@ finish_pass_1_quant (j_decompress_ptr cinfo) * Shouldn't get to this module! */ -METHODDEF void +METHODDEF(void) new_color_map_1_quant (j_decompress_ptr cinfo) { ERREXIT(cinfo, JERR_MODE_CHANGE); @@ -817,7 +817,7 @@ new_color_map_1_quant (j_decompress_ptr cinfo) * Module initialization routine for 1-pass color quantization. */ -GLOBAL void +GLOBAL(void) jinit_1pass_quantizer (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize; diff --git a/src/jpeg-6/jquant2.c b/src/jpeg-6b/jquant2.c index 25043982..af601e33 100644 --- a/src/jpeg-6/jquant2.c +++ b/src/jpeg-6b/jquant2.c @@ -1,7 +1,7 @@ /* * jquant2.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -220,7 +220,7 @@ typedef my_cquantizer * my_cquantize_ptr; * NULL pointer). */ -METHODDEF void +METHODDEF(void) prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) { @@ -269,7 +269,7 @@ typedef struct { typedef box * boxptr; -LOCAL boxptr +LOCAL(boxptr) find_biggest_color_pop (boxptr boxlist, int numboxes) /* Find the splittable box with the largest color population */ /* Returns NULL if no splittable boxes remain */ @@ -289,7 +289,7 @@ find_biggest_color_pop (boxptr boxlist, int numboxes) } -LOCAL boxptr +LOCAL(boxptr) find_biggest_volume (boxptr boxlist, int numboxes) /* Find the splittable box with the largest (scaled) volume */ /* Returns NULL if no splittable boxes remain */ @@ -309,7 +309,7 @@ find_biggest_volume (boxptr boxlist, int numboxes) } -LOCAL void +LOCAL(void) update_box (j_decompress_ptr cinfo, boxptr boxp) /* Shrink the min/max bounds of a box to enclose only nonzero elements, */ /* and recompute its volume and population */ @@ -420,7 +420,7 @@ update_box (j_decompress_ptr cinfo, boxptr boxp) } -LOCAL int +LOCAL(int) median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, int desired_colors) /* Repeatedly select and split the largest box until we have enough boxes */ @@ -495,7 +495,7 @@ median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, } -LOCAL void +LOCAL(void) compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) /* Compute representative color for a box, put it in colormap[icolor] */ { @@ -535,7 +535,7 @@ compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) } -LOCAL void +LOCAL(void) select_colors (j_decompress_ptr cinfo, int desired_colors) /* Master routine for color selection */ { @@ -642,7 +642,7 @@ select_colors (j_decompress_ptr cinfo, int desired_colors) * inner-loop variables. */ -LOCAL int +LOCAL(int) find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, JSAMPLE colorlist[]) /* Locate the colormap entries close enough to an update box to be candidates @@ -771,7 +771,7 @@ find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, } -LOCAL void +LOCAL(void) find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) /* Find the closest colormap entry for each cell in the update box, @@ -851,7 +851,7 @@ find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, } -LOCAL void +LOCAL(void) fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) /* Fill the inverse-colormap entries in the update box that contains */ /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ @@ -911,7 +911,7 @@ fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) * Map some rows of pixels to the output colormapped representation. */ -METHODDEF void +METHODDEF(void) pass2_no_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* This version performs no dithering */ @@ -945,7 +945,7 @@ pass2_no_dither (j_decompress_ptr cinfo, } -METHODDEF void +METHODDEF(void) pass2_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) /* This version performs Floyd-Steinberg dithering */ @@ -1104,7 +1104,7 @@ pass2_fs_dither (j_decompress_ptr cinfo, * to Aaron Giles for this idea. */ -LOCAL void +LOCAL(void) init_error_limit (j_decompress_ptr cinfo) /* Allocate and fill in the error_limiter table */ { @@ -1139,7 +1139,7 @@ init_error_limit (j_decompress_ptr cinfo) * Finish up at the end of each pass. */ -METHODDEF void +METHODDEF(void) finish_pass1 (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -1152,7 +1152,7 @@ finish_pass1 (j_decompress_ptr cinfo) } -METHODDEF void +METHODDEF(void) finish_pass2 (j_decompress_ptr cinfo) { /* no work */ @@ -1163,7 +1163,7 @@ finish_pass2 (j_decompress_ptr cinfo) * Initialize for each processing pass. */ -METHODDEF void +METHODDEF(void) start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -1226,7 +1226,7 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) * Switch to a new external colormap between output passes. */ -METHODDEF void +METHODDEF(void) new_color_map_2_quant (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; @@ -1240,7 +1240,7 @@ new_color_map_2_quant (j_decompress_ptr cinfo) * Module initialization routine for 2-pass color quantization. */ -GLOBAL void +GLOBAL(void) jinit_2pass_quantizer (j_decompress_ptr cinfo) { my_cquantize_ptr cquantize; diff --git a/src/jpeg-6/jutils.c b/src/jpeg-6b/jutils.c index 4ba2a543..d18a9555 100644 --- a/src/jpeg-6/jutils.c +++ b/src/jpeg-6b/jutils.c @@ -1,7 +1,7 @@ /* * jutils.c * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1996, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -21,6 +21,8 @@ * of a DCT block read in natural order (left to right, top to bottom). */ +#if 0 /* This table is not actually needed in v6a */ + const int jpeg_zigzag_order[DCTSIZE2] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, @@ -32,6 +34,8 @@ const int jpeg_zigzag_order[DCTSIZE2] = { 35, 36, 48, 49, 57, 58, 62, 63 }; +#endif + /* * jpeg_natural_order[i] is the natural-order position of the i'th element * of zigzag order. @@ -64,7 +68,7 @@ const int jpeg_natural_order[DCTSIZE2+16] = { * Arithmetic utilities */ -GLOBAL long +GLOBAL(long) jdiv_round_up (long a, long b) /* Compute a/b rounded up to next integer, ie, ceil(a/b) */ /* Assumes a >= 0, b > 0 */ @@ -73,7 +77,7 @@ jdiv_round_up (long a, long b) } -GLOBAL long +GLOBAL(long) jround_up (long a, long b) /* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ /* Assumes a >= 0, b > 0 */ @@ -103,7 +107,7 @@ jround_up (long a, long b) #endif -GLOBAL void +GLOBAL(void) jcopy_sample_rows (JSAMPARRAY input_array, int source_row, JSAMPARRAY output_array, int dest_row, int num_rows, JDIMENSION num_cols) @@ -137,7 +141,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row, } -GLOBAL void +GLOBAL(void) jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks) /* Copy a row of coefficient blocks from one place to another. */ @@ -157,7 +161,7 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, } -GLOBAL void +GLOBAL(void) jzero_far (void FAR * target, size_t bytestozero) /* Zero out a chunk of FAR memory. */ /* This might be sample-array data, block-array data, or alloc_large data. */ diff --git a/src/jpeg-6/jversion.h b/src/jpeg-6b/jversion.h index f2f1b8da..6472c58d 100644 --- a/src/jpeg-6/jversion.h +++ b/src/jpeg-6b/jversion.h @@ -1,7 +1,7 @@ /* * jversion.h * - * Copyright (C) 1991-1995, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -9,6 +9,6 @@ */ -#define JVERSION "6 2-Aug-95" +#define JVERSION "6b 27-Mar-1998" -#define JCOPYRIGHT "Copyright (C) 1995, Thomas G. Lane" +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/src/null/null_client.c b/src/null/null_client.c index 8346ff93..e7340804 100644 --- a/src/null/null_client.c +++ b/src/null/null_client.c @@ -21,7 +21,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ -#include "../client/client.h" +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" cvar_t *cl_shownet; diff --git a/src/null/null_input.c b/src/null/null_input.c index 93841e77..ae9eab59 100644 --- a/src/null/null_input.c +++ b/src/null/null_input.c @@ -20,7 +20,6 @@ along with Tremulous; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ -#include "../client/client.h" void IN_Init( void ) { } @@ -31,6 +30,9 @@ void IN_Frame (void) { void IN_Shutdown( void ) { } +void IN_Restart( void ) { +} + void Sys_SendKeyEvents (void) { } diff --git a/src/null/null_snddma.c b/src/null/null_snddma.c index 995203fd..27f60798 100644 --- a/src/null/null_snddma.c +++ b/src/null/null_snddma.c @@ -24,7 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // snddma_null.c // all other sound mixing is portable -#include "../client/client.h" +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" qboolean SNDDMA_Init(void) { diff --git a/src/qcommon/common.c b/src/qcommon/common.c index 586c334c..f16234c2 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -81,7 +81,9 @@ cvar_t *sv_packetdelay; cvar_t *com_cameraMode; cvar_t *com_ansiColor; cvar_t *com_unfocused; +cvar_t *com_maxfpsUnfocused; cvar_t *com_minimized; +cvar_t *com_maxfpsMinimized; // com_speeds times int time_game; @@ -2481,7 +2483,9 @@ void Com_Init( char *commandLine ) { com_ansiColor = Cvar_Get( "com_ansiColor", "0", CVAR_ARCHIVE ); com_unfocused = Cvar_Get( "com_unfocused", "0", CVAR_ROM ); + com_maxfpsUnfocused = Cvar_Get( "com_maxfpsUnfocused", "0", CVAR_ARCHIVE ); com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM ); + com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE ); if ( com_developer && com_developer->integer ) { Cmd_AddCommand ("error", Com_Error_f); @@ -2696,12 +2700,30 @@ void Com_Frame( void ) { } // we may want to spin here if things are going too fast - if ( !com_dedicated->integer && com_maxfps->integer > 0 && !com_timedemo->integer ) { - minMsec = 1000 / com_maxfps->integer; + if ( !com_dedicated->integer && !com_timedemo->integer ) { + if( com_minimized->integer && com_maxfpsMinimized->integer > 0 ) { + minMsec = 1000 / com_maxfpsMinimized->integer; + } else if( com_unfocused->integer && com_maxfpsUnfocused->integer > 0 ) { + minMsec = 1000 / com_maxfpsUnfocused->integer; + } else if( com_maxfps->integer > 0 ) { + minMsec = 1000 / com_maxfps->integer; + } else { + minMsec = 1; + } } else { minMsec = 1; } + + msec = minMsec; do { + int timeRemaining = minMsec - msec; + + // The existing Sys_Sleep implementations aren't really + // precise enough to be of use beyond 100fps + // FIXME: implement a more precise sleep (RDTSC or something) + if( timeRemaining >= 10 ) + Sys_Sleep( timeRemaining ); + com_frameTime = Com_EventLoop(); if ( lastTime > com_frameTime ) { lastTime = com_frameTime; // possible on first frame diff --git a/src/qcommon/files.c b/src/qcommon/files.c index 53385244..6b407c20 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -299,6 +299,11 @@ char lastValidGame[MAX_OSPATH]; FILE* missingFiles = NULL; #endif +/* C99 defines __func__ */ +#ifndef __func__ +#define __func__ "(unknown)" +#endif + /* ============== FS_Initialized @@ -527,7 +532,7 @@ static void FS_CopyFile( char *fromOSPath, char *toOSPath ) { Com_Printf( "copy %s to %s\n", fromOSPath, toOSPath ); - FS_FilenameIsExecutable( toOSPath, __FUNCTION__ ); + FS_FilenameIsExecutable( toOSPath, __func__ ); if (strstr(fromOSPath, "journal.dat") || strstr(fromOSPath, "journaldata.dat")) { Com_Printf( "Ignoring journal files\n"); @@ -570,7 +575,7 @@ FS_Remove =========== */ void FS_Remove( const char *osPath ) { - FS_FilenameIsExecutable( osPath, __FUNCTION__ ); + FS_FilenameIsExecutable( osPath, __func__ ); remove( osPath ); } @@ -582,7 +587,7 @@ FS_HomeRemove =========== */ void FS_HomeRemove( const char *homePath ) { - FS_FilenameIsExecutable( homePath, __FUNCTION__ ); + FS_FilenameIsExecutable( homePath, __func__ ); remove( FS_BuildOSPath( fs_homepath->string, fs_gamedir, homePath ) ); @@ -661,7 +666,7 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) { Com_Printf( "FS_SV_FOpenFileWrite: %s\n", ospath ); } - FS_FilenameIsExecutable( ospath, __FUNCTION__ ); + FS_FilenameIsExecutable( ospath, __func__ ); if( FS_CreatePath( ospath ) ) { return 0; @@ -772,7 +777,7 @@ void FS_SV_Rename( const char *from, const char *to ) { Com_Printf( "FS_SV_Rename: %s --> %s\n", from_ospath, to_ospath ); } - FS_FilenameIsExecutable( to_ospath, __FUNCTION__ ); + FS_FilenameIsExecutable( to_ospath, __func__ ); if (rename( from_ospath, to_ospath )) { // Failed, try copying it and deleting the original @@ -806,7 +811,7 @@ void FS_Rename( const char *from, const char *to ) { Com_Printf( "FS_Rename: %s --> %s\n", from_ospath, to_ospath ); } - FS_FilenameIsExecutable( to_ospath, __FUNCTION__ ); + FS_FilenameIsExecutable( to_ospath, __func__ ); if (rename( from_ospath, to_ospath )) { // Failed, try copying it and deleting the original @@ -869,7 +874,7 @@ fileHandle_t FS_FOpenFileWrite( const char *filename ) { Com_Printf( "FS_FOpenFileWrite: %s\n", ospath ); } - FS_FilenameIsExecutable( ospath, __FUNCTION__ ); + FS_FilenameIsExecutable( ospath, __func__ ); if( FS_CreatePath( ospath ) ) { return 0; @@ -917,7 +922,7 @@ fileHandle_t FS_FOpenFileAppend( const char *filename ) { Com_Printf( "FS_FOpenFileAppend: %s\n", ospath ); } - FS_FilenameIsExecutable( ospath, __FUNCTION__ ); + FS_FilenameIsExecutable( ospath, __func__ ); if( FS_CreatePath( ospath ) ) { return 0; diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c index d98b6a78..37c61c31 100644 --- a/src/qcommon/msg.c +++ b/src/qcommon/msg.c @@ -994,8 +994,6 @@ If the delta removes the entity, entityState_t->number will be set to MAX_GENTIT Can go from either a baseline or a previous packet_entity ================== */ -extern cvar_t *cl_shownet; - void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, int number) { int i, lc; diff --git a/src/qcommon/net_ip.c b/src/qcommon/net_ip.c index 9ecd5e9e..baf70a17 100644 --- a/src/qcommon/net_ip.c +++ b/src/qcommon/net_ip.c @@ -24,61 +24,68 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../qcommon/qcommon.h" #ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#if WINVER < 0x501 -#include <wspiapi.h> -#else -#include <ws2spi.h> -#endif +# include <winsock2.h> +# include <ws2tcpip.h> +# if WINVER < 0x501 +# ifdef __MINGW32__ + // wspiapi.h isn't available on MinGW, so if it's + // present it's because the end user has added it + // and we should look for it in our tree +# include "wspiapi.h" +# else +# include <wspiapi.h> +# endif +# else +# include <ws2spi.h> +# endif typedef int socklen_t; -#ifdef ADDRESS_FAMILY -#define sa_family_t ADDRESS_FAMILY -#else +# ifdef ADDRESS_FAMILY +# define sa_family_t ADDRESS_FAMILY +# else typedef unsigned short sa_family_t; -#endif +# endif -#define EAGAIN WSAEWOULDBLOCK -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define ECONNRESET WSAECONNRESET -#define socketError WSAGetLastError( ) +# define EAGAIN WSAEWOULDBLOCK +# define EADDRNOTAVAIL WSAEADDRNOTAVAIL +# define EAFNOSUPPORT WSAEAFNOSUPPORT +# define ECONNRESET WSAECONNRESET +# define socketError WSAGetLastError( ) static WSADATA winsockdata; static qboolean winsockInitialized = qfalse; #else -#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020 - // needed for socklen_t on OSX 10.2 -# define _BSD_SOCKLEN_T_ -#endif - -#include <arpa/inet.h> -#include <errno.h> -#include <netdb.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <net/if.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/time.h> -#include <unistd.h> -#if !defined(__sun) && !defined(__sgi) -#include <ifaddrs.h> -#endif - -#ifdef __sun -#include <sys/filio.h> -#endif +# if MAC_OS_X_VERSION_MIN_REQUIRED == 1020 + // needed for socklen_t on OSX 10.2 +# define _BSD_SOCKLEN_T_ +# endif + +# include <arpa/inet.h> +# include <errno.h> +# include <netdb.h> +# include <netinet/in.h> +# include <sys/socket.h> +# include <net/if.h> +# include <sys/ioctl.h> +# include <sys/types.h> +# include <sys/time.h> +# include <unistd.h> +# if !defined(__sun) && !defined(__sgi) +# include <ifaddrs.h> +# endif + +# ifdef __sun +# include <sys/filio.h> +# endif typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket close -#define ioctlsocket ioctl -#define socketError errno +# define INVALID_SOCKET -1 +# define SOCKET_ERROR -1 +# define closesocket close +# define ioctlsocket ioctl +# define socketError errno #endif diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index 62012914..d6f7ea03 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -588,7 +588,6 @@ fileHandle_t FS_FOpenFileWrite( const char *qpath ); fileHandle_t FS_FOpenFileAppend( const char *filename ); // will properly create any needed paths and deal with seperater character issues -int FS_filelength( fileHandle_t f ); fileHandle_t FS_SV_FOpenFileWrite( const char *filename ); int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp ); void FS_SV_Rename( const char *from, const char *to ); @@ -790,7 +789,9 @@ extern cvar_t *com_journal; extern cvar_t *com_cameraMode; extern cvar_t *com_ansiColor; extern cvar_t *com_unfocused; +extern cvar_t *com_maxfpsUnfocused; extern cvar_t *com_minimized; +extern cvar_t *com_maxfpsMinimized; extern cvar_t *com_altivec; // both client and server must agree to pause diff --git a/src/qcommon/unzip.c b/src/qcommon/unzip.c index 7daf271b..90f5354d 100644 --- a/src/qcommon/unzip.c +++ b/src/qcommon/unzip.c @@ -7,7 +7,8 @@ * *****************************************************************************/ -#include "../client/client.h" +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" #include "unzip.h" /* unzip.h -- IO for uncompress .zip files using zlib diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c index f9071669..eb14e94b 100644 --- a/src/qcommon/vm_interpreted.c +++ b/src/qcommon/vm_interpreted.c @@ -481,7 +481,7 @@ nextInstruction2: case OP_BLOCK_COPY: { int *src, *dest; - int i, count, srci, desti; + int count, srci, desti; count = r2; // MrE: copy range check @@ -490,16 +490,10 @@ nextInstruction2: count = ((srci + count) & dataMask) - srci; count = ((desti + count) & dataMask) - desti; - src = (int *)&image[ r0&dataMask ]; - dest = (int *)&image[ r1&dataMask ]; - if ( ( (intptr_t)src | (intptr_t)dest | count ) & 3 ) { - // happens in westernq3 - Com_Printf( S_COLOR_YELLOW "Warning: OP_BLOCK_COPY not dword aligned\n"); - } - count >>= 2; - for ( i = count-1 ; i>= 0 ; i-- ) { - dest[i] = src[i]; - } + src = (int *)&image[ srci ]; + dest = (int *)&image[ desti ]; + + memcpy(dest, src, count); programCounter += 4; opStack -= 2; } diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c index 5eb49b0b..64af7d11 100644 --- a/src/qcommon/vm_x86.c +++ b/src/qcommon/vm_x86.c @@ -54,7 +54,6 @@ static void VM_Destroy_Compiled(vm_t* self); */ -// TTimo: initialised the statics, this fixes a crash when entering a compiled VM static byte *buf = NULL; static byte *jused = NULL; static int compiledOfs = 0; @@ -72,9 +71,6 @@ int _ftol( float ); static int ftolPtr = (int)_ftol; #endif -void AsmCall( void ); -static int asmCallPtr = (int)AsmCall; - #else // _MSC_VER #if defined( FTOL_PTR ) @@ -89,10 +85,11 @@ int qftol0F7F( void ); static int ftolPtr = (int)qftol0F7F; #endif // FTOL_PTR -void doAsmCall( void ); -static int asmCallPtr = (int)doAsmCall; #endif +void AsmCall(void); +static void (*const asmCallPtr)(void) = AsmCall; + static int callMask = 0; @@ -125,7 +122,7 @@ vm_t* savedVM; __asm { mov eax, dword ptr [edi] sub edi, 4 - or eax,eax + test eax,eax jl systemCall // calling another vm function shl eax,2 @@ -138,8 +135,7 @@ systemCall: // convert negative num to system call number // and store right before the first arg - neg eax - dec eax + not eax push ebp mov ebp, esp @@ -181,68 +177,58 @@ _asm { #else //!_MSC_VER #if defined(__MINGW32__) || defined(MACOS_X) // _ is prepended to compiled symbols -#define CMANG(sym) "_"#sym +# define CMANG(sym) "_"#sym #else -#define CMANG(sym) #sym +# define CMANG(sym) #sym #endif -static int callProgramStack; -static int *callOpStack; -static int callSyscallNum; - -void callAsmCall(void) +static void __attribute__((cdecl, used)) CallAsmCall(int const syscallNum, + int const programStack, int* const opStack) { - vm_t *savedVM; - int *callOpStack2; - - savedVM = currentVM; - callOpStack2 = callOpStack; + vm_t *const vm = currentVM; + intptr_t *const data = (intptr_t*)(vm->dataBase + programStack + 4); // save the stack to allow recursive VM entry - currentVM->programStack = callProgramStack - 4; - *(int *)((byte *)currentVM->dataBase + callProgramStack + 4) = callSyscallNum; - //VM_LogSyscalls((int *)((byte *)currentVM->dataBase + callProgramStack + 4) ); - *(callOpStack2+1) = currentVM->systemCall( (intptr_t *)((byte *)currentVM->dataBase + callProgramStack + 4) ); + vm->programStack = programStack - 4; + *data = syscallNum; + opStack[1] = vm->systemCall(data); - currentVM = savedVM; + currentVM = vm; } -// Note the C space function AsmCall is never actually called, and is in fact -// arbitrarily named (though this is not true for the MSC version). When a vm -// makes a system call, control jumps straight to the doAsmCall label. -void AsmCall( void ) { - __asm__( CMANG(doAsmCall) ": \n\t" \ - " movl (%%edi),%%eax \n\t" \ - " subl $4,%%edi \n\t" \ - " orl %%eax,%%eax \n\t" \ - " jl systemCall \n\t" \ - " shll $2,%%eax \n\t" \ - " addl %3,%%eax \n\t" \ - " call *(%%eax) \n\t" \ - " movl (%%edi),%%eax \n\t" \ - " andl " CMANG(callMask) ", %%eax \n\t" \ - " jmp doret \n\t" \ - "systemCall: \n\t" \ - " negl %%eax \n\t" \ - " decl %%eax \n\t" \ - " movl %%eax,%0 \n\t" \ - " movl %%esi,%1 \n\t" \ - " movl %%edi,%2 \n\t" \ - " pushl %%ecx \n\t" \ - " pushl %%esi \n\t" \ - " pushl %%edi \n\t" \ - " call " CMANG(callAsmCall) " \n\t" \ - " popl %%edi \n\t" \ - " popl %%esi \n\t" \ - " popl %%ecx \n\t" \ - " addl $4,%%edi \n\t" \ - "doret: \n\t" \ - " ret \n\t" \ - : "=rm" (callSyscallNum), "=rm" (callProgramStack), "=rm" (callOpStack) \ - : "m" (instructionPointers) \ - : "ax", "di", "si", "cx" \ - ); -} +__asm__( + ".text\n\t" + ".p2align 4,,15\n\t" +#if defined __ELF__ + ".type " CMANG(AsmCall) ", @function\n" +#endif + CMANG(AsmCall) ":\n\t" + "movl (%edi), %eax\n\t" + "subl $4, %edi\n\t" + "testl %eax, %eax\n\t" + "jl 0f\n\t" + "shll $2, %eax\n\t" + "addl " CMANG(instructionPointers) ", %eax\n\t" + "call *(%eax)\n\t" + "movl (%edi), %eax\n\t" + "andl " CMANG(callMask) ", %eax\n\t" + "ret\n" + "0:\n\t" // system call + "notl %eax\n\t" + "pushl %ecx\n\t" + "pushl %edi\n\t" // opStack + "pushl %esi\n\t" // programStack + "pushl %eax\n\t" // syscallNum + "call " CMANG(CallAsmCall) "\n\t" + "addl $12, %esp\n\t" + "popl %ecx\n\t" + "addl $4, %edi\n\t" + "ret\n\t" +#if defined __ELF__ + ".size " CMANG(AsmCall)", .-" CMANG(AsmCall) +#endif +); + #endif static int Constant4( void ) { @@ -1124,7 +1110,7 @@ void VM_Destroy_Compiled(vm_t* self) #ifdef VM_X86_MMAP munmap(self->codeBase, self->codeLength); #elif _WIN32 - VirtualFree(self->codeBase, self->codeLength, MEM_RELEASE); + VirtualFree(self->codeBase, 0, MEM_RELEASE); #else free(self->codeBase); #endif @@ -1143,7 +1129,6 @@ int VM_CallCompiled( vm_t *vm, int *args ) { int programStack; int stackOnEntry; byte *image; - void *entryPoint; void *opStack; int *oldInstructionPointers; @@ -1182,45 +1167,38 @@ int VM_CallCompiled( vm_t *vm, int *args ) { *(int *)&image[ programStack ] = -1; // will terminate the loop on return // off we go into generated code... - entryPoint = vm->codeBase; opStack = &stack; + { #ifdef _MSC_VER - __asm { - pushad - mov esi, programStack; - mov edi, opStack - call entryPoint - mov programStack, esi - mov opStack, edi - popad - } + void *entryPoint = vm->codeBase; + + __asm { + pushad + mov esi, programStack + mov edi, opStack + call entryPoint + mov programStack, esi + mov opStack, edi + popad + } #else - { - static int memProgramStack; - static void *memOpStack; - static void *memEntryPoint; - - memProgramStack = programStack; - memOpStack = opStack; - memEntryPoint = entryPoint; - - __asm__(" pushal \n" \ - " movl %0,%%esi \n" \ - " movl %1,%%edi \n" \ - " call *%2 \n" \ - " movl %%esi,%0 \n" \ - " movl %%edi,%1 \n" \ - " popal \n" \ - : "=m" (memProgramStack), "=m" (memOpStack) \ - : "m" (memEntryPoint), "m" (memProgramStack), "m" (memOpStack) \ - : "si", "di" \ + /* These registers are used as scratch registers and are destroyed after the + * call. Do not use clobber, so they can be used as input for the asm. */ + unsigned eax; + unsigned ebx; + unsigned ecx; + unsigned edx; + + __asm__ volatile( + "call *%6" + : "+S" (programStack), "+D" (opStack), + "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "mr" (vm->codeBase) + : "cc", "memory" ); - - programStack = memProgramStack; - opStack = memOpStack; - } #endif + } if ( opStack != &stack[1] ) { Com_Error( ERR_DROP, "opStack corrupted in compiled code" ); diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c index 0eb79306..09a9c6d1 100644 --- a/src/qcommon/vm_x86_64.c +++ b/src/qcommon/vm_x86_64.c @@ -1041,7 +1041,7 @@ void VM_Destroy_Compiled(vm_t* self) #ifdef USE_GAS munmap(self->codeBase, self->codeLength); #elif _WIN32 - VirtualFree(self->codeBase, self->codeLength, MEM_RELEASE); + VirtualFree(self->codeBase, 0, MEM_RELEASE); #else munmap(self->codeBase, self->codeLength); #endif diff --git a/src/renderer/tr_backend.c b/src/renderer/tr_backend.c index 5eed467a..4f1e9955 100644 --- a/src/renderer/tr_backend.c +++ b/src/renderer/tr_backend.c @@ -777,8 +777,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); } else { if (dirty) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing @@ -819,8 +819,8 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); } else { if (dirty) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing diff --git a/src/renderer/tr_bsp.c b/src/renderer/tr_bsp.c index 1f63f9f0..fd1b64b6 100644 --- a/src/renderer/tr_bsp.c +++ b/src/renderer/tr_bsp.c @@ -206,7 +206,7 @@ static void R_LoadLightmaps( lump_t *l ) { } } tr.lightmaps[i] = R_CreateImage( va("*lightmap%d",i), image, - LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP ); + LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE ); } if ( r_lightmap->integer == 2 ) { diff --git a/src/renderer/tr_font.c b/src/renderer/tr_font.c index ea7b9e80..95df7a15 100644 --- a/src/renderer/tr_font.c +++ b/src/renderer/tr_font.c @@ -494,7 +494,7 @@ void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) { } //Com_sprintf (name, sizeof(name), "fonts/fontImage_%i_%i", imageNumber++, pointSize); - image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP); + image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP_TO_EDGE); h = RE_RegisterShaderFromImage(name, LIGHTMAP_2D, image, qfalse); for (j = lastStart; j < i; j++) { font->glyphs[j].glyph = h; diff --git a/src/renderer/tr_image.c b/src/renderer/tr_image.c index a2e92e49..836433b5 100644 --- a/src/renderer/tr_image.c +++ b/src/renderer/tr_image.c @@ -200,7 +200,7 @@ void R_ImageList_f( void ) { case GL_REPEAT: ri.Printf( PRINT_ALL, "rept " ); break; - case GL_CLAMP: + case GL_CLAMP_TO_EDGE: ri.Printf( PRINT_ALL, "clmp " ); break; default: @@ -1005,7 +1005,7 @@ static void R_CreateDlightImage( void ) { data[y][x][3] = 255; } } - tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, qfalse, qfalse, GL_CLAMP ); + tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE ); } @@ -1095,7 +1095,7 @@ static void R_CreateFogImage( void ) { // standard openGL clamping doesn't really do what we want -- it includes // the border color at the edges. OpenGL 1.2 has clamp-to-edge, which does // what we want. - tr.fogImage = R_CreateImage("*fog", (byte *)data, FOG_S, FOG_T, qfalse, qfalse, GL_CLAMP ); + tr.fogImage = R_CreateImage("*fog", (byte *)data, FOG_S, FOG_T, qfalse, qfalse, GL_CLAMP_TO_EDGE ); ri.Hunk_FreeTempMemory( data ); borderColor[0] = 1.0; @@ -1173,7 +1173,7 @@ void R_CreateBuiltinImages( void ) { for(x=0;x<32;x++) { // scratchimage is usually used for cinematic drawing - tr.scratchImage[x] = R_CreateImage("*scratch", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, qfalse, qtrue, GL_CLAMP ); + tr.scratchImage[x] = R_CreateImage("*scratch", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, qfalse, qtrue, GL_CLAMP_TO_EDGE ); } R_CreateDlightImage(); diff --git a/src/renderer/tr_image_jpg.c b/src/renderer/tr_image_jpg.c index 8a9bbc4e..fb4f2121 100644 --- a/src/renderer/tr_image_jpg.c +++ b/src/renderer/tr_image_jpg.c @@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define JPEG_INTERNALS -#include "../jpeg-6/jpeglib.h" +#include "../jpeg-6b/jpeglib.h" void R_LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) { /* This struct contains the JPEG decompression parameters and pointers to diff --git a/src/renderer/tr_local.h b/src/renderer/tr_local.h index b8d89af8..ef434718 100644 --- a/src/renderer/tr_local.h +++ b/src/renderer/tr_local.h @@ -104,7 +104,7 @@ typedef struct image_s { qboolean mipmap; qboolean allowPicmip; - int wrapClampMode; // GL_CLAMP or GL_REPEAT + int wrapClampMode; // GL_CLAMP_TO_EDGE or GL_REPEAT struct image_s* next; } image_t; diff --git a/src/renderer/tr_scene.c b/src/renderer/tr_scene.c index 82084886..22b3842b 100644 --- a/src/renderer/tr_scene.c +++ b/src/renderer/tr_scene.c @@ -209,8 +209,7 @@ void RE_AddRefEntityToScene( const refEntity_t *ent ) { if ( !tr.registered ) { return; } - // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=402 - if ( r_numentities >= ENTITYNUM_WORLD ) { + if ( r_numentities >= MAX_ENTITIES ) { return; } if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { diff --git a/src/renderer/tr_shader.c b/src/renderer/tr_shader.c index f3f8a331..bcd817bb 100644 --- a/src/renderer/tr_shader.c +++ b/src/renderer/tr_shader.c @@ -658,7 +658,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) return qfalse; } - stage->bundle[0].image[0] = R_FindImageFile( token, !shader.noMipMaps, !shader.noPicMip, GL_CLAMP ); + stage->bundle[0].image[0] = R_FindImageFile( token, !shader.noMipMaps, !shader.noPicMip, GL_CLAMP_TO_EDGE ); if ( !stage->bundle[0].image[0] ) { ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name ); @@ -1231,11 +1231,8 @@ static void ParseSkyParms( char **text ) { for (i=0 ; i<6 ; i++) { Com_sprintf( pathname, sizeof(pathname), "%s_%s.tga" , token, suf[i] ); -#ifdef GL_CLAMP_TO_EDGE shader.sky.outerbox[i] = R_FindImageFile( ( char * ) pathname, qtrue, qtrue, GL_CLAMP_TO_EDGE ); -#else - shader.sky.outerbox[i] = R_FindImageFile( ( char * ) pathname, qtrue, qtrue, GL_CLAMP ); -#endif + if ( !shader.sky.outerbox[i] ) { shader.sky.outerbox[i] = tr.defaultImage; } @@ -2517,7 +2514,7 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag // if not defined in the in-memory shader descriptions, // look for a single supported image file // - image = R_FindImageFile( name, mipRawImage, mipRawImage, mipRawImage ? GL_REPEAT : GL_CLAMP ); + image = R_FindImageFile( name, mipRawImage, mipRawImage, mipRawImage ? GL_REPEAT : GL_CLAMP_TO_EDGE ); if ( !image ) { ri.Printf( PRINT_DEVELOPER, "Couldn't find image file for shader %s\n", name ); shader.defaultShader = qtrue; diff --git a/src/sdl/sdl_glimp.c b/src/sdl/sdl_glimp.c index 068ab02c..6125a321 100644 --- a/src/sdl/sdl_glimp.c +++ b/src/sdl/sdl_glimp.c @@ -76,8 +76,10 @@ typedef enum } rserr_t; static SDL_Surface *screen = NULL; +static const SDL_VideoInfo *videoInfo = NULL; cvar_t *r_allowSoftwareGL; // Don't abort out if a hardware visual can't be obtained +cvar_t *r_sdlDriver; void (APIENTRYP qglActiveTextureARB) (GLenum texture); void (APIENTRYP qglClientActiveTextureARB) (GLenum texture); @@ -152,8 +154,16 @@ static void GLimp_DetectAvailableModes(void) SDL_Rect **modes; int numModes; int i; + SDL_PixelFormat *format = NULL; - modes = SDL_ListModes( NULL, SDL_OPENGL | SDL_FULLSCREEN ); +#if SDL_VERSION_ATLEAST(1, 2, 10) + format = videoInfo->vfmt; +# if MINSDL_PATCH >= 10 +# error Ifdeffery no longer necessary, please remove +# endif +#endif + + modes = SDL_ListModes( format, SDL_OPENGL | SDL_FULLSCREEN ); if( !modes ) { @@ -207,27 +217,37 @@ static int GLimp_SetMode( qboolean failSafe, qboolean fullscreen ) int i = 0; SDL_Surface *vidscreen = NULL; Uint32 flags = SDL_OPENGL; - const SDL_VideoInfo *videoInfo; ri.Printf( PRINT_ALL, "Initializing OpenGL display\n"); - if( glConfig.displayAspect == 0.0f ) - { #if !SDL_VERSION_ATLEAST(1, 2, 10) - // 1.2.10 is needed to get the desktop resolution - glConfig.displayAspect = 4.0f / 3.0f; + // 1.2.10 is needed to get the desktop resolution + glConfig.displayAspect = 4.0f / 3.0f; #elif MINSDL_PATCH >= 10 # error Ifdeffery no longer necessary, please remove #else + if( videoInfo == NULL ) + { + static SDL_VideoInfo sVideoInfo; + static SDL_PixelFormat sPixelFormat; + + videoInfo = SDL_GetVideoInfo( ); + + // Take a copy of the videoInfo + Com_Memcpy( &sPixelFormat, videoInfo->vfmt, sizeof( SDL_PixelFormat ) ); + sPixelFormat.palette = NULL; // Should already be the case + Com_Memcpy( &sVideoInfo, videoInfo, sizeof( SDL_VideoInfo ) ); + sVideoInfo.vfmt = &sPixelFormat; + videoInfo = &sVideoInfo; + // Guess the display aspect ratio through the desktop resolution // by assuming (relatively safely) that it is set at or close to // the display's native aspect ratio - videoInfo = SDL_GetVideoInfo( ); glConfig.displayAspect = (float)videoInfo->current_w / (float)videoInfo->current_h; -#endif ri.Printf( PRINT_ALL, "Estimated display aspect: %.3f\n", glConfig.displayAspect ); } +#endif if( !failSafe ) { @@ -431,13 +451,18 @@ static qboolean GLimp_StartDriverAndSetMode( qboolean failSafe, qboolean fullscr if (!SDL_WasInit(SDL_INIT_VIDEO)) { - ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO )... "); + char driverName[ 64 ]; + if (SDL_Init(SDL_INIT_VIDEO) == -1) { - ri.Printf( PRINT_ALL, "FAILED (%s)\n", SDL_GetError()); + ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO ) FAILED (%s)\n", + SDL_GetError()); return qfalse; } - ri.Printf( PRINT_ALL, "OK\n"); + + SDL_VideoDriverName( driverName, sizeof( driverName ) - 1 ); + ri.Printf( PRINT_ALL, "SDL using driver \"%s\"\n", driverName ); + Cvar_Set( "r_sdlDriver", driverName ); } if (fullscreen && Cvar_VariableIntegerValue( "in_nograb" ) ) @@ -655,6 +680,9 @@ void GLimp_Init( void ) qboolean success = qtrue; r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH ); + r_sdlDriver = ri.Cvar_Get( "r_sdlDriver", "", CVAR_ROM ); + + Sys_GLimpInit( ); // create the window and set up the context if( !GLimp_StartDriverAndSetMode( qfalse, r_fullscreen->integer ) ) @@ -686,8 +714,6 @@ void GLimp_Init( void ) // This depends on SDL_INIT_VIDEO, hence having it here IN_Init( ); - - return; } @@ -709,18 +735,16 @@ void GLimp_EndFrame( void ) if( r_fullscreen->modified ) { qboolean fullscreen; + qboolean needToToggle = qtrue; qboolean sdlToggled = qfalse; SDL_Surface *s = SDL_GetVideoSurface( ); if( s ) { // Find out the current state - if( s->flags & SDL_FULLSCREEN ) - fullscreen = qtrue; - else - fullscreen = qfalse; + fullscreen = !!( s->flags & SDL_FULLSCREEN ); - if (r_fullscreen->integer && Cvar_VariableIntegerValue( "in_nograb" )) + if( r_fullscreen->integer && Cvar_VariableIntegerValue( "in_nograb" ) ) { ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n"); ri.Cvar_Set( "r_fullscreen", "0" ); @@ -728,15 +752,20 @@ void GLimp_EndFrame( void ) } // Is the state we want different from the current state? - if( !!r_fullscreen->integer != fullscreen ) + needToToggle = !!r_fullscreen->integer != fullscreen; + + if( needToToggle ) sdlToggled = SDL_WM_ToggleFullScreen( s ); - else - sdlToggled = qtrue; } - // SDL_WM_ToggleFullScreen didn't work, so do it the slow way - if( !sdlToggled ) - Cbuf_AddText( "vid_restart" ); + if( needToToggle ) + { + // SDL_WM_ToggleFullScreen didn't work, so do it the slow way + if( !sdlToggled ) + Cbuf_AddText( "vid_restart" ); + + IN_Restart( ); + } r_fullscreen->modified = qfalse; } diff --git a/src/sdl/sdl_input.c b/src/sdl/sdl_input.c index f7cb0d85..c209f0a5 100644 --- a/src/sdl/sdl_input.c +++ b/src/sdl/sdl_input.c @@ -34,6 +34,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../client/client.h" #include "../sys/sys_local.h" +#define ARRAYLEN(x) (sizeof(x)/sizeof(x[0])) + #ifdef MACOS_X // Mouse acceleration needs to be disabled #define MACOS_X_ACCELERATION_HACK @@ -48,7 +50,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include <IOKit/hidsystem/event_status_driver.h> #endif -//#define KBD_DBG +static cvar_t *in_keyboardDebug = NULL; static SDL_Joystick *stick = NULL; @@ -56,9 +58,9 @@ static qboolean mouseAvailable = qfalse; static qboolean mouseActive = qfalse; static qboolean keyRepeatEnabled = qfalse; -static cvar_t *in_mouse; +static cvar_t *in_mouse = NULL; #ifdef MACOS_X_ACCELERATION_HACK -static cvar_t *in_disablemacosxmouseaccel; +static cvar_t *in_disablemacosxmouseaccel = NULL; static double originalMouseSpeed = -1.0; #endif static cvar_t *in_nograb; @@ -66,23 +68,66 @@ static cvar_t *in_nograb; static cvar_t *in_joystick = NULL; static cvar_t *in_joystickDebug = NULL; static cvar_t *in_joystickThreshold = NULL; +static cvar_t *in_joystickNo = NULL; + +#define CTRL(a) ((a)-'a'+1) + +/* +=============== +IN_PrintKey +=============== +*/ +static void IN_PrintKey( const SDL_keysym *keysym, int key, qboolean down ) +{ + if( down ) + Com_Printf( "+ " ); + else + Com_Printf( " " ); + + Com_Printf( "0x%hx \"%s\"", keysym->scancode, + SDL_GetKeyName( keysym->sym ) ); + + if( keysym->mod & KMOD_LSHIFT ) Com_Printf( " KMOD_LSHIFT" ); + if( keysym->mod & KMOD_RSHIFT ) Com_Printf( " KMOD_RSHIFT" ); + if( keysym->mod & KMOD_LCTRL ) Com_Printf( " KMOD_LCTRL" ); + if( keysym->mod & KMOD_RCTRL ) Com_Printf( " KMOD_RCTRL" ); + if( keysym->mod & KMOD_LALT ) Com_Printf( " KMOD_LALT" ); + if( keysym->mod & KMOD_RALT ) Com_Printf( " KMOD_RALT" ); + if( keysym->mod & KMOD_LMETA ) Com_Printf( " KMOD_LMETA" ); + if( keysym->mod & KMOD_RMETA ) Com_Printf( " KMOD_RMETA" ); + if( keysym->mod & KMOD_NUM ) Com_Printf( " KMOD_NUM" ); + if( keysym->mod & KMOD_CAPS ) Com_Printf( " KMOD_CAPS" ); + if( keysym->mod & KMOD_MODE ) Com_Printf( " KMOD_MODE" ); + if( keysym->mod & KMOD_RESERVED ) Com_Printf( " KMOD_RESERVED" ); + + if( keysym->unicode ) + { + Com_Printf( " %d", keysym->unicode ); + + if( keysym->unicode > ' ' && keysym->unicode < '~' ) + Com_Printf( "(%c)", (char)keysym->unicode ); + } + + Com_Printf( " %d(%s)\n", key, Key_KeynumToString( key ) ); +} /* =============== IN_TranslateSDLToQ3Key =============== */ -static const char *IN_TranslateSDLToQ3Key(SDL_keysym *keysym, int *key) +static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, + int *key, qboolean down ) { - static char buf[2] = { '\0', '\0' }; - *buf = '\0'; + static char buf[ 2 ] = { '\0', '\0' }; + *buf = '\0'; *key = 0; - // these happen to match the ASCII chars. - if ((keysym->sym >= ' ') && (keysym->sym <= '~')) + if( keysym->sym >= SDLK_SPACE && keysym->sym < SDLK_DELETE ) { - *key = (int) keysym->sym; + // These happen to match the ASCII chars + *key = (int)keysym->sym; } else { @@ -124,7 +169,7 @@ static const char *IN_TranslateSDLToQ3Key(SDL_keysym *keysym, int *key) case SDLK_F14: *key = K_F14; break; case SDLK_F15: *key = K_F15; break; - case SDLK_BACKSPACE: *key = K_BACKSPACE; break; // ctrl-h + case SDLK_BACKSPACE: *key = K_BACKSPACE; break; case SDLK_KP_PERIOD: *key = K_KP_DEL; break; case SDLK_DELETE: *key = K_DEL; break; case SDLK_PAUSE: *key = K_PAUSE; break; @@ -167,51 +212,42 @@ static const char *IN_TranslateSDLToQ3Key(SDL_keysym *keysym, int *key) case SDLK_CAPSLOCK: *key = K_CAPSLOCK; break; default: - if (keysym->sym >= SDLK_WORLD_0 && keysym->sym <= SDLK_WORLD_95) - *key = (keysym->sym - SDLK_WORLD_0) + K_WORLD_0; + if( keysym->sym >= SDLK_WORLD_0 && keysym->sym <= SDLK_WORLD_95 ) + *key = ( keysym->sym - SDLK_WORLD_0 ) + K_WORLD_0; break; } } - if( keysym->unicode <= 127 ) // maps to ASCII? + if( down && !( keysym->unicode & 0xFF80 ) ) { - char ch = (char) keysym->unicode; - if (ch == '~') - *key = '~'; // console HACK + char ch = (char)keysym->unicode & 0x7F; - // translate K_BACKSPACE to ctrl-h for MACOS_X (others?) - if (ch == K_BACKSPACE && keysym->sym != SDLK_DELETE) + switch( ch ) { - *key = 'h' - 'a' + 1; - buf[0] = *key; - } - else - buf[0] = ch; - } + // So the key marked ~ always drops the console + case '~': *key = '~'; break; - return buf; -} + case 127: // ASCII delete + if( *key != K_DEL ) + { + // ctrl-h + *buf = CTRL('h'); + break; + } + // fallthrough -/* -=============== -IN_PrintKey -=============== -*/ -static void IN_PrintKey(const SDL_Event* event) -{ -#ifdef KBD_DBG - fprintf( stderr, "key name: %s", SDL_GetKeyName (event->key.keysym.sym ) ); - if(event->key.keysym.unicode) - { - fprintf( stderr, " unicode: %hx", event->key.keysym.unicode ); - if( event->key.keysym.unicode >= '0' && - event->key.keysym.unicode <= '~') // printable? - { - fprintf( stderr, " (%c)", (unsigned char)event->key.keysym.unicode ); + default: *buf = ch; break; } } - fflush( stderr ); -#endif + + // Never allow a '~' SE_CHAR event to be generated + if( *key == '~' ) + *buf = '\0'; + + if( in_keyboardDebug->integer ) + IN_PrintKey( keysym, *key, down ); + + return buf; } #ifdef MACOS_X_ACCELERATION_HACK @@ -323,7 +359,15 @@ IN_DeactivateMouse */ static void IN_DeactivateMouse( void ) { - if (!mouseAvailable || !SDL_WasInit( SDL_INIT_VIDEO ) ) + if( !SDL_WasInit( SDL_INIT_VIDEO ) ) + return; + + // Always show the cursor when the mouse is disabled, + // but not when fullscreen + if( !r_fullscreen->integer ) + SDL_ShowCursor( 1 ); + + if( !mouseAvailable ) return; #ifdef MACOS_X_ACCELERATION_HACK @@ -348,8 +392,10 @@ static void IN_DeactivateMouse( void ) if( mouseActive ) { SDL_WM_GrabInput( SDL_GRAB_OFF ); - SDL_WarpMouse( glConfig.vidWidth >> 1, glConfig.vidHeight >> 1 ); - SDL_ShowCursor( 1 ); + + // Don't warp the mouse unless the cursor is within the window + if( SDL_GetAppState( ) & SDL_APPMOUSEFOCUS ) + SDL_WarpMouse( glConfig.vidWidth / 2, glConfig.vidHeight / 2 ); mouseActive = qfalse; } @@ -382,12 +428,6 @@ static int hat_keys[16] = { }; -extern cvar_t * in_joystick; -extern cvar_t * in_joystickDebug; -extern cvar_t * in_joystickThreshold; -cvar_t *in_joystickNo; - -#define ARRAYLEN(x) (sizeof (x) / sizeof (x[0])) struct { qboolean buttons[16]; // !!! FIXME: these might be too many. @@ -398,10 +438,10 @@ struct /* =============== -IN_StartupJoystick +IN_InitJoystick =============== */ -static void IN_StartupJoystick( void ) +static void IN_InitJoystick( void ) { int i = 0; int total = 0; @@ -452,8 +492,22 @@ static void IN_StartupJoystick( void ) Com_DPrintf( "Balls: %d\n", SDL_JoystickNumBalls(stick) ); SDL_JoystickEventState(SDL_QUERY); +} - return; +/* +=============== +IN_ShutdownJoystick +=============== +*/ +static void IN_ShutdownJoystick( void ) +{ + if (stick) + { + SDL_JoystickClose(stick); + stick = NULL; + } + + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } /* @@ -653,7 +707,6 @@ static void IN_ProcessEvents( void ) SDL_Event e; const char *p = NULL; int key = 0; - int mx = 0, my = 0; if( !SDL_WasInit( SDL_INIT_VIDEO ) ) return; @@ -670,13 +723,12 @@ static void IN_ProcessEvents( void ) keyRepeatEnabled = qtrue; } - while (SDL_PollEvent(&e)) + while( SDL_PollEvent( &e ) ) { - switch (e.type) + switch( e.type ) { case SDL_KEYDOWN: - IN_PrintKey(&e); - p = IN_TranslateSDLToQ3Key(&e.key.keysym, &key); + p = IN_TranslateSDLToQ3Key( &e.key.keysym, &key, qtrue ); if( key ) Com_QueueEvent( 0, SE_KEY, key, qtrue, 0, NULL ); @@ -688,23 +740,20 @@ static void IN_ProcessEvents( void ) break; case SDL_KEYUP: - IN_TranslateSDLToQ3Key(&e.key.keysym, &key); + IN_TranslateSDLToQ3Key( &e.key.keysym, &key, qfalse ); Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL ); break; case SDL_MOUSEMOTION: - if (mouseActive) - { - mx += e.motion.xrel; - my += e.motion.yrel; - } + if( mouseActive ) + Com_QueueEvent( 0, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL ); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { unsigned char b; - switch (e.button.button) + switch( e.button.button ) { case 1: b = K_MOUSE1; break; case 2: b = K_MOUSE3; break; @@ -713,33 +762,21 @@ static void IN_ProcessEvents( void ) case 5: b = K_MWHEELDOWN; break; case 6: b = K_MOUSE4; break; case 7: b = K_MOUSE5; break; - default: b = K_AUX1 + (e.button.button - 8)%16; break; + default: b = K_AUX1 + ( e.button.button - 8 ) % 16; break; } Com_QueueEvent( 0, SE_KEY, b, ( e.type == SDL_MOUSEBUTTONDOWN ? qtrue : qfalse ), 0, NULL ); } break; - case SDL_ACTIVEEVENT: - if( e.active.state == SDL_APPINPUTFOCUS ) { - if( e.active.gain ) - IN_ActivateMouse(); - else - IN_DeactivateMouse(); - } - break; - case SDL_QUIT: - Sys_Quit(); + Sys_Quit( ); break; default: break; } } - - if(mx || my) - Com_QueueEvent( 0, SE_MOUSE, mx, my, 0, NULL ); } /* @@ -747,19 +784,33 @@ static void IN_ProcessEvents( void ) IN_Frame =============== */ -void IN_Frame (void) +void IN_Frame( void ) { + qboolean loading; + IN_JoyMove( ); + IN_ProcessEvents( ); + + // If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading + loading = !!( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE ); - // Release the mouse if the console is down in windowed mode - // or if the window loses focus due to task switching - if( ( ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) && !r_fullscreen->integer ) || - !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) ) + if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) + { + // Console is down in windowed mode + IN_DeactivateMouse( ); + } + else if( !r_fullscreen->integer && loading ) + { + // Loading in windowed mode + IN_DeactivateMouse( ); + } + else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) ) + { + // Window not got focus IN_DeactivateMouse( ); + } else IN_ActivateMouse( ); - - IN_ProcessEvents( ); } /* @@ -767,7 +818,7 @@ void IN_Frame (void) IN_Init =============== */ -void IN_Init(void) +void IN_Init( void ) { if( !SDL_WasInit( SDL_INIT_VIDEO ) ) { @@ -775,33 +826,39 @@ void IN_Init(void) return; } - Com_DPrintf ("\n------- Input Initialization -------\n"); + Com_DPrintf( "\n------- Input Initialization -------\n" ); + + in_keyboardDebug = Cvar_Get( "in_keyboardDebug", "0", CVAR_ARCHIVE ); // mouse variables - in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE); - in_nograb = Cvar_Get ("in_nograb", "0", CVAR_ARCHIVE); + in_mouse = Cvar_Get( "in_mouse", "1", CVAR_ARCHIVE ); + in_nograb = Cvar_Get( "in_nograb", "0", CVAR_ARCHIVE ); - in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH); - in_joystickDebug = Cvar_Get ("in_debugjoystick", "0", CVAR_TEMP); - in_joystickThreshold = Cvar_Get ("in_joystickThreshold", "0.15", CVAR_ARCHIVE); + in_joystick = Cvar_Get( "in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH ); + in_joystickDebug = Cvar_Get( "in_joystickDebug", "0", CVAR_TEMP ); + in_joystickThreshold = Cvar_Get( "in_joystickThreshold", "0.15", CVAR_ARCHIVE ); #ifdef MACOS_X_ACCELERATION_HACK - in_disablemacosxmouseaccel = Cvar_Get ("in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE); + in_disablemacosxmouseaccel = Cvar_Get( "in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE ); #endif - Cvar_Set( "cl_platformSensitivity", "1.0" ); - - SDL_EnableUNICODE(1); - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + SDL_EnableUNICODE( 1 ); + SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); keyRepeatEnabled = qtrue; - if (in_mouse->value) + if( in_mouse->value ) + { mouseAvailable = qtrue; + IN_ActivateMouse( ); + } else + { + IN_DeactivateMouse( ); mouseAvailable = qfalse; + } - IN_StartupJoystick( ); - Com_DPrintf ("------------------------------------\n"); + IN_InitJoystick( ); + Com_DPrintf( "------------------------------------\n" ); } /* @@ -809,17 +866,21 @@ void IN_Init(void) IN_Shutdown =============== */ -void IN_Shutdown(void) +void IN_Shutdown( void ) { - IN_DeactivateMouse(); - + IN_DeactivateMouse( ); mouseAvailable = qfalse; - if (stick) - { - SDL_JoystickClose(stick); - stick = NULL; - } + IN_ShutdownJoystick( ); +} - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +/* +=============== +IN_Restart +=============== +*/ +void IN_Restart( void ) +{ + IN_ShutdownJoystick( ); + IN_Init( ); } diff --git a/src/sys/sys_loadlib.h b/src/sys/sys_loadlib.h index a0196f38..3d20b8ce 100644 --- a/src/sys/sys_loadlib.h +++ b/src/sys/sys_loadlib.h @@ -33,10 +33,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # define Sys_UnloadLibrary(h) dlclose(h) # define Sys_LoadFunction(h,fn) dlsym(h,fn) # define Sys_LibraryError() dlerror() -#endif +# endif #else -# include "SDL.h" -# include "SDL_loadso.h" +# ifdef USE_LOCAL_HEADERS +# include "SDL.h" +# include "SDL_loadso.h" +# else +# include <SDL.h> +# include <SDL_loadso.h> +# endif # define Sys_LoadLibrary(f) SDL_LoadObject(f) # define Sys_UnloadLibrary(h) SDL_UnloadObject(h) # define Sys_LoadFunction(h,fn) SDL_LoadFunction(h,fn) diff --git a/src/sys/sys_local.h b/src/sys/sys_local.h index 40336e3a..6d001046 100644 --- a/src/sys/sys_local.h +++ b/src/sys/sys_local.h @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA void IN_Init( void ); void IN_Frame( void ); void IN_Shutdown( void ); +void IN_Restart( void ); // Console void CON_Shutdown( void ); @@ -47,6 +48,8 @@ unsigned int CON_LogRead( char *out, unsigned int outSize ); char *Sys_StripAppBundle( char *pwd ); #endif +void Sys_GLimpInit( void ); +void Sys_PlatformInit( void ); void Sys_SigHandler( int signal ); void Sys_ErrorDialog( const char *error ); void Sys_AnsiColorPrint( const char *msg ); diff --git a/src/sys/sys_main.c b/src/sys/sys_main.c index af0f66a9..0d682261 100644 --- a/src/sys/sys_main.c +++ b/src/sys/sys_main.c @@ -112,8 +112,7 @@ Restart the input subsystem */ void Sys_In_Restart_f( void ) { - IN_Shutdown(); - IN_Init(); + IN_Restart( ); } /* @@ -441,42 +440,6 @@ void *Sys_LoadDll( const char *name, char *fqpath , /* ================= -Sys_Idle -================= -*/ -static void Sys_Idle( void ) -{ -#ifndef DEDICATED - int appState = SDL_GetAppState( ); - int sleep = 0; - - // If we have no input focus at all, sleep a bit - if( !( appState & ( SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS ) ) ) - { - Cvar_SetValue( "com_unfocused", 1 ); - sleep += 16; - } - else - Cvar_SetValue( "com_unfocused", 0 ); - - // If we're minimised, sleep a bit more - if( !( appState & SDL_APPACTIVE ) ) - { - Cvar_SetValue( "com_minimized", 1 ); - sleep += 32; - } - else - Cvar_SetValue( "com_minimized", 0 ); - - if( !com_dedicated->integer && sleep ) - SDL_Delay( sleep ); -#else - // Dedicated server idles via NET_Sleep -#endif -} - -/* -================= Sys_ParseArgs ================= */ @@ -569,6 +532,8 @@ int main( int argc, char **argv ) } #endif + Sys_PlatformInit( ); + Sys_ParseArgs( argc, argv ); Sys_SetBinaryPath( Sys_Dirname( argv[ 0 ] ) ); Sys_SetDefaultInstallPath( DEFAULT_BASEDIR ); @@ -585,16 +550,6 @@ int main( int argc, char **argv ) CON_Init( ); -#ifndef _WIN32 - // Windows doesn't have these signals - // see CON_CtrlHandler() in con_win32.c - signal( SIGHUP, Sys_SigHandler ); - signal( SIGQUIT, Sys_SigHandler ); - signal( SIGTRAP, Sys_SigHandler ); - signal( SIGIOT, Sys_SigHandler ); - signal( SIGBUS, Sys_SigHandler ); -#endif - signal( SIGILL, Sys_SigHandler ); signal( SIGFPE, Sys_SigHandler ); signal( SIGSEGV, Sys_SigHandler ); @@ -602,7 +557,13 @@ int main( int argc, char **argv ) while( 1 ) { - Sys_Idle( ); +#ifndef DEDICATED + int appState = SDL_GetAppState( ); + + Cvar_SetValue( "com_unfocused", !( appState & SDL_APPINPUTFOCUS ) ); + Cvar_SetValue( "com_minimized", !( appState & SDL_APPACTIVE ) ); +#endif + IN_Frame( ); Com_Frame( ); } diff --git a/src/sys/sys_unix.c b/src/sys/sys_unix.c index 090e9e43..760b6022 100644 --- a/src/sys/sys_unix.c +++ b/src/sys/sys_unix.c @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../qcommon/qcommon.h" #include "sys_local.h" +#include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> @@ -463,6 +464,9 @@ void Sys_Sleep( int msec ) { fd_set fdset; + if( msec == 0 ) + return; + FD_ZERO(&fdset); FD_SET(fileno(stdin), &fdset); if( msec < 0 ) @@ -508,3 +512,31 @@ void Sys_ErrorDialog( const char *error ) FS_FCloseFile( f ); } + +/* +============== +Sys_GLimpInit + +Unix specific GL implementation initialisation +============== +*/ +void Sys_GLimpInit( void ) +{ + // NOP +} + +/* +============== +Sys_PlatformInit + +Unix specific initialisation +============== +*/ +void Sys_PlatformInit( void ) +{ + signal( SIGHUP, Sys_SigHandler ); + signal( SIGQUIT, Sys_SigHandler ); + signal( SIGTRAP, Sys_SigHandler ); + signal( SIGIOT, Sys_SigHandler ); + signal( SIGBUS, Sys_SigHandler ); +} diff --git a/src/sys/sys_win32.c b/src/sys/sys_win32.c index df8861d3..aac4384d 100644 --- a/src/sys/sys_win32.c +++ b/src/sys/sys_win32.c @@ -514,15 +514,26 @@ void Sys_FreeFileList( char **list ) ============== Sys_Sleep -Block execution for msec or until input is recieved. +Block execution for msec or until input is received. ============== */ void Sys_Sleep( int msec ) { + if( msec == 0 ) + return; + +#ifdef DEDICATED if( msec < 0 ) WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), INFINITE ); else WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), msec ); +#else + // Client Sys_Sleep doesn't support waiting on stdin + if( msec < 0 ) + return; + + Sleep( msec ); +#endif } /* @@ -565,3 +576,60 @@ void Sys_ErrorDialog( const char *error ) } } } + +#ifndef DEDICATED +static qboolean SDL_VIDEODRIVER_externallySet = qfalse; +#endif + +/* +============== +Sys_GLimpInit + +Windows specific GL implementation initialisation +============== +*/ +void Sys_GLimpInit( void ) +{ +#ifndef DEDICATED + if( !SDL_VIDEODRIVER_externallySet ) + { + // It's a little bit weird having in_mouse control the + // video driver, but from ioq3's point of view they're + // virtually the same except for the mouse input anyway + if( Cvar_VariableIntegerValue( "in_mouse" ) == -1 ) + { + // Use the windib SDL backend, which is closest to + // the behaviour of idq3 with in_mouse set to -1 + _putenv( "SDL_VIDEODRIVER=windib" ); + } + else + { + // Use the DirectX SDL backend + _putenv( "SDL_VIDEODRIVER=directx" ); + } + } +#endif +} + +/* +============== +Sys_PlatformInit + +Windows specific initialisation +============== +*/ +void Sys_PlatformInit( void ) +{ +#ifndef DEDICATED + const char *SDL_VIDEODRIVER = getenv( "SDL_VIDEODRIVER" ); + + if( SDL_VIDEODRIVER ) + { + Com_Printf( "SDL_VIDEODRIVER is externally set to \"%s\", " + "in_mouse -1 will have no effect\n", SDL_VIDEODRIVER ); + SDL_VIDEODRIVER_externallySet = qtrue; + } + else + SDL_VIDEODRIVER_externallySet = qfalse; +#endif +} |