summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile28
-rwxr-xr-xmake-macosx-ub.sh24
-rw-r--r--src/client/cl_cin.c1
-rw-r--r--src/client/cl_input.c3
-rw-r--r--src/client/cl_keys.c1
-rw-r--r--src/client/cl_main.c4
-rw-r--r--src/client/cl_scrn.c5
-rw-r--r--src/client/client.h3
-rw-r--r--src/client/snd_dma.c1
-rw-r--r--src/client/snd_openal.c25
-rw-r--r--src/jpeg-6b/README (renamed from src/jpeg-6/README)0
-rw-r--r--src/jpeg-6b/ioq3-changes.diff916
-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.c3
-rw-r--r--src/null/null_input.c4
-rw-r--r--src/null/null_snddma.c3
-rw-r--r--src/qcommon/common.c26
-rw-r--r--src/qcommon/files.c21
-rw-r--r--src/qcommon/msg.c2
-rw-r--r--src/qcommon/net_ip.c93
-rw-r--r--src/qcommon/qcommon.h3
-rw-r--r--src/qcommon/unzip.c3
-rw-r--r--src/qcommon/vm_interpreted.c16
-rw-r--r--src/qcommon/vm_x86.c172
-rw-r--r--src/qcommon/vm_x86_64.c2
-rw-r--r--src/renderer/tr_backend.c8
-rw-r--r--src/renderer/tr_bsp.c2
-rw-r--r--src/renderer/tr_font.c2
-rw-r--r--src/renderer/tr_image.c8
-rw-r--r--src/renderer/tr_image_jpg.c2
-rw-r--r--src/renderer/tr_local.h2
-rw-r--r--src/renderer/tr_scene.c3
-rw-r--r--src/renderer/tr_shader.c9
-rw-r--r--src/sdl/sdl_glimp.c77
-rw-r--r--src/sdl/sdl_input.c287
-rw-r--r--src/sys/sys_loadlib.h11
-rw-r--r--src/sys/sys_local.h3
-rw-r--r--src/sys/sys_main.c59
-rw-r--r--src/sys/sys_unix.c32
-rw-r--r--src/sys/sys_win32.c70
101 files changed, 4008 insertions, 1858 deletions
diff --git a/Makefile b/Makefile
index af33b56d..caa68fae 100644
--- a/Makefile
+++ b/Makefile
@@ -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
+}