diff options
Diffstat (limited to 'libs')
43 files changed, 19213 insertions, 19213 deletions
diff --git a/libs/cmdlib.h b/libs/cmdlib.h index 72fba67..9c95d03 100755 --- a/libs/cmdlib.h +++ b/libs/cmdlib.h @@ -19,79 +19,79 @@ along with Foobar; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  ===========================================================================  */ -//
 -// start of shared cmdlib stuff
 -// 
 -
 -#ifndef __CMDLIB__
 -#define __CMDLIB__
 -
 -#include <stdio.h>
 -#include <string.h>
 -#include <stdlib.h>
 -#include <errno.h>
 -#include <ctype.h>
 -#include <time.h>
 -#include <stdarg.h>
 -
 -#ifndef __BYTEBOOL__
 -#define __BYTEBOOL__
 -
 -#ifndef __cplusplus
 -  typedef enum {false, true} boolean;
 -#else
 -  typedef unsigned char boolean;
 -#endif
 -
 -
 -typedef unsigned char byte;
 -//typedef unsigned char byte;
 -#endif
 -
 -FILE	*SafeOpenWrite (const char *filename);
 -FILE	*SafeOpenRead (const char *filename);
 -void	SafeRead (FILE *f, void *buffer, int count);
 -void	SafeWrite (FILE *f, const void *buffer, int count);
 -int		LoadFile (const char *filename, void **bufferptr);
 -int		LoadFileNoCrash (const char *filename, void **bufferptr);
 -void	SaveFile (const char *filename, void *buffer, int count);
 -void 	DefaultExtension (char *path, char *extension);
 -void 	DefaultPath (char *path, char *basepath);
 -void 	StripFilename (char *path);
 -void 	StripExtension (char *path);
 -void 	ExtractFilePath (const char *path, char *dest);
 -void	ExtractFileName (const char *path, char *dest);
 -void 	ExtractFileBase (const char *path, char *dest);
 -void	ExtractFileExtension (const char *path, char *dest);
 -short	BigShort (short l);
 -short	LittleShort (short l);
 -int		BigLong (int l);
 -int		LittleLong (int l);
 -float	BigFloat (float l);
 -float	LittleFloat (float l);
 -void *qmalloc (size_t size);
 -void* qblockmalloc(size_t nSize);
 -
 -
 -
 -// error and printf functions
 -typedef void (PFN_ERR)(const char *pFormat, ...);
 -typedef void (PFN_PRINTF)(const char *pFormat, ...);
 -typedef void (PFN_ERR_NUM)(int nNum, const char *pFormat, ...);
 -typedef void (PFN_PRINTF_NUM)(int nNum, const char *pFormat, ...);
 -
 -void Error(const char *pFormat, ...);
 -void Printf(const char *pFormat, ...);
 -void ErrorNum(int n, const char *pFormat, ...);
 -void PrintfNum(int n, const char *pFormat, ...);
 -
 -void SetErrorHandler(PFN_ERR pe);
 -void SetPrintfHandler(PFN_PRINTF pe);
 -void SetErrorHandlerNum(PFN_ERR_NUM pe);
 -void SetPrintfHandlerNum(PFN_PRINTF_NUM pe);
 -void ConvertDOSToUnixName( char *dst, const char *src );
 -char* StrDup(char* pStr);
 -char* StrDup(const char* pStr);
 -
 -
 +// +// start of shared cmdlib stuff +//  + +#ifndef __CMDLIB__ +#define __CMDLIB__ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <ctype.h> +#include <time.h> +#include <stdarg.h> + +#ifndef __BYTEBOOL__ +#define __BYTEBOOL__ + +#ifndef __cplusplus +  typedef enum {false, true} boolean; +#else +  typedef unsigned char boolean; +#endif + + +typedef unsigned char byte; +//typedef unsigned char byte; +#endif + +FILE	*SafeOpenWrite (const char *filename); +FILE	*SafeOpenRead (const char *filename); +void	SafeRead (FILE *f, void *buffer, int count); +void	SafeWrite (FILE *f, const void *buffer, int count); +int		LoadFile (const char *filename, void **bufferptr); +int		LoadFileNoCrash (const char *filename, void **bufferptr); +void	SaveFile (const char *filename, void *buffer, int count); +void 	DefaultExtension (char *path, char *extension); +void 	DefaultPath (char *path, char *basepath); +void 	StripFilename (char *path); +void 	StripExtension (char *path); +void 	ExtractFilePath (const char *path, char *dest); +void	ExtractFileName (const char *path, char *dest); +void 	ExtractFileBase (const char *path, char *dest); +void	ExtractFileExtension (const char *path, char *dest); +short	BigShort (short l); +short	LittleShort (short l); +int		BigLong (int l); +int		LittleLong (int l); +float	BigFloat (float l); +float	LittleFloat (float l); +void *qmalloc (size_t size); +void* qblockmalloc(size_t nSize); + + + +// error and printf functions +typedef void (PFN_ERR)(const char *pFormat, ...); +typedef void (PFN_PRINTF)(const char *pFormat, ...); +typedef void (PFN_ERR_NUM)(int nNum, const char *pFormat, ...); +typedef void (PFN_PRINTF_NUM)(int nNum, const char *pFormat, ...); + +void Error(const char *pFormat, ...); +void Printf(const char *pFormat, ...); +void ErrorNum(int n, const char *pFormat, ...); +void PrintfNum(int n, const char *pFormat, ...); + +void SetErrorHandler(PFN_ERR pe); +void SetPrintfHandler(PFN_PRINTF pe); +void SetErrorHandlerNum(PFN_ERR_NUM pe); +void SetPrintfHandlerNum(PFN_PRINTF_NUM pe); +void ConvertDOSToUnixName( char *dst, const char *src ); +char* StrDup(char* pStr); +char* StrDup(const char* pStr); + +  #endif
\ No newline at end of file diff --git a/libs/cmdlib/cmdlib.cpp b/libs/cmdlib/cmdlib.cpp index c1e9d8b..15cf3f6 100755 --- a/libs/cmdlib/cmdlib.cpp +++ b/libs/cmdlib/cmdlib.cpp @@ -1,550 +1,550 @@ -//
 -// start of shared cmdlib stuff
 -// 
 -
 -
 -#include "cmdlib.h"
 -#include "windows.h"
 -
 -#define PATHSEPERATOR   '/'
 -
 -// rad additions
 -// 11.29.99
 -PFN_ERR *g_pfnError = NULL;
 -PFN_PRINTF *g_pfnPrintf = NULL;
 -PFN_ERR_NUM *g_pfnErrorNum = NULL;
 -PFN_PRINTF_NUM *g_pfnPrintfNum = NULL;
 -
 -
 -void Error(const char *pFormat, ...)
 -{
 -  if (g_pfnError)
 -  {
 -    va_list arg_ptr;
 -    va_start(arg_ptr, pFormat);
 -    g_pfnError(pFormat, arg_ptr);
 -    va_end(arg_ptr);
 -  }
 -}
 -
 -void Printf(const char *pFormat, ...)
 -{
 -  if (g_pfnPrintf)
 -  {
 -    va_list arg_ptr;
 -    va_start(arg_ptr, pFormat);
 -    g_pfnPrintf(pFormat, arg_ptr);
 -    va_end(arg_ptr);
 -  }
 -}
 -
 -void ErrorNum(int nErr, const char *pFormat, ...)
 -{
 -  if (g_pfnErrorNum)
 -  {
 -    va_list arg_ptr;
 -    va_start(arg_ptr, pFormat);
 -    g_pfnErrorNum(nErr, pFormat, arg_ptr);
 -    va_end(arg_ptr);
 -  }
 -}
 -
 -void PrintfNum(int nErr, const char *pFormat, ...)
 -{
 -  if (g_pfnPrintfNum)
 -  {
 -    va_list arg_ptr;
 -    va_start(arg_ptr, pFormat);
 -    g_pfnPrintfNum(nErr, pFormat, arg_ptr);
 -    va_end(arg_ptr);
 -  }
 -}
 -
 -
 -
 -void SetErrorHandler(PFN_ERR pe)
 -{
 -  g_pfnError = pe;
 -}
 -
 -void SetPrintfHandler(PFN_PRINTF pe)
 -{
 -  g_pfnPrintf = pe;
 -}
 -
 -void SetErrorHandlerNum(PFN_ERR_NUM pe)
 -{
 -  g_pfnErrorNum = pe;
 -}
 -
 -void SetPrintfHandler(PFN_PRINTF_NUM pe)
 -{
 -  g_pfnPrintfNum = pe;
 -}
 -
 -
 -
 -// rad end
 -
 -#define MEM_BLOCKSIZE 4096
 -void* qblockmalloc(size_t nSize)
 -{
 -	void *b;
 -  // round up to threshold
 -  int nAllocSize = nSize % MEM_BLOCKSIZE;
 -  if ( nAllocSize > 0)
 -  {
 -    nSize += MEM_BLOCKSIZE - nAllocSize;
 -  }
 -	b = malloc(nSize + 1);
 -	memset (b, 0, nSize);
 -	return b;
 -}
 -
 -void* qmalloc (size_t nSize)
 -{
 -	void *b;
 -	b = malloc(nSize + 1);
 -	memset (b, 0, nSize);
 -	return b;
 -}
 -
 -/*
 -================
 -Q_filelength
 -================
 -*/
 -int Q_filelength (FILE *f)
 -{
 -	int		pos;
 -	int		end;
 -
 -	pos = ftell (f);
 -	fseek (f, 0, SEEK_END);
 -	end = ftell (f);
 -	fseek (f, pos, SEEK_SET);
 -
 -	return end;
 -}
 -
 -
 -// FIXME: need error handler
 -FILE *SafeOpenWrite (const char *filename)
 -{
 -	FILE	*f;
 -
 -	f = fopen(filename, "wb");
 -
 -	if (!f)
 -  {
 -		Error ("Error opening %s: %s",filename,strerror(errno));
 -  }
 -
 -	return f;
 -}
 -
 -FILE *SafeOpenRead (const char *filename)
 -{
 -	FILE	*f;
 -
 -	f = fopen(filename, "rb");
 -
 -	if (!f)
 -  {
 -		Error ("Error opening %s: %s",filename,strerror(errno));
 -  }
 -
 -	return f;
 -}
 -
 -
 -void SafeRead (FILE *f, void *buffer, int count)
 -{
 -	if ( (int)fread (buffer, 1, count, f) != count)
 -		Error ("File read failure");
 -}
 -
 -
 -void SafeWrite (FILE *f, const void *buffer, int count)
 -{
 -	if ( (int)fwrite (buffer, 1, count, f) != count)
 -		Error ("File read failure");
 -}
 -
 -
 -
 -/*
 -==============
 -LoadFile
 -==============
 -*/
 -int LoadFile (const char *filename, void **bufferptr)
 -{
 -	FILE	*f;
 -	int    length;
 -	void    *buffer;
 -
 -  *bufferptr = NULL;
 -  
 -  if (filename == NULL || strlen(filename) == 0)
 -  {
 -    return -1;
 -  }
 -
 -	f = fopen (filename, "rb");
 -	if (!f)
 -	{
 -		return -1;
 -	}
 -	length = Q_filelength (f);
 -	buffer = qblockmalloc (length+1);
 -	((char *)buffer)[length] = 0;
 -	SafeRead (f, buffer, length);
 -	fclose (f);
 -
 -	*bufferptr = buffer;
 -	return length;
 -}
 -
 -
 -/*
 -==============
 -LoadFileNoCrash
 -
 -returns -1 length if not present
 -==============
 -*/
 -int    LoadFileNoCrash (const char *filename, void **bufferptr)
 -{
 -	FILE	*f;
 -	int    length;
 -	void    *buffer;
 -
 -	f = fopen (filename, "rb");
 -	if (!f)
 -		return -1;
 -	length = Q_filelength (f);
 -	buffer = qmalloc (length+1);
 -	((char *)buffer)[length] = 0;
 -	SafeRead (f, buffer, length);
 -	fclose (f);
 -
 -	*bufferptr = buffer;
 -	return length;
 -}
 -
 -
 -/*
 -==============
 -SaveFile
 -==============
 -*/
 -void    SaveFile (const char *filename, void *buffer, int count)
 -{
 -	FILE	*f;
 -
 -	f = SafeOpenWrite (filename);
 -	SafeWrite (f, buffer, count);
 -	fclose (f);
 -}
 -
 -
 -
 -void DefaultExtension (char *path, char *extension)
 -{
 -	char    *src;
 -//
 -// if path doesn't have a .EXT, append extension
 -// (extension should include the .)
 -//
 -	src = path + strlen(path) - 1;
 -
 -	while (*src != PATHSEPERATOR && src != path)
 -	{
 -		if (*src == '.')
 -			return;                 // it has an extension
 -		src--;
 -	}
 -
 -	strcat (path, extension);
 -}
 -
 -
 -void DefaultPath (char *path, char *basepath)
 -{
 -	char    temp[128];
 -
 -	if (path[0] == PATHSEPERATOR)
 -		return;                   // absolute path location
 -	strcpy (temp,path);
 -	strcpy (path,basepath);
 -	strcat (path,temp);
 -}
 -
 -
 -void    StripFilename (char *path)
 -{
 -	int             length;
 -
 -	length = strlen(path)-1;
 -	while (length > 0 && path[length] != PATHSEPERATOR)
 -		length--;
 -	path[length] = 0;
 -}
 -
 -void    StripExtension (char *path)
 -{
 -	int             length;
 -
 -	length = strlen(path)-1;
 -	while (length > 0 && path[length] != '.')
 -	{
 -		length--;
 -		if (path[length] == '/')
 -			return;		// no extension
 -	}
 -	if (length)
 -		path[length] = 0;
 -}
 -
 -
 -/*
 -====================
 -Extract file parts
 -====================
 -*/
 -void ExtractFilePath (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != PATHSEPERATOR)
 -		src--;
 -
 -	memcpy (dest, path, src-path);
 -	dest[src-path] = 0;
 -}
 -
 -void ExtractFileName (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != '/' 
 -		 && *(src-1) != '\\' )
 -		src--;
 -
 -	while (*src)
 -	{
 -		*dest++ = *src++;
 -	}
 -	*dest = 0;
 -}
 -
 -void ExtractFileBase (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != '/' 
 -		 && *(src-1) != '\\' )
 -		src--;
 -
 -	while (*src && *src != '.')
 -	{
 -		*dest++ = *src++;
 -	}
 -	*dest = 0;
 -}
 -
 -void ExtractFileExtension (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a . or the start
 -//
 -	while (src != path && *(src-1) != '.')
 -		src--;
 -	if (src == path)
 -	{
 -		*dest = 0;	// no extension
 -		return;
 -	}
 -
 -	strcpy (dest,src);
 -}
 -
 -
 -void ConvertDOSToUnixName( char *dst, const char *src )
 -{
 -	while ( *src )
 -	{
 -		if ( *src == '\\' )
 -			*dst = '/';
 -		else
 -			*dst = *src;
 -		dst++; src++;
 -	}
 -	*dst = 0;
 -}
 -
 -
 -char* StrDup(char* pStr)
 -{ 
 -  if (pStr)
 -  {
 -    return strcpy(new char[strlen(pStr)+1], pStr); 
 -  }
 -  return NULL;
 -}
 -
 -char* StrDup(const char* pStr)
 -{ 
 -  if (pStr)
 -  {
 -    return strcpy(new char[strlen(pStr)+1], pStr); 
 -  }
 -  return NULL;
 -}
 -
 -
 -/*
 -============================================================================
 -
 -					BYTE ORDER FUNCTIONS
 -
 -============================================================================
 -*/
 -
 -#ifdef _SGI_SOURCE
 -#define	__BIG_ENDIAN__
 -#endif
 -
 -#ifdef __BIG_ENDIAN__
 -
 -short   LittleShort (short l)
 -{
 -	byte    b1,b2;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -
 -	return (b1<<8) + b2;
 -}
 -
 -short   BigShort (short l)
 -{
 -	return l;
 -}
 -
 -
 -int    LittleLong (int l)
 -{
 -	byte    b1,b2,b3,b4;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -	b3 = (l>>16)&255;
 -	b4 = (l>>24)&255;
 -
 -	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
 -}
 -
 -int    BigLong (int l)
 -{
 -	return l;
 -}
 -
 -
 -float	LittleFloat (float l)
 -{
 -	union {byte b[4]; float f;} in, out;
 -	
 -	in.f = l;
 -	out.b[0] = in.b[3];
 -	out.b[1] = in.b[2];
 -	out.b[2] = in.b[1];
 -	out.b[3] = in.b[0];
 -	
 -	return out.f;
 -}
 -
 -float	BigFloat (float l)
 -{
 -	return l;
 -}
 -
 -
 -#else
 -
 -
 -short   BigShort (short l)
 -{
 -	byte    b1,b2;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -
 -	return (b1<<8) + b2;
 -}
 -
 -short   LittleShort (short l)
 -{
 -	return l;
 -}
 -
 -
 -int    BigLong (int l)
 -{
 -	byte    b1,b2,b3,b4;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -	b3 = (l>>16)&255;
 -	b4 = (l>>24)&255;
 -
 -	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
 -}
 -
 -int    LittleLong (int l)
 -{
 -	return l;
 -}
 -
 -float	BigFloat (float l)
 -{
 -	union {byte b[4]; float f;} in, out;
 -	
 -	in.f = l;
 -	out.b[0] = in.b[3];
 -	out.b[1] = in.b[2];
 -	out.b[2] = in.b[1];
 -	out.b[3] = in.b[0];
 -	
 -	return out.f;
 -}
 -
 -float	LittleFloat (float l)
 -{
 -	return l;
 -}
 -
 -
 -
 -#endif
 -
 +// +// start of shared cmdlib stuff +//  + + +#include "cmdlib.h" +#include "windows.h" + +#define PATHSEPERATOR   '/' + +// rad additions +// 11.29.99 +PFN_ERR *g_pfnError = NULL; +PFN_PRINTF *g_pfnPrintf = NULL; +PFN_ERR_NUM *g_pfnErrorNum = NULL; +PFN_PRINTF_NUM *g_pfnPrintfNum = NULL; + + +void Error(const char *pFormat, ...) +{ +  if (g_pfnError) +  { +    va_list arg_ptr; +    va_start(arg_ptr, pFormat); +    g_pfnError(pFormat, arg_ptr); +    va_end(arg_ptr); +  } +} + +void Printf(const char *pFormat, ...) +{ +  if (g_pfnPrintf) +  { +    va_list arg_ptr; +    va_start(arg_ptr, pFormat); +    g_pfnPrintf(pFormat, arg_ptr); +    va_end(arg_ptr); +  } +} + +void ErrorNum(int nErr, const char *pFormat, ...) +{ +  if (g_pfnErrorNum) +  { +    va_list arg_ptr; +    va_start(arg_ptr, pFormat); +    g_pfnErrorNum(nErr, pFormat, arg_ptr); +    va_end(arg_ptr); +  } +} + +void PrintfNum(int nErr, const char *pFormat, ...) +{ +  if (g_pfnPrintfNum) +  { +    va_list arg_ptr; +    va_start(arg_ptr, pFormat); +    g_pfnPrintfNum(nErr, pFormat, arg_ptr); +    va_end(arg_ptr); +  } +} + + + +void SetErrorHandler(PFN_ERR pe) +{ +  g_pfnError = pe; +} + +void SetPrintfHandler(PFN_PRINTF pe) +{ +  g_pfnPrintf = pe; +} + +void SetErrorHandlerNum(PFN_ERR_NUM pe) +{ +  g_pfnErrorNum = pe; +} + +void SetPrintfHandler(PFN_PRINTF_NUM pe) +{ +  g_pfnPrintfNum = pe; +} + + + +// rad end + +#define MEM_BLOCKSIZE 4096 +void* qblockmalloc(size_t nSize) +{ +	void *b; +  // round up to threshold +  int nAllocSize = nSize % MEM_BLOCKSIZE; +  if ( nAllocSize > 0) +  { +    nSize += MEM_BLOCKSIZE - nAllocSize; +  } +	b = malloc(nSize + 1); +	memset (b, 0, nSize); +	return b; +} + +void* qmalloc (size_t nSize) +{ +	void *b; +	b = malloc(nSize + 1); +	memset (b, 0, nSize); +	return b; +} + +/* +================ +Q_filelength +================ +*/ +int Q_filelength (FILE *f) +{ +	int		pos; +	int		end; + +	pos = ftell (f); +	fseek (f, 0, SEEK_END); +	end = ftell (f); +	fseek (f, pos, SEEK_SET); + +	return end; +} + + +// FIXME: need error handler +FILE *SafeOpenWrite (const char *filename) +{ +	FILE	*f; + +	f = fopen(filename, "wb"); + +	if (!f) +  { +		Error ("Error opening %s: %s",filename,strerror(errno)); +  } + +	return f; +} + +FILE *SafeOpenRead (const char *filename) +{ +	FILE	*f; + +	f = fopen(filename, "rb"); + +	if (!f) +  { +		Error ("Error opening %s: %s",filename,strerror(errno)); +  } + +	return f; +} + + +void SafeRead (FILE *f, void *buffer, int count) +{ +	if ( (int)fread (buffer, 1, count, f) != count) +		Error ("File read failure"); +} + + +void SafeWrite (FILE *f, const void *buffer, int count) +{ +	if ( (int)fwrite (buffer, 1, count, f) != count) +		Error ("File read failure"); +} + + + +/* +============== +LoadFile +============== +*/ +int LoadFile (const char *filename, void **bufferptr) +{ +	FILE	*f; +	int    length; +	void    *buffer; + +  *bufferptr = NULL; +   +  if (filename == NULL || strlen(filename) == 0) +  { +    return -1; +  } + +	f = fopen (filename, "rb"); +	if (!f) +	{ +		return -1; +	} +	length = Q_filelength (f); +	buffer = qblockmalloc (length+1); +	((char *)buffer)[length] = 0; +	SafeRead (f, buffer, length); +	fclose (f); + +	*bufferptr = buffer; +	return length; +} + + +/* +============== +LoadFileNoCrash + +returns -1 length if not present +============== +*/ +int    LoadFileNoCrash (const char *filename, void **bufferptr) +{ +	FILE	*f; +	int    length; +	void    *buffer; + +	f = fopen (filename, "rb"); +	if (!f) +		return -1; +	length = Q_filelength (f); +	buffer = qmalloc (length+1); +	((char *)buffer)[length] = 0; +	SafeRead (f, buffer, length); +	fclose (f); + +	*bufferptr = buffer; +	return length; +} + + +/* +============== +SaveFile +============== +*/ +void    SaveFile (const char *filename, void *buffer, int count) +{ +	FILE	*f; + +	f = SafeOpenWrite (filename); +	SafeWrite (f, buffer, count); +	fclose (f); +} + + + +void DefaultExtension (char *path, char *extension) +{ +	char    *src; +// +// if path doesn't have a .EXT, append extension +// (extension should include the .) +// +	src = path + strlen(path) - 1; + +	while (*src != PATHSEPERATOR && src != path) +	{ +		if (*src == '.') +			return;                 // it has an extension +		src--; +	} + +	strcat (path, extension); +} + + +void DefaultPath (char *path, char *basepath) +{ +	char    temp[128]; + +	if (path[0] == PATHSEPERATOR) +		return;                   // absolute path location +	strcpy (temp,path); +	strcpy (path,basepath); +	strcat (path,temp); +} + + +void    StripFilename (char *path) +{ +	int             length; + +	length = strlen(path)-1; +	while (length > 0 && path[length] != PATHSEPERATOR) +		length--; +	path[length] = 0; +} + +void    StripExtension (char *path) +{ +	int             length; + +	length = strlen(path)-1; +	while (length > 0 && path[length] != '.') +	{ +		length--; +		if (path[length] == '/') +			return;		// no extension +	} +	if (length) +		path[length] = 0; +} + + +/* +==================== +Extract file parts +==================== +*/ +void ExtractFilePath (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != PATHSEPERATOR) +		src--; + +	memcpy (dest, path, src-path); +	dest[src-path] = 0; +} + +void ExtractFileName (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != '/'  +		 && *(src-1) != '\\' ) +		src--; + +	while (*src) +	{ +		*dest++ = *src++; +	} +	*dest = 0; +} + +void ExtractFileBase (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != '/'  +		 && *(src-1) != '\\' ) +		src--; + +	while (*src && *src != '.') +	{ +		*dest++ = *src++; +	} +	*dest = 0; +} + +void ExtractFileExtension (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a . or the start +// +	while (src != path && *(src-1) != '.') +		src--; +	if (src == path) +	{ +		*dest = 0;	// no extension +		return; +	} + +	strcpy (dest,src); +} + + +void ConvertDOSToUnixName( char *dst, const char *src ) +{ +	while ( *src ) +	{ +		if ( *src == '\\' ) +			*dst = '/'; +		else +			*dst = *src; +		dst++; src++; +	} +	*dst = 0; +} + + +char* StrDup(char* pStr) +{  +  if (pStr) +  { +    return strcpy(new char[strlen(pStr)+1], pStr);  +  } +  return NULL; +} + +char* StrDup(const char* pStr) +{  +  if (pStr) +  { +    return strcpy(new char[strlen(pStr)+1], pStr);  +  } +  return NULL; +} + + +/* +============================================================================ + +					BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +#ifdef _SGI_SOURCE +#define	__BIG_ENDIAN__ +#endif + +#ifdef __BIG_ENDIAN__ + +short   LittleShort (short l) +{ +	byte    b1,b2; + +	b1 = l&255; +	b2 = (l>>8)&255; + +	return (b1<<8) + b2; +} + +short   BigShort (short l) +{ +	return l; +} + + +int    LittleLong (int l) +{ +	byte    b1,b2,b3,b4; + +	b1 = l&255; +	b2 = (l>>8)&255; +	b3 = (l>>16)&255; +	b4 = (l>>24)&255; + +	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int    BigLong (int l) +{ +	return l; +} + + +float	LittleFloat (float l) +{ +	union {byte b[4]; float f;} in, out; +	 +	in.f = l; +	out.b[0] = in.b[3]; +	out.b[1] = in.b[2]; +	out.b[2] = in.b[1]; +	out.b[3] = in.b[0]; +	 +	return out.f; +} + +float	BigFloat (float l) +{ +	return l; +} + + +#else + + +short   BigShort (short l) +{ +	byte    b1,b2; + +	b1 = l&255; +	b2 = (l>>8)&255; + +	return (b1<<8) + b2; +} + +short   LittleShort (short l) +{ +	return l; +} + + +int    BigLong (int l) +{ +	byte    b1,b2,b3,b4; + +	b1 = l&255; +	b2 = (l>>8)&255; +	b3 = (l>>16)&255; +	b4 = (l>>24)&255; + +	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int    LittleLong (int l) +{ +	return l; +} + +float	BigFloat (float l) +{ +	union {byte b[4]; float f;} in, out; +	 +	in.f = l; +	out.b[0] = in.b[3]; +	out.b[1] = in.b[2]; +	out.b[2] = in.b[1]; +	out.b[3] = in.b[0]; +	 +	return out.f; +} + +float	LittleFloat (float l) +{ +	return l; +} + + + +#endif + diff --git a/libs/cmdlib/cmdlib.vcproj b/libs/cmdlib/cmdlib.vcproj index f471b07..b5a58d8 100755 --- a/libs/cmdlib/cmdlib.vcproj +++ b/libs/cmdlib/cmdlib.vcproj @@ -1,156 +1,156 @@ -<?xml version="1.0" encoding="Windows-1252"?>
 -<VisualStudioProject
 -	ProjectType="Visual C++"
 -	Version="7.10"
 -	Name="cmdlib"
 -	SccProjectName=""$/source/q3radiant", FEFAAAAA"
 -	SccLocalPath="..\..\q3radiant">
 -	<Platforms>
 -		<Platform
 -			Name="Win32"/>
 -	</Platforms>
 -	<Configurations>
 -		<Configuration
 -			Name="Release|Win32"
 -			OutputDirectory=".\Release"
 -			IntermediateDirectory=".\Release"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="2"
 -				InlineFunctionExpansion="1"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
 -				StringPooling="TRUE"
 -				RuntimeLibrary="0"
 -				EnableFunctionLevelLinking="TRUE"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Release/cmdlib.pch"
 -				AssemblerListingLocation=".\Release/"
 -				ObjectFile=".\Release/"
 -				ProgramDataBaseFileName=".\Release/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\cmdlib.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="NDEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -		<Configuration
 -			Name="Debug|Win32"
 -			OutputDirectory=".\Debug"
 -			IntermediateDirectory=".\Debug"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="0"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
 -				BasicRuntimeChecks="3"
 -				RuntimeLibrary="1"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Debug/cmdlib.pch"
 -				AssemblerListingLocation=".\Debug/"
 -				ObjectFile=".\Debug/"
 -				ProgramDataBaseFileName=".\Debug/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				DebugInformationFormat="4"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\cmdlibd.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="_DEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -	</Configurations>
 -	<References>
 -	</References>
 -	<Files>
 -		<Filter
 -			Name="Source Files"
 -			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
 -			<File
 -				RelativePath="cmdlib.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -		</Filter>
 -		<Filter
 -			Name="Header Files"
 -			Filter="h;hpp;hxx;hm;inl">
 -			<File
 -				RelativePath="..\cmdlib.h">
 -			</File>
 -		</Filter>
 -	</Files>
 -	<Globals>
 -	</Globals>
 -</VisualStudioProject>
 +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject +	ProjectType="Visual C++" +	Version="7.10" +	Name="cmdlib" +	SccProjectName=""$/source/q3radiant", FEFAAAAA" +	SccLocalPath="..\..\q3radiant"> +	<Platforms> +		<Platform +			Name="Win32"/> +	</Platforms> +	<Configurations> +		<Configuration +			Name="Release|Win32" +			OutputDirectory=".\Release" +			IntermediateDirectory=".\Release" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="2" +				InlineFunctionExpansion="1" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;NDEBUG;_LIB" +				StringPooling="TRUE" +				RuntimeLibrary="0" +				EnableFunctionLevelLinking="TRUE" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Release/cmdlib.pch" +				AssemblerListingLocation=".\Release/" +				ObjectFile=".\Release/" +				ProgramDataBaseFileName=".\Release/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\cmdlib.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="NDEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Debug|Win32" +			OutputDirectory=".\Debug" +			IntermediateDirectory=".\Debug" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;_DEBUG;_LIB" +				BasicRuntimeChecks="3" +				RuntimeLibrary="1" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Debug/cmdlib.pch" +				AssemblerListingLocation=".\Debug/" +				ObjectFile=".\Debug/" +				ProgramDataBaseFileName=".\Debug/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				DebugInformationFormat="4" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\cmdlibd.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="_DEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +	</Configurations> +	<References> +	</References> +	<Files> +		<Filter +			Name="Source Files" +			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> +			<File +				RelativePath="cmdlib.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +		</Filter> +		<Filter +			Name="Header Files" +			Filter="h;hpp;hxx;hm;inl"> +			<File +				RelativePath="..\cmdlib.h"> +			</File> +		</Filter> +	</Files> +	<Globals> +	</Globals> +</VisualStudioProject> diff --git a/libs/jpeg6/jchuff.h b/libs/jpeg6/jchuff.h index 0a81d54..f43d571 100755 --- a/libs/jpeg6/jchuff.h +++ b/libs/jpeg6/jchuff.h @@ -1,34 +1,34 @@ -/*
 - * jchuff.h
 - *
 - * Copyright (C) 1991-1995, 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 declarations for Huffman entropy encoding routines
 - * that are shared between the sequential encoder (jchuff.c) and the
 - * progressive encoder (jcphuff.c).  No other modules need to see these.
 - */
 -
 -/* Derived data constructed for each Huffman table */
 -
 -typedef struct {
 -  unsigned int ehufco[256];	/* code for each symbol */
 -  char ehufsi[256];		/* length of code for each symbol */
 -  /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
 -} c_derived_tbl;
 -
 -/* Short forms of external names for systems with brain-damaged linkers. */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_make_c_derived_tbl	jMkCDerived
 -#define jpeg_gen_optimal_table	jGenOptTbl
 -#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));
 -
 -/* 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[]));
 +/* + * jchuff.h + * + * Copyright (C) 1991-1995, 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 declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c).  No other modules need to see these. + */ + +/* Derived data constructed for each Huffman table */ + +typedef struct { +  unsigned int ehufco[256];	/* code for each symbol */ +  char ehufsi[256];		/* length of code for each symbol */ +  /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl	jMkCDerived +#define jpeg_gen_optimal_table	jGenOptTbl +#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)); + +/* 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[])); diff --git a/libs/jpeg6/jcomapi.cpp b/libs/jpeg6/jcomapi.cpp index 8f417c0..c10903f 100755 --- a/libs/jpeg6/jcomapi.cpp +++ b/libs/jpeg6/jcomapi.cpp @@ -1,94 +1,94 @@ -/*
 - * jcomapi.c
 - *
 - * Copyright (C) 1994, 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 application interface routines that are used for both
 - * compression and decompression.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/*
 - * Abort processing of a JPEG compression or decompression operation,
 - * but don't destroy the object itself.
 - *
 - * For this, we merely clean up all the nonpermanent memory pools.
 - * Note that temp files (virtual arrays) are not allowed to belong to
 - * the permanent pool, so we will be able to close all temp files here.
 - * Closing a data source or destination, if necessary, is the application's
 - * responsibility.
 - */
 -
 -GLOBAL void
 -jpeg_abort (j_common_ptr cinfo)
 -{
 -  int pool;
 -
 -  /* Releasing pools in reverse order might help avoid fragmentation
 -   * with some (brain-damaged) malloc libraries.
 -   */
 -  for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
 -    (*cinfo->mem->free_pool) (cinfo, pool);
 -  }
 -
 -  /* Reset overall state for possible reuse of object */
 -  cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START);
 -}
 -
 -
 -/*
 - * Destruction of a JPEG object.
 - *
 - * Everything gets deallocated except the master jpeg_compress_struct itself
 - * and the error manager struct.  Both of these are supplied by the application
 - * and must be freed, if necessary, by the application.  (Often they are on
 - * the stack and so don't need to be freed anyway.)
 - * Closing a data source or destination, if necessary, is the application's
 - * responsibility.
 - */
 -
 -GLOBAL void
 -jpeg_destroy (j_common_ptr cinfo)
 -{
 -  /* We need only tell the memory manager to release everything. */
 -  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
 -  if (cinfo->mem != NULL)
 -    (*cinfo->mem->self_destruct) (cinfo);
 -  cinfo->mem = NULL;		/* be safe if jpeg_destroy is called twice */
 -  cinfo->global_state = 0;	/* mark it destroyed */
 -}
 -
 -
 -/*
 - * Convenience routines for allocating quantization and Huffman tables.
 - * (Would jutils.c be a more reasonable place to put these?)
 - */
 -
 -GLOBAL JQUANT_TBL *
 -jpeg_alloc_quant_table (j_common_ptr cinfo)
 -{
 -  JQUANT_TBL *tbl;
 -
 -  tbl = (JQUANT_TBL *)
 -    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
 -  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
 -  return tbl;
 -}
 -
 -
 -GLOBAL JHUFF_TBL *
 -jpeg_alloc_huff_table (j_common_ptr cinfo)
 -{
 -  JHUFF_TBL *tbl;
 -
 -  tbl = (JHUFF_TBL *)
 -    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
 -  tbl->sent_table = FALSE;	/* make sure this is false in any new table */
 -  return tbl;
 -}
 +/* + * jcomapi.c + * + * Copyright (C) 1994, 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 application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Abort processing of a JPEG compression or decompression operation, + * but don't destroy the object itself. + * + * For this, we merely clean up all the nonpermanent memory pools. + * Note that temp files (virtual arrays) are not allowed to belong to + * the permanent pool, so we will be able to close all temp files here. + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL void +jpeg_abort (j_common_ptr cinfo) +{ +  int pool; + +  /* Releasing pools in reverse order might help avoid fragmentation +   * with some (brain-damaged) malloc libraries. +   */ +  for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { +    (*cinfo->mem->free_pool) (cinfo, pool); +  } + +  /* Reset overall state for possible reuse of object */ +  cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START); +} + + +/* + * Destruction of a JPEG object. + * + * Everything gets deallocated except the master jpeg_compress_struct itself + * and the error manager struct.  Both of these are supplied by the application + * and must be freed, if necessary, by the application.  (Often they are on + * the stack and so don't need to be freed anyway.) + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL void +jpeg_destroy (j_common_ptr cinfo) +{ +  /* We need only tell the memory manager to release everything. */ +  /* NB: mem pointer is NULL if memory mgr failed to initialize. */ +  if (cinfo->mem != NULL) +    (*cinfo->mem->self_destruct) (cinfo); +  cinfo->mem = NULL;		/* be safe if jpeg_destroy is called twice */ +  cinfo->global_state = 0;	/* mark it destroyed */ +} + + +/* + * Convenience routines for allocating quantization and Huffman tables. + * (Would jutils.c be a more reasonable place to put these?) + */ + +GLOBAL JQUANT_TBL * +jpeg_alloc_quant_table (j_common_ptr cinfo) +{ +  JQUANT_TBL *tbl; + +  tbl = (JQUANT_TBL *) +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); +  tbl->sent_table = FALSE;	/* make sure this is false in any new table */ +  return tbl; +} + + +GLOBAL JHUFF_TBL * +jpeg_alloc_huff_table (j_common_ptr cinfo) +{ +  JHUFF_TBL *tbl; + +  tbl = (JHUFF_TBL *) +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); +  tbl->sent_table = FALSE;	/* make sure this is false in any new table */ +  return tbl; +} diff --git a/libs/jpeg6/jconfig.h b/libs/jpeg6/jconfig.h index 187ecfc..7d2f733 100755 --- a/libs/jpeg6/jconfig.h +++ b/libs/jpeg6/jconfig.h @@ -1,41 +1,41 @@ -/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
 -/* see jconfig.doc for explanations */
 -
 -#define HAVE_PROTOTYPES
 -#define HAVE_UNSIGNED_CHAR
 -#define HAVE_UNSIGNED_SHORT
 -/* #define void char */
 -/* #define const */
 -#define CHAR_IS_UNSIGNED
 -#define HAVE_STDDEF_H
 -#define HAVE_STDLIB_H
 -#undef NEED_BSD_STRINGS
 -#undef NEED_SYS_TYPES_H
 -#undef NEED_FAR_POINTERS	/* Watcom uses flat 32-bit addressing */
 -#undef NEED_SHORT_EXTERNAL_NAMES
 -#undef INCOMPLETE_TYPES_BROKEN
 -
 -#define JDCT_DEFAULT  JDCT_FLOAT
 -#define JDCT_FASTEST  JDCT_FLOAT
 -
 -#ifdef JPEG_INTERNALS
 -
 -#undef RIGHT_SHIFT_IS_UNSIGNED
 -
 -#endif /* JPEG_INTERNALS */
 -
 -#ifdef JPEG_CJPEG_DJPEG
 -
 -#define BMP_SUPPORTED		/* BMP image file format */
 -#define GIF_SUPPORTED		/* GIF image file format */
 -#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
 -#undef RLE_SUPPORTED		/* Utah RLE image file format */
 -#define TARGA_SUPPORTED		/* Targa image file format */
 -
 -#undef TWO_FILE_COMMANDLINE	/* optional */
 -#define USE_SETMODE		/* Needed to make one-file style work in Watcom */
 -#undef NEED_SIGNAL_CATCHER	/* Define this if you use jmemname.c */
 -#undef DONT_USE_B_MODE
 -#undef PROGRESS_REPORT		/* optional */
 -
 -#endif /* JPEG_CJPEG_DJPEG */
 +/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#define CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS	/* Watcom uses flat 32-bit addressing */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#define JDCT_DEFAULT  JDCT_FLOAT +#define JDCT_FASTEST  JDCT_FLOAT + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED		/* BMP image file format */ +#define GIF_SUPPORTED		/* GIF image file format */ +#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED		/* Utah RLE image file format */ +#define TARGA_SUPPORTED		/* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE	/* optional */ +#define USE_SETMODE		/* Needed to make one-file style work in Watcom */ +#undef NEED_SIGNAL_CATCHER	/* Define this if you use jmemname.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT		/* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/libs/jpeg6/jdapimin.cpp b/libs/jpeg6/jdapimin.cpp index 1bae6a2..1ea7ef1 100755 --- a/libs/jpeg6/jdapimin.cpp +++ b/libs/jpeg6/jdapimin.cpp @@ -1,400 +1,400 @@ -/*
 - * jdapimin.c
 - *
 - * Copyright (C) 1994-1995, 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 application interface code for the decompression half
 - * of the JPEG library.  These are the "minimum" API routines that may be
 - * needed in either the normal full-decompression case or the
 - * transcoding-only case.
 - *
 - * Most of the routines intended to be called directly by an application
 - * are in this file or in jdapistd.c.  But also see jcomapi.c for routines
 - * shared by compression and decompression, and jdtrans.c for the transcoding
 - * case.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/*
 - * Initialization of a JPEG decompression object.
 - * The error manager must already be set up (in case memory manager fails).
 - */
 -
 -GLOBAL void
 -jpeg_create_decompress (j_decompress_ptr cinfo)
 -{
 -  int i;
 -
 -  /* For debugging purposes, zero the whole master structure.
 -   * But error manager pointer is already there, so save and restore it.
 -   */
 -  {
 -    struct jpeg_error_mgr * err = cinfo->err;
 -    i = sizeof(struct jpeg_decompress_struct);
 -    i = SIZEOF(struct jpeg_decompress_struct);
 -    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
 -    cinfo->err = err;
 -  }
 -  cinfo->is_decompressor = TRUE;
 -
 -  /* Initialize a memory manager instance for this object */
 -  jinit_memory_mgr((j_common_ptr) cinfo);
 -
 -  /* Zero out pointers to permanent structures. */
 -  cinfo->progress = NULL;
 -  cinfo->src = NULL;
 -
 -  for (i = 0; i < NUM_QUANT_TBLS; i++)
 -    cinfo->quant_tbl_ptrs[i] = NULL;
 -
 -  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 -    cinfo->dc_huff_tbl_ptrs[i] = NULL;
 -    cinfo->ac_huff_tbl_ptrs[i] = NULL;
 -  }
 -
 -  /* Initialize marker processor so application can override methods
 -   * for COM, APPn markers before calling jpeg_read_header.
 -   */
 -  jinit_marker_reader(cinfo);
 -
 -  /* And initialize the overall input controller. */
 -  jinit_input_controller(cinfo);
 -
 -  /* OK, I'm ready */
 -  cinfo->global_state = DSTATE_START;
 -}
 -
 -
 -/*
 - * Destruction of a JPEG decompression object
 - */
 -
 -GLOBAL void
 -jpeg_destroy_decompress (j_decompress_ptr cinfo)
 -{
 -  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
 -}
 -
 -
 -/*
 - * Abort processing of a JPEG decompression operation,
 - * but don't destroy the object itself.
 - */
 -
 -GLOBAL void
 -jpeg_abort_decompress (j_decompress_ptr cinfo)
 -{
 -  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
 -}
 -
 -
 -/*
 - * 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
 -default_decompress_parms (j_decompress_ptr cinfo)
 -{
 -  /* Guess the input colorspace, and set output colorspace accordingly. */
 -  /* (Wish JPEG committee had provided a real way to specify this...) */
 -  /* Note application may override our guesses. */
 -  switch (cinfo->num_components) {
 -  case 1:
 -    cinfo->jpeg_color_space = JCS_GRAYSCALE;
 -    cinfo->out_color_space = JCS_GRAYSCALE;
 -    break;
 -    
 -  case 3:
 -    if (cinfo->saw_JFIF_marker) {
 -      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
 -    } else if (cinfo->saw_Adobe_marker) {
 -      switch (cinfo->Adobe_transform) {
 -      case 0:
 -	cinfo->jpeg_color_space = JCS_RGB;
 -	break;
 -      case 1:
 -	cinfo->jpeg_color_space = JCS_YCbCr;
 -	break;
 -      default:
 -	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
 -	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
 -	break;
 -      }
 -    } else {
 -      /* Saw no special markers, try to guess from the component IDs */
 -      int cid0 = cinfo->comp_info[0].component_id;
 -      int cid1 = cinfo->comp_info[1].component_id;
 -      int cid2 = cinfo->comp_info[2].component_id;
 -
 -      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
 -	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
 -      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
 -	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
 -      else {
 -	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
 -	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
 -      }
 -    }
 -    /* Always guess RGB is proper output colorspace. */
 -    cinfo->out_color_space = JCS_RGB;
 -    break;
 -    
 -  case 4:
 -    if (cinfo->saw_Adobe_marker) {
 -      switch (cinfo->Adobe_transform) {
 -      case 0:
 -	cinfo->jpeg_color_space = JCS_CMYK;
 -	break;
 -      case 2:
 -	cinfo->jpeg_color_space = JCS_YCCK;
 -	break;
 -      default:
 -	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
 -	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
 -	break;
 -      }
 -    } else {
 -      /* No special markers, assume straight CMYK. */
 -      cinfo->jpeg_color_space = JCS_CMYK;
 -    }
 -    cinfo->out_color_space = JCS_CMYK;
 -    break;
 -    
 -  default:
 -    cinfo->jpeg_color_space = JCS_UNKNOWN;
 -    cinfo->out_color_space = JCS_UNKNOWN;
 -    break;
 -  }
 -
 -  /* Set defaults for other decompression parameters. */
 -  cinfo->scale_num = 1;		/* 1:1 scaling */
 -  cinfo->scale_denom = 1;
 -  cinfo->output_gamma = 1.0;
 -  cinfo->buffered_image = FALSE;
 -  cinfo->raw_data_out = FALSE;
 -  cinfo->dct_method = JDCT_DEFAULT;
 -  cinfo->do_fancy_upsampling = TRUE;
 -  cinfo->do_block_smoothing = TRUE;
 -  cinfo->quantize_colors = FALSE;
 -  /* We set these in case application only sets quantize_colors. */
 -  cinfo->dither_mode = JDITHER_FS;
 -#ifdef QUANT_2PASS_SUPPORTED
 -  cinfo->two_pass_quantize = TRUE;
 -#else
 -  cinfo->two_pass_quantize = FALSE;
 -#endif
 -  cinfo->desired_number_of_colors = 256;
 -  cinfo->colormap = NULL;
 -  /* Initialize for no mode change in buffered-image mode. */
 -  cinfo->enable_1pass_quant = FALSE;
 -  cinfo->enable_external_quant = FALSE;
 -  cinfo->enable_2pass_quant = FALSE;
 -}
 -
 -
 -/*
 - * Decompression startup: read start of JPEG datastream to see what's there.
 - * Need only initialize JPEG object and supply a data source before calling.
 - *
 - * This routine will read as far as the first SOS marker (ie, actual start of
 - * compressed data), and will save all tables and parameters in the JPEG
 - * object.  It will also initialize the decompression parameters to default
 - * values, and finally return JPEG_HEADER_OK.  On return, the application may
 - * adjust the decompression parameters and then call jpeg_start_decompress.
 - * (Or, if the application only wanted to determine the image parameters,
 - * the data need not be decompressed.  In that case, call jpeg_abort or
 - * jpeg_destroy to release any temporary space.)
 - * If an abbreviated (tables only) datastream is presented, the routine will
 - * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then
 - * re-use the JPEG object to read the abbreviated image datastream(s).
 - * It is unnecessary (but OK) to call jpeg_abort in this case.
 - * The JPEG_SUSPENDED return code only occurs if the data source module
 - * requests suspension of the decompressor.  In this case the application
 - * should load more source data and then re-call jpeg_read_header to resume
 - * processing.
 - * If a non-suspending data source is used and require_image is TRUE, then the
 - * return code need not be inspected since only JPEG_HEADER_OK is possible.
 - *
 - * This routine is now just a front end to jpeg_consume_input, with some
 - * extra error checking.
 - */
 -
 -GLOBAL int
 -jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
 -{
 -  int retcode;
 -
 -  if (cinfo->global_state != DSTATE_START &&
 -      cinfo->global_state != DSTATE_INHEADER)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -
 -  retcode = jpeg_consume_input(cinfo);
 -
 -  switch (retcode) {
 -  case JPEG_REACHED_SOS:
 -    retcode = JPEG_HEADER_OK;
 -    break;
 -  case JPEG_REACHED_EOI:
 -    if (require_image)		/* Complain if application wanted an image */
 -      ERREXIT(cinfo, JERR_NO_IMAGE);
 -    /* Reset to start state; it would be safer to require the application to
 -     * call jpeg_abort, but we can't change it now for compatibility reasons.
 -     * A side effect is to free any temporary memory (there shouldn't be any).
 -     */
 -    jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
 -    retcode = JPEG_HEADER_TABLES_ONLY;
 -    break;
 -  case JPEG_SUSPENDED:
 -    /* no work */
 -    break;
 -  }
 -
 -  return retcode;
 -}
 -
 -
 -/*
 - * Consume data in advance of what the decompressor requires.
 - * This can be called at any time once the decompressor object has
 - * been created and a data source has been set up.
 - *
 - * This routine is essentially a state machine that handles a couple
 - * of critical state-transition actions, namely initial setup and
 - * transition from header scanning to ready-for-start_decompress.
 - * All the actual input is done via the input controller's consume_input
 - * method.
 - */
 -
 -GLOBAL int
 -jpeg_consume_input (j_decompress_ptr cinfo)
 -{
 -  int retcode = JPEG_SUSPENDED;
 -
 -  /* NB: every possible DSTATE value should be listed in this switch */
 -  switch (cinfo->global_state) {
 -  case DSTATE_START:
 -    /* Start-of-datastream actions: reset appropriate modules */
 -    (*cinfo->inputctl->reset_input_controller) (cinfo);
 -    /* Initialize application's data source module */
 -    (*cinfo->src->init_source) (cinfo);
 -    cinfo->global_state = DSTATE_INHEADER;
 -    /*FALLTHROUGH*/
 -  case DSTATE_INHEADER:
 -    retcode = (*cinfo->inputctl->consume_input) (cinfo);
 -    if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
 -      /* Set up default parameters based on header data */
 -      default_decompress_parms(cinfo);
 -      /* Set global state: ready for start_decompress */
 -      cinfo->global_state = DSTATE_READY;
 -    }
 -    break;
 -  case DSTATE_READY:
 -    /* Can't advance past first SOS until start_decompress is called */
 -    retcode = JPEG_REACHED_SOS;
 -    break;
 -  case DSTATE_PRELOAD:
 -  case DSTATE_PRESCAN:
 -  case DSTATE_SCANNING:
 -  case DSTATE_RAW_OK:
 -  case DSTATE_BUFIMAGE:
 -  case DSTATE_BUFPOST:
 -  case DSTATE_STOPPING:
 -    retcode = (*cinfo->inputctl->consume_input) (cinfo);
 -    break;
 -  default:
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  }
 -  return retcode;
 -}
 -
 -
 -/*
 - * Have we finished reading the input file?
 - */
 -
 -GLOBAL boolean
 -jpeg_input_complete (j_decompress_ptr cinfo)
 -{
 -  /* Check for valid jpeg object */
 -  if (cinfo->global_state < DSTATE_START ||
 -      cinfo->global_state > DSTATE_STOPPING)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  return cinfo->inputctl->eoi_reached;
 -}
 -
 -
 -/*
 - * Is there more than one scan?
 - */
 -
 -GLOBAL boolean
 -jpeg_has_multiple_scans (j_decompress_ptr cinfo)
 -{
 -  /* Only valid after jpeg_read_header completes */
 -  if (cinfo->global_state < DSTATE_READY ||
 -      cinfo->global_state > DSTATE_STOPPING)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  return cinfo->inputctl->has_multiple_scans;
 -}
 -
 -
 -/*
 - * Finish JPEG decompression.
 - *
 - * This will normally just verify the file trailer and release temp storage.
 - *
 - * Returns FALSE if suspended.  The return value need be inspected only if
 - * a suspending data source is used.
 - */
 -
 -GLOBAL boolean
 -jpeg_finish_decompress (j_decompress_ptr cinfo)
 -{
 -  if ((cinfo->global_state == DSTATE_SCANNING ||
 -       cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
 -    /* Terminate final pass of non-buffered mode */
 -    if (cinfo->output_scanline < cinfo->output_height)
 -      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
 -    (*cinfo->master->finish_output_pass) (cinfo);
 -    cinfo->global_state = DSTATE_STOPPING;
 -  } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
 -    /* Finishing after a buffered-image operation */
 -    cinfo->global_state = DSTATE_STOPPING;
 -  } else if (cinfo->global_state != DSTATE_STOPPING) {
 -    /* STOPPING = repeat call after a suspension, anything else is error */
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  }
 -  /* Read until EOI */
 -  while (! cinfo->inputctl->eoi_reached) {
 -    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
 -      return FALSE;		/* Suspend, come back later */
 -  }
 -  /* Do final cleanup */
 -  (*cinfo->src->term_source) (cinfo);
 -  /* We can use jpeg_abort to release memory and reset global_state */
 -  jpeg_abort((j_common_ptr) cinfo);
 -  return TRUE;
 -}
 +/* + * jdapimin.c + * + * Copyright (C) 1994-1995, 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 application interface code for the decompression half + * of the JPEG library.  These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c.  But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG decompression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL void +jpeg_create_decompress (j_decompress_ptr cinfo) +{ +  int i; + +  /* For debugging purposes, zero the whole master structure. +   * But error manager pointer is already there, so save and restore it. +   */ +  { +    struct jpeg_error_mgr * err = cinfo->err; +    i = sizeof(struct jpeg_decompress_struct); +    i = SIZEOF(struct jpeg_decompress_struct); +    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); +    cinfo->err = err; +  } +  cinfo->is_decompressor = TRUE; + +  /* Initialize a memory manager instance for this object */ +  jinit_memory_mgr((j_common_ptr) cinfo); + +  /* Zero out pointers to permanent structures. */ +  cinfo->progress = NULL; +  cinfo->src = NULL; + +  for (i = 0; i < NUM_QUANT_TBLS; i++) +    cinfo->quant_tbl_ptrs[i] = NULL; + +  for (i = 0; i < NUM_HUFF_TBLS; i++) { +    cinfo->dc_huff_tbl_ptrs[i] = NULL; +    cinfo->ac_huff_tbl_ptrs[i] = NULL; +  } + +  /* Initialize marker processor so application can override methods +   * for COM, APPn markers before calling jpeg_read_header. +   */ +  jinit_marker_reader(cinfo); + +  /* And initialize the overall input controller. */ +  jinit_input_controller(cinfo); + +  /* OK, I'm ready */ +  cinfo->global_state = DSTATE_START; +} + + +/* + * Destruction of a JPEG decompression object + */ + +GLOBAL void +jpeg_destroy_decompress (j_decompress_ptr cinfo) +{ +  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG decompression operation, + * but don't destroy the object itself. + */ + +GLOBAL void +jpeg_abort_decompress (j_decompress_ptr cinfo) +{ +  jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * 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 +default_decompress_parms (j_decompress_ptr cinfo) +{ +  /* Guess the input colorspace, and set output colorspace accordingly. */ +  /* (Wish JPEG committee had provided a real way to specify this...) */ +  /* Note application may override our guesses. */ +  switch (cinfo->num_components) { +  case 1: +    cinfo->jpeg_color_space = JCS_GRAYSCALE; +    cinfo->out_color_space = JCS_GRAYSCALE; +    break; +     +  case 3: +    if (cinfo->saw_JFIF_marker) { +      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ +    } else if (cinfo->saw_Adobe_marker) { +      switch (cinfo->Adobe_transform) { +      case 0: +	cinfo->jpeg_color_space = JCS_RGB; +	break; +      case 1: +	cinfo->jpeg_color_space = JCS_YCbCr; +	break; +      default: +	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ +	break; +      } +    } else { +      /* Saw no special markers, try to guess from the component IDs */ +      int cid0 = cinfo->comp_info[0].component_id; +      int cid1 = cinfo->comp_info[1].component_id; +      int cid2 = cinfo->comp_info[2].component_id; + +      if (cid0 == 1 && cid1 == 2 && cid2 == 3) +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ +      else if (cid0 == 82 && cid1 == 71 && cid2 == 66) +	cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ +      else { +	TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); +	cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ +      } +    } +    /* Always guess RGB is proper output colorspace. */ +    cinfo->out_color_space = JCS_RGB; +    break; +     +  case 4: +    if (cinfo->saw_Adobe_marker) { +      switch (cinfo->Adobe_transform) { +      case 0: +	cinfo->jpeg_color_space = JCS_CMYK; +	break; +      case 2: +	cinfo->jpeg_color_space = JCS_YCCK; +	break; +      default: +	WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); +	cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ +	break; +      } +    } else { +      /* No special markers, assume straight CMYK. */ +      cinfo->jpeg_color_space = JCS_CMYK; +    } +    cinfo->out_color_space = JCS_CMYK; +    break; +     +  default: +    cinfo->jpeg_color_space = JCS_UNKNOWN; +    cinfo->out_color_space = JCS_UNKNOWN; +    break; +  } + +  /* Set defaults for other decompression parameters. */ +  cinfo->scale_num = 1;		/* 1:1 scaling */ +  cinfo->scale_denom = 1; +  cinfo->output_gamma = 1.0; +  cinfo->buffered_image = FALSE; +  cinfo->raw_data_out = FALSE; +  cinfo->dct_method = JDCT_DEFAULT; +  cinfo->do_fancy_upsampling = TRUE; +  cinfo->do_block_smoothing = TRUE; +  cinfo->quantize_colors = FALSE; +  /* We set these in case application only sets quantize_colors. */ +  cinfo->dither_mode = JDITHER_FS; +#ifdef QUANT_2PASS_SUPPORTED +  cinfo->two_pass_quantize = TRUE; +#else +  cinfo->two_pass_quantize = FALSE; +#endif +  cinfo->desired_number_of_colors = 256; +  cinfo->colormap = NULL; +  /* Initialize for no mode change in buffered-image mode. */ +  cinfo->enable_1pass_quant = FALSE; +  cinfo->enable_external_quant = FALSE; +  cinfo->enable_2pass_quant = FALSE; +} + + +/* + * Decompression startup: read start of JPEG datastream to see what's there. + * Need only initialize JPEG object and supply a data source before calling. + * + * This routine will read as far as the first SOS marker (ie, actual start of + * compressed data), and will save all tables and parameters in the JPEG + * object.  It will also initialize the decompression parameters to default + * values, and finally return JPEG_HEADER_OK.  On return, the application may + * adjust the decompression parameters and then call jpeg_start_decompress. + * (Or, if the application only wanted to determine the image parameters, + * the data need not be decompressed.  In that case, call jpeg_abort or + * jpeg_destroy to release any temporary space.) + * If an abbreviated (tables only) datastream is presented, the routine will + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then + * re-use the JPEG object to read the abbreviated image datastream(s). + * It is unnecessary (but OK) to call jpeg_abort in this case. + * The JPEG_SUSPENDED return code only occurs if the data source module + * requests suspension of the decompressor.  In this case the application + * should load more source data and then re-call jpeg_read_header to resume + * processing. + * If a non-suspending data source is used and require_image is TRUE, then the + * return code need not be inspected since only JPEG_HEADER_OK is possible. + * + * This routine is now just a front end to jpeg_consume_input, with some + * extra error checking. + */ + +GLOBAL int +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) +{ +  int retcode; + +  if (cinfo->global_state != DSTATE_START && +      cinfo->global_state != DSTATE_INHEADER) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +  retcode = jpeg_consume_input(cinfo); + +  switch (retcode) { +  case JPEG_REACHED_SOS: +    retcode = JPEG_HEADER_OK; +    break; +  case JPEG_REACHED_EOI: +    if (require_image)		/* Complain if application wanted an image */ +      ERREXIT(cinfo, JERR_NO_IMAGE); +    /* Reset to start state; it would be safer to require the application to +     * call jpeg_abort, but we can't change it now for compatibility reasons. +     * A side effect is to free any temporary memory (there shouldn't be any). +     */ +    jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ +    retcode = JPEG_HEADER_TABLES_ONLY; +    break; +  case JPEG_SUSPENDED: +    /* no work */ +    break; +  } + +  return retcode; +} + + +/* + * Consume data in advance of what the decompressor requires. + * This can be called at any time once the decompressor object has + * been created and a data source has been set up. + * + * This routine is essentially a state machine that handles a couple + * of critical state-transition actions, namely initial setup and + * transition from header scanning to ready-for-start_decompress. + * All the actual input is done via the input controller's consume_input + * method. + */ + +GLOBAL int +jpeg_consume_input (j_decompress_ptr cinfo) +{ +  int retcode = JPEG_SUSPENDED; + +  /* NB: every possible DSTATE value should be listed in this switch */ +  switch (cinfo->global_state) { +  case DSTATE_START: +    /* Start-of-datastream actions: reset appropriate modules */ +    (*cinfo->inputctl->reset_input_controller) (cinfo); +    /* Initialize application's data source module */ +    (*cinfo->src->init_source) (cinfo); +    cinfo->global_state = DSTATE_INHEADER; +    /*FALLTHROUGH*/ +  case DSTATE_INHEADER: +    retcode = (*cinfo->inputctl->consume_input) (cinfo); +    if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ +      /* Set up default parameters based on header data */ +      default_decompress_parms(cinfo); +      /* Set global state: ready for start_decompress */ +      cinfo->global_state = DSTATE_READY; +    } +    break; +  case DSTATE_READY: +    /* Can't advance past first SOS until start_decompress is called */ +    retcode = JPEG_REACHED_SOS; +    break; +  case DSTATE_PRELOAD: +  case DSTATE_PRESCAN: +  case DSTATE_SCANNING: +  case DSTATE_RAW_OK: +  case DSTATE_BUFIMAGE: +  case DSTATE_BUFPOST: +  case DSTATE_STOPPING: +    retcode = (*cinfo->inputctl->consume_input) (cinfo); +    break; +  default: +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  } +  return retcode; +} + + +/* + * Have we finished reading the input file? + */ + +GLOBAL boolean +jpeg_input_complete (j_decompress_ptr cinfo) +{ +  /* Check for valid jpeg object */ +  if (cinfo->global_state < DSTATE_START || +      cinfo->global_state > DSTATE_STOPPING) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  return cinfo->inputctl->eoi_reached; +} + + +/* + * Is there more than one scan? + */ + +GLOBAL boolean +jpeg_has_multiple_scans (j_decompress_ptr cinfo) +{ +  /* Only valid after jpeg_read_header completes */ +  if (cinfo->global_state < DSTATE_READY || +      cinfo->global_state > DSTATE_STOPPING) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  return cinfo->inputctl->has_multiple_scans; +} + + +/* + * Finish JPEG decompression. + * + * This will normally just verify the file trailer and release temp storage. + * + * Returns FALSE if suspended.  The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_finish_decompress (j_decompress_ptr cinfo) +{ +  if ((cinfo->global_state == DSTATE_SCANNING || +       cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { +    /* Terminate final pass of non-buffered mode */ +    if (cinfo->output_scanline < cinfo->output_height) +      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); +    (*cinfo->master->finish_output_pass) (cinfo); +    cinfo->global_state = DSTATE_STOPPING; +  } else if (cinfo->global_state == DSTATE_BUFIMAGE) { +    /* Finishing after a buffered-image operation */ +    cinfo->global_state = DSTATE_STOPPING; +  } else if (cinfo->global_state != DSTATE_STOPPING) { +    /* STOPPING = repeat call after a suspension, anything else is error */ +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  } +  /* Read until EOI */ +  while (! cinfo->inputctl->eoi_reached) { +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) +      return FALSE;		/* Suspend, come back later */ +  } +  /* Do final cleanup */ +  (*cinfo->src->term_source) (cinfo); +  /* We can use jpeg_abort to release memory and reset global_state */ +  jpeg_abort((j_common_ptr) cinfo); +  return TRUE; +} diff --git a/libs/jpeg6/jdapistd.cpp b/libs/jpeg6/jdapistd.cpp index 7781e16..e36f25c 100755 --- a/libs/jpeg6/jdapistd.cpp +++ b/libs/jpeg6/jdapistd.cpp @@ -1,275 +1,275 @@ -/*
 - * jdapistd.c
 - *
 - * Copyright (C) 1994-1995, 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 application interface code for the decompression half
 - * of the JPEG library.  These are the "standard" API routines that are
 - * used in the normal full-decompression case.  They are not used by a
 - * transcoding-only application.  Note that if an application links in
 - * jpeg_start_decompress, it will end up linking in the entire decompressor.
 - * We thus must separate this file from jdapimin.c to avoid linking the
 - * whole decompression library into a transcoder.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Forward declarations */
 -LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo));
 -
 -
 -/*
 - * Decompression initialization.
 - * jpeg_read_header must be completed before calling this.
 - *
 - * If a multipass operating mode was selected, this will do all but the
 - * last pass, and thus may take a great deal of time.
 - *
 - * Returns FALSE if suspended.  The return value need be inspected only if
 - * a suspending data source is used.
 - */
 -
 -GLOBAL boolean
 -jpeg_start_decompress (j_decompress_ptr cinfo)
 -{
 -  if (cinfo->global_state == DSTATE_READY) {
 -    /* First call: initialize master control, select active modules */
 -    jinit_master_decompress(cinfo);
 -    if (cinfo->buffered_image) {
 -      /* No more work here; expecting jpeg_start_output next */
 -      cinfo->global_state = DSTATE_BUFIMAGE;
 -      return TRUE;
 -    }
 -    cinfo->global_state = DSTATE_PRELOAD;
 -  }
 -  if (cinfo->global_state == DSTATE_PRELOAD) {
 -    /* If file has multiple scans, absorb them all into the coef buffer */
 -    if (cinfo->inputctl->has_multiple_scans) {
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -      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 FALSE;
 -	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) {
 -	    /* jdmaster underestimated number of scans; ratchet up one scan */
 -	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
 -	  }
 -	}
 -      }
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif /* D_MULTISCAN_FILES_SUPPORTED */
 -    }
 -    cinfo->output_scan_number = cinfo->input_scan_number;
 -  } else if (cinfo->global_state != DSTATE_PRESCAN)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  /* Perform any dummy output passes, and set up for the final pass */
 -  return output_pass_setup(cinfo);
 -}
 -
 -
 -/*
 - * Set up for an output pass, and perform any dummy pass(es) needed.
 - * Common subroutine for jpeg_start_decompress and jpeg_start_output.
 - * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
 - * Exit: If done, returns TRUE and sets global_state for proper output mode.
 - *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
 - */
 -
 -LOCAL boolean
 -output_pass_setup (j_decompress_ptr cinfo)
 -{
 -  if (cinfo->global_state != DSTATE_PRESCAN) {
 -    /* First call: do pass setup */
 -    (*cinfo->master->prepare_for_output_pass) (cinfo);
 -    cinfo->output_scanline = 0;
 -    cinfo->global_state = DSTATE_PRESCAN;
 -  }
 -  /* Loop over any required dummy passes */
 -  while (cinfo->master->is_dummy_pass) {
 -#ifdef QUANT_2PASS_SUPPORTED
 -    /* Crank through the dummy pass */
 -    while (cinfo->output_scanline < cinfo->output_height) {
 -      JDIMENSION last_scanline;
 -      /* Call progress monitor hook if present */
 -      if (cinfo->progress != NULL) {
 -	cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 -	cinfo->progress->pass_limit = (long) cinfo->output_height;
 -	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 -      }
 -      /* Process some data */
 -      last_scanline = cinfo->output_scanline;
 -      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
 -				    &cinfo->output_scanline, (JDIMENSION) 0);
 -      if (cinfo->output_scanline == last_scanline)
 -	return FALSE;		/* No progress made, must suspend */
 -    }
 -    /* Finish up dummy pass, and set up for another one */
 -    (*cinfo->master->finish_output_pass) (cinfo);
 -    (*cinfo->master->prepare_for_output_pass) (cinfo);
 -    cinfo->output_scanline = 0;
 -#else
 -    ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif /* QUANT_2PASS_SUPPORTED */
 -  }
 -  /* Ready for application to drive output pass through
 -   * jpeg_read_scanlines or jpeg_read_raw_data.
 -   */
 -  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Read some scanlines of data from the JPEG decompressor.
 - *
 - * The return value will be the number of lines actually read.
 - * This may be less than the number requested in several cases,
 - * including bottom of image, data source suspension, and operating
 - * modes that emit multiple scanlines at a time.
 - *
 - * Note: we warn about excess calls to jpeg_read_scanlines() since
 - * this likely signals an application programmer error.  However,
 - * an oversize buffer (max_lines > scanlines remaining) is not an error.
 - */
 -
 -GLOBAL JDIMENSION
 -jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
 -		     JDIMENSION max_lines)
 -{
 -  JDIMENSION row_ctr;
 -
 -  if (cinfo->global_state != DSTATE_SCANNING)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  if (cinfo->output_scanline >= cinfo->output_height) {
 -    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
 -    return 0;
 -  }
 -
 -  /* Call progress monitor hook if present */
 -  if (cinfo->progress != NULL) {
 -    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 -    cinfo->progress->pass_limit = (long) cinfo->output_height;
 -    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 -  }
 -
 -  /* Process some data */
 -  row_ctr = 0;
 -  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
 -  cinfo->output_scanline += row_ctr;
 -  return row_ctr;
 -}
 -
 -
 -/*
 - * Alternate entry point to read raw data.
 - * Processes exactly one iMCU row per call, unless suspended.
 - */
 -
 -GLOBAL JDIMENSION
 -jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
 -		    JDIMENSION max_lines)
 -{
 -  JDIMENSION lines_per_iMCU_row;
 -
 -  if (cinfo->global_state != DSTATE_RAW_OK)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  if (cinfo->output_scanline >= cinfo->output_height) {
 -    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
 -    return 0;
 -  }
 -
 -  /* Call progress monitor hook if present */
 -  if (cinfo->progress != NULL) {
 -    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 -    cinfo->progress->pass_limit = (long) cinfo->output_height;
 -    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 -  }
 -
 -  /* Verify that at least one iMCU row can be returned. */
 -  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
 -  if (max_lines < lines_per_iMCU_row)
 -    ERREXIT(cinfo, JERR_BUFFER_SIZE);
 -
 -  /* Decompress directly into user's buffer. */
 -  if (! (*cinfo->coef->decompress_data) (cinfo, data))
 -    return 0;			/* suspension forced, can do nothing more */
 -
 -  /* OK, we processed one iMCU row. */
 -  cinfo->output_scanline += lines_per_iMCU_row;
 -  return lines_per_iMCU_row;
 -}
 -
 -
 -/* Additional entry points for buffered-image mode. */
 -
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -
 -/*
 - * Initialize for an output pass in buffered-image mode.
 - */
 -
 -GLOBAL boolean
 -jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
 -{
 -  if (cinfo->global_state != DSTATE_BUFIMAGE &&
 -      cinfo->global_state != DSTATE_PRESCAN)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  /* Limit scan number to valid range */
 -  if (scan_number <= 0)
 -    scan_number = 1;
 -  if (cinfo->inputctl->eoi_reached &&
 -      scan_number > cinfo->input_scan_number)
 -    scan_number = cinfo->input_scan_number;
 -  cinfo->output_scan_number = scan_number;
 -  /* Perform any dummy output passes, and set up for the real pass */
 -  return output_pass_setup(cinfo);
 -}
 -
 -
 -/*
 - * Finish up after an output pass in buffered-image mode.
 - *
 - * Returns FALSE if suspended.  The return value need be inspected only if
 - * a suspending data source is used.
 - */
 -
 -GLOBAL boolean
 -jpeg_finish_output (j_decompress_ptr cinfo)
 -{
 -  if ((cinfo->global_state == DSTATE_SCANNING ||
 -       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
 -    /* Terminate this pass. */
 -    /* We do not require the whole pass to have been completed. */
 -    (*cinfo->master->finish_output_pass) (cinfo);
 -    cinfo->global_state = DSTATE_BUFPOST;
 -  } else if (cinfo->global_state != DSTATE_BUFPOST) {
 -    /* BUFPOST = repeat call after a suspension, anything else is error */
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -  }
 -  /* Read markers looking for SOS or EOI */
 -  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 -	 ! cinfo->inputctl->eoi_reached) {
 -    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
 -      return FALSE;		/* Suspend, come back later */
 -  }
 -  cinfo->global_state = DSTATE_BUFIMAGE;
 -  return TRUE;
 -}
 -
 -#endif /* D_MULTISCAN_FILES_SUPPORTED */
 +/* + * jdapistd.c + * + * Copyright (C) 1994-1995, 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 application interface code for the decompression half + * of the JPEG library.  These are the "standard" API routines that are + * used in the normal full-decompression case.  They are not used by a + * transcoding-only application.  Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); + + +/* + * Decompression initialization. + * jpeg_read_header must be completed before calling this. + * + * If a multipass operating mode was selected, this will do all but the + * last pass, and thus may take a great deal of time. + * + * Returns FALSE if suspended.  The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_start_decompress (j_decompress_ptr cinfo) +{ +  if (cinfo->global_state == DSTATE_READY) { +    /* First call: initialize master control, select active modules */ +    jinit_master_decompress(cinfo); +    if (cinfo->buffered_image) { +      /* No more work here; expecting jpeg_start_output next */ +      cinfo->global_state = DSTATE_BUFIMAGE; +      return TRUE; +    } +    cinfo->global_state = DSTATE_PRELOAD; +  } +  if (cinfo->global_state == DSTATE_PRELOAD) { +    /* If file has multiple scans, absorb them all into the coef buffer */ +    if (cinfo->inputctl->has_multiple_scans) { +#ifdef D_MULTISCAN_FILES_SUPPORTED +      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 FALSE; +	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) { +	    /* jdmaster underestimated number of scans; ratchet up one scan */ +	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; +	  } +	} +      } +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +    } +    cinfo->output_scan_number = cinfo->input_scan_number; +  } else if (cinfo->global_state != DSTATE_PRESCAN) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  /* Perform any dummy output passes, and set up for the final pass */ +  return output_pass_setup(cinfo); +} + + +/* + * Set up for an output pass, and perform any dummy pass(es) needed. + * Common subroutine for jpeg_start_decompress and jpeg_start_output. + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. + * Exit: If done, returns TRUE and sets global_state for proper output mode. + *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. + */ + +LOCAL boolean +output_pass_setup (j_decompress_ptr cinfo) +{ +  if (cinfo->global_state != DSTATE_PRESCAN) { +    /* First call: do pass setup */ +    (*cinfo->master->prepare_for_output_pass) (cinfo); +    cinfo->output_scanline = 0; +    cinfo->global_state = DSTATE_PRESCAN; +  } +  /* Loop over any required dummy passes */ +  while (cinfo->master->is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED +    /* Crank through the dummy pass */ +    while (cinfo->output_scanline < cinfo->output_height) { +      JDIMENSION last_scanline; +      /* Call progress monitor hook if present */ +      if (cinfo->progress != NULL) { +	cinfo->progress->pass_counter = (long) cinfo->output_scanline; +	cinfo->progress->pass_limit = (long) cinfo->output_height; +	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); +      } +      /* Process some data */ +      last_scanline = cinfo->output_scanline; +      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, +				    &cinfo->output_scanline, (JDIMENSION) 0); +      if (cinfo->output_scanline == last_scanline) +	return FALSE;		/* No progress made, must suspend */ +    } +    /* Finish up dummy pass, and set up for another one */ +    (*cinfo->master->finish_output_pass) (cinfo); +    (*cinfo->master->prepare_for_output_pass) (cinfo); +    cinfo->output_scanline = 0; +#else +    ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ +  } +  /* Ready for application to drive output pass through +   * jpeg_read_scanlines or jpeg_read_raw_data. +   */ +  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; +  return TRUE; +} + + +/* + * Read some scanlines of data from the JPEG decompressor. + * + * The return value will be the number of lines actually read. + * This may be less than the number requested in several cases, + * including bottom of image, data source suspension, and operating + * modes that emit multiple scanlines at a time. + * + * Note: we warn about excess calls to jpeg_read_scanlines() since + * this likely signals an application programmer error.  However, + * an oversize buffer (max_lines > scanlines remaining) is not an error. + */ + +GLOBAL JDIMENSION +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, +		     JDIMENSION max_lines) +{ +  JDIMENSION row_ctr; + +  if (cinfo->global_state != DSTATE_SCANNING) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  if (cinfo->output_scanline >= cinfo->output_height) { +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA); +    return 0; +  } + +  /* Call progress monitor hook if present */ +  if (cinfo->progress != NULL) { +    cinfo->progress->pass_counter = (long) cinfo->output_scanline; +    cinfo->progress->pass_limit = (long) cinfo->output_height; +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); +  } + +  /* Process some data */ +  row_ctr = 0; +  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); +  cinfo->output_scanline += row_ctr; +  return row_ctr; +} + + +/* + * Alternate entry point to read raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL JDIMENSION +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, +		    JDIMENSION max_lines) +{ +  JDIMENSION lines_per_iMCU_row; + +  if (cinfo->global_state != DSTATE_RAW_OK) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  if (cinfo->output_scanline >= cinfo->output_height) { +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA); +    return 0; +  } + +  /* Call progress monitor hook if present */ +  if (cinfo->progress != NULL) { +    cinfo->progress->pass_counter = (long) cinfo->output_scanline; +    cinfo->progress->pass_limit = (long) cinfo->output_height; +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); +  } + +  /* Verify that at least one iMCU row can be returned. */ +  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; +  if (max_lines < lines_per_iMCU_row) +    ERREXIT(cinfo, JERR_BUFFER_SIZE); + +  /* Decompress directly into user's buffer. */ +  if (! (*cinfo->coef->decompress_data) (cinfo, data)) +    return 0;			/* suspension forced, can do nothing more */ + +  /* OK, we processed one iMCU row. */ +  cinfo->output_scanline += lines_per_iMCU_row; +  return lines_per_iMCU_row; +} + + +/* Additional entry points for buffered-image mode. */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Initialize for an output pass in buffered-image mode. + */ + +GLOBAL boolean +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) +{ +  if (cinfo->global_state != DSTATE_BUFIMAGE && +      cinfo->global_state != DSTATE_PRESCAN) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  /* Limit scan number to valid range */ +  if (scan_number <= 0) +    scan_number = 1; +  if (cinfo->inputctl->eoi_reached && +      scan_number > cinfo->input_scan_number) +    scan_number = cinfo->input_scan_number; +  cinfo->output_scan_number = scan_number; +  /* Perform any dummy output passes, and set up for the real pass */ +  return output_pass_setup(cinfo); +} + + +/* + * Finish up after an output pass in buffered-image mode. + * + * Returns FALSE if suspended.  The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL boolean +jpeg_finish_output (j_decompress_ptr cinfo) +{ +  if ((cinfo->global_state == DSTATE_SCANNING || +       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { +    /* Terminate this pass. */ +    /* We do not require the whole pass to have been completed. */ +    (*cinfo->master->finish_output_pass) (cinfo); +    cinfo->global_state = DSTATE_BUFPOST; +  } else if (cinfo->global_state != DSTATE_BUFPOST) { +    /* BUFPOST = repeat call after a suspension, anything else is error */ +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +  } +  /* Read markers looking for SOS or EOI */ +  while (cinfo->input_scan_number <= cinfo->output_scan_number && +	 ! cinfo->inputctl->eoi_reached) { +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) +      return FALSE;		/* Suspend, come back later */ +  } +  cinfo->global_state = DSTATE_BUFIMAGE; +  return TRUE; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/libs/jpeg6/jdatasrc.cpp b/libs/jpeg6/jdatasrc.cpp index 5c1696d..0bf7866 100755 --- a/libs/jpeg6/jdatasrc.cpp +++ b/libs/jpeg6/jdatasrc.cpp @@ -1,204 +1,204 @@ -/*
 - * jdatasrc.c
 - *
 - * Copyright (C) 1994, 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 decompression data source routines for the case of
 - * reading JPEG data from a file (or any stdio stream).  While these routines
 - * are sufficient for most applications, some will want to use a different
 - * source manager.
 - * IMPORTANT: we assume that fread() will correctly transcribe an array of
 - * JOCTETs from 8-bit-wide elements on external storage.  If char is wider
 - * than 8 bits on your machine, you may need to do some tweaking.
 - */
 -
 -
 -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jerror.h"
 -
 -
 -/* Expanded data source object for stdio input */
 -
 -typedef struct {
 -  struct jpeg_source_mgr pub;	/* public fields */
 -
 -  unsigned char *infile;		/* source stream */
 -  JOCTET * buffer;		/* start of buffer */
 -  boolean start_of_file;	/* have we gotten any data yet? */
 -} my_source_mgr;
 -
 -typedef my_source_mgr * my_src_ptr;
 -
 -#define INPUT_BUF_SIZE  4096	/* choose an efficiently fread'able size */
 -
 -
 -/*
 - * Initialize source --- called by jpeg_read_header
 - * before any data is actually read.
 - */
 -
 -METHODDEF void
 -init_source (j_decompress_ptr cinfo)
 -{
 -  my_src_ptr src = (my_src_ptr) cinfo->src;
 -
 -  /* We reset the empty-input-file flag for each image,
 -   * but we don't clear the input buffer.
 -   * This is correct behavior for reading a series of images from one source.
 -   */
 -  src->start_of_file = TRUE;
 -}
 -
 -
 -/*
 - * Fill the input buffer --- called whenever buffer is emptied.
 - *
 - * In typical applications, this should read fresh data into the buffer
 - * (ignoring the current state of next_input_byte & bytes_in_buffer),
 - * reset the pointer & count to the start of the buffer, and return TRUE
 - * indicating that the buffer has been reloaded.  It is not necessary to
 - * fill the buffer entirely, only to obtain at least one more byte.
 - *
 - * There is no such thing as an EOF return.  If the end of the file has been
 - * reached, the routine has a choice of ERREXIT() or inserting fake data into
 - * the buffer.  In most cases, generating a warning message and inserting a
 - * fake EOI marker is the best course of action --- this will allow the
 - * decompressor to output however much of the image is there.  However,
 - * the resulting error message is misleading if the real problem is an empty
 - * input file, so we handle that case specially.
 - *
 - * In applications that need to be able to suspend compression due to input
 - * not being available yet, a FALSE return indicates that no more data can be
 - * obtained right now, but more may be forthcoming later.  In this situation,
 - * the decompressor will return to its caller (with an indication of the
 - * number of scanlines it has read, if any).  The application should resume
 - * decompression after it has loaded more data into the input buffer.  Note
 - * that there are substantial restrictions on the use of suspension --- see
 - * the documentation.
 - *
 - * When suspending, the decompressor will back up to a convenient restart point
 - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
 - * indicate where the restart point will be if the current call returns FALSE.
 - * Data beyond this point must be rescanned after resumption, so move it to
 - * the front of the buffer rather than discarding it.
 - */
 -
 -METHODDEF boolean
 -fill_input_buffer (j_decompress_ptr cinfo)
 -{
 -  my_src_ptr src = (my_src_ptr) cinfo->src;
 -
 -  memcpy( src->buffer, src->infile, INPUT_BUF_SIZE );
 -
 -  src->infile += INPUT_BUF_SIZE;
 -
 -  src->pub.next_input_byte = src->buffer;
 -  src->pub.bytes_in_buffer = INPUT_BUF_SIZE;
 -  src->start_of_file = FALSE;
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Skip data --- used to skip over a potentially large amount of
 - * uninteresting data (such as an APPn marker).
 - *
 - * Writers of suspendable-input applications must note that skip_input_data
 - * is not granted the right to give a suspension return.  If the skip extends
 - * beyond the data currently in the buffer, the buffer can be marked empty so
 - * that the next read will cause a fill_input_buffer call that can suspend.
 - * Arranging for additional bytes to be discarded before reloading the input
 - * buffer is the application writer's problem.
 - */
 -
 -METHODDEF void
 -skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 -{
 -  my_src_ptr src = (my_src_ptr) cinfo->src;
 -
 -  /* Just a dumb implementation for now.  Could use fseek() except
 -   * it doesn't work on pipes.  Not clear that being smart is worth
 -   * any trouble anyway --- large skips are infrequent.
 -   */
 -  if (num_bytes > 0) {
 -    while (num_bytes > (long) src->pub.bytes_in_buffer) {
 -      num_bytes -= (long) src->pub.bytes_in_buffer;
 -      (void) fill_input_buffer(cinfo);
 -      /* note we assume that fill_input_buffer will never return FALSE,
 -       * so suspension need not be handled.
 -       */
 -    }
 -    src->pub.next_input_byte += (size_t) num_bytes;
 -    src->pub.bytes_in_buffer -= (size_t) num_bytes;
 -  }
 -}
 -
 -
 -/*
 - * An additional method that can be provided by data source modules is the
 - * resync_to_restart method for error recovery in the presence of RST markers.
 - * For the moment, this source module just uses the default resync method
 - * provided by the JPEG library.  That method assumes that no backtracking
 - * is possible.
 - */
 -
 -
 -/*
 - * Terminate source --- called by jpeg_finish_decompress
 - * after all data has been read.  Often a no-op.
 - *
 - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
 - * application must deal with any cleanup that should happen even
 - * for error exit.
 - */
 -
 -METHODDEF void
 -term_source (j_decompress_ptr cinfo)
 -{
 -  /* no work necessary here */
 -}
 -
 -
 -/*
 - * Prepare for input from a stdio stream.
 - * The caller must have already opened the stream, and is responsible
 - * for closing it after finishing decompression.
 - */
 -
 -GLOBAL void
 -jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile)
 -{
 -  my_src_ptr src;
 -
 -  /* The source object and input buffer are made permanent so that a series
 -   * of JPEG images can be read from the same file by calling jpeg_stdio_src
 -   * only before the first one.  (If we discarded the buffer at the end of
 -   * one image, we'd likely lose the start of the next one.)
 -   * This makes it unsafe to use this manager and a different source
 -   * manager serially with the same JPEG object.  Caveat programmer.
 -   */
 -  if (cinfo->src == NULL) {	/* first time for this JPEG object? */
 -    cinfo->src = (struct jpeg_source_mgr *)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 -				  SIZEOF(my_source_mgr));
 -    src = (my_src_ptr) cinfo->src;
 -    src->buffer = (JOCTET *)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 -				  INPUT_BUF_SIZE * SIZEOF(JOCTET));
 -  }
 -
 -  src = (my_src_ptr) cinfo->src;
 -  src->pub.init_source = init_source;
 -  src->pub.fill_input_buffer = fill_input_buffer;
 -  src->pub.skip_input_data = skip_input_data;
 -  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
 -  src->pub.term_source = term_source;
 -  src->infile = infile;
 -  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
 -  src->pub.next_input_byte = NULL; /* until buffer loaded */
 -}
 +/* + * jdatasrc.c + * + * Copyright (C) 1994, 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 decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream).  While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage.  If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for stdio input */ + +typedef struct { +  struct jpeg_source_mgr pub;	/* public fields */ + +  unsigned char *infile;		/* source stream */ +  JOCTET * buffer;		/* start of buffer */ +  boolean start_of_file;	/* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE  4096	/* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF void +init_source (j_decompress_ptr cinfo) +{ +  my_src_ptr src = (my_src_ptr) cinfo->src; + +  /* We reset the empty-input-file flag for each image, +   * but we don't clear the input buffer. +   * This is correct behavior for reading a series of images from one source. +   */ +  src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded.  It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return.  If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer.  In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there.  However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later.  In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any).  The application should resume + * decompression after it has loaded more data into the input buffer.  Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF boolean +fill_input_buffer (j_decompress_ptr cinfo) +{ +  my_src_ptr src = (my_src_ptr) cinfo->src; + +  memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); + +  src->infile += INPUT_BUF_SIZE; + +  src->pub.next_input_byte = src->buffer; +  src->pub.bytes_in_buffer = INPUT_BUF_SIZE; +  src->start_of_file = FALSE; + +  return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return.  If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF void +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ +  my_src_ptr src = (my_src_ptr) cinfo->src; + +  /* Just a dumb implementation for now.  Could use fseek() except +   * it doesn't work on pipes.  Not clear that being smart is worth +   * any trouble anyway --- large skips are infrequent. +   */ +  if (num_bytes > 0) { +    while (num_bytes > (long) src->pub.bytes_in_buffer) { +      num_bytes -= (long) src->pub.bytes_in_buffer; +      (void) fill_input_buffer(cinfo); +      /* note we assume that fill_input_buffer will never return FALSE, +       * so suspension need not be handled. +       */ +    } +    src->pub.next_input_byte += (size_t) num_bytes; +    src->pub.bytes_in_buffer -= (size_t) num_bytes; +  } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library.  That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read.  Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF void +term_source (j_decompress_ptr cinfo) +{ +  /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL void +jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) +{ +  my_src_ptr src; + +  /* The source object and input buffer are made permanent so that a series +   * of JPEG images can be read from the same file by calling jpeg_stdio_src +   * only before the first one.  (If we discarded the buffer at the end of +   * one image, we'd likely lose the start of the next one.) +   * This makes it unsafe to use this manager and a different source +   * manager serially with the same JPEG object.  Caveat programmer. +   */ +  if (cinfo->src == NULL) {	/* first time for this JPEG object? */ +    cinfo->src = (struct jpeg_source_mgr *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, +				  SIZEOF(my_source_mgr)); +    src = (my_src_ptr) cinfo->src; +    src->buffer = (JOCTET *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, +				  INPUT_BUF_SIZE * SIZEOF(JOCTET)); +  } + +  src = (my_src_ptr) cinfo->src; +  src->pub.init_source = init_source; +  src->pub.fill_input_buffer = fill_input_buffer; +  src->pub.skip_input_data = skip_input_data; +  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ +  src->pub.term_source = term_source; +  src->infile = infile; +  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ +  src->pub.next_input_byte = NULL; /* until buffer loaded */ +} diff --git a/libs/jpeg6/jdcoefct.cpp b/libs/jpeg6/jdcoefct.cpp index 2b20c07..ba153f5 100755 --- a/libs/jpeg6/jdcoefct.cpp +++ b/libs/jpeg6/jdcoefct.cpp @@ -1,725 +1,725 @@ -/*
 - * jdcoefct.c
 - *
 - * Copyright (C) 1994-1995, 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 the coefficient buffer controller for decompression.
 - * This controller is the top level of the JPEG decompressor proper.
 - * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
 - *
 - * In buffered-image mode, this controller is the interface between
 - * input-oriented processing and output-oriented processing.
 - * Also, the input side (only) is used when reading a file for transcoding.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -/* Block smoothing is only applicable for progressive JPEG, so: */
 -#ifndef D_PROGRESSIVE_SUPPORTED
 -#undef BLOCK_SMOOTHING_SUPPORTED
 -#endif
 -
 -/* Private buffer controller object */
 -
 -typedef struct {
 -  struct jpeg_d_coef_controller pub; /* public fields */
 -
 -  /* These variables keep track of the current location of the input side. */
 -  /* cinfo->input_iMCU_row is also used for this. */
 -  JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */
 -  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
 -  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
 -
 -  /* The output side's location is represented by cinfo->output_iMCU_row. */
 -
 -  /* In single-pass modes, it's sufficient to buffer just one MCU.
 -   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
 -   * and let the entropy decoder write into that workspace each time.
 -   * (On 80x86, the workspace is FAR even though it's not really very big;
 -   * this is to keep the module interfaces unchanged when a large coefficient
 -   * buffer is necessary.)
 -   * In multi-pass modes, this array points to the current MCU's blocks
 -   * within the virtual arrays; it is used only by the input side.
 -   */
 -  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
 -
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -  /* In multi-pass modes, we need a virtual block array for each component. */
 -  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
 -#endif
 -
 -#ifdef BLOCK_SMOOTHING_SUPPORTED
 -  /* When doing block smoothing, we latch coefficient Al values here */
 -  int * coef_bits_latch;
 -#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
 -#endif
 -} my_coef_controller;
 -
 -typedef my_coef_controller * my_coef_ptr;
 -
 -/* Forward declarations */
 -METHODDEF int decompress_onepass
 -	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -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
 -	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
 -#endif
 -
 -
 -LOCAL void
 -start_iMCU_row (j_decompress_ptr cinfo)
 -/* Reset within-iMCU-row counters for a new row (input side) */
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -
 -  /* In an interleaved scan, an MCU row is the same as an iMCU row.
 -   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
 -   * But at the bottom of the image, process only what's left.
 -   */
 -  if (cinfo->comps_in_scan > 1) {
 -    coef->MCU_rows_per_iMCU_row = 1;
 -  } else {
 -    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
 -      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
 -    else
 -      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
 -  }
 -
 -  coef->MCU_ctr = 0;
 -  coef->MCU_vert_offset = 0;
 -}
 -
 -
 -/*
 - * Initialize for an input processing pass.
 - */
 -
 -METHODDEF void
 -start_input_pass (j_decompress_ptr cinfo)
 -{
 -  cinfo->input_iMCU_row = 0;
 -  start_iMCU_row(cinfo);
 -}
 -
 -
 -/*
 - * Initialize for an output processing pass.
 - */
 -
 -METHODDEF void
 -start_output_pass (j_decompress_ptr cinfo)
 -{
 -#ifdef BLOCK_SMOOTHING_SUPPORTED
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -
 -  /* If multipass, check to see whether to use block smoothing on this pass */
 -  if (coef->pub.coef_arrays != NULL) {
 -    if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
 -      coef->pub.decompress_data = decompress_smooth_data;
 -    else
 -      coef->pub.decompress_data = decompress_data;
 -  }
 -#endif
 -  cinfo->output_iMCU_row = 0;
 -}
 -
 -
 -/*
 - * Decompress and return some data in the single-pass case.
 - * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
 - * 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.
 - */
 -
 -METHODDEF int
 -decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 -  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
 -  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 -  int blkn, ci, xindex, yindex, yoffset, useful_width;
 -  JSAMPARRAY output_ptr;
 -  JDIMENSION start_col, output_col;
 -  jpeg_component_info *compptr;
 -  inverse_DCT_method_ptr inverse_DCT;
 -
 -  /* Loop to process as much as one whole iMCU row */
 -  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 -       yoffset++) {
 -    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
 -	 MCU_col_num++) {
 -      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
 -      jzero_far((void FAR *) coef->MCU_buffer[0],
 -		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
 -      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
 -	/* Suspension forced; update state counters and exit */
 -	coef->MCU_vert_offset = yoffset;
 -	coef->MCU_ctr = MCU_col_num;
 -	return JPEG_SUSPENDED;
 -      }
 -      /* Determine where data should go in output_buf and do the IDCT thing.
 -       * We skip dummy blocks at the right and bottom edges (but blkn gets
 -       * incremented past them!).  Note the inner loop relies on having
 -       * allocated the MCU_buffer[] blocks sequentially.
 -       */
 -      blkn = 0;			/* index of current DCT block within MCU */
 -      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -	compptr = cinfo->cur_comp_info[ci];
 -	/* Don't bother to IDCT an uninteresting component. */
 -	if (! compptr->component_needed) {
 -	  blkn += compptr->MCU_blocks;
 -	  continue;
 -	}
 -	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;
 -	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 ||
 -	      yoffset+yindex < compptr->last_row_height) {
 -	    output_col = start_col;
 -	    for (xindex = 0; xindex < useful_width; xindex++) {
 -	      (*inverse_DCT) (cinfo, compptr,
 -			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
 -			      output_ptr, output_col);
 -	      output_col += compptr->DCT_scaled_size;
 -	    }
 -	  }
 -	  blkn += compptr->MCU_width;
 -	  output_ptr += compptr->DCT_scaled_size;
 -	}
 -      }
 -    }
 -    /* Completed an MCU row, but perhaps not an iMCU row */
 -    coef->MCU_ctr = 0;
 -  }
 -  /* Completed the iMCU row, advance counters for next one */
 -  cinfo->output_iMCU_row++;
 -  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
 -    start_iMCU_row(cinfo);
 -    return JPEG_ROW_COMPLETED;
 -  }
 -  /* Completed the scan */
 -  (*cinfo->inputctl->finish_input_pass) (cinfo);
 -  return JPEG_SCAN_COMPLETED;
 -}
 -
 -
 -/*
 - * Dummy consume-input routine for single-pass operation.
 - */
 -
 -METHODDEF int
 -dummy_consume_data (j_decompress_ptr cinfo)
 -{
 -  return JPEG_SUSPENDED;	/* Always indicate nothing was done */
 -}
 -
 -
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -
 -/*
 - * Consume input data and store it in the full-image coefficient buffer.
 - * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
 - * ie, v_samp_factor block rows for each component in the scan.
 - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 - */
 -
 -METHODDEF int
 -consume_data (j_decompress_ptr cinfo)
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -  JDIMENSION MCU_col_num;	/* index of current MCU within row */
 -  int blkn, ci, xindex, yindex, yoffset;
 -  JDIMENSION start_col;
 -  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
 -  JBLOCKROW buffer_ptr;
 -  jpeg_component_info *compptr;
 -
 -  /* Align the virtual buffers for the components used in this scan. */
 -  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -    compptr = cinfo->cur_comp_info[ci];
 -    buffer[ci] = (*cinfo->mem->access_virt_barray)
 -      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
 -       cinfo->input_iMCU_row * compptr->v_samp_factor,
 -       (JDIMENSION) compptr->v_samp_factor, TRUE);
 -    /* Note: entropy decoder expects buffer to be zeroed,
 -     * but this is handled automatically by the memory manager
 -     * because we requested a pre-zeroed array.
 -     */
 -  }
 -
 -  /* Loop to process one whole iMCU row */
 -  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
 -       yoffset++) {
 -    for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
 -	 MCU_col_num++) {
 -      /* Construct list of pointers to DCT blocks belonging to this MCU */
 -      blkn = 0;			/* index of current DCT block within MCU */
 -      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -	compptr = cinfo->cur_comp_info[ci];
 -	start_col = MCU_col_num * compptr->MCU_width;
 -	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 -	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
 -	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
 -	    coef->MCU_buffer[blkn++] = buffer_ptr++;
 -	  }
 -	}
 -      }
 -      /* Try to fetch the MCU. */
 -      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
 -	/* Suspension forced; update state counters and exit */
 -	coef->MCU_vert_offset = yoffset;
 -	coef->MCU_ctr = MCU_col_num;
 -	return JPEG_SUSPENDED;
 -      }
 -    }
 -    /* Completed an MCU row, but perhaps not an iMCU row */
 -    coef->MCU_ctr = 0;
 -  }
 -  /* Completed the iMCU row, advance counters for next one */
 -  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
 -    start_iMCU_row(cinfo);
 -    return JPEG_ROW_COMPLETED;
 -  }
 -  /* Completed the scan */
 -  (*cinfo->inputctl->finish_input_pass) (cinfo);
 -  return JPEG_SCAN_COMPLETED;
 -}
 -
 -
 -/*
 - * Decompress and return some data in the multi-pass case.
 - * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
 - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 - *
 - * NB: output_buf contains a plane for each component in image.
 - */
 -
 -METHODDEF int
 -decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 -  JDIMENSION block_num;
 -  int ci, block_row, block_rows;
 -  JBLOCKARRAY buffer;
 -  JBLOCKROW buffer_ptr;
 -  JSAMPARRAY output_ptr;
 -  JDIMENSION output_col;
 -  jpeg_component_info *compptr;
 -  inverse_DCT_method_ptr inverse_DCT;
 -
 -  /* Force some input to be done if we are getting ahead of the input. */
 -  while (cinfo->input_scan_number < cinfo->output_scan_number ||
 -	 (cinfo->input_scan_number == cinfo->output_scan_number &&
 -	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
 -    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
 -      return JPEG_SUSPENDED;
 -  }
 -
 -  /* OK, output from the virtual arrays. */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Don't bother to IDCT an uninteresting component. */
 -    if (! compptr->component_needed)
 -      continue;
 -    /* Align the virtual buffer for this component. */
 -    buffer = (*cinfo->mem->access_virt_barray)
 -      ((j_common_ptr) cinfo, coef->whole_image[ci],
 -       cinfo->output_iMCU_row * compptr->v_samp_factor,
 -       (JDIMENSION) compptr->v_samp_factor, FALSE);
 -    /* Count non-dummy DCT block rows in this iMCU row. */
 -    if (cinfo->output_iMCU_row < last_iMCU_row)
 -      block_rows = compptr->v_samp_factor;
 -    else {
 -      /* NB: can't use last_row_height here; it is input-side-dependent! */
 -      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 -      if (block_rows == 0) block_rows = compptr->v_samp_factor;
 -    }
 -    inverse_DCT = cinfo->idct->inverse_DCT[ci];
 -    output_ptr = output_buf[ci];
 -    /* Loop over all DCT blocks to be processed. */
 -    for (block_row = 0; block_row < block_rows; block_row++) {
 -      buffer_ptr = buffer[block_row];
 -      output_col = 0;
 -      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
 -	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
 -			output_ptr, output_col);
 -	buffer_ptr++;
 -	output_col += compptr->DCT_scaled_size;
 -      }
 -      output_ptr += compptr->DCT_scaled_size;
 -    }
 -  }
 -
 -  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
 -    return JPEG_ROW_COMPLETED;
 -  return JPEG_SCAN_COMPLETED;
 -}
 -
 -#endif /* D_MULTISCAN_FILES_SUPPORTED */
 -
 -
 -#ifdef BLOCK_SMOOTHING_SUPPORTED
 -
 -/*
 - * This code applies interblock smoothing as described by section K.8
 - * of the JPEG standard: the first 5 AC coefficients are estimated from
 - * the DC values of a DCT block and its 8 neighboring blocks.
 - * We apply smoothing only for progressive JPEG decoding, and only if
 - * the coefficients it can estimate are not yet known to full precision.
 - */
 -
 -/*
 - * Determine whether block smoothing is applicable and safe.
 - * We also latch the current states of the coef_bits[] entries for the
 - * AC coefficients; otherwise, if the input side of the decompressor
 - * advances into a new scan, we might think the coefficients are known
 - * more accurately than they really are.
 - */
 -
 -LOCAL boolean
 -smoothing_ok (j_decompress_ptr cinfo)
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -  boolean smoothing_useful = FALSE;
 -  int ci, coefi;
 -  jpeg_component_info *compptr;
 -  JQUANT_TBL * qtable;
 -  int * coef_bits;
 -  int * coef_bits_latch;
 -
 -  if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
 -    return FALSE;
 -
 -  /* Allocate latch area if not already done */
 -  if (coef->coef_bits_latch == NULL)
 -    coef->coef_bits_latch = (int *)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  cinfo->num_components *
 -				  (SAVED_COEFS * SIZEOF(int)));
 -  coef_bits_latch = coef->coef_bits_latch;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* All components' quantization values must already be latched. */
 -    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;
 -    }
 -    /* DC values must be at least partly known for all components. */
 -    coef_bits = cinfo->coef_bits[ci];
 -    if (coef_bits[0] < 0)
 -      return FALSE;
 -    /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
 -    for (coefi = 1; coefi <= 5; coefi++) {
 -      coef_bits_latch[coefi] = coef_bits[coefi];
 -      if (coef_bits[coefi] != 0)
 -	smoothing_useful = TRUE;
 -    }
 -    coef_bits_latch += SAVED_COEFS;
 -  }
 -
 -  return smoothing_useful;
 -}
 -
 -
 -/*
 - * Variant of decompress_data for use when doing block smoothing.
 - */
 -
 -METHODDEF int
 -decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
 -{
 -  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
 -  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
 -  JDIMENSION block_num, last_block_column;
 -  int ci, block_row, block_rows, access_rows;
 -  JBLOCKARRAY buffer;
 -  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
 -  JSAMPARRAY output_ptr;
 -  JDIMENSION output_col;
 -  jpeg_component_info *compptr;
 -  inverse_DCT_method_ptr inverse_DCT;
 -  boolean first_row, last_row;
 -  JBLOCK workspace;
 -  int *coef_bits;
 -  JQUANT_TBL *quanttbl;
 -  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
 -  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
 -  int Al, pred;
 -
 -  /* Force some input to be done if we are getting ahead of the input. */
 -  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 -	 ! cinfo->inputctl->eoi_reached) {
 -    if (cinfo->input_scan_number == cinfo->output_scan_number) {
 -      /* If input is working on current scan, we ordinarily want it to
 -       * have completed the current row.  But if input scan is DC,
 -       * we want it to keep one row ahead so that next block row's DC
 -       * values are up to date.
 -       */
 -      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
 -      if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
 -	break;
 -    }
 -    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
 -      return JPEG_SUSPENDED;
 -  }
 -
 -  /* OK, output from the virtual arrays. */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Don't bother to IDCT an uninteresting component. */
 -    if (! compptr->component_needed)
 -      continue;
 -    /* Count non-dummy DCT block rows in this iMCU row. */
 -    if (cinfo->output_iMCU_row < last_iMCU_row) {
 -      block_rows = compptr->v_samp_factor;
 -      access_rows = block_rows * 2; /* this and next iMCU row */
 -      last_row = FALSE;
 -    } else {
 -      /* NB: can't use last_row_height here; it is input-side-dependent! */
 -      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 -      if (block_rows == 0) block_rows = compptr->v_samp_factor;
 -      access_rows = block_rows; /* this iMCU row only */
 -      last_row = TRUE;
 -    }
 -    /* Align the virtual buffer for this component. */
 -    if (cinfo->output_iMCU_row > 0) {
 -      access_rows += compptr->v_samp_factor; /* prior iMCU row too */
 -      buffer = (*cinfo->mem->access_virt_barray)
 -	((j_common_ptr) cinfo, coef->whole_image[ci],
 -	 (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
 -	 (JDIMENSION) access_rows, FALSE);
 -      buffer += compptr->v_samp_factor;	/* point to current iMCU row */
 -      first_row = FALSE;
 -    } else {
 -      buffer = (*cinfo->mem->access_virt_barray)
 -	((j_common_ptr) cinfo, coef->whole_image[ci],
 -	 (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
 -      first_row = TRUE;
 -    }
 -    /* Fetch component-dependent info */
 -    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];
 -    inverse_DCT = cinfo->idct->inverse_DCT[ci];
 -    output_ptr = output_buf[ci];
 -    /* Loop over all DCT blocks to be processed. */
 -    for (block_row = 0; block_row < block_rows; block_row++) {
 -      buffer_ptr = buffer[block_row];
 -      if (first_row && block_row == 0)
 -	prev_block_row = buffer_ptr;
 -      else
 -	prev_block_row = buffer[block_row-1];
 -      if (last_row && block_row == block_rows-1)
 -	next_block_row = buffer_ptr;
 -      else
 -	next_block_row = buffer[block_row+1];
 -      /* We fetch the surrounding DC values using a sliding-register approach.
 -       * Initialize all nine here so as to do the right thing on narrow pics.
 -       */
 -      DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
 -      DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
 -      DC7 = DC8 = DC9 = (int) next_block_row[0][0];
 -      output_col = 0;
 -      last_block_column = compptr->width_in_blocks - 1;
 -      for (block_num = 0; block_num <= last_block_column; block_num++) {
 -	/* Fetch current DCT block into workspace so we can modify it. */
 -	jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
 -	/* Update DC values */
 -	if (block_num < last_block_column) {
 -	  DC3 = (int) prev_block_row[1][0];
 -	  DC6 = (int) buffer_ptr[1][0];
 -	  DC9 = (int) next_block_row[1][0];
 -	}
 -	/* Compute coefficient estimates per K.8.
 -	 * An estimate is applied only if coefficient is still zero,
 -	 * and is not known to be fully accurate.
 -	 */
 -	/* AC01 */
 -	if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
 -	  num = 36 * Q00 * (DC4 - DC6);
 -	  if (num >= 0) {
 -	    pred = (int) (((Q01<<7) + num) / (Q01<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	  } else {
 -	    pred = (int) (((Q01<<7) - num) / (Q01<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	    pred = -pred;
 -	  }
 -	  workspace[1] = (JCOEF) pred;
 -	}
 -	/* AC10 */
 -	if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
 -	  num = 36 * Q00 * (DC2 - DC8);
 -	  if (num >= 0) {
 -	    pred = (int) (((Q10<<7) + num) / (Q10<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	  } else {
 -	    pred = (int) (((Q10<<7) - num) / (Q10<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	    pred = -pred;
 -	  }
 -	  workspace[8] = (JCOEF) pred;
 -	}
 -	/* AC20 */
 -	if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
 -	  num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
 -	  if (num >= 0) {
 -	    pred = (int) (((Q20<<7) + num) / (Q20<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	  } else {
 -	    pred = (int) (((Q20<<7) - num) / (Q20<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	    pred = -pred;
 -	  }
 -	  workspace[16] = (JCOEF) pred;
 -	}
 -	/* AC11 */
 -	if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
 -	  num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
 -	  if (num >= 0) {
 -	    pred = (int) (((Q11<<7) + num) / (Q11<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	  } else {
 -	    pred = (int) (((Q11<<7) - num) / (Q11<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	    pred = -pred;
 -	  }
 -	  workspace[9] = (JCOEF) pred;
 -	}
 -	/* AC02 */
 -	if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
 -	  num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
 -	  if (num >= 0) {
 -	    pred = (int) (((Q02<<7) + num) / (Q02<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	  } else {
 -	    pred = (int) (((Q02<<7) - num) / (Q02<<8));
 -	    if (Al > 0 && pred >= (1<<Al))
 -	      pred = (1<<Al)-1;
 -	    pred = -pred;
 -	  }
 -	  workspace[2] = (JCOEF) pred;
 -	}
 -	/* OK, do the IDCT */
 -	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
 -			output_ptr, output_col);
 -	/* Advance for next column */
 -	DC1 = DC2; DC2 = DC3;
 -	DC4 = DC5; DC5 = DC6;
 -	DC7 = DC8; DC8 = DC9;
 -	buffer_ptr++, prev_block_row++, next_block_row++;
 -	output_col += compptr->DCT_scaled_size;
 -      }
 -      output_ptr += compptr->DCT_scaled_size;
 -    }
 -  }
 -
 -  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
 -    return JPEG_ROW_COMPLETED;
 -  return JPEG_SCAN_COMPLETED;
 -}
 -
 -#endif /* BLOCK_SMOOTHING_SUPPORTED */
 -
 -
 -/*
 - * Initialize coefficient buffer controller.
 - */
 -
 -GLOBAL void
 -jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 -{
 -  my_coef_ptr coef;
 -
 -  coef = (my_coef_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(my_coef_controller));
 -  cinfo->coef = (struct jpeg_d_coef_controller *) coef;
 -  coef->pub.start_input_pass = start_input_pass;
 -  coef->pub.start_output_pass = start_output_pass;
 -#ifdef BLOCK_SMOOTHING_SUPPORTED
 -  coef->coef_bits_latch = NULL;
 -#endif
 -
 -  /* Create the coefficient buffer. */
 -  if (need_full_buffer) {
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -    /* Allocate a full-image virtual array for each component, */
 -    /* padded to a multiple of samp_factor DCT blocks in each direction. */
 -    /* Note we ask for a pre-zeroed array. */
 -    int ci, access_rows;
 -    jpeg_component_info *compptr;
 -
 -    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -	 ci++, compptr++) {
 -      access_rows = compptr->v_samp_factor;
 -#ifdef BLOCK_SMOOTHING_SUPPORTED
 -      /* If block smoothing could be used, need a bigger window */
 -      if (cinfo->progressive_mode)
 -	access_rows *= 3;
 -#endif
 -      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
 -	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
 -	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
 -				(long) compptr->h_samp_factor),
 -	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
 -				(long) compptr->v_samp_factor),
 -	 (JDIMENSION) access_rows);
 -    }
 -    coef->pub.consume_data = consume_data;
 -    coef->pub.decompress_data = decompress_data;
 -    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
 -#else
 -    ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -  } else {
 -    /* We only need a single-MCU buffer. */
 -    JBLOCKROW buffer;
 -    int i;
 -
 -    buffer = (JBLOCKROW)
 -      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
 -    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
 -      coef->MCU_buffer[i] = buffer + i;
 -    }
 -    coef->pub.consume_data = dummy_consume_data;
 -    coef->pub.decompress_data = decompress_onepass;
 -    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
 -  }
 -}
 +/* + * jdcoefct.c + * + * Copyright (C) 1994-1995, 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 the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* Block smoothing is only applicable for progressive JPEG, so: */ +#ifndef D_PROGRESSIVE_SUPPORTED +#undef BLOCK_SMOOTHING_SUPPORTED +#endif + +/* Private buffer controller object */ + +typedef struct { +  struct jpeg_d_coef_controller pub; /* public fields */ + +  /* These variables keep track of the current location of the input side. */ +  /* cinfo->input_iMCU_row is also used for this. */ +  JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */ +  int MCU_vert_offset;		/* counts MCU rows within iMCU row */ +  int MCU_rows_per_iMCU_row;	/* number of such rows needed */ + +  /* The output side's location is represented by cinfo->output_iMCU_row. */ + +  /* In single-pass modes, it's sufficient to buffer just one MCU. +   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, +   * and let the entropy decoder write into that workspace each time. +   * (On 80x86, the workspace is FAR even though it's not really very big; +   * this is to keep the module interfaces unchanged when a large coefficient +   * buffer is necessary.) +   * In multi-pass modes, this array points to the current MCU's blocks +   * within the virtual arrays; it is used only by the input side. +   */ +  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + +#ifdef D_MULTISCAN_FILES_SUPPORTED +  /* In multi-pass modes, we need a virtual block array for each component. */ +  jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +#endif + +#ifdef BLOCK_SMOOTHING_SUPPORTED +  /* When doing block smoothing, we latch coefficient Al values here */ +  int * coef_bits_latch; +#define SAVED_COEFS  6		/* we save coef_bits[0..5] */ +#endif +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* Forward declarations */ +METHODDEF int decompress_onepass +	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +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 +	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL void +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + +  /* In an interleaved scan, an MCU row is the same as an iMCU row. +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. +   * But at the bottom of the image, process only what's left. +   */ +  if (cinfo->comps_in_scan > 1) { +    coef->MCU_rows_per_iMCU_row = 1; +  } else { +    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; +    else +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; +  } + +  coef->MCU_ctr = 0; +  coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF void +start_input_pass (j_decompress_ptr cinfo) +{ +  cinfo->input_iMCU_row = 0; +  start_iMCU_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF void +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + +  /* If multipass, check to see whether to use block smoothing on this pass */ +  if (coef->pub.coef_arrays != NULL) { +    if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) +      coef->pub.decompress_data = decompress_smooth_data; +    else +      coef->pub.decompress_data = decompress_data; +  } +#endif +  cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the single-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * 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. + */ + +METHODDEF int +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; +  JDIMENSION MCU_col_num;	/* index of current MCU within row */ +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; +  int blkn, ci, xindex, yindex, yoffset, useful_width; +  JSAMPARRAY output_ptr; +  JDIMENSION start_col, output_col; +  jpeg_component_info *compptr; +  inverse_DCT_method_ptr inverse_DCT; + +  /* Loop to process as much as one whole iMCU row */ +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; +       yoffset++) { +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; +	 MCU_col_num++) { +      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */ +      jzero_far((void FAR *) coef->MCU_buffer[0], +		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { +	/* Suspension forced; update state counters and exit */ +	coef->MCU_vert_offset = yoffset; +	coef->MCU_ctr = MCU_col_num; +	return JPEG_SUSPENDED; +      } +      /* Determine where data should go in output_buf and do the IDCT thing. +       * We skip dummy blocks at the right and bottom edges (but blkn gets +       * incremented past them!).  Note the inner loop relies on having +       * allocated the MCU_buffer[] blocks sequentially. +       */ +      blkn = 0;			/* index of current DCT block within MCU */ +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +	compptr = cinfo->cur_comp_info[ci]; +	/* Don't bother to IDCT an uninteresting component. */ +	if (! compptr->component_needed) { +	  blkn += compptr->MCU_blocks; +	  continue; +	} +	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; +	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 || +	      yoffset+yindex < compptr->last_row_height) { +	    output_col = start_col; +	    for (xindex = 0; xindex < useful_width; xindex++) { +	      (*inverse_DCT) (cinfo, compptr, +			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex], +			      output_ptr, output_col); +	      output_col += compptr->DCT_scaled_size; +	    } +	  } +	  blkn += compptr->MCU_width; +	  output_ptr += compptr->DCT_scaled_size; +	} +      } +    } +    /* Completed an MCU row, but perhaps not an iMCU row */ +    coef->MCU_ctr = 0; +  } +  /* Completed the iMCU row, advance counters for next one */ +  cinfo->output_iMCU_row++; +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { +    start_iMCU_row(cinfo); +    return JPEG_ROW_COMPLETED; +  } +  /* Completed the scan */ +  (*cinfo->inputctl->finish_input_pass) (cinfo); +  return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF int +dummy_consume_data (j_decompress_ptr cinfo) +{ +  return JPEG_SUSPENDED;	/* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image coefficient buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor block rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF int +consume_data (j_decompress_ptr cinfo) +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; +  JDIMENSION MCU_col_num;	/* index of current MCU within row */ +  int blkn, ci, xindex, yindex, yoffset; +  JDIMENSION start_col; +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; +  JBLOCKROW buffer_ptr; +  jpeg_component_info *compptr; + +  /* Align the virtual buffers for the components used in this scan. */ +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +    compptr = cinfo->cur_comp_info[ci]; +    buffer[ci] = (*cinfo->mem->access_virt_barray) +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], +       cinfo->input_iMCU_row * compptr->v_samp_factor, +       (JDIMENSION) compptr->v_samp_factor, TRUE); +    /* Note: entropy decoder expects buffer to be zeroed, +     * but this is handled automatically by the memory manager +     * because we requested a pre-zeroed array. +     */ +  } + +  /* Loop to process one whole iMCU row */ +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; +       yoffset++) { +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; +	 MCU_col_num++) { +      /* Construct list of pointers to DCT blocks belonging to this MCU */ +      blkn = 0;			/* index of current DCT block within MCU */ +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +	compptr = cinfo->cur_comp_info[ci]; +	start_col = MCU_col_num * compptr->MCU_width; +	for (yindex = 0; yindex < compptr->MCU_height; yindex++) { +	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col; +	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) { +	    coef->MCU_buffer[blkn++] = buffer_ptr++; +	  } +	} +      } +      /* Try to fetch the MCU. */ +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { +	/* Suspension forced; update state counters and exit */ +	coef->MCU_vert_offset = yoffset; +	coef->MCU_ctr = MCU_col_num; +	return JPEG_SUSPENDED; +      } +    } +    /* Completed an MCU row, but perhaps not an iMCU row */ +    coef->MCU_ctr = 0; +  } +  /* Completed the iMCU row, advance counters for next one */ +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { +    start_iMCU_row(cinfo); +    return JPEG_ROW_COMPLETED; +  } +  /* Completed the scan */ +  (*cinfo->inputctl->finish_input_pass) (cinfo); +  return JPEG_SCAN_COMPLETED; +} + + +/* + * Decompress and return some data in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF int +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; +  JDIMENSION block_num; +  int ci, block_row, block_rows; +  JBLOCKARRAY buffer; +  JBLOCKROW buffer_ptr; +  JSAMPARRAY output_ptr; +  JDIMENSION output_col; +  jpeg_component_info *compptr; +  inverse_DCT_method_ptr inverse_DCT; + +  /* Force some input to be done if we are getting ahead of the input. */ +  while (cinfo->input_scan_number < cinfo->output_scan_number || +	 (cinfo->input_scan_number == cinfo->output_scan_number && +	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) +      return JPEG_SUSPENDED; +  } + +  /* OK, output from the virtual arrays. */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Don't bother to IDCT an uninteresting component. */ +    if (! compptr->component_needed) +      continue; +    /* Align the virtual buffer for this component. */ +    buffer = (*cinfo->mem->access_virt_barray) +      ((j_common_ptr) cinfo, coef->whole_image[ci], +       cinfo->output_iMCU_row * compptr->v_samp_factor, +       (JDIMENSION) compptr->v_samp_factor, FALSE); +    /* Count non-dummy DCT block rows in this iMCU row. */ +    if (cinfo->output_iMCU_row < last_iMCU_row) +      block_rows = compptr->v_samp_factor; +    else { +      /* NB: can't use last_row_height here; it is input-side-dependent! */ +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); +      if (block_rows == 0) block_rows = compptr->v_samp_factor; +    } +    inverse_DCT = cinfo->idct->inverse_DCT[ci]; +    output_ptr = output_buf[ci]; +    /* Loop over all DCT blocks to be processed. */ +    for (block_row = 0; block_row < block_rows; block_row++) { +      buffer_ptr = buffer[block_row]; +      output_col = 0; +      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { +	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, +			output_ptr, output_col); +	buffer_ptr++; +	output_col += compptr->DCT_scaled_size; +      } +      output_ptr += compptr->DCT_scaled_size; +    } +  } + +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) +    return JPEG_ROW_COMPLETED; +  return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +#ifdef BLOCK_SMOOTHING_SUPPORTED + +/* + * This code applies interblock smoothing as described by section K.8 + * of the JPEG standard: the first 5 AC coefficients are estimated from + * the DC values of a DCT block and its 8 neighboring blocks. + * We apply smoothing only for progressive JPEG decoding, and only if + * the coefficients it can estimate are not yet known to full precision. + */ + +/* + * Determine whether block smoothing is applicable and safe. + * We also latch the current states of the coef_bits[] entries for the + * AC coefficients; otherwise, if the input side of the decompressor + * advances into a new scan, we might think the coefficients are known + * more accurately than they really are. + */ + +LOCAL boolean +smoothing_ok (j_decompress_ptr cinfo) +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; +  boolean smoothing_useful = FALSE; +  int ci, coefi; +  jpeg_component_info *compptr; +  JQUANT_TBL * qtable; +  int * coef_bits; +  int * coef_bits_latch; + +  if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) +    return FALSE; + +  /* Allocate latch area if not already done */ +  if (coef->coef_bits_latch == NULL) +    coef->coef_bits_latch = (int *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  cinfo->num_components * +				  (SAVED_COEFS * SIZEOF(int))); +  coef_bits_latch = coef->coef_bits_latch; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* All components' quantization values must already be latched. */ +    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; +    } +    /* DC values must be at least partly known for all components. */ +    coef_bits = cinfo->coef_bits[ci]; +    if (coef_bits[0] < 0) +      return FALSE; +    /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ +    for (coefi = 1; coefi <= 5; coefi++) { +      coef_bits_latch[coefi] = coef_bits[coefi]; +      if (coef_bits[coefi] != 0) +	smoothing_useful = TRUE; +    } +    coef_bits_latch += SAVED_COEFS; +  } + +  return smoothing_useful; +} + + +/* + * Variant of decompress_data for use when doing block smoothing. + */ + +METHODDEF int +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef; +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; +  JDIMENSION block_num, last_block_column; +  int ci, block_row, block_rows, access_rows; +  JBLOCKARRAY buffer; +  JBLOCKROW buffer_ptr, prev_block_row, next_block_row; +  JSAMPARRAY output_ptr; +  JDIMENSION output_col; +  jpeg_component_info *compptr; +  inverse_DCT_method_ptr inverse_DCT; +  boolean first_row, last_row; +  JBLOCK workspace; +  int *coef_bits; +  JQUANT_TBL *quanttbl; +  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; +  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; +  int Al, pred; + +  /* Force some input to be done if we are getting ahead of the input. */ +  while (cinfo->input_scan_number <= cinfo->output_scan_number && +	 ! cinfo->inputctl->eoi_reached) { +    if (cinfo->input_scan_number == cinfo->output_scan_number) { +      /* If input is working on current scan, we ordinarily want it to +       * have completed the current row.  But if input scan is DC, +       * we want it to keep one row ahead so that next block row's DC +       * values are up to date. +       */ +      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; +      if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) +	break; +    } +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) +      return JPEG_SUSPENDED; +  } + +  /* OK, output from the virtual arrays. */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Don't bother to IDCT an uninteresting component. */ +    if (! compptr->component_needed) +      continue; +    /* Count non-dummy DCT block rows in this iMCU row. */ +    if (cinfo->output_iMCU_row < last_iMCU_row) { +      block_rows = compptr->v_samp_factor; +      access_rows = block_rows * 2; /* this and next iMCU row */ +      last_row = FALSE; +    } else { +      /* NB: can't use last_row_height here; it is input-side-dependent! */ +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); +      if (block_rows == 0) block_rows = compptr->v_samp_factor; +      access_rows = block_rows; /* this iMCU row only */ +      last_row = TRUE; +    } +    /* Align the virtual buffer for this component. */ +    if (cinfo->output_iMCU_row > 0) { +      access_rows += compptr->v_samp_factor; /* prior iMCU row too */ +      buffer = (*cinfo->mem->access_virt_barray) +	((j_common_ptr) cinfo, coef->whole_image[ci], +	 (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, +	 (JDIMENSION) access_rows, FALSE); +      buffer += compptr->v_samp_factor;	/* point to current iMCU row */ +      first_row = FALSE; +    } else { +      buffer = (*cinfo->mem->access_virt_barray) +	((j_common_ptr) cinfo, coef->whole_image[ci], +	 (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); +      first_row = TRUE; +    } +    /* Fetch component-dependent info */ +    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]; +    inverse_DCT = cinfo->idct->inverse_DCT[ci]; +    output_ptr = output_buf[ci]; +    /* Loop over all DCT blocks to be processed. */ +    for (block_row = 0; block_row < block_rows; block_row++) { +      buffer_ptr = buffer[block_row]; +      if (first_row && block_row == 0) +	prev_block_row = buffer_ptr; +      else +	prev_block_row = buffer[block_row-1]; +      if (last_row && block_row == block_rows-1) +	next_block_row = buffer_ptr; +      else +	next_block_row = buffer[block_row+1]; +      /* We fetch the surrounding DC values using a sliding-register approach. +       * Initialize all nine here so as to do the right thing on narrow pics. +       */ +      DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; +      DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; +      DC7 = DC8 = DC9 = (int) next_block_row[0][0]; +      output_col = 0; +      last_block_column = compptr->width_in_blocks - 1; +      for (block_num = 0; block_num <= last_block_column; block_num++) { +	/* Fetch current DCT block into workspace so we can modify it. */ +	jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); +	/* Update DC values */ +	if (block_num < last_block_column) { +	  DC3 = (int) prev_block_row[1][0]; +	  DC6 = (int) buffer_ptr[1][0]; +	  DC9 = (int) next_block_row[1][0]; +	} +	/* Compute coefficient estimates per K.8. +	 * An estimate is applied only if coefficient is still zero, +	 * and is not known to be fully accurate. +	 */ +	/* AC01 */ +	if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { +	  num = 36 * Q00 * (DC4 - DC6); +	  if (num >= 0) { +	    pred = (int) (((Q01<<7) + num) / (Q01<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	  } else { +	    pred = (int) (((Q01<<7) - num) / (Q01<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	    pred = -pred; +	  } +	  workspace[1] = (JCOEF) pred; +	} +	/* AC10 */ +	if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) { +	  num = 36 * Q00 * (DC2 - DC8); +	  if (num >= 0) { +	    pred = (int) (((Q10<<7) + num) / (Q10<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	  } else { +	    pred = (int) (((Q10<<7) - num) / (Q10<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	    pred = -pred; +	  } +	  workspace[8] = (JCOEF) pred; +	} +	/* AC20 */ +	if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) { +	  num = 9 * Q00 * (DC2 + DC8 - 2*DC5); +	  if (num >= 0) { +	    pred = (int) (((Q20<<7) + num) / (Q20<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	  } else { +	    pred = (int) (((Q20<<7) - num) / (Q20<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	    pred = -pred; +	  } +	  workspace[16] = (JCOEF) pred; +	} +	/* AC11 */ +	if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) { +	  num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9); +	  if (num >= 0) { +	    pred = (int) (((Q11<<7) + num) / (Q11<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	  } else { +	    pred = (int) (((Q11<<7) - num) / (Q11<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	    pred = -pred; +	  } +	  workspace[9] = (JCOEF) pred; +	} +	/* AC02 */ +	if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) { +	  num = 9 * Q00 * (DC4 + DC6 - 2*DC5); +	  if (num >= 0) { +	    pred = (int) (((Q02<<7) + num) / (Q02<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	  } else { +	    pred = (int) (((Q02<<7) - num) / (Q02<<8)); +	    if (Al > 0 && pred >= (1<<Al)) +	      pred = (1<<Al)-1; +	    pred = -pred; +	  } +	  workspace[2] = (JCOEF) pred; +	} +	/* OK, do the IDCT */ +	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace, +			output_ptr, output_col); +	/* Advance for next column */ +	DC1 = DC2; DC2 = DC3; +	DC4 = DC5; DC5 = DC6; +	DC7 = DC8; DC8 = DC9; +	buffer_ptr++, prev_block_row++, next_block_row++; +	output_col += compptr->DCT_scaled_size; +      } +      output_ptr += compptr->DCT_scaled_size; +    } +  } + +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) +    return JPEG_ROW_COMPLETED; +  return JPEG_SCAN_COMPLETED; +} + +#endif /* BLOCK_SMOOTHING_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL void +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ +  my_coef_ptr coef; + +  coef = (my_coef_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(my_coef_controller)); +  cinfo->coef = (struct jpeg_d_coef_controller *) coef; +  coef->pub.start_input_pass = start_input_pass; +  coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED +  coef->coef_bits_latch = NULL; +#endif + +  /* Create the coefficient buffer. */ +  if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED +    /* Allocate a full-image virtual array for each component, */ +    /* padded to a multiple of samp_factor DCT blocks in each direction. */ +    /* Note we ask for a pre-zeroed array. */ +    int ci, access_rows; +    jpeg_component_info *compptr; + +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +	 ci++, compptr++) { +      access_rows = compptr->v_samp_factor; +#ifdef BLOCK_SMOOTHING_SUPPORTED +      /* If block smoothing could be used, need a bigger window */ +      if (cinfo->progressive_mode) +	access_rows *= 3; +#endif +      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) +	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, +	 (JDIMENSION) jround_up((long) compptr->width_in_blocks, +				(long) compptr->h_samp_factor), +	 (JDIMENSION) jround_up((long) compptr->height_in_blocks, +				(long) compptr->v_samp_factor), +	 (JDIMENSION) access_rows); +    } +    coef->pub.consume_data = consume_data; +    coef->pub.decompress_data = decompress_data; +    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ +#else +    ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +  } else { +    /* We only need a single-MCU buffer. */ +    JBLOCKROW buffer; +    int i; + +    buffer = (JBLOCKROW) +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); +    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { +      coef->MCU_buffer[i] = buffer + i; +    } +    coef->pub.consume_data = dummy_consume_data; +    coef->pub.decompress_data = decompress_onepass; +    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ +  } +} diff --git a/libs/jpeg6/jdcolor.cpp b/libs/jpeg6/jdcolor.cpp index d360b53..b2bdf6e 100755 --- a/libs/jpeg6/jdcolor.cpp +++ b/libs/jpeg6/jdcolor.cpp @@ -1,367 +1,367 @@ -/*
 - * jdcolor.c
 - *
 - * Copyright (C) 1991-1995, 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 output colorspace conversion routines.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Private subobject */
 -
 -typedef struct {
 -  struct jpeg_color_deconverter pub; /* public fields */
 -
 -  /* Private state for YCC->RGB conversion */
 -  int * Cr_r_tab;		/* => table for Cr to R conversion */
 -  int * Cb_b_tab;		/* => table for Cb to B conversion */
 -  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
 -  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
 -} my_color_deconverter;
 -
 -typedef my_color_deconverter * my_cconvert_ptr;
 -
 -
 -/**************** YCbCr -> RGB conversion: most common case **************/
 -
 -/*
 - * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
 - * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
 - * The conversion equations to be implemented are therefore
 - *	R = Y                + 1.40200 * Cr
 - *	G = Y - 0.34414 * Cb - 0.71414 * Cr
 - *	B = Y + 1.77200 * Cb
 - * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
 - * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
 - *
 - * To avoid floating-point arithmetic, we represent the fractional constants
 - * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
 - * the products by 2^16, with appropriate rounding, to get the correct answer.
 - * Notice that Y, being an integral input, does not contribute any fraction
 - * so it need not participate in the rounding.
 - *
 - * For even more speed, we avoid doing any multiplications in the inner loop
 - * by precalculating the constants times Cb and Cr for all possible values.
 - * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
 - * for 12-bit samples it is still acceptable.  It's not very reasonable for
 - * 16-bit samples, but if you want lossless storage you shouldn't be changing
 - * colorspace anyway.
 - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
 - * values for the G calculation are left scaled up, since we must add them
 - * together before rounding.
 - */
 -
 -#define SCALEBITS	16	/* speediest right-shift on some machines */
 -#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
 -#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
 -
 -
 -/*
 - * Initialize tables for YCC->RGB colorspace conversion.
 - */
 -
 -LOCAL void
 -build_ycc_rgb_table (j_decompress_ptr cinfo)
 -{
 -  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 -  int i;
 -  INT32 x;
 -  SHIFT_TEMPS
 -
 -  cconvert->Cr_r_tab = (int *)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				(MAXJSAMPLE+1) * SIZEOF(int));
 -  cconvert->Cb_b_tab = (int *)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				(MAXJSAMPLE+1) * SIZEOF(int));
 -  cconvert->Cr_g_tab = (INT32 *)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				(MAXJSAMPLE+1) * SIZEOF(INT32));
 -  cconvert->Cb_g_tab = (INT32 *)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				(MAXJSAMPLE+1) * SIZEOF(INT32));
 -
 -  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
 -    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
 -    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
 -    /* Cr=>R value is nearest int to 1.40200 * x */
 -    cconvert->Cr_r_tab[i] = (int)
 -		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
 -    /* Cb=>B value is nearest int to 1.77200 * x */
 -    cconvert->Cb_b_tab[i] = (int)
 -		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
 -    /* Cr=>G value is scaled-up -0.71414 * x */
 -    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
 -    /* Cb=>G value is scaled-up -0.34414 * x */
 -    /* We also add in ONE_HALF so that need not do it in inner loop */
 -    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
 -  }
 -}
 -
 -
 -/*
 - * Convert some rows of samples to the output colorspace.
 - *
 - * Note that we change from noninterleaved, one-plane-per-component format
 - * to interleaved-pixel format.  The output buffer is therefore three times
 - * as wide as the input buffer.
 - * A starting row offset is provided only for the input buffer.  The caller
 - * can easily adjust the passed output_buf value to accommodate any row
 - * offset required on that side.
 - */
 -
 -METHODDEF void
 -ycc_rgb_convert (j_decompress_ptr cinfo,
 -		 JSAMPIMAGE input_buf, JDIMENSION input_row,
 -		 JSAMPARRAY output_buf, int num_rows)
 -{
 -  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 -  register int y, cb, cr;
 -  register JSAMPROW outptr;
 -  register JSAMPROW inptr0, inptr1, inptr2;
 -  register JDIMENSION col;
 -  JDIMENSION num_cols = cinfo->output_width;
 -  /* copy these pointers into registers if possible */
 -  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 -  register int * Crrtab = cconvert->Cr_r_tab;
 -  register int * Cbbtab = cconvert->Cb_b_tab;
 -  register INT32 * Crgtab = cconvert->Cr_g_tab;
 -  register INT32 * Cbgtab = cconvert->Cb_g_tab;
 -  SHIFT_TEMPS
 -
 -  while (--num_rows >= 0) {
 -    inptr0 = input_buf[0][input_row];
 -    inptr1 = input_buf[1][input_row];
 -    inptr2 = input_buf[2][input_row];
 -    input_row++;
 -    outptr = *output_buf++;
 -    for (col = 0; col < num_cols; col++) {
 -      y  = GETJSAMPLE(inptr0[col]);
 -      cb = GETJSAMPLE(inptr1[col]);
 -      cr = GETJSAMPLE(inptr2[col]);
 -      /* Range-limiting is essential due to noise introduced by DCT losses. */
 -      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
 -      outptr[RGB_GREEN] = range_limit[y +
 -			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 -						 SCALEBITS))];
 -      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
 -      outptr += RGB_PIXELSIZE;
 -    }
 -  }
 -}
 -
 -
 -/**************** Cases other than YCbCr -> RGB **************/
 -
 -
 -/*
 - * Color conversion for no colorspace change: just copy the data,
 - * converting from separate-planes to interleaved representation.
 - */
 -
 -METHODDEF void
 -null_convert (j_decompress_ptr cinfo,
 -	      JSAMPIMAGE input_buf, JDIMENSION input_row,
 -	      JSAMPARRAY output_buf, int num_rows)
 -{
 -  register JSAMPROW inptr, outptr;
 -  register JDIMENSION count;
 -  register int num_components = cinfo->num_components;
 -  JDIMENSION num_cols = cinfo->output_width;
 -  int ci;
 -
 -  while (--num_rows >= 0) {
 -    for (ci = 0; ci < num_components; ci++) {
 -      inptr = input_buf[ci][input_row];
 -      outptr = output_buf[0] + ci;
 -      for (count = num_cols; count > 0; count--) {
 -	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
 -	outptr += num_components;
 -      }
 -    }
 -    input_row++;
 -    output_buf++;
 -  }
 -}
 -
 -
 -/*
 - * Color conversion for grayscale: just copy the data.
 - * This also works for YCbCr -> grayscale conversion, in which
 - * we just copy the Y (luminance) component and ignore chrominance.
 - */
 -
 -METHODDEF void
 -grayscale_convert (j_decompress_ptr cinfo,
 -		   JSAMPIMAGE input_buf, JDIMENSION input_row,
 -		   JSAMPARRAY output_buf, int num_rows)
 -{
 -  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
 -		    num_rows, cinfo->output_width);
 -}
 -
 -
 -/*
 - * 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
 -ycck_cmyk_convert (j_decompress_ptr cinfo,
 -		   JSAMPIMAGE input_buf, JDIMENSION input_row,
 -		   JSAMPARRAY output_buf, int num_rows)
 -{
 -  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 -  register int y, cb, cr;
 -  register JSAMPROW outptr;
 -  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
 -  register JDIMENSION col;
 -  JDIMENSION num_cols = cinfo->output_width;
 -  /* copy these pointers into registers if possible */
 -  register JSAMPLE * range_limit = cinfo->sample_range_limit;
 -  register int * Crrtab = cconvert->Cr_r_tab;
 -  register int * Cbbtab = cconvert->Cb_b_tab;
 -  register INT32 * Crgtab = cconvert->Cr_g_tab;
 -  register INT32 * Cbgtab = cconvert->Cb_g_tab;
 -  SHIFT_TEMPS
 -
 -  while (--num_rows >= 0) {
 -    inptr0 = input_buf[0][input_row];
 -    inptr1 = input_buf[1][input_row];
 -    inptr2 = input_buf[2][input_row];
 -    inptr3 = input_buf[3][input_row];
 -    input_row++;
 -    outptr = *output_buf++;
 -    for (col = 0; col < num_cols; col++) {
 -      y  = GETJSAMPLE(inptr0[col]);
 -      cb = GETJSAMPLE(inptr1[col]);
 -      cr = GETJSAMPLE(inptr2[col]);
 -      /* Range-limiting is essential due to noise introduced by DCT losses. */
 -      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
 -      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
 -			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
 -						 SCALEBITS)))];
 -      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
 -      /* K passes through unchanged */
 -      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
 -      outptr += 4;
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Empty method for start_pass.
 - */
 -
 -METHODDEF void
 -start_pass_dcolor (j_decompress_ptr cinfo)
 -{
 -  /* no work needed */
 -}
 -
 -
 -/*
 - * Module initialization routine for output colorspace conversion.
 - */
 -
 -GLOBAL void
 -jinit_color_deconverter (j_decompress_ptr cinfo)
 -{
 -  my_cconvert_ptr cconvert;
 -  int ci;
 -
 -  cconvert = (my_cconvert_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(my_color_deconverter));
 -  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
 -  cconvert->pub.start_pass = start_pass_dcolor;
 -
 -  /* Make sure num_components agrees with jpeg_color_space */
 -  switch (cinfo->jpeg_color_space) {
 -  case JCS_GRAYSCALE:
 -    if (cinfo->num_components != 1)
 -      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 -    break;
 -
 -  case JCS_RGB:
 -  case JCS_YCbCr:
 -    if (cinfo->num_components != 3)
 -      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 -    break;
 -
 -  case JCS_CMYK:
 -  case JCS_YCCK:
 -    if (cinfo->num_components != 4)
 -      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 -    break;
 -
 -  default:			/* JCS_UNKNOWN can be anything */
 -    if (cinfo->num_components < 1)
 -      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 -    break;
 -  }
 -
 -  /* Set out_color_components and conversion method based on requested space.
 -   * Also clear the component_needed flags for any unused components,
 -   * so that earlier pipeline stages can avoid useless computation.
 -   */
 -
 -  switch (cinfo->out_color_space) {
 -  case JCS_GRAYSCALE:
 -    cinfo->out_color_components = 1;
 -    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
 -	cinfo->jpeg_color_space == JCS_YCbCr) {
 -      cconvert->pub.color_convert = grayscale_convert;
 -      /* For color->grayscale conversion, only the Y (0) component is needed */
 -      for (ci = 1; ci < cinfo->num_components; ci++)
 -	cinfo->comp_info[ci].component_needed = FALSE;
 -    } else
 -      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 -    break;
 -
 -  case JCS_RGB:
 -    cinfo->out_color_components = RGB_PIXELSIZE;
 -    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_RGB && RGB_PIXELSIZE == 3) {
 -      cconvert->pub.color_convert = null_convert;
 -    } else
 -      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 -    break;
 -
 -  case JCS_CMYK:
 -    cinfo->out_color_components = 4;
 -    if (cinfo->jpeg_color_space == JCS_YCCK) {
 -      cconvert->pub.color_convert = ycck_cmyk_convert;
 -      build_ycc_rgb_table(cinfo);
 -    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
 -      cconvert->pub.color_convert = null_convert;
 -    } else
 -      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 -    break;
 -
 -  default:
 -    /* Permit null conversion to same output space */
 -    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
 -      cinfo->out_color_components = cinfo->num_components;
 -      cconvert->pub.color_convert = null_convert;
 -    } else			/* unsupported non-null conversion */
 -      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 -    break;
 -  }
 -
 -  if (cinfo->quantize_colors)
 -    cinfo->output_components = 1; /* single colormapped output component */
 -  else
 -    cinfo->output_components = cinfo->out_color_components;
 -}
 +/* + * jdcolor.c + * + * Copyright (C) 1991-1995, 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 output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { +  struct jpeg_color_deconverter pub; /* public fields */ + +  /* Private state for YCC->RGB conversion */ +  int * Cr_r_tab;		/* => table for Cr to R conversion */ +  int * Cb_b_tab;		/* => table for Cb to B conversion */ +  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */ +  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */ +} my_color_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** YCbCr -> RGB conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + *	R = Y                + 1.40200 * Cr + *	G = Y - 0.34414 * Cb - 0.71414 * Cr + *	B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less CENTERJSAMPLE. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable.  It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + +#define SCALEBITS	16	/* speediest right-shift on some machines */ +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1)) +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) + + +/* + * Initialize tables for YCC->RGB colorspace conversion. + */ + +LOCAL void +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; +  int i; +  INT32 x; +  SHIFT_TEMPS + +  cconvert->Cr_r_tab = (int *) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				(MAXJSAMPLE+1) * SIZEOF(int)); +  cconvert->Cb_b_tab = (int *) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				(MAXJSAMPLE+1) * SIZEOF(int)); +  cconvert->Cr_g_tab = (INT32 *) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				(MAXJSAMPLE+1) * SIZEOF(INT32)); +  cconvert->Cb_g_tab = (INT32 *) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				(MAXJSAMPLE+1) * SIZEOF(INT32)); + +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ +    /* Cr=>R value is nearest int to 1.40200 * x */ +    cconvert->Cr_r_tab[i] = (int) +		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); +    /* Cb=>B value is nearest int to 1.77200 * x */ +    cconvert->Cb_b_tab[i] = (int) +		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); +    /* Cr=>G value is scaled-up -0.71414 * x */ +    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; +    /* Cb=>G value is scaled-up -0.34414 * x */ +    /* We also add in ONE_HALF so that need not do it in inner loop */ +    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; +  } +} + + +/* + * Convert some rows of samples to the output colorspace. + * + * Note that we change from noninterleaved, one-plane-per-component format + * to interleaved-pixel format.  The output buffer is therefore three times + * as wide as the input buffer. + * A starting row offset is provided only for the input buffer.  The caller + * can easily adjust the passed output_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF void +ycc_rgb_convert (j_decompress_ptr cinfo, +		 JSAMPIMAGE input_buf, JDIMENSION input_row, +		 JSAMPARRAY output_buf, int num_rows) +{ +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; +  register int y, cb, cr; +  register JSAMPROW outptr; +  register JSAMPROW inptr0, inptr1, inptr2; +  register JDIMENSION col; +  JDIMENSION num_cols = cinfo->output_width; +  /* copy these pointers into registers if possible */ +  register JSAMPLE * range_limit = cinfo->sample_range_limit; +  register int * Crrtab = cconvert->Cr_r_tab; +  register int * Cbbtab = cconvert->Cb_b_tab; +  register INT32 * Crgtab = cconvert->Cr_g_tab; +  register INT32 * Cbgtab = cconvert->Cb_g_tab; +  SHIFT_TEMPS + +  while (--num_rows >= 0) { +    inptr0 = input_buf[0][input_row]; +    inptr1 = input_buf[1][input_row]; +    inptr2 = input_buf[2][input_row]; +    input_row++; +    outptr = *output_buf++; +    for (col = 0; col < num_cols; col++) { +      y  = GETJSAMPLE(inptr0[col]); +      cb = GETJSAMPLE(inptr1[col]); +      cr = GETJSAMPLE(inptr2[col]); +      /* Range-limiting is essential due to noise introduced by DCT losses. */ +      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]]; +      outptr[RGB_GREEN] = range_limit[y + +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], +						 SCALEBITS))]; +      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]]; +      outptr += RGB_PIXELSIZE; +    } +  } +} + + +/**************** Cases other than YCbCr -> RGB **************/ + + +/* + * Color conversion for no colorspace change: just copy the data, + * converting from separate-planes to interleaved representation. + */ + +METHODDEF void +null_convert (j_decompress_ptr cinfo, +	      JSAMPIMAGE input_buf, JDIMENSION input_row, +	      JSAMPARRAY output_buf, int num_rows) +{ +  register JSAMPROW inptr, outptr; +  register JDIMENSION count; +  register int num_components = cinfo->num_components; +  JDIMENSION num_cols = cinfo->output_width; +  int ci; + +  while (--num_rows >= 0) { +    for (ci = 0; ci < num_components; ci++) { +      inptr = input_buf[ci][input_row]; +      outptr = output_buf[0] + ci; +      for (count = num_cols; count > 0; count--) { +	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */ +	outptr += num_components; +      } +    } +    input_row++; +    output_buf++; +  } +} + + +/* + * Color conversion for grayscale: just copy the data. + * This also works for YCbCr -> grayscale conversion, in which + * we just copy the Y (luminance) component and ignore chrominance. + */ + +METHODDEF void +grayscale_convert (j_decompress_ptr cinfo, +		   JSAMPIMAGE input_buf, JDIMENSION input_row, +		   JSAMPARRAY output_buf, int num_rows) +{ +  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, +		    num_rows, cinfo->output_width); +} + + +/* + * 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 +ycck_cmyk_convert (j_decompress_ptr cinfo, +		   JSAMPIMAGE input_buf, JDIMENSION input_row, +		   JSAMPARRAY output_buf, int num_rows) +{ +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; +  register int y, cb, cr; +  register JSAMPROW outptr; +  register JSAMPROW inptr0, inptr1, inptr2, inptr3; +  register JDIMENSION col; +  JDIMENSION num_cols = cinfo->output_width; +  /* copy these pointers into registers if possible */ +  register JSAMPLE * range_limit = cinfo->sample_range_limit; +  register int * Crrtab = cconvert->Cr_r_tab; +  register int * Cbbtab = cconvert->Cb_b_tab; +  register INT32 * Crgtab = cconvert->Cr_g_tab; +  register INT32 * Cbgtab = cconvert->Cb_g_tab; +  SHIFT_TEMPS + +  while (--num_rows >= 0) { +    inptr0 = input_buf[0][input_row]; +    inptr1 = input_buf[1][input_row]; +    inptr2 = input_buf[2][input_row]; +    inptr3 = input_buf[3][input_row]; +    input_row++; +    outptr = *output_buf++; +    for (col = 0; col < num_cols; col++) { +      y  = GETJSAMPLE(inptr0[col]); +      cb = GETJSAMPLE(inptr1[col]); +      cr = GETJSAMPLE(inptr2[col]); +      /* Range-limiting is essential due to noise introduced by DCT losses. */ +      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */ +      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */ +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], +						 SCALEBITS)))]; +      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */ +      /* K passes through unchanged */ +      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */ +      outptr += 4; +    } +  } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF void +start_pass_dcolor (j_decompress_ptr cinfo) +{ +  /* no work needed */ +} + + +/* + * Module initialization routine for output colorspace conversion. + */ + +GLOBAL void +jinit_color_deconverter (j_decompress_ptr cinfo) +{ +  my_cconvert_ptr cconvert; +  int ci; + +  cconvert = (my_cconvert_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(my_color_deconverter)); +  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; +  cconvert->pub.start_pass = start_pass_dcolor; + +  /* Make sure num_components agrees with jpeg_color_space */ +  switch (cinfo->jpeg_color_space) { +  case JCS_GRAYSCALE: +    if (cinfo->num_components != 1) +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); +    break; + +  case JCS_RGB: +  case JCS_YCbCr: +    if (cinfo->num_components != 3) +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); +    break; + +  case JCS_CMYK: +  case JCS_YCCK: +    if (cinfo->num_components != 4) +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); +    break; + +  default:			/* JCS_UNKNOWN can be anything */ +    if (cinfo->num_components < 1) +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); +    break; +  } + +  /* Set out_color_components and conversion method based on requested space. +   * Also clear the component_needed flags for any unused components, +   * so that earlier pipeline stages can avoid useless computation. +   */ + +  switch (cinfo->out_color_space) { +  case JCS_GRAYSCALE: +    cinfo->out_color_components = 1; +    if (cinfo->jpeg_color_space == JCS_GRAYSCALE || +	cinfo->jpeg_color_space == JCS_YCbCr) { +      cconvert->pub.color_convert = grayscale_convert; +      /* For color->grayscale conversion, only the Y (0) component is needed */ +      for (ci = 1; ci < cinfo->num_components; ci++) +	cinfo->comp_info[ci].component_needed = FALSE; +    } else +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); +    break; + +  case JCS_RGB: +    cinfo->out_color_components = RGB_PIXELSIZE; +    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_RGB && RGB_PIXELSIZE == 3) { +      cconvert->pub.color_convert = null_convert; +    } else +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); +    break; + +  case JCS_CMYK: +    cinfo->out_color_components = 4; +    if (cinfo->jpeg_color_space == JCS_YCCK) { +      cconvert->pub.color_convert = ycck_cmyk_convert; +      build_ycc_rgb_table(cinfo); +    } else if (cinfo->jpeg_color_space == JCS_CMYK) { +      cconvert->pub.color_convert = null_convert; +    } else +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); +    break; + +  default: +    /* Permit null conversion to same output space */ +    if (cinfo->out_color_space == cinfo->jpeg_color_space) { +      cinfo->out_color_components = cinfo->num_components; +      cconvert->pub.color_convert = null_convert; +    } else			/* unsupported non-null conversion */ +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); +    break; +  } + +  if (cinfo->quantize_colors) +    cinfo->output_components = 1; /* single colormapped output component */ +  else +    cinfo->output_components = cinfo->out_color_components; +} diff --git a/libs/jpeg6/jdct.h b/libs/jpeg6/jdct.h index 1d66d4f..3ce790b 100755 --- a/libs/jpeg6/jdct.h +++ b/libs/jpeg6/jdct.h @@ -1,176 +1,176 @@ -/*
 - * jdct.h
 - *
 - * Copyright (C) 1994, 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 include file contains common declarations for the forward and
 - * inverse DCT modules.  These declarations are private to the DCT managers
 - * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
 - * The individual DCT algorithms are kept in separate files to ease 
 - * machine-dependent tuning (e.g., assembly coding).
 - */
 -
 -
 -/*
 - * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
 - * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
 - * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
 - * implementations use an array of type FAST_FLOAT, instead.)
 - * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
 - * The DCT outputs are returned scaled up by a factor of 8; they therefore
 - * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
 - * convention improves accuracy in integer implementations and saves some
 - * work in floating-point ones.
 - * Quantization of the output coefficients is done by jcdctmgr.c.
 - */
 -
 -#if BITS_IN_JSAMPLE == 8
 -typedef int DCTELEM;		/* 16 or 32 bits is fine */
 -#else
 -typedef INT32 DCTELEM;		/* must have 32 bits */
 -#endif
 -
 -typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
 -typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
 -
 -
 -/*
 - * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
 - * to an output sample array.  The routine must dequantize the input data as
 - * well as perform the IDCT; for dequantization, it uses the multiplier table
 - * pointed to by compptr->dct_table.  The output data is to be placed into the
 - * sample array starting at a specified column.  (Any row offset needed will
 - * be applied to the array pointer before it is passed to the IDCT code.)
 - * Note that the number of samples emitted by the IDCT routine is
 - * DCT_scaled_size * DCT_scaled_size.
 - */
 -
 -/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
 -
 -/*
 - * Each IDCT routine has its own ideas about the best dct_table element type.
 - */
 -
 -typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
 -#if BITS_IN_JSAMPLE == 8
 -typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
 -#define IFAST_SCALE_BITS  2	/* fractional bits in scale factors */
 -#else
 -typedef INT32 IFAST_MULT_TYPE;	/* need 32 bits for scaled quantizers */
 -#define IFAST_SCALE_BITS  13	/* fractional bits in scale factors */
 -#endif
 -typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
 -
 -
 -/*
 - * Each IDCT routine is responsible for range-limiting its results and
 - * converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
 - * be quite far out of range if the input data is corrupt, so a bulletproof
 - * range-limiting step is required.  We use a mask-and-table-lookup method
 - * to do the combined operations quickly.  See the comments with
 - * prepare_range_limit_table (in jdmaster.c) for more info.
 - */
 -
 -#define IDCT_range_limit(cinfo)  ((cinfo)->sample_range_limit + CENTERJSAMPLE)
 -
 -#define RANGE_MASK  (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
 -
 -
 -/* Short forms of external names for systems with brain-damaged linkers. */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_fdct_islow		jFDislow
 -#define jpeg_fdct_ifast		jFDifast
 -#define jpeg_fdct_float		jFDfloat
 -#define jpeg_idct_islow		jRDislow
 -#define jpeg_idct_ifast		jRDifast
 -#define jpeg_idct_float		jRDfloat
 -#define jpeg_idct_4x4		jRD4x4
 -#define jpeg_idct_2x2		jRD2x2
 -#define jpeg_idct_1x1		jRD1x1
 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
 -
 -/* 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_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
 -    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 -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
 -    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 -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
 -    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
 -
 -
 -/*
 - * Macros for handling fixed-point arithmetic; these are used by many
 - * but not all of the DCT/IDCT modules.
 - *
 - * All values are expected to be of type INT32.
 - * Fractional constants are scaled left by CONST_BITS bits.
 - * CONST_BITS is defined within each module using these macros,
 - * and may differ from one module to the next.
 - */
 -
 -#define ONE	((INT32) 1)
 -#define CONST_SCALE (ONE << CONST_BITS)
 -
 -/* Convert a positive real constant to an integer scaled by CONST_SCALE.
 - * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
 - * thus causing a lot of useless floating-point operations at run time.
 - */
 -
 -#define FIX(x)	((INT32) ((x) * CONST_SCALE + 0.5))
 -
 -/* Descale and correctly round an INT32 value that's scaled by N bits.
 - * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
 - * the fudge factor is correct for either sign of X.
 - */
 -
 -#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
 -
 -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
 - * This macro is used only when the two inputs will actually be no more than
 - * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
 - * full 32x32 multiply.  This provides a useful speedup on many machines.
 - * Unfortunately there is no way to specify a 16x16->32 multiply portably
 - * in C, but some C compilers will do the right thing if you provide the
 - * correct combination of casts.
 - */
 -
 -#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
 -#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT16) (const)))
 -#endif
 -#ifdef SHORTxLCONST_32		/* known to work with Microsoft C 6.0 */
 -#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT32) (const)))
 -#endif
 -
 -#ifndef MULTIPLY16C16		/* default definition */
 -#define MULTIPLY16C16(var,const)  ((var) * (const))
 -#endif
 -
 -/* Same except both inputs are variables. */
 -
 -#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
 -#define MULTIPLY16V16(var1,var2)  (((INT16) (var1)) * ((INT16) (var2)))
 -#endif
 -
 -#ifndef MULTIPLY16V16		/* default definition */
 -#define MULTIPLY16V16(var1,var2)  ((var1) * (var2))
 -#endif
 +/* + * jdct.h + * + * Copyright (C) 1994, 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 include file contains common declarations for the forward and + * inverse DCT modules.  These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease  + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM;		/* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM;		/* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array.  The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table.  The output data is to be placed into the + * sample array starting at a specified column.  (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS  2	/* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE;	/* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS  13	/* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required.  We use a mask-and-table-lookup method + * to do the combined operations quickly.  See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo)  ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK  (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow		jFDislow +#define jpeg_fdct_ifast		jFDifast +#define jpeg_fdct_float		jFDfloat +#define jpeg_idct_islow		jRDislow +#define jpeg_idct_ifast		jRDifast +#define jpeg_idct_float		jRDfloat +#define jpeg_idct_4x4		jRD4x4 +#define jpeg_idct_2x2		jRD2x2 +#define jpeg_idct_1x1		jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* 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_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 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +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 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +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 +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, +	 JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE	((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x)	((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply.  This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32		/* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16		/* default definition */ +#define MULTIPLY16C16(var,const)  ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2)  (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16		/* default definition */ +#define MULTIPLY16V16(var1,var2)  ((var1) * (var2)) +#endif diff --git a/libs/jpeg6/jddctmgr.cpp b/libs/jpeg6/jddctmgr.cpp index ba01fc6..71215f1 100755 --- a/libs/jpeg6/jddctmgr.cpp +++ b/libs/jpeg6/jddctmgr.cpp @@ -1,270 +1,270 @@ -/*
 - * jddctmgr.c
 - *
 - * Copyright (C) 1994-1995, 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 the inverse-DCT management logic.
 - * This code selects a particular IDCT implementation to be used,
 - * and it performs related housekeeping chores.  No code in this file
 - * is executed per IDCT step, only during output pass setup.
 - *
 - * Note that the IDCT routines are responsible for performing coefficient
 - * dequantization as well as the IDCT proper.  This module sets up the
 - * dequantization multiplier table needed by the IDCT routine.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jdct.h"		/* Private declarations for DCT subsystem */
 -
 -
 -/*
 - * The decompressor input side (jdinput.c) saves away the appropriate
 - * quantization table for each component at the start of the first scan
 - * involving that component.  (This is necessary in order to correctly
 - * decode files that reuse Q-table slots.)
 - * When we are ready to make an output pass, the saved Q-table is converted
 - * to a multiplier table that will actually be used by the IDCT routine.
 - * The multiplier table contents are IDCT-method-dependent.  To support
 - * application changes in IDCT method between scans, we can remake the
 - * multiplier tables if necessary.
 - * In buffered-image mode, the first output pass may occur before any data
 - * has been seen for some components, and thus before their Q-tables have
 - * been saved away.  To handle this case, multiplier tables are preset
 - * to zeroes; the result of the IDCT will be a neutral gray level.
 - */
 -
 -
 -/* Private subobject for this module */
 -
 -typedef struct {
 -  struct jpeg_inverse_dct pub;	/* public fields */
 -
 -  /* This array contains the IDCT method code that each multiplier table
 -   * is currently set up for, or -1 if it's not yet set up.
 -   * The actual multiplier tables are pointed to by dct_table in the
 -   * per-component comp_info structures.
 -   */
 -  int cur_method[MAX_COMPONENTS];
 -} my_idct_controller;
 -
 -typedef my_idct_controller * my_idct_ptr;
 -
 -
 -/* Allocated multiplier tables: big enough for any supported variant */
 -
 -typedef union {
 -  ISLOW_MULT_TYPE islow_array[DCTSIZE2];
 -#ifdef DCT_IFAST_SUPPORTED
 -  IFAST_MULT_TYPE ifast_array[DCTSIZE2];
 -#endif
 -#ifdef DCT_FLOAT_SUPPORTED
 -  FLOAT_MULT_TYPE float_array[DCTSIZE2];
 -#endif
 -} multiplier_table;
 -
 -
 -/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
 - * so be sure to compile that code if either ISLOW or SCALING is requested.
 - */
 -#ifdef DCT_ISLOW_SUPPORTED
 -#define PROVIDE_ISLOW_TABLES
 -#else
 -#ifdef IDCT_SCALING_SUPPORTED
 -#define PROVIDE_ISLOW_TABLES
 -#endif
 -#endif
 -
 -
 -/*
 - * Prepare for an output pass.
 - * Here we select the proper IDCT routine for each component and build
 - * a matching multiplier table.
 - */
 -
 -METHODDEF void
 -start_pass (j_decompress_ptr cinfo)
 -{
 -  my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
 -  int ci, i;
 -  jpeg_component_info *compptr;
 -  int method = 0;
 -  inverse_DCT_method_ptr method_ptr = NULL;
 -  JQUANT_TBL * qtbl;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Select the proper IDCT routine for this component's scaling */
 -    switch (compptr->DCT_scaled_size) {
 -#ifdef IDCT_SCALING_SUPPORTED
 -    case 1:
 -      method_ptr = jpeg_idct_1x1;
 -      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 -      break;
 -    case 2:
 -      method_ptr = jpeg_idct_2x2;
 -      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 -      break;
 -    case 4:
 -      method_ptr = jpeg_idct_4x4;
 -      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
 -      break;
 -#endif
 -    case DCTSIZE:
 -      switch (cinfo->dct_method) {
 -#ifdef DCT_ISLOW_SUPPORTED
 -      case JDCT_ISLOW:
 -	method_ptr = jpeg_idct_islow;
 -	method = JDCT_ISLOW;
 -	break;
 -#endif
 -#ifdef DCT_IFAST_SUPPORTED
 -      case JDCT_IFAST:
 -	method_ptr = jpeg_idct_ifast;
 -	method = JDCT_IFAST;
 -	break;
 -#endif
 -#ifdef DCT_FLOAT_SUPPORTED
 -      case JDCT_FLOAT:
 -	method_ptr = jpeg_idct_float;
 -	method = JDCT_FLOAT;
 -	break;
 -#endif
 -      default:
 -	ERREXIT(cinfo, JERR_NOT_COMPILED);
 -	break;
 -      }
 -      break;
 -    default:
 -      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
 -      break;
 -    }
 -    idct->pub.inverse_DCT[ci] = method_ptr;
 -    /* Create multiplier table from quant table.
 -     * However, we can skip this if the component is uninteresting
 -     * or if we already built the table.  Also, if no quant table
 -     * has yet been saved for the component, we leave the
 -     * multiplier table all-zero; we'll be reading zeroes from the
 -     * coefficient controller's buffer anyway.
 -     */
 -    if (! compptr->component_needed || idct->cur_method[ci] == method)
 -      continue;
 -    qtbl = compptr->quant_table;
 -    if (qtbl == NULL)		/* happens if no data yet for component */
 -      continue;
 -    idct->cur_method[ci] = method;
 -    switch (method) {
 -#ifdef PROVIDE_ISLOW_TABLES
 -    case JDCT_ISLOW:
 -      {
 -	/* For LL&M IDCT method, multipliers are equal to raw quantization
 -	 * coefficients, but are stored in natural order as ints.
 -	 */
 -	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]];
 -	}
 -      }
 -      break;
 -#endif
 -#ifdef DCT_IFAST_SUPPORTED
 -    case JDCT_IFAST:
 -      {
 -	/* For AA&N IDCT method, multipliers are equal to quantization
 -	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
 -	 *   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_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
 -#define CONST_BITS 14
 -	static const INT16 aanscales[DCTSIZE2] = {
 -	  /* 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,
 -	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
 -	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 -	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
 -	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
 -	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
 -	};
 -	SHIFT_TEMPS
 -
 -	for (i = 0; i < DCTSIZE2; i++) {
 -	  ifmtbl[i] = (IFAST_MULT_TYPE)
 -	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]],
 -				  (INT32) aanscales[i]),
 -		    CONST_BITS-IFAST_SCALE_BITS);
 -	}
 -      }
 -      break;
 -#endif
 -#ifdef DCT_FLOAT_SUPPORTED
 -    case JDCT_FLOAT:
 -      {
 -	/* For float AA&N IDCT method, multipliers are equal to quantization
 -	 * 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;
 -	static const double aanscalefactor[DCTSIZE] = {
 -	  1.0, 1.387039845, 1.306562965, 1.175875602,
 -	  1.0, 0.785694958, 0.541196100, 0.275899379
 -	};
 -
 -	i = 0;
 -	for (row = 0; row < DCTSIZE; row++) {
 -	  for (col = 0; col < DCTSIZE; col++) {
 -	    fmtbl[i] = (FLOAT_MULT_TYPE)
 -	      ((double) qtbl->quantval[jpeg_zigzag_order[i]] *
 -	       aanscalefactor[row] * aanscalefactor[col]);
 -	    i++;
 -	  }
 -	}
 -      }
 -      break;
 -#endif
 -    default:
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -      break;
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Initialize IDCT manager.
 - */
 -
 -GLOBAL void
 -jinit_inverse_dct (j_decompress_ptr cinfo)
 -{
 -  my_idct_ptr idct;
 -  int ci;
 -  jpeg_component_info *compptr;
 -
 -  idct = (my_idct_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(my_idct_controller));
 -  cinfo->idct = (struct jpeg_inverse_dct *) idct;
 -  idct->pub.start_pass = start_pass;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Allocate and pre-zero a multiplier table for each component */
 -    compptr->dct_table =
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  SIZEOF(multiplier_table));
 -    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
 -    /* Mark multiplier table not yet set up for any method */
 -    idct->cur_method[ci] = -1;
 -  }
 -}
 +/* + * jddctmgr.c + * + * Copyright (C) 1994-1995, 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 the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores.  No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper.  This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h"		/* Private declarations for DCT subsystem */ + + +/* + * The decompressor input side (jdinput.c) saves away the appropriate + * quantization table for each component at the start of the first scan + * involving that component.  (This is necessary in order to correctly + * decode files that reuse Q-table slots.) + * When we are ready to make an output pass, the saved Q-table is converted + * to a multiplier table that will actually be used by the IDCT routine. + * The multiplier table contents are IDCT-method-dependent.  To support + * application changes in IDCT method between scans, we can remake the + * multiplier tables if necessary. + * In buffered-image mode, the first output pass may occur before any data + * has been seen for some components, and thus before their Q-tables have + * been saved away.  To handle this case, multiplier tables are preset + * to zeroes; the result of the IDCT will be a neutral gray level. + */ + + +/* Private subobject for this module */ + +typedef struct { +  struct jpeg_inverse_dct pub;	/* public fields */ + +  /* This array contains the IDCT method code that each multiplier table +   * is currently set up for, or -1 if it's not yet set up. +   * The actual multiplier tables are pointed to by dct_table in the +   * per-component comp_info structures. +   */ +  int cur_method[MAX_COMPONENTS]; +} my_idct_controller; + +typedef my_idct_controller * my_idct_ptr; + + +/* Allocated multiplier tables: big enough for any supported variant */ + +typedef union { +  ISLOW_MULT_TYPE islow_array[DCTSIZE2]; +#ifdef DCT_IFAST_SUPPORTED +  IFAST_MULT_TYPE ifast_array[DCTSIZE2]; +#endif +#ifdef DCT_FLOAT_SUPPORTED +  FLOAT_MULT_TYPE float_array[DCTSIZE2]; +#endif +} multiplier_table; + + +/* The current scaled-IDCT routines require ISLOW-style multiplier tables, + * so be sure to compile that code if either ISLOW or SCALING is requested. + */ +#ifdef DCT_ISLOW_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#else +#ifdef IDCT_SCALING_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#endif +#endif + + +/* + * Prepare for an output pass. + * Here we select the proper IDCT routine for each component and build + * a matching multiplier table. + */ + +METHODDEF void +start_pass (j_decompress_ptr cinfo) +{ +  my_idct_ptr idct = (my_idct_ptr) cinfo->idct; +  int ci, i; +  jpeg_component_info *compptr; +  int method = 0; +  inverse_DCT_method_ptr method_ptr = NULL; +  JQUANT_TBL * qtbl; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Select the proper IDCT routine for this component's scaling */ +    switch (compptr->DCT_scaled_size) { +#ifdef IDCT_SCALING_SUPPORTED +    case 1: +      method_ptr = jpeg_idct_1x1; +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */ +      break; +    case 2: +      method_ptr = jpeg_idct_2x2; +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */ +      break; +    case 4: +      method_ptr = jpeg_idct_4x4; +      method = JDCT_ISLOW;	/* jidctred uses islow-style table */ +      break; +#endif +    case DCTSIZE: +      switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED +      case JDCT_ISLOW: +	method_ptr = jpeg_idct_islow; +	method = JDCT_ISLOW; +	break; +#endif +#ifdef DCT_IFAST_SUPPORTED +      case JDCT_IFAST: +	method_ptr = jpeg_idct_ifast; +	method = JDCT_IFAST; +	break; +#endif +#ifdef DCT_FLOAT_SUPPORTED +      case JDCT_FLOAT: +	method_ptr = jpeg_idct_float; +	method = JDCT_FLOAT; +	break; +#endif +      default: +	ERREXIT(cinfo, JERR_NOT_COMPILED); +	break; +      } +      break; +    default: +      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); +      break; +    } +    idct->pub.inverse_DCT[ci] = method_ptr; +    /* Create multiplier table from quant table. +     * However, we can skip this if the component is uninteresting +     * or if we already built the table.  Also, if no quant table +     * has yet been saved for the component, we leave the +     * multiplier table all-zero; we'll be reading zeroes from the +     * coefficient controller's buffer anyway. +     */ +    if (! compptr->component_needed || idct->cur_method[ci] == method) +      continue; +    qtbl = compptr->quant_table; +    if (qtbl == NULL)		/* happens if no data yet for component */ +      continue; +    idct->cur_method[ci] = method; +    switch (method) { +#ifdef PROVIDE_ISLOW_TABLES +    case JDCT_ISLOW: +      { +	/* For LL&M IDCT method, multipliers are equal to raw quantization +	 * coefficients, but are stored in natural order as ints. +	 */ +	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]]; +	} +      } +      break; +#endif +#ifdef DCT_IFAST_SUPPORTED +    case JDCT_IFAST: +      { +	/* For AA&N IDCT method, multipliers are equal to quantization +	 * coefficients scaled by scalefactor[row]*scalefactor[col], where +	 *   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_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; +#define CONST_BITS 14 +	static const INT16 aanscales[DCTSIZE2] = { +	  /* 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, +	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315, +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520, +	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552, +	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446, +	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247 +	}; +	SHIFT_TEMPS + +	for (i = 0; i < DCTSIZE2; i++) { +	  ifmtbl[i] = (IFAST_MULT_TYPE) +	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], +				  (INT32) aanscales[i]), +		    CONST_BITS-IFAST_SCALE_BITS); +	} +      } +      break; +#endif +#ifdef DCT_FLOAT_SUPPORTED +    case JDCT_FLOAT: +      { +	/* For float AA&N IDCT method, multipliers are equal to quantization +	 * 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; +	static const double aanscalefactor[DCTSIZE] = { +	  1.0, 1.387039845, 1.306562965, 1.175875602, +	  1.0, 0.785694958, 0.541196100, 0.275899379 +	}; + +	i = 0; +	for (row = 0; row < DCTSIZE; row++) { +	  for (col = 0; col < DCTSIZE; col++) { +	    fmtbl[i] = (FLOAT_MULT_TYPE) +	      ((double) qtbl->quantval[jpeg_zigzag_order[i]] * +	       aanscalefactor[row] * aanscalefactor[col]); +	    i++; +	  } +	} +      } +      break; +#endif +    default: +      ERREXIT(cinfo, JERR_NOT_COMPILED); +      break; +    } +  } +} + + +/* + * Initialize IDCT manager. + */ + +GLOBAL void +jinit_inverse_dct (j_decompress_ptr cinfo) +{ +  my_idct_ptr idct; +  int ci; +  jpeg_component_info *compptr; + +  idct = (my_idct_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(my_idct_controller)); +  cinfo->idct = (struct jpeg_inverse_dct *) idct; +  idct->pub.start_pass = start_pass; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Allocate and pre-zero a multiplier table for each component */ +    compptr->dct_table = +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  SIZEOF(multiplier_table)); +    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); +    /* Mark multiplier table not yet set up for any method */ +    idct->cur_method[ci] = -1; +  } +} diff --git a/libs/jpeg6/jdhuff.cpp b/libs/jpeg6/jdhuff.cpp index db42772..95174b1 100755 --- a/libs/jpeg6/jdhuff.cpp +++ b/libs/jpeg6/jdhuff.cpp @@ -1,574 +1,574 @@ -/*
 - * jdhuff.c
 - *
 - * Copyright (C) 1991-1995, 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 Huffman entropy decoding routines.
 - *
 - * Much of the complexity here has to do with supporting input suspension.
 - * If the data source module demands suspension, we want to be able to back
 - * up to the start of the current MCU.  To do this, we copy state variables
 - * into local working storage, and update them back to the permanent
 - * storage only upon successful completion of an MCU.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jdhuff.h"		/* Declarations shared with jdphuff.c */
 -
 -
 -/*
 - * Expanded entropy decoder object for Huffman decoding.
 - *
 - * The savable_state subrecord contains fields that change within an MCU,
 - * but must not be updated permanently until we complete the MCU.
 - */
 -
 -typedef struct {
 -  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
 -} savable_state;
 -
 -/* This macro is to work around compilers with missing or broken
 - * structure assignment.  You'll need to fix this code if you have
 - * such a compiler and you change MAX_COMPS_IN_SCAN.
 - */
 -
 -#ifndef NO_STRUCT_ASSIGN
 -#define ASSIGN_STATE(dest,src)  ((dest) = (src))
 -#else
 -#if MAX_COMPS_IN_SCAN == 4
 -#define ASSIGN_STATE(dest,src)  \
 -	((dest).last_dc_val[0] = (src).last_dc_val[0], \
 -	 (dest).last_dc_val[1] = (src).last_dc_val[1], \
 -	 (dest).last_dc_val[2] = (src).last_dc_val[2], \
 -	 (dest).last_dc_val[3] = (src).last_dc_val[3])
 -#endif
 -#endif
 -
 -
 -typedef struct {
 -  struct jpeg_entropy_decoder pub; /* public fields */
 -
 -  /* These fields are loaded into local variables at start of each MCU.
 -   * In case of suspension, we exit WITHOUT updating them.
 -   */
 -  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */
 -  savable_state saved;		/* Other state at start of MCU */
 -
 -  /* These fields are NOT loaded into local working state. */
 -  unsigned int restarts_to_go;	/* MCUs left in this restart interval */
 -
 -  /* 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];
 -} huff_entropy_decoder;
 -
 -typedef huff_entropy_decoder * huff_entropy_ptr;
 -
 -
 -/*
 - * Initialize for a Huffman-compressed scan.
 - */
 -
 -METHODDEF void
 -start_pass_huff_decoder (j_decompress_ptr cinfo)
 -{
 -  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 -  int ci, dctbl, actbl;
 -  jpeg_component_info * compptr;
 -
 -  /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
 -   * This ought to be an error condition, but we make it a warning because
 -   * there are some baseline files out there with all zeroes in these bytes.
 -   */
 -  if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
 -      cinfo->Ah != 0 || cinfo->Al != 0)
 -    WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
 -
 -  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -    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],
 -			    & entropy->dc_derived_tbls[dctbl]);
 -    jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl],
 -			    & entropy->ac_derived_tbls[actbl]);
 -    /* Initialize DC predictions to 0 */
 -    entropy->saved.last_dc_val[ci] = 0;
 -  }
 -
 -  /* Initialize bitread state variables */
 -  entropy->bitstate.bits_left = 0;
 -  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
 -  entropy->bitstate.printed_eod = FALSE;
 -
 -  /* Initialize restart counter */
 -  entropy->restarts_to_go = cinfo->restart_interval;
 -}
 -
 -
 -/*
 - * Compute the derived values for a Huffman table.
 - * Note this is also used by jdphuff.c.
 - */
 -
 -GLOBAL void
 -jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
 -			 d_derived_tbl ** pdtbl)
 -{
 -  d_derived_tbl *dtbl;
 -  int p, i, l, si;
 -  int lookbits, ctr;
 -  char huffsize[257];
 -  unsigned int huffcode[257];
 -  unsigned int code;
 -
 -  /* Allocate a workspace if we haven't already done so. */
 -  if (*pdtbl == NULL)
 -    *pdtbl = (d_derived_tbl *)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  SIZEOF(d_derived_tbl));
 -  dtbl = *pdtbl;
 -  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++)
 -      huffsize[p++] = (char) l;
 -  }
 -  huffsize[p] = 0;
 -  
 -  /* Figure C.2: generate the codes themselves */
 -  /* Note that this is in code-length order. */
 -  
 -  code = 0;
 -  si = huffsize[0];
 -  p = 0;
 -  while (huffsize[p]) {
 -    while (((int) huffsize[p]) == si) {
 -      huffcode[p++] = code;
 -      code++;
 -    }
 -    code <<= 1;
 -    si++;
 -  }
 -
 -  /* Figure F.15: generate decoding tables for bit-sequential decoding */
 -
 -  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 */
 -      p += htbl->bits[l];
 -      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
 -    } else {
 -      dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
 -    }
 -  }
 -  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
 -
 -  /* Compute lookahead tables to speed up decoding.
 -   * First we set all the table entries to 0, indicating "too long";
 -   * then we iterate through the Huffman codes that are short enough and
 -   * fill in all the entries that correspond to bit sequences starting
 -   * with that code.
 -   */
 -
 -  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
 -
 -  p = 0;
 -  for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
 -    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
 -      /* l = current code's length, p = its index in huffcode[] & huffval[]. */
 -      /* Generate left-justified code followed by all possible bit sequences */
 -      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
 -      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
 -	dtbl->look_nbits[lookbits] = l;
 -	dtbl->look_sym[lookbits] = htbl->huffval[p];
 -	lookbits++;
 -      }
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Out-of-line code for bit fetching (shared with jdphuff.c).
 - * See jdhuff.h for info about usage.
 - * Note: current values of get_buffer and bits_left are passed as parameters,
 - * but are returned in the corresponding fields of the state struct.
 - *
 - * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
 - * of get_buffer to be used.  (On machines with wider words, an even larger
 - * buffer could be used.)  However, on some machines 32-bit shifts are
 - * quite slow and take time proportional to the number of places shifted.
 - * (This is true with most PC compilers, for instance.)  In this case it may
 - * be a win to set MIN_GET_BITS to the minimum value of 15.  This reduces the
 - * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
 - */
 -
 -#ifdef SLOW_SHIFT_32
 -#define MIN_GET_BITS  15	/* minimum allowable value */
 -#else
 -#define MIN_GET_BITS  (BIT_BUF_SIZE-7)
 -#endif
 -
 -
 -GLOBAL boolean
 -jpeg_fill_bit_buffer (bitread_working_state * state,
 -		      register bit_buf_type get_buffer, register int bits_left,
 -		      int nbits)
 -/* Load up the bit buffer to a depth of at least nbits */
 -{
 -  /* 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;
 -
 -  /* 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.
 -	 */
 -	if (! *(state->printed_eod_ptr)) {
 -	  WARNMS(state->cinfo, JWRN_HIT_MARKER);
 -	  *(state->printed_eod_ptr) = TRUE;
 -	}
 -	c = 0;			/* insert a zero byte into bit buffer */
 -      }
 -    }
 -
 -    /* OK, load c into get_buffer */
 -    get_buffer = (get_buffer << 8) | c;
 -    bits_left += 8;
 -  }
 -
 -  /* Unload the local registers */
 -  state->next_input_byte = next_input_byte;
 -  state->bytes_in_buffer = bytes_in_buffer;
 -  state->get_buffer = get_buffer;
 -  state->bits_left = bits_left;
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Out-of-line code for Huffman code decoding.
 - * See jdhuff.h for info about usage.
 - */
 -
 -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)
 -{
 -  register int l = min_bits;
 -  register INT32 code;
 -
 -  /* HUFF_DECODE has determined that the code is at least min_bits */
 -  /* bits long, so fetch that many bits in one swoop. */
 -
 -  CHECK_BIT_BUFFER(*state, l, return -1);
 -  code = GET_BITS(l);
 -
 -  /* Collect the rest of the Huffman code one bit at a time. */
 -  /* This is per Figure F.16 in the JPEG spec. */
 -
 -  while (code > htbl->maxcode[l]) {
 -    code <<= 1;
 -    CHECK_BIT_BUFFER(*state, 1, return -1);
 -    code |= GET_BITS(1);
 -    l++;
 -  }
 -
 -  /* Unload the local registers */
 -  state->get_buffer = get_buffer;
 -  state->bits_left = bits_left;
 -
 -  /* With garbage input we may reach the sentinel value l = 17. */
 -
 -  if (l > 16) {
 -    WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
 -    return 0;			/* fake a zero as the safest result */
 -  }
 -
 -  return htbl->pub->huffval[ htbl->valptr[l] +
 -			    ((int) (code - htbl->mincode[l])) ];
 -}
 -
 -
 -/*
 - * Figure F.12: extend sign bit.
 - * On some machines, a shift and add will be faster than a table lookup.
 - */
 -
 -#ifdef AVOID_TABLES
 -
 -#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
 -
 -#else
 -
 -#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
 -
 -static const int extend_test[16] =   /* entry n is 2**(n-1) */
 -  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
 -    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
 -
 -static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
 -  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
 -    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
 -    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
 -    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
 -
 -#endif /* AVOID_TABLES */
 -
 -
 -/*
 - * Check for a restart marker & resynchronize decoder.
 - * Returns FALSE if must suspend.
 - */
 -
 -LOCAL boolean
 -process_restart (j_decompress_ptr cinfo)
 -{
 -  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
 -  int ci;
 -
 -  /* Throw away any unused bits remaining in bit buffer; */
 -  /* include any full bytes in next_marker's count of discarded bytes */
 -  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
 -  entropy->bitstate.bits_left = 0;
 -
 -  /* Advance past the RSTn marker */
 -  if (! (*cinfo->marker->read_restart_marker) (cinfo))
 -    return FALSE;
 -
 -  /* Re-initialize DC predictions to 0 */
 -  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
 -    entropy->saved.last_dc_val[ci] = 0;
 -
 -  /* Reset restart counter */
 -  entropy->restarts_to_go = cinfo->restart_interval;
 -
 -  /* Next segment can get another out-of-data warning */
 -  entropy->bitstate.printed_eod = FALSE;
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Decode and return one MCU's worth of Huffman-compressed coefficients.
 - * The coefficients are reordered from zigzag order into natural array order,
 - * but are not dequantized.
 - *
 - * The i'th block of the MCU is stored into the block pointed to by
 - * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
 - * (Wholesale zeroing is usually a little faster than retail...)
 - *
 - * Returns FALSE if data source requested suspension.  In that case no
 - * changes have been made to permanent state.  (Exception: some output
 - * coefficients may already have been assigned.  This is harmless for
 - * this module, since we'll just re-assign them on the next call.)
 - */
 -
 -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;
 -  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) {
 -    if (entropy->restarts_to_go == 0)
 -      if (! process_restart(cinfo))
 -	return FALSE;
 -  }
 -
 -  /* Load up working state */
 -  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 -  ASSIGN_STATE(state, entropy->saved);
 -
 -  /* 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];
 -    dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no];
 -    actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no];
 -
 -    /* Decode a single block's worth of coefficients */
 -
 -    /* 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);
 -    }
 -
 -    /* Shortcut if component's values are not interesting */
 -    if (! compptr->component_needed)
 -      goto skip_ACs;
 -
 -    /* 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;
 -
 -    /* Do we need to decode the AC coefficients for this component? */
 -    if (compptr->DCT_scaled_size > 1) {
 -
 -      /* 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;
 -      
 -	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:
 -
 -      /* 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;
 -      
 -	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);
 -
 -  /* Account for restart interval (no-op if not using restarts) */
 -  entropy->restarts_to_go--;
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Module initialization routine for Huffman entropy decoding.
 - */
 -
 -GLOBAL void
 -jinit_huff_decoder (j_decompress_ptr cinfo)
 -{
 -  huff_entropy_ptr entropy;
 -  int i;
 -
 -  entropy = (huff_entropy_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(huff_entropy_decoder));
 -  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
 -  entropy->pub.start_pass = start_pass_huff_decoder;
 -  entropy->pub.decode_mcu = decode_mcu;
 -
 -  /* Mark tables unallocated */
 -  for (i = 0; i < NUM_HUFF_TBLS; i++) {
 -    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
 -  }
 -}
 +/* + * jdhuff.c + * + * Copyright (C) 1991-1995, 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 Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU.  To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h"		/* Declarations shared with jdphuff.c */ + + +/* + * Expanded entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment.  You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src)  ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src)  \ +	((dest).last_dc_val[0] = (src).last_dc_val[0], \ +	 (dest).last_dc_val[1] = (src).last_dc_val[1], \ +	 (dest).last_dc_val[2] = (src).last_dc_val[2], \ +	 (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { +  struct jpeg_entropy_decoder pub; /* public fields */ + +  /* These fields are loaded into local variables at start of each MCU. +   * In case of suspension, we exit WITHOUT updating them. +   */ +  bitread_perm_state bitstate;	/* Bit buffer at start of MCU */ +  savable_state saved;		/* Other state at start of MCU */ + +  /* These fields are NOT loaded into local working state. */ +  unsigned int restarts_to_go;	/* MCUs left in this restart interval */ + +  /* 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]; +} huff_entropy_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF void +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; +  int ci, dctbl, actbl; +  jpeg_component_info * compptr; + +  /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. +   * This ought to be an error condition, but we make it a warning because +   * there are some baseline files out there with all zeroes in these bytes. +   */ +  if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || +      cinfo->Ah != 0 || cinfo->Al != 0) +    WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +    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], +			    & entropy->dc_derived_tbls[dctbl]); +    jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], +			    & entropy->ac_derived_tbls[actbl]); +    /* Initialize DC predictions to 0 */ +    entropy->saved.last_dc_val[ci] = 0; +  } + +  /* Initialize bitread state variables */ +  entropy->bitstate.bits_left = 0; +  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ +  entropy->bitstate.printed_eod = FALSE; + +  /* Initialize restart counter */ +  entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Compute the derived values for a Huffman table. + * Note this is also used by jdphuff.c. + */ + +GLOBAL void +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, +			 d_derived_tbl ** pdtbl) +{ +  d_derived_tbl *dtbl; +  int p, i, l, si; +  int lookbits, ctr; +  char huffsize[257]; +  unsigned int huffcode[257]; +  unsigned int code; + +  /* Allocate a workspace if we haven't already done so. */ +  if (*pdtbl == NULL) +    *pdtbl = (d_derived_tbl *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  SIZEOF(d_derived_tbl)); +  dtbl = *pdtbl; +  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++) +      huffsize[p++] = (char) l; +  } +  huffsize[p] = 0; +   +  /* Figure C.2: generate the codes themselves */ +  /* Note that this is in code-length order. */ +   +  code = 0; +  si = huffsize[0]; +  p = 0; +  while (huffsize[p]) { +    while (((int) huffsize[p]) == si) { +      huffcode[p++] = code; +      code++; +    } +    code <<= 1; +    si++; +  } + +  /* Figure F.15: generate decoding tables for bit-sequential decoding */ + +  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 */ +      p += htbl->bits[l]; +      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ +    } else { +      dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */ +    } +  } +  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ + +  /* Compute lookahead tables to speed up decoding. +   * First we set all the table entries to 0, indicating "too long"; +   * then we iterate through the Huffman codes that are short enough and +   * fill in all the entries that correspond to bit sequences starting +   * with that code. +   */ + +  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); + +  p = 0; +  for (l = 1; l <= HUFF_LOOKAHEAD; l++) { +    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { +      /* l = current code's length, p = its index in huffcode[] & huffval[]. */ +      /* Generate left-justified code followed by all possible bit sequences */ +      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); +      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { +	dtbl->look_nbits[lookbits] = l; +	dtbl->look_sym[lookbits] = htbl->huffval[p]; +	lookbits++; +      } +    } +  } +} + + +/* + * Out-of-line code for bit fetching (shared with jdphuff.c). + * See jdhuff.h for info about usage. + * Note: current values of get_buffer and bits_left are passed as parameters, + * but are returned in the corresponding fields of the state struct. + * + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + * of get_buffer to be used.  (On machines with wider words, an even larger + * buffer could be used.)  However, on some machines 32-bit shifts are + * quite slow and take time proportional to the number of places shifted. + * (This is true with most PC compilers, for instance.)  In this case it may + * be a win to set MIN_GET_BITS to the minimum value of 15.  This reduces the + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. + */ + +#ifdef SLOW_SHIFT_32 +#define MIN_GET_BITS  15	/* minimum allowable value */ +#else +#define MIN_GET_BITS  (BIT_BUF_SIZE-7) +#endif + + +GLOBAL boolean +jpeg_fill_bit_buffer (bitread_working_state * state, +		      register bit_buf_type get_buffer, register int bits_left, +		      int nbits) +/* Load up the bit buffer to a depth of at least nbits */ +{ +  /* 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; + +  /* 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. +	 */ +	if (! *(state->printed_eod_ptr)) { +	  WARNMS(state->cinfo, JWRN_HIT_MARKER); +	  *(state->printed_eod_ptr) = TRUE; +	} +	c = 0;			/* insert a zero byte into bit buffer */ +      } +    } + +    /* OK, load c into get_buffer */ +    get_buffer = (get_buffer << 8) | c; +    bits_left += 8; +  } + +  /* Unload the local registers */ +  state->next_input_byte = next_input_byte; +  state->bytes_in_buffer = bytes_in_buffer; +  state->get_buffer = get_buffer; +  state->bits_left = bits_left; + +  return TRUE; +} + + +/* + * Out-of-line code for Huffman code decoding. + * See jdhuff.h for info about usage. + */ + +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) +{ +  register int l = min_bits; +  register INT32 code; + +  /* HUFF_DECODE has determined that the code is at least min_bits */ +  /* bits long, so fetch that many bits in one swoop. */ + +  CHECK_BIT_BUFFER(*state, l, return -1); +  code = GET_BITS(l); + +  /* Collect the rest of the Huffman code one bit at a time. */ +  /* This is per Figure F.16 in the JPEG spec. */ + +  while (code > htbl->maxcode[l]) { +    code <<= 1; +    CHECK_BIT_BUFFER(*state, 1, return -1); +    code |= GET_BITS(1); +    l++; +  } + +  /* Unload the local registers */ +  state->get_buffer = get_buffer; +  state->bits_left = bits_left; + +  /* With garbage input we may reach the sentinel value l = 17. */ + +  if (l > 16) { +    WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); +    return 0;			/* fake a zero as the safest result */ +  } + +  return htbl->pub->huffval[ htbl->valptr[l] + +			    ((int) (code - htbl->mincode[l])) ]; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] =   /* entry n is 2**(n-1) */ +  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, +    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ +  { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, +    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, +    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, +    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL boolean +process_restart (j_decompress_ptr cinfo) +{ +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; +  int ci; + +  /* Throw away any unused bits remaining in bit buffer; */ +  /* include any full bytes in next_marker's count of discarded bytes */ +  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; +  entropy->bitstate.bits_left = 0; + +  /* Advance past the RSTn marker */ +  if (! (*cinfo->marker->read_restart_marker) (cinfo)) +    return FALSE; + +  /* Re-initialize DC predictions to 0 */ +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) +    entropy->saved.last_dc_val[ci] = 0; + +  /* Reset restart counter */ +  entropy->restarts_to_go = cinfo->restart_interval; + +  /* Next segment can get another out-of-data warning */ +  entropy->bitstate.printed_eod = FALSE; + +  return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension.  In that case no + * changes have been made to permanent state.  (Exception: some output + * coefficients may already have been assigned.  This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +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; +  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) { +    if (entropy->restarts_to_go == 0) +      if (! process_restart(cinfo)) +	return FALSE; +  } + +  /* Load up working state */ +  BITREAD_LOAD_STATE(cinfo,entropy->bitstate); +  ASSIGN_STATE(state, entropy->saved); + +  /* 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]; +    dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no]; +    actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + +    /* Decode a single block's worth of coefficients */ + +    /* 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); +    } + +    /* Shortcut if component's values are not interesting */ +    if (! compptr->component_needed) +      goto skip_ACs; + +    /* 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; + +    /* Do we need to decode the AC coefficients for this component? */ +    if (compptr->DCT_scaled_size > 1) { + +      /* 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; +       +	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: + +      /* 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; +       +	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); + +  /* Account for restart interval (no-op if not using restarts) */ +  entropy->restarts_to_go--; + +  return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL void +jinit_huff_decoder (j_decompress_ptr cinfo) +{ +  huff_entropy_ptr entropy; +  int i; + +  entropy = (huff_entropy_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(huff_entropy_decoder)); +  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; +  entropy->pub.start_pass = start_pass_huff_decoder; +  entropy->pub.decode_mcu = decode_mcu; + +  /* Mark tables unallocated */ +  for (i = 0; i < NUM_HUFF_TBLS; i++) { +    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +  } +} diff --git a/libs/jpeg6/jdhuff.h b/libs/jpeg6/jdhuff.h index 65f3054..d375c78 100755 --- a/libs/jpeg6/jdhuff.h +++ b/libs/jpeg6/jdhuff.h @@ -1,202 +1,202 @@ -/*
 - * jdhuff.h
 - *
 - * Copyright (C) 1991-1995, 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 declarations for Huffman entropy decoding routines
 - * that are shared between the sequential decoder (jdhuff.c) and the
 - * progressive decoder (jdphuff.c).  No other modules need to see these.
 - */
 -
 -/* Short forms of external names for systems with brain-damaged linkers. */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_make_d_derived_tbl	jMkDDerived
 -#define jpeg_fill_bit_buffer	jFilBitBuf
 -#define jpeg_huff_decode	jHufDecode
 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
 -
 -
 -/* Derived data constructed for each Huffman table */
 -
 -#define HUFF_LOOKAHEAD	8	/* # of bits of lookahead */
 -
 -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 */
 -
 -  /* Link to public Huffman table (needed only in jpeg_huff_decode) */
 -  JHUFF_TBL *pub;
 -
 -  /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
 -   * the input data stream.  If the next Huffman code is no more
 -   * than HUFF_LOOKAHEAD bits long, we can obtain its length and
 -   * the corresponding symbol directly from these tables.
 -   */
 -  int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
 -  UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
 -} 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));
 -
 -
 -/*
 - * Fetching the next N bits from the input stream is a time-critical operation
 - * for the Huffman decoders.  We implement it with a combination of inline
 - * macros and out-of-line subroutines.  Note that N (the number of bits
 - * demanded at one time) never exceeds 15 for JPEG use.
 - *
 - * We read source bytes into get_buffer and dole out bits as needed.
 - * If get_buffer already contains enough bits, they are fetched in-line
 - * by the macros CHECK_BIT_BUFFER and GET_BITS.  When there aren't enough
 - * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
 - * as full as possible (not just to the number of bits needed; this
 - * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
 - * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
 - * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
 - * at least the requested number of bits --- dummy zeroes are inserted if
 - * necessary.
 - */
 -
 -typedef INT32 bit_buf_type;	/* type of bit-extraction buffer */
 -#define BIT_BUF_SIZE  32	/* size of buffer in bits */
 -
 -/* 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)
 - * 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 */
 -  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,
 -   * 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 */
 -  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
 -
 -#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
 -
 -#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
 -
 -/*
 - * These macros provide the in-line portion of bit fetching.
 - * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
 - * before using GET_BITS, PEEK_BITS, or DROP_BITS.
 - * The variables get_buffer and bits_left are assumed to be locals,
 - * but the state struct might not be (jpeg_huff_decode needs this).
 - *	CHECK_BIT_BUFFER(state,n,action);
 - *		Ensure there are N bits in get_buffer; if suspend, take action.
 - *      val = GET_BITS(n);
 - *		Fetch next N bits.
 - *      val = PEEK_BITS(n);
 - *		Fetch next N bits without removing them from the buffer.
 - *	DROP_BITS(n);
 - *		Discard next N bits.
 - * The value N should be a simple variable, not an expression, because it
 - * is evaluated multiple times.
 - */
 -
 -#define CHECK_BIT_BUFFER(state,nbits,action) \
 -	{ if (bits_left < (nbits)) {  \
 -	    if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits))  \
 -	      { action; }  \
 -	    get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
 -
 -#define GET_BITS(nbits) \
 -	(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
 -
 -#define PEEK_BITS(nbits) \
 -	(((int) (get_buffer >> (bits_left -  (nbits)))) & ((1<<(nbits))-1))
 -
 -#define DROP_BITS(nbits) \
 -	(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));
 -
 -
 -/*
 - * Code for extracting next Huffman-coded symbol from input bit stream.
 - * Again, this is time-critical and we make the main paths be macros.
 - *
 - * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
 - * without looping.  Usually, more than 95% of the Huffman codes will be 8
 - * or fewer bits long.  The few overlength codes are handled with a loop,
 - * which need not be inline code.
 - *
 - * Notes about the HUFF_DECODE macro:
 - * 1. Near the end of the data segment, we may fail to get enough bits
 - *    for a lookahead.  In that case, we do it the hard way.
 - * 2. If the lookahead table contains no entry, the next code must be
 - *    more than HUFF_LOOKAHEAD bits long.
 - * 3. jpeg_huff_decode returns -1 if forced to suspend.
 - */
 -
 -#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
 -{ register int nb, look; \
 -  if (bits_left < HUFF_LOOKAHEAD) { \
 -    if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
 -    get_buffer = state.get_buffer; bits_left = state.bits_left; \
 -    if (bits_left < HUFF_LOOKAHEAD) { \
 -      nb = 1; goto slowlabel; \
 -    } \
 -  } \
 -  look = PEEK_BITS(HUFF_LOOKAHEAD); \
 -  if ((nb = htbl->look_nbits[look]) != 0) { \
 -    DROP_BITS(nb); \
 -    result = htbl->look_sym[look]; \
 -  } else { \
 -    nb = HUFF_LOOKAHEAD+1; \
 -slowlabel: \
 -    if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
 -	{ failaction; } \
 -    get_buffer = state.get_buffer; bits_left = state.bits_left; \
 -  } \
 -}
 -
 -/* 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));
 +/* + * jdhuff.h + * + * Copyright (C) 1991-1995, 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 declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c).  No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl	jMkDDerived +#define jpeg_fill_bit_buffer	jFilBitBuf +#define jpeg_huff_decode	jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD	8	/* # of bits of lookahead */ + +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 */ + +  /* Link to public Huffman table (needed only in jpeg_huff_decode) */ +  JHUFF_TBL *pub; + +  /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of +   * the input data stream.  If the next Huffman code is no more +   * than HUFF_LOOKAHEAD bits long, we can obtain its length and +   * the corresponding symbol directly from these tables. +   */ +  int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */ +  UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */ +} 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)); + + +/* + * Fetching the next N bits from the input stream is a time-critical operation + * for the Huffman decoders.  We implement it with a combination of inline + * macros and out-of-line subroutines.  Note that N (the number of bits + * demanded at one time) never exceeds 15 for JPEG use. + * + * We read source bytes into get_buffer and dole out bits as needed. + * If get_buffer already contains enough bits, they are fetched in-line + * by the macros CHECK_BIT_BUFFER and GET_BITS.  When there aren't enough + * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer + * as full as possible (not just to the number of bits needed; this + * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer). + * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension. + * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains + * at least the requested number of bits --- dummy zeroes are inserted if + * necessary. + */ + +typedef INT32 bit_buf_type;	/* type of bit-extraction buffer */ +#define BIT_BUF_SIZE  32	/* size of buffer in bits */ + +/* 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) + * 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 */ +  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, +   * 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 */ +  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 + +#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 + +#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 + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + *	CHECK_BIT_BUFFER(state,n,action); + *		Ensure there are N bits in get_buffer; if suspend, take action. + *      val = GET_BITS(n); + *		Fetch next N bits. + *      val = PEEK_BITS(n); + *		Fetch next N bits without removing them from the buffer. + *	DROP_BITS(n); + *		Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ +	{ if (bits_left < (nbits)) {  \ +	    if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits))  \ +	      { action; }  \ +	    get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ +	(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ +	(((int) (get_buffer >> (bits_left -  (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ +	(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)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping.  Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long.  The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + *    for a lookahead.  In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + *    more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ +  if (bits_left < HUFF_LOOKAHEAD) { \ +    if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ +    get_buffer = state.get_buffer; bits_left = state.bits_left; \ +    if (bits_left < HUFF_LOOKAHEAD) { \ +      nb = 1; goto slowlabel; \ +    } \ +  } \ +  look = PEEK_BITS(HUFF_LOOKAHEAD); \ +  if ((nb = htbl->look_nbits[look]) != 0) { \ +    DROP_BITS(nb); \ +    result = htbl->look_sym[look]; \ +  } else { \ +    nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ +    if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ +	{ failaction; } \ +    get_buffer = state.get_buffer; bits_left = state.bits_left; \ +  } \ +} + +/* 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)); diff --git a/libs/jpeg6/jdinput.cpp b/libs/jpeg6/jdinput.cpp index 5b4774f..3061a17 100755 --- a/libs/jpeg6/jdinput.cpp +++ b/libs/jpeg6/jdinput.cpp @@ -1,381 +1,381 @@ -/*
 - * jdinput.c
 - *
 - * Copyright (C) 1991-1995, 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 input control logic for the JPEG decompressor.
 - * These routines are concerned with controlling the decompressor's input
 - * processing (marker reading and coefficient decoding).  The actual input
 - * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Private state */
 -
 -typedef struct {
 -  struct jpeg_input_controller pub; /* public fields */
 -
 -  boolean inheaders;		/* TRUE until first SOS is reached */
 -} my_input_controller;
 -
 -typedef my_input_controller * my_inputctl_ptr;
 -
 -
 -/* Forward declarations */
 -METHODDEF int consume_markers JPP((j_decompress_ptr cinfo));
 -
 -
 -/*
 - * Routines to calculate various quantities related to the size of the image.
 - */
 -
 -LOCAL void
 -initial_setup (j_decompress_ptr cinfo)
 -/* Called once, when first SOS marker is reached */
 -{
 -  int ci;
 -  jpeg_component_info *compptr;
 -
 -  /* Make sure image isn't bigger than I can handle */
 -  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
 -      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
 -    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
 -
 -  /* For now, precision must match compiled-in value... */
 -  if (cinfo->data_precision != BITS_IN_JSAMPLE)
 -    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
 -
 -  /* Check that number of components won't exceed internal array sizes */
 -  if (cinfo->num_components > MAX_COMPONENTS)
 -    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
 -	     MAX_COMPONENTS);
 -
 -  /* Compute maximum sampling factors; check factor validity */
 -  cinfo->max_h_samp_factor = 1;
 -  cinfo->max_v_samp_factor = 1;
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
 -	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
 -      ERREXIT(cinfo, JERR_BAD_SAMPLING);
 -    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
 -				   compptr->h_samp_factor);
 -    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
 -				   compptr->v_samp_factor);
 -  }
 -
 -  /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
 -   * In the full decompressor, this will be overridden by jdmaster.c;
 -   * but in the transcoder, jdmaster.c is not used, so we must do it here.
 -   */
 -  cinfo->min_DCT_scaled_size = DCTSIZE;
 -
 -  /* Compute dimensions of components */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    compptr->DCT_scaled_size = DCTSIZE;
 -    /* Size in DCT blocks */
 -    compptr->width_in_blocks = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
 -		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
 -    compptr->height_in_blocks = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
 -		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
 -    /* downsampled_width and downsampled_height will also be overridden by
 -     * jdmaster.c if we are doing full decompression.  The transcoder library
 -     * doesn't use these values, but the calling application might.
 -     */
 -    /* Size in samples */
 -    compptr->downsampled_width = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
 -		    (long) cinfo->max_h_samp_factor);
 -    compptr->downsampled_height = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
 -		    (long) cinfo->max_v_samp_factor);
 -    /* Mark component needed, until color conversion says otherwise */
 -    compptr->component_needed = TRUE;
 -    /* Mark no quantization table yet saved for component */
 -    compptr->quant_table = NULL;
 -  }
 -
 -  /* Compute number of fully interleaved MCU rows. */
 -  cinfo->total_iMCU_rows = (JDIMENSION)
 -    jdiv_round_up((long) cinfo->image_height,
 -		  (long) (cinfo->max_v_samp_factor*DCTSIZE));
 -
 -  /* Decide whether file contains multiple scans */
 -  if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
 -    cinfo->inputctl->has_multiple_scans = TRUE;
 -  else
 -    cinfo->inputctl->has_multiple_scans = FALSE;
 -}
 -
 -
 -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 */
 -{
 -  int ci, mcublks, tmp;
 -  jpeg_component_info *compptr;
 -  
 -  if (cinfo->comps_in_scan == 1) {
 -    
 -    /* Noninterleaved (single-component) scan */
 -    compptr = cinfo->cur_comp_info[0];
 -    
 -    /* Overall image size in MCUs */
 -    cinfo->MCUs_per_row = compptr->width_in_blocks;
 -    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
 -    
 -    /* For noninterleaved scan, always one block per MCU */
 -    compptr->MCU_width = 1;
 -    compptr->MCU_height = 1;
 -    compptr->MCU_blocks = 1;
 -    compptr->MCU_sample_width = compptr->DCT_scaled_size;
 -    compptr->last_col_width = 1;
 -    /* For noninterleaved scans, it is convenient to define last_row_height
 -     * as the number of block rows present in the last iMCU row.
 -     */
 -    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
 -    if (tmp == 0) tmp = compptr->v_samp_factor;
 -    compptr->last_row_height = tmp;
 -    
 -    /* Prepare array describing MCU composition */
 -    cinfo->blocks_in_MCU = 1;
 -    cinfo->MCU_membership[0] = 0;
 -    
 -  } else {
 -    
 -    /* Interleaved (multi-component) scan */
 -    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
 -      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
 -	       MAX_COMPS_IN_SCAN);
 -    
 -    /* Overall image size in MCUs */
 -    cinfo->MCUs_per_row = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width,
 -		    (long) (cinfo->max_h_samp_factor*DCTSIZE));
 -    cinfo->MCU_rows_in_scan = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height,
 -		    (long) (cinfo->max_v_samp_factor*DCTSIZE));
 -    
 -    cinfo->blocks_in_MCU = 0;
 -    
 -    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -      compptr = cinfo->cur_comp_info[ci];
 -      /* Sampling factors give # of blocks of component in each MCU */
 -      compptr->MCU_width = compptr->h_samp_factor;
 -      compptr->MCU_height = compptr->v_samp_factor;
 -      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
 -      compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
 -      /* Figure number of non-dummy blocks in last MCU column & row */
 -      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
 -      if (tmp == 0) tmp = compptr->MCU_width;
 -      compptr->last_col_width = tmp;
 -      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
 -      if (tmp == 0) tmp = compptr->MCU_height;
 -      compptr->last_row_height = tmp;
 -      /* Prepare array describing MCU composition */
 -      mcublks = compptr->MCU_blocks;
 -      if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
 -	ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
 -      while (mcublks-- > 0) {
 -	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
 -      }
 -    }
 -    
 -  }
 -}
 -
 -
 -/*
 - * Save away a copy of the Q-table referenced by each component present
 - * in the current scan, unless already saved during a prior scan.
 - *
 - * In a multiple-scan JPEG file, the encoder could assign different components
 - * the same Q-table slot number, but change table definitions between scans
 - * so that each component uses a different Q-table.  (The IJG encoder is not
 - * currently capable of doing this, but other encoders might.)  Since we want
 - * to be able to dequantize all the components at the end of the file, this
 - * means that we have to save away the table actually used for each component.
 - * We do this by copying the table at the start of the first scan containing
 - * the component.
 - * The JPEG spec prohibits the encoder from changing the contents of a Q-table
 - * slot between scans of a component using that slot.  If the encoder does so
 - * anyway, this decoder will simply use the Q-table values that were current
 - * at the start of the first scan for the component.
 - *
 - * The decompressor output side looks only at the saved quant tables,
 - * not at the current Q-table slots.
 - */
 -
 -LOCAL void
 -latch_quant_tables (j_decompress_ptr cinfo)
 -{
 -  int ci, qtblno;
 -  jpeg_component_info *compptr;
 -  JQUANT_TBL * qtbl;
 -
 -  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
 -    compptr = cinfo->cur_comp_info[ci];
 -    /* No work if we already saved Q-table for this component */
 -    if (compptr->quant_table != NULL)
 -      continue;
 -    /* Make sure specified quantization table is present */
 -    qtblno = compptr->quant_tbl_no;
 -    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
 -	cinfo->quant_tbl_ptrs[qtblno] == NULL)
 -      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
 -    /* OK, save away the quantization table */
 -    qtbl = (JQUANT_TBL *)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  SIZEOF(JQUANT_TBL));
 -    MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
 -    compptr->quant_table = qtbl;
 -  }
 -}
 -
 -
 -/*
 - * Initialize the input modules to read a scan of compressed data.
 - * The first call to this is done by jdmaster.c after initializing
 - * the entire decompressor (during jpeg_start_decompress).
 - * Subsequent calls come from consume_markers, below.
 - */
 -
 -METHODDEF void
 -start_input_pass (j_decompress_ptr cinfo)
 -{
 -  per_scan_setup(cinfo);
 -  latch_quant_tables(cinfo);
 -  (*cinfo->entropy->start_pass) (cinfo);
 -  (*cinfo->coef->start_input_pass) (cinfo);
 -  cinfo->inputctl->consume_input = cinfo->coef->consume_data;
 -}
 -
 -
 -/*
 - * Finish up after inputting a compressed-data scan.
 - * This is called by the coefficient controller after it's read all
 - * the expected data of the scan.
 - */
 -
 -METHODDEF void
 -finish_input_pass (j_decompress_ptr cinfo)
 -{
 -  cinfo->inputctl->consume_input = consume_markers;
 -}
 -
 -
 -/*
 - * Read JPEG markers before, between, or after compressed-data scans.
 - * Change state as necessary when a new scan is reached.
 - * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 - *
 - * The consume_input method pointer points either here or to the
 - * coefficient controller's consume_data routine, depending on whether
 - * we are reading a compressed data segment or inter-segment markers.
 - */
 -
 -METHODDEF int
 -consume_markers (j_decompress_ptr cinfo)
 -{
 -  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
 -  int val;
 -
 -  if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
 -    return JPEG_REACHED_EOI;
 -
 -  val = (*cinfo->marker->read_markers) (cinfo);
 -
 -  switch (val) {
 -  case JPEG_REACHED_SOS:	/* Found SOS */
 -    if (inputctl->inheaders) {	/* 1st SOS */
 -      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
 -       * responsible for enforcing this sequencing.
 -       */
 -    } else {			/* 2nd or later SOS marker */
 -      if (! inputctl->pub.has_multiple_scans)
 -	ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
 -      start_input_pass(cinfo);
 -    }
 -    break;
 -  case JPEG_REACHED_EOI:	/* Found EOI */
 -    inputctl->pub.eoi_reached = TRUE;
 -    if (inputctl->inheaders) {	/* Tables-only datastream, apparently */
 -      if (cinfo->marker->saw_SOF)
 -	ERREXIT(cinfo, JERR_SOF_NO_SOS);
 -    } else {
 -      /* Prevent infinite loop in coef ctlr's decompress_data routine
 -       * if user set output_scan_number larger than number of scans.
 -       */
 -      if (cinfo->output_scan_number > cinfo->input_scan_number)
 -	cinfo->output_scan_number = cinfo->input_scan_number;
 -    }
 -    break;
 -  case JPEG_SUSPENDED:
 -    break;
 -  }
 -
 -  return val;
 -}
 -
 -
 -/*
 - * Reset state to begin a fresh datastream.
 - */
 -
 -METHODDEF void
 -reset_input_controller (j_decompress_ptr cinfo)
 -{
 -  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
 -
 -  inputctl->pub.consume_input = consume_markers;
 -  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
 -  inputctl->pub.eoi_reached = FALSE;
 -  inputctl->inheaders = TRUE;
 -  /* Reset other modules */
 -  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
 -  (*cinfo->marker->reset_marker_reader) (cinfo);
 -  /* Reset progression state -- would be cleaner if entropy decoder did this */
 -  cinfo->coef_bits = NULL;
 -}
 -
 -
 -/*
 - * Initialize the input controller module.
 - * This is called only once, when the decompression object is created.
 - */
 -
 -GLOBAL void
 -jinit_input_controller (j_decompress_ptr cinfo)
 -{
 -  my_inputctl_ptr inputctl;
 -
 -  /* Create subobject in permanent pool */
 -  inputctl = (my_inputctl_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
 -				SIZEOF(my_input_controller));
 -  cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
 -  /* Initialize method pointers */
 -  inputctl->pub.consume_input = consume_markers;
 -  inputctl->pub.reset_input_controller = reset_input_controller;
 -  inputctl->pub.start_input_pass = start_input_pass;
 -  inputctl->pub.finish_input_pass = finish_input_pass;
 -  /* Initialize state: can't use reset_input_controller since we don't
 -   * want to try to reset other modules yet.
 -   */
 -  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
 -  inputctl->pub.eoi_reached = FALSE;
 -  inputctl->inheaders = TRUE;
 -}
 +/* + * jdinput.c + * + * Copyright (C) 1991-1995, 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 input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding).  The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { +  struct jpeg_input_controller pub; /* public fields */ + +  boolean inheaders;		/* TRUE until first SOS is reached */ +} my_input_controller; + +typedef my_input_controller * my_inputctl_ptr; + + +/* Forward declarations */ +METHODDEF int consume_markers JPP((j_decompress_ptr cinfo)); + + +/* + * Routines to calculate various quantities related to the size of the image. + */ + +LOCAL void +initial_setup (j_decompress_ptr cinfo) +/* Called once, when first SOS marker is reached */ +{ +  int ci; +  jpeg_component_info *compptr; + +  /* Make sure image isn't bigger than I can handle */ +  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || +      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + +  /* For now, precision must match compiled-in value... */ +  if (cinfo->data_precision != BITS_IN_JSAMPLE) +    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + +  /* Check that number of components won't exceed internal array sizes */ +  if (cinfo->num_components > MAX_COMPONENTS) +    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, +	     MAX_COMPONENTS); + +  /* Compute maximum sampling factors; check factor validity */ +  cinfo->max_h_samp_factor = 1; +  cinfo->max_v_samp_factor = 1; +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || +	compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) +      ERREXIT(cinfo, JERR_BAD_SAMPLING); +    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, +				   compptr->h_samp_factor); +    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, +				   compptr->v_samp_factor); +  } + +  /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. +   * In the full decompressor, this will be overridden by jdmaster.c; +   * but in the transcoder, jdmaster.c is not used, so we must do it here. +   */ +  cinfo->min_DCT_scaled_size = DCTSIZE; + +  /* Compute dimensions of components */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    compptr->DCT_scaled_size = DCTSIZE; +    /* Size in DCT blocks */ +    compptr->width_in_blocks = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, +		    (long) (cinfo->max_h_samp_factor * DCTSIZE)); +    compptr->height_in_blocks = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, +		    (long) (cinfo->max_v_samp_factor * DCTSIZE)); +    /* downsampled_width and downsampled_height will also be overridden by +     * jdmaster.c if we are doing full decompression.  The transcoder library +     * doesn't use these values, but the calling application might. +     */ +    /* Size in samples */ +    compptr->downsampled_width = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, +		    (long) cinfo->max_h_samp_factor); +    compptr->downsampled_height = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, +		    (long) cinfo->max_v_samp_factor); +    /* Mark component needed, until color conversion says otherwise */ +    compptr->component_needed = TRUE; +    /* Mark no quantization table yet saved for component */ +    compptr->quant_table = NULL; +  } + +  /* Compute number of fully interleaved MCU rows. */ +  cinfo->total_iMCU_rows = (JDIMENSION) +    jdiv_round_up((long) cinfo->image_height, +		  (long) (cinfo->max_v_samp_factor*DCTSIZE)); + +  /* Decide whether file contains multiple scans */ +  if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) +    cinfo->inputctl->has_multiple_scans = TRUE; +  else +    cinfo->inputctl->has_multiple_scans = FALSE; +} + + +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 */ +{ +  int ci, mcublks, tmp; +  jpeg_component_info *compptr; +   +  if (cinfo->comps_in_scan == 1) { +     +    /* Noninterleaved (single-component) scan */ +    compptr = cinfo->cur_comp_info[0]; +     +    /* Overall image size in MCUs */ +    cinfo->MCUs_per_row = compptr->width_in_blocks; +    cinfo->MCU_rows_in_scan = compptr->height_in_blocks; +     +    /* For noninterleaved scan, always one block per MCU */ +    compptr->MCU_width = 1; +    compptr->MCU_height = 1; +    compptr->MCU_blocks = 1; +    compptr->MCU_sample_width = compptr->DCT_scaled_size; +    compptr->last_col_width = 1; +    /* For noninterleaved scans, it is convenient to define last_row_height +     * as the number of block rows present in the last iMCU row. +     */ +    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); +    if (tmp == 0) tmp = compptr->v_samp_factor; +    compptr->last_row_height = tmp; +     +    /* Prepare array describing MCU composition */ +    cinfo->blocks_in_MCU = 1; +    cinfo->MCU_membership[0] = 0; +     +  } else { +     +    /* Interleaved (multi-component) scan */ +    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, +	       MAX_COMPS_IN_SCAN); +     +    /* Overall image size in MCUs */ +    cinfo->MCUs_per_row = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width, +		    (long) (cinfo->max_h_samp_factor*DCTSIZE)); +    cinfo->MCU_rows_in_scan = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height, +		    (long) (cinfo->max_v_samp_factor*DCTSIZE)); +     +    cinfo->blocks_in_MCU = 0; +     +    for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +      compptr = cinfo->cur_comp_info[ci]; +      /* Sampling factors give # of blocks of component in each MCU */ +      compptr->MCU_width = compptr->h_samp_factor; +      compptr->MCU_height = compptr->v_samp_factor; +      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; +      compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; +      /* Figure number of non-dummy blocks in last MCU column & row */ +      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); +      if (tmp == 0) tmp = compptr->MCU_width; +      compptr->last_col_width = tmp; +      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); +      if (tmp == 0) tmp = compptr->MCU_height; +      compptr->last_row_height = tmp; +      /* Prepare array describing MCU composition */ +      mcublks = compptr->MCU_blocks; +      if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) +	ERREXIT(cinfo, JERR_BAD_MCU_SIZE); +      while (mcublks-- > 0) { +	cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; +      } +    } +     +  } +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table.  (The IJG encoder is not + * currently capable of doing this, but other encoders might.)  Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot.  If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL void +latch_quant_tables (j_decompress_ptr cinfo) +{ +  int ci, qtblno; +  jpeg_component_info *compptr; +  JQUANT_TBL * qtbl; + +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) { +    compptr = cinfo->cur_comp_info[ci]; +    /* No work if we already saved Q-table for this component */ +    if (compptr->quant_table != NULL) +      continue; +    /* Make sure specified quantization table is present */ +    qtblno = compptr->quant_tbl_no; +    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || +	cinfo->quant_tbl_ptrs[qtblno] == NULL) +      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); +    /* OK, save away the quantization table */ +    qtbl = (JQUANT_TBL *) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  SIZEOF(JQUANT_TBL)); +    MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); +    compptr->quant_table = qtbl; +  } +} + + +/* + * Initialize the input modules to read a scan of compressed data. + * The first call to this is done by jdmaster.c after initializing + * the entire decompressor (during jpeg_start_decompress). + * Subsequent calls come from consume_markers, below. + */ + +METHODDEF void +start_input_pass (j_decompress_ptr cinfo) +{ +  per_scan_setup(cinfo); +  latch_quant_tables(cinfo); +  (*cinfo->entropy->start_pass) (cinfo); +  (*cinfo->coef->start_input_pass) (cinfo); +  cinfo->inputctl->consume_input = cinfo->coef->consume_data; +} + + +/* + * Finish up after inputting a compressed-data scan. + * This is called by the coefficient controller after it's read all + * the expected data of the scan. + */ + +METHODDEF void +finish_input_pass (j_decompress_ptr cinfo) +{ +  cinfo->inputctl->consume_input = consume_markers; +} + + +/* + * Read JPEG markers before, between, or after compressed-data scans. + * Change state as necessary when a new scan is reached. + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * The consume_input method pointer points either here or to the + * coefficient controller's consume_data routine, depending on whether + * we are reading a compressed data segment or inter-segment markers. + */ + +METHODDEF int +consume_markers (j_decompress_ptr cinfo) +{ +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; +  int val; + +  if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ +    return JPEG_REACHED_EOI; + +  val = (*cinfo->marker->read_markers) (cinfo); + +  switch (val) { +  case JPEG_REACHED_SOS:	/* Found SOS */ +    if (inputctl->inheaders) {	/* 1st SOS */ +      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 +       * responsible for enforcing this sequencing. +       */ +    } else {			/* 2nd or later SOS marker */ +      if (! inputctl->pub.has_multiple_scans) +	ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ +      start_input_pass(cinfo); +    } +    break; +  case JPEG_REACHED_EOI:	/* Found EOI */ +    inputctl->pub.eoi_reached = TRUE; +    if (inputctl->inheaders) {	/* Tables-only datastream, apparently */ +      if (cinfo->marker->saw_SOF) +	ERREXIT(cinfo, JERR_SOF_NO_SOS); +    } else { +      /* Prevent infinite loop in coef ctlr's decompress_data routine +       * if user set output_scan_number larger than number of scans. +       */ +      if (cinfo->output_scan_number > cinfo->input_scan_number) +	cinfo->output_scan_number = cinfo->input_scan_number; +    } +    break; +  case JPEG_SUSPENDED: +    break; +  } + +  return val; +} + + +/* + * Reset state to begin a fresh datastream. + */ + +METHODDEF void +reset_input_controller (j_decompress_ptr cinfo) +{ +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + +  inputctl->pub.consume_input = consume_markers; +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ +  inputctl->pub.eoi_reached = FALSE; +  inputctl->inheaders = TRUE; +  /* Reset other modules */ +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); +  (*cinfo->marker->reset_marker_reader) (cinfo); +  /* Reset progression state -- would be cleaner if entropy decoder did this */ +  cinfo->coef_bits = NULL; +} + + +/* + * Initialize the input controller module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL void +jinit_input_controller (j_decompress_ptr cinfo) +{ +  my_inputctl_ptr inputctl; + +  /* Create subobject in permanent pool */ +  inputctl = (my_inputctl_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, +				SIZEOF(my_input_controller)); +  cinfo->inputctl = (struct jpeg_input_controller *) inputctl; +  /* Initialize method pointers */ +  inputctl->pub.consume_input = consume_markers; +  inputctl->pub.reset_input_controller = reset_input_controller; +  inputctl->pub.start_input_pass = start_input_pass; +  inputctl->pub.finish_input_pass = finish_input_pass; +  /* Initialize state: can't use reset_input_controller since we don't +   * want to try to reset other modules yet. +   */ +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ +  inputctl->pub.eoi_reached = FALSE; +  inputctl->inheaders = TRUE; +} diff --git a/libs/jpeg6/jdmainct.cpp b/libs/jpeg6/jdmainct.cpp index c4e0d54..f3a06e5 100755 --- a/libs/jpeg6/jdmainct.cpp +++ b/libs/jpeg6/jdmainct.cpp @@ -1,512 +1,512 @@ -/*
 - * jdmainct.c
 - *
 - * Copyright (C) 1994-1995, 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 the main buffer controller for decompression.
 - * The main buffer lies between the JPEG decompressor proper and the
 - * post-processor; it holds downsampled data in the JPEG colorspace.
 - *
 - * Note that this code is bypassed in raw-data mode, since the application
 - * supplies the equivalent of the main buffer in that case.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/*
 - * In the current system design, the main buffer need never be a full-image
 - * buffer; any full-height buffers will be found inside the coefficient or
 - * postprocessing controllers.  Nonetheless, the main controller is not
 - * trivial.  Its responsibility is to provide context rows for upsampling/
 - * rescaling, and doing this in an efficient fashion is a bit tricky.
 - *
 - * Postprocessor input data is counted in "row groups".  A row group
 - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
 - * sample rows of each component.  (We require DCT_scaled_size values to be
 - * chosen such that these numbers are integers.  In practice DCT_scaled_size
 - * values will likely be powers of two, so we actually have the stronger
 - * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
 - * Upsampling will typically produce max_v_samp_factor pixel rows from each
 - * row group (times any additional scale factor that the upsampler is
 - * applying).
 - *
 - * The coefficient controller will deliver data to us one iMCU row at a time;
 - * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
 - * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds
 - * to one row of MCUs when the image is fully interleaved.)  Note that the
 - * number of sample rows varies across components, but the number of row
 - * groups does not.  Some garbage sample rows may be included in the last iMCU
 - * row at the bottom of the image.
 - *
 - * Depending on the vertical scaling algorithm used, the upsampler may need
 - * access to the sample row(s) above and below its current input row group.
 - * The upsampler is required to set need_context_rows TRUE at global selection
 - * time if so.  When need_context_rows is FALSE, this controller can simply
 - * obtain one iMCU row at a time from the coefficient controller and dole it
 - * out as row groups to the postprocessor.
 - *
 - * When need_context_rows is TRUE, this controller guarantees that the buffer
 - * passed to postprocessing contains at least one row group's worth of samples
 - * above and below the row group(s) being processed.  Note that the context
 - * rows "above" the first passed row group appear at negative row offsets in
 - * the passed buffer.  At the top and bottom of the image, the required
 - * context rows are manufactured by duplicating the first or last real sample
 - * row; this avoids having special cases in the upsampling inner loops.
 - *
 - * The amount of context is fixed at one row group just because that's a
 - * convenient number for this controller to work with.  The existing
 - * upsamplers really only need one sample row of context.  An upsampler
 - * supporting arbitrary output rescaling might wish for more than one row
 - * group of context when shrinking the image; tough, we don't handle that.
 - * (This is justified by the assumption that downsizing will be handled mostly
 - * by adjusting the DCT_scaled_size values, so that the actual scale factor at
 - * the upsample step needn't be much less than one.)
 - *
 - * To provide the desired context, we have to retain the last two row groups
 - * of one iMCU row while reading in the next iMCU row.  (The last row group
 - * can't be processed until we have another row group for its below-context,
 - * and so we have to save the next-to-last group too for its above-context.)
 - * We could do this most simply by copying data around in our buffer, but
 - * that'd be very slow.  We can avoid copying any data by creating a rather
 - * strange pointer structure.  Here's how it works.  We allocate a workspace
 - * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
 - * of row groups per iMCU row).  We create two sets of redundant pointers to
 - * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
 - * pointer lists look like this:
 - *                   M+1                          M-1
 - * master pointer --> 0         master pointer --> 0
 - *                    1                            1
 - *                   ...                          ...
 - *                   M-3                          M-3
 - *                   M-2                           M
 - *                   M-1                          M+1
 - *                    M                           M-2
 - *                   M+1                          M-1
 - *                    0                            0
 - * We read alternate iMCU rows using each master pointer; thus the last two
 - * row groups of the previous iMCU row remain un-overwritten in the workspace.
 - * The pointer lists are set up so that the required context rows appear to
 - * be adjacent to the proper places when we pass the pointer lists to the
 - * upsampler.
 - *
 - * The above pictures describe the normal state of the pointer lists.
 - * At top and bottom of the image, we diddle the pointer lists to duplicate
 - * the first or last sample row as necessary (this is cheaper than copying
 - * sample rows around).
 - *
 - * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
 - * situation each iMCU row provides only one row group so the buffering logic
 - * must be different (eg, we must read two iMCU rows before we can emit the
 - * first row group).  For now, we simply do not support providing context
 - * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
 - * be worth providing --- if someone wants a 1/8th-size preview, they probably
 - * want it quick and dirty, so a context-free upsampler is sufficient.
 - */
 -
 -
 -/* Private buffer controller object */
 -
 -typedef struct {
 -  struct jpeg_d_main_controller pub; /* public fields */
 -
 -  /* Pointer to allocated workspace (M or M+2 row groups). */
 -  JSAMPARRAY buffer[MAX_COMPONENTS];
 -
 -  boolean buffer_full;		/* Have we gotten an iMCU row from decoder? */
 -  JDIMENSION rowgroup_ctr;	/* counts row groups output to postprocessor */
 -
 -  /* Remaining fields are only used in the context case. */
 -
 -  /* These are the master pointers to the funny-order pointer lists. */
 -  JSAMPIMAGE xbuffer[2];	/* pointers to weird pointer lists */
 -
 -  int whichptr;			/* indicates which pointer set is now in use */
 -  int context_state;		/* process_data state machine status */
 -  JDIMENSION rowgroups_avail;	/* row groups available to postprocessor */
 -  JDIMENSION iMCU_row_ctr;	/* counts iMCU rows to detect image top/bot */
 -} my_main_controller;
 -
 -typedef my_main_controller * my_main_ptr;
 -
 -/* context_state values: */
 -#define CTX_PREPARE_FOR_IMCU	0	/* need to prepare for MCU row */
 -#define CTX_PROCESS_IMCU	1	/* feeding iMCU to postprocessor */
 -#define CTX_POSTPONED_ROW	2	/* feeding postponed row group */
 -
 -
 -/* Forward declarations */
 -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
 -	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
 -	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
 -	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
 -#endif
 -
 -
 -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.
 - */
 -{
 -  my_main_ptr main = (my_main_ptr) cinfo->main;
 -  int ci, rgroup;
 -  int M = cinfo->min_DCT_scaled_size;
 -  jpeg_component_info *compptr;
 -  JSAMPARRAY xbuf;
 -
 -  /* Get top-level space for component array pointers.
 -   * We alloc both arrays with one call to save a few cycles.
 -   */
 -  main->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;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 -      cinfo->min_DCT_scaled_size; /* height of a row group of component */
 -    /* Get space for pointer lists --- M+4 row groups in each list.
 -     * We alloc both pointer lists with one call to save a few cycles.
 -     */
 -    xbuf = (JSAMPARRAY)
 -      (*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;
 -    xbuf += rgroup * (M + 4);
 -    main->xbuffer[1][ci] = xbuf;
 -  }
 -}
 -
 -
 -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),
 - * 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;
 -  int ci, i, rgroup;
 -  int M = cinfo->min_DCT_scaled_size;
 -  jpeg_component_info *compptr;
 -  JSAMPARRAY buf, xbuf0, xbuf1;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       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];
 -    /* First copy the workspace pointers as-is */
 -    buf = main->buffer[ci];
 -    for (i = 0; i < rgroup * (M + 2); i++) {
 -      xbuf0[i] = xbuf1[i] = buf[i];
 -    }
 -    /* In the second list, put the last four row groups in swapped order */
 -    for (i = 0; i < rgroup * 2; i++) {
 -      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
 -      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
 -    }
 -    /* The wraparound pointers at top and bottom will be filled later
 -     * (see set_wraparound_pointers, below).  Initially we want the "above"
 -     * pointers to duplicate the first actual data line.  This only needs
 -     * to happen in xbuffer[0].
 -     */
 -    for (i = 0; i < rgroup; i++) {
 -      xbuf0[i - rgroup] = xbuf0[0];
 -    }
 -  }
 -}
 -
 -
 -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.
 - */
 -{
 -  my_main_ptr main = (my_main_ptr) cinfo->main;
 -  int ci, i, rgroup;
 -  int M = cinfo->min_DCT_scaled_size;
 -  jpeg_component_info *compptr;
 -  JSAMPARRAY xbuf0, xbuf1;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       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];
 -    for (i = 0; i < rgroup; i++) {
 -      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
 -      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
 -      xbuf0[rgroup*(M+2) + i] = xbuf0[i];
 -      xbuf1[rgroup*(M+2) + i] = xbuf1[i];
 -    }
 -  }
 -}
 -
 -
 -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.
 - * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
 - */
 -{
 -  my_main_ptr main = (my_main_ptr) cinfo->main;
 -  int ci, i, rgroup, iMCUheight, rows_left;
 -  jpeg_component_info *compptr;
 -  JSAMPARRAY xbuf;
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Count sample rows in one iMCU row and in one row group */
 -    iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
 -    rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
 -    /* Count nondummy sample rows remaining for this component */
 -    rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
 -    if (rows_left == 0) rows_left = iMCUheight;
 -    /* Count nondummy row groups.  Should get same answer for each component,
 -     * so we need only do it once.
 -     */
 -    if (ci == 0) {
 -      main->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];
 -    for (i = 0; i < rgroup * 2; i++) {
 -      xbuf[rows_left + i] = xbuf[rows_left-1];
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Initialize for a processing pass.
 - */
 -
 -METHODDEF void
 -start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
 -{
 -  my_main_ptr main = (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;
 -      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;
 -    } else {
 -      /* Simple case with no context needed */
 -      main->pub.process_data = process_data_simple_main;
 -    }
 -    main->buffer_full = FALSE;	/* Mark buffer empty */
 -    main->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;
 -    break;
 -#endif
 -  default:
 -    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -    break;
 -  }
 -}
 -
 -
 -/*
 - * Process some data.
 - * This handles the simple case where no context is required.
 - */
 -
 -METHODDEF void
 -process_data_simple_main (j_decompress_ptr cinfo,
 -			  JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 -			  JDIMENSION out_rows_avail)
 -{
 -  my_main_ptr main = (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))
 -      return;			/* suspension forced, can do nothing more */
 -    main->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. */
 -  rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
 -  /* Note: at the bottom of the image, we may pass extra garbage row groups
 -   * to the postprocessor.  The postprocessor has to check for bottom
 -   * of image anyway (at row resolution), so no point in us doing it too.
 -   */
 -
 -  /* Feed the postprocessor */
 -  (*cinfo->post->post_process_data) (cinfo, main->buffer,
 -				     &main->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;
 -  }
 -}
 -
 -
 -/*
 - * Process some data.
 - * This handles the case where context rows must be provided.
 - */
 -
 -METHODDEF void
 -process_data_context_main (j_decompress_ptr cinfo,
 -			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 -			   JDIMENSION out_rows_avail)
 -{
 -  my_main_ptr main = (my_main_ptr) cinfo->main;
 -
 -  /* Read input data if we haven't filled the main buffer yet */
 -  if (! main->buffer_full) {
 -    if (! (*cinfo->coef->decompress_data) (cinfo,
 -					   main->xbuffer[main->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 */
 -  }
 -
 -  /* Postprocessor typically will not swallow all the input data it is handed
 -   * in one call (due to filling the output buffer first).  Must be prepared
 -   * 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) {
 -  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,
 -			output_buf, out_row_ctr, out_rows_avail);
 -    if (main->rowgroup_ctr < main->rowgroups_avail)
 -      return;			/* Need to suspend */
 -    main->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);
 -    /* 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)
 -      set_bottom_pointers(cinfo);
 -    main->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,
 -			output_buf, out_row_ctr, out_rows_avail);
 -    if (main->rowgroup_ctr < main->rowgroups_avail)
 -      return;			/* Need to suspend */
 -    /* After the first iMCU, change wraparound pointers to normal state */
 -    if (main->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;
 -    /* 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;
 -  }
 -}
 -
 -
 -/*
 - * Process some data.
 - * Final pass of two-pass quantization: just call the postprocessor.
 - * Source data will be the postprocessor controller's internal buffer.
 - */
 -
 -#ifdef QUANT_2PASS_SUPPORTED
 -
 -METHODDEF void
 -process_data_crank_post (j_decompress_ptr cinfo,
 -			 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 -			 JDIMENSION out_rows_avail)
 -{
 -  (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
 -				     (JDIMENSION *) NULL, (JDIMENSION) 0,
 -				     output_buf, out_row_ctr, out_rows_avail);
 -}
 -
 -#endif /* QUANT_2PASS_SUPPORTED */
 -
 -
 -/*
 - * Initialize main buffer controller.
 - */
 -
 -GLOBAL void
 -jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 -{
 -  my_main_ptr main;
 -  int ci, rgroup, ngroups;
 -  jpeg_component_info *compptr;
 -
 -  main = (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;
 -
 -  if (need_full_buffer)		/* shouldn't happen */
 -    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -
 -  /* Allocate the workspace.
 -   * ngroups is the number of row groups we need.
 -   */
 -  if (cinfo->upsample->need_context_rows) {
 -    if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
 -      ERREXIT(cinfo, JERR_NOTIMPL);
 -    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
 -    ngroups = cinfo->min_DCT_scaled_size + 2;
 -  } else {
 -    ngroups = cinfo->min_DCT_scaled_size;
 -  }
 -
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       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)
 -			((j_common_ptr) cinfo, JPOOL_IMAGE,
 -			 compptr->width_in_blocks * compptr->DCT_scaled_size,
 -			 (JDIMENSION) (rgroup * ngroups));
 -  }
 -}
 +/* + * jdmainct.c + * + * Copyright (C) 1994-1995, 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 the main buffer controller for decompression. + * The main buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers.  Nonetheless, the main controller is not + * trivial.  Its responsibility is to provide context rows for upsampling/ + * rescaling, and doing this in an efficient fashion is a bit tricky. + * + * Postprocessor input data is counted in "row groups".  A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component.  (We require DCT_scaled_size values to be + * chosen such that these numbers are integers.  In practice DCT_scaled_size + * values will likely be powers of two, so we actually have the stronger + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * Upsampling will typically produce max_v_samp_factor pixel rows from each + * row group (times any additional scale factor that the upsampler is + * applying). + * + * The coefficient controller will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds + * to one row of MCUs when the image is fully interleaved.)  Note that the + * number of sample rows varies across components, but the number of row + * groups does not.  Some garbage sample rows may be included in the last iMCU + * row at the bottom of the image. + * + * Depending on the vertical scaling algorithm used, the upsampler may need + * access to the sample row(s) above and below its current input row group. + * The upsampler is required to set need_context_rows TRUE at global selection + * time if so.  When need_context_rows is FALSE, this controller can simply + * obtain one iMCU row at a time from the coefficient controller and dole it + * out as row groups to the postprocessor. + * + * When need_context_rows is TRUE, this controller guarantees that the buffer + * passed to postprocessing contains at least one row group's worth of samples + * above and below the row group(s) being processed.  Note that the context + * rows "above" the first passed row group appear at negative row offsets in + * the passed buffer.  At the top and bottom of the image, the required + * context rows are manufactured by duplicating the first or last real sample + * row; this avoids having special cases in the upsampling inner loops. + * + * The amount of context is fixed at one row group just because that's a + * convenient number for this controller to work with.  The existing + * upsamplers really only need one sample row of context.  An upsampler + * supporting arbitrary output rescaling might wish for more than one row + * group of context when shrinking the image; tough, we don't handle that. + * (This is justified by the assumption that downsizing will be handled mostly + * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * the upsample step needn't be much less than one.) + * + * To provide the desired context, we have to retain the last two row groups + * of one iMCU row while reading in the next iMCU row.  (The last row group + * can't be processed until we have another row group for its below-context, + * and so we have to save the next-to-last group too for its above-context.) + * We could do this most simply by copying data around in our buffer, but + * that'd be very slow.  We can avoid copying any data by creating a rather + * strange pointer structure.  Here's how it works.  We allocate a workspace + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * of row groups per iMCU row).  We create two sets of redundant pointers to + * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized + * pointer lists look like this: + *                   M+1                          M-1 + * master pointer --> 0         master pointer --> 0 + *                    1                            1 + *                   ...                          ... + *                   M-3                          M-3 + *                   M-2                           M + *                   M-1                          M+1 + *                    M                           M-2 + *                   M+1                          M-1 + *                    0                            0 + * We read alternate iMCU rows using each master pointer; thus the last two + * row groups of the previous iMCU row remain un-overwritten in the workspace. + * The pointer lists are set up so that the required context rows appear to + * be adjacent to the proper places when we pass the pointer lists to the + * upsampler. + * + * The above pictures describe the normal state of the pointer lists. + * At top and bottom of the image, we diddle the pointer lists to duplicate + * the first or last sample row as necessary (this is cheaper than copying + * sample rows around). + * + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that + * situation each iMCU row provides only one row group so the buffering logic + * must be different (eg, we must read two iMCU rows before we can emit the + * first row group).  For now, we simply do not support providing context + * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to + * be worth providing --- if someone wants a 1/8th-size preview, they probably + * want it quick and dirty, so a context-free upsampler is sufficient. + */ + + +/* Private buffer controller object */ + +typedef struct { +  struct jpeg_d_main_controller pub; /* public fields */ + +  /* Pointer to allocated workspace (M or M+2 row groups). */ +  JSAMPARRAY buffer[MAX_COMPONENTS]; + +  boolean buffer_full;		/* Have we gotten an iMCU row from decoder? */ +  JDIMENSION rowgroup_ctr;	/* counts row groups output to postprocessor */ + +  /* Remaining fields are only used in the context case. */ + +  /* These are the master pointers to the funny-order pointer lists. */ +  JSAMPIMAGE xbuffer[2];	/* pointers to weird pointer lists */ + +  int whichptr;			/* indicates which pointer set is now in use */ +  int context_state;		/* process_data state machine status */ +  JDIMENSION rowgroups_avail;	/* row groups available to postprocessor */ +  JDIMENSION iMCU_row_ctr;	/* counts iMCU rows to detect image top/bot */ +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + +/* context_state values: */ +#define CTX_PREPARE_FOR_IMCU	0	/* need to prepare for MCU row */ +#define CTX_PROCESS_IMCU	1	/* feeding iMCU to postprocessor */ +#define CTX_POSTPONED_ROW	2	/* feeding postponed row group */ + + +/* Forward declarations */ +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 +	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 +	JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, +	     JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#endif + + +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. + */ +{ +  my_main_ptr main = (my_main_ptr) cinfo->main; +  int ci, rgroup; +  int M = cinfo->min_DCT_scaled_size; +  jpeg_component_info *compptr; +  JSAMPARRAY xbuf; + +  /* Get top-level space for component array pointers. +   * We alloc both arrays with one call to save a few cycles. +   */ +  main->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; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / +      cinfo->min_DCT_scaled_size; /* height of a row group of component */ +    /* Get space for pointer lists --- M+4 row groups in each list. +     * We alloc both pointer lists with one call to save a few cycles. +     */ +    xbuf = (JSAMPARRAY) +      (*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; +    xbuf += rgroup * (M + 4); +    main->xbuffer[1][ci] = xbuf; +  } +} + + +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), + * 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; +  int ci, i, rgroup; +  int M = cinfo->min_DCT_scaled_size; +  jpeg_component_info *compptr; +  JSAMPARRAY buf, xbuf0, xbuf1; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       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]; +    /* First copy the workspace pointers as-is */ +    buf = main->buffer[ci]; +    for (i = 0; i < rgroup * (M + 2); i++) { +      xbuf0[i] = xbuf1[i] = buf[i]; +    } +    /* In the second list, put the last four row groups in swapped order */ +    for (i = 0; i < rgroup * 2; i++) { +      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; +      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; +    } +    /* The wraparound pointers at top and bottom will be filled later +     * (see set_wraparound_pointers, below).  Initially we want the "above" +     * pointers to duplicate the first actual data line.  This only needs +     * to happen in xbuffer[0]. +     */ +    for (i = 0; i < rgroup; i++) { +      xbuf0[i - rgroup] = xbuf0[0]; +    } +  } +} + + +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. + */ +{ +  my_main_ptr main = (my_main_ptr) cinfo->main; +  int ci, i, rgroup; +  int M = cinfo->min_DCT_scaled_size; +  jpeg_component_info *compptr; +  JSAMPARRAY xbuf0, xbuf1; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       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]; +    for (i = 0; i < rgroup; i++) { +      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; +      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; +      xbuf0[rgroup*(M+2) + i] = xbuf0[i]; +      xbuf1[rgroup*(M+2) + i] = xbuf1[i]; +    } +  } +} + + +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. + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ +{ +  my_main_ptr main = (my_main_ptr) cinfo->main; +  int ci, i, rgroup, iMCUheight, rows_left; +  jpeg_component_info *compptr; +  JSAMPARRAY xbuf; + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Count sample rows in one iMCU row and in one row group */ +    iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; +    rgroup = iMCUheight / cinfo->min_DCT_scaled_size; +    /* Count nondummy sample rows remaining for this component */ +    rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); +    if (rows_left == 0) rows_left = iMCUheight; +    /* Count nondummy row groups.  Should get same answer for each component, +     * so we need only do it once. +     */ +    if (ci == 0) { +      main->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]; +    for (i = 0; i < rgroup * 2; i++) { +      xbuf[rows_left + i] = xbuf[rows_left-1]; +    } +  } +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ +  my_main_ptr main = (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; +      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; +    } else { +      /* Simple case with no context needed */ +      main->pub.process_data = process_data_simple_main; +    } +    main->buffer_full = FALSE;	/* Mark buffer empty */ +    main->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; +    break; +#endif +  default: +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +    break; +  } +} + + +/* + * Process some data. + * This handles the simple case where no context is required. + */ + +METHODDEF void +process_data_simple_main (j_decompress_ptr cinfo, +			  JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, +			  JDIMENSION out_rows_avail) +{ +  my_main_ptr main = (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)) +      return;			/* suspension forced, can do nothing more */ +    main->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. */ +  rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; +  /* Note: at the bottom of the image, we may pass extra garbage row groups +   * to the postprocessor.  The postprocessor has to check for bottom +   * of image anyway (at row resolution), so no point in us doing it too. +   */ + +  /* Feed the postprocessor */ +  (*cinfo->post->post_process_data) (cinfo, main->buffer, +				     &main->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; +  } +} + + +/* + * Process some data. + * This handles the case where context rows must be provided. + */ + +METHODDEF void +process_data_context_main (j_decompress_ptr cinfo, +			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, +			   JDIMENSION out_rows_avail) +{ +  my_main_ptr main = (my_main_ptr) cinfo->main; + +  /* Read input data if we haven't filled the main buffer yet */ +  if (! main->buffer_full) { +    if (! (*cinfo->coef->decompress_data) (cinfo, +					   main->xbuffer[main->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 */ +  } + +  /* Postprocessor typically will not swallow all the input data it is handed +   * in one call (due to filling the output buffer first).  Must be prepared +   * 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) { +  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, +			output_buf, out_row_ctr, out_rows_avail); +    if (main->rowgroup_ctr < main->rowgroups_avail) +      return;			/* Need to suspend */ +    main->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); +    /* 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) +      set_bottom_pointers(cinfo); +    main->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, +			output_buf, out_row_ctr, out_rows_avail); +    if (main->rowgroup_ctr < main->rowgroups_avail) +      return;			/* Need to suspend */ +    /* After the first iMCU, change wraparound pointers to normal state */ +    if (main->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; +    /* 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; +  } +} + + +/* + * Process some data. + * Final pass of two-pass quantization: just call the postprocessor. + * Source data will be the postprocessor controller's internal buffer. + */ + +#ifdef QUANT_2PASS_SUPPORTED + +METHODDEF void +process_data_crank_post (j_decompress_ptr cinfo, +			 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, +			 JDIMENSION out_rows_avail) +{ +  (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, +				     (JDIMENSION *) NULL, (JDIMENSION) 0, +				     output_buf, out_row_ctr, out_rows_avail); +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL void +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ +  my_main_ptr main; +  int ci, rgroup, ngroups; +  jpeg_component_info *compptr; + +  main = (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; + +  if (need_full_buffer)		/* shouldn't happen */ +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + +  /* Allocate the workspace. +   * ngroups is the number of row groups we need. +   */ +  if (cinfo->upsample->need_context_rows) { +    if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ +      ERREXIT(cinfo, JERR_NOTIMPL); +    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ +    ngroups = cinfo->min_DCT_scaled_size + 2; +  } else { +    ngroups = cinfo->min_DCT_scaled_size; +  } + +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       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) +			((j_common_ptr) cinfo, JPOOL_IMAGE, +			 compptr->width_in_blocks * compptr->DCT_scaled_size, +			 (JDIMENSION) (rgroup * ngroups)); +  } +} diff --git a/libs/jpeg6/jdmarker.cpp b/libs/jpeg6/jdmarker.cpp index 6c3c519..80e5f78 100755 --- a/libs/jpeg6/jdmarker.cpp +++ b/libs/jpeg6/jdmarker.cpp @@ -1,1052 +1,1052 @@ -/*
 - * jdmarker.c
 - *
 - * Copyright (C) 1991-1995, 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 routines to decode JPEG datastream markers.
 - * Most of the complexity arises from our desire to support input
 - * suspension: if not all of the data for a marker is available,
 - * we must exit back to the application.  On resumption, we reprocess
 - * the marker.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -typedef enum {			/* JPEG marker codes */
 -  M_SOF0  = 0xc0,
 -  M_SOF1  = 0xc1,
 -  M_SOF2  = 0xc2,
 -  M_SOF3  = 0xc3,
 -  
 -  M_SOF5  = 0xc5,
 -  M_SOF6  = 0xc6,
 -  M_SOF7  = 0xc7,
 -  
 -  M_JPG   = 0xc8,
 -  M_SOF9  = 0xc9,
 -  M_SOF10 = 0xca,
 -  M_SOF11 = 0xcb,
 -  
 -  M_SOF13 = 0xcd,
 -  M_SOF14 = 0xce,
 -  M_SOF15 = 0xcf,
 -  
 -  M_DHT   = 0xc4,
 -  
 -  M_DAC   = 0xcc,
 -  
 -  M_RST0  = 0xd0,
 -  M_RST1  = 0xd1,
 -  M_RST2  = 0xd2,
 -  M_RST3  = 0xd3,
 -  M_RST4  = 0xd4,
 -  M_RST5  = 0xd5,
 -  M_RST6  = 0xd6,
 -  M_RST7  = 0xd7,
 -  
 -  M_SOI   = 0xd8,
 -  M_EOI   = 0xd9,
 -  M_SOS   = 0xda,
 -  M_DQT   = 0xdb,
 -  M_DNL   = 0xdc,
 -  M_DRI   = 0xdd,
 -  M_DHP   = 0xde,
 -  M_EXP   = 0xdf,
 -  
 -  M_APP0  = 0xe0,
 -  M_APP1  = 0xe1,
 -  M_APP2  = 0xe2,
 -  M_APP3  = 0xe3,
 -  M_APP4  = 0xe4,
 -  M_APP5  = 0xe5,
 -  M_APP6  = 0xe6,
 -  M_APP7  = 0xe7,
 -  M_APP8  = 0xe8,
 -  M_APP9  = 0xe9,
 -  M_APP10 = 0xea,
 -  M_APP11 = 0xeb,
 -  M_APP12 = 0xec,
 -  M_APP13 = 0xed,
 -  M_APP14 = 0xee,
 -  M_APP15 = 0xef,
 -  
 -  M_JPG0  = 0xf0,
 -  M_JPG13 = 0xfd,
 -  M_COM   = 0xfe,
 -  
 -  M_TEM   = 0x01,
 -  
 -  M_ERROR = 0x100
 -} JPEG_MARKER;
 -
 -
 -/*
 - * Macros for fetching data from the data source module.
 - *
 - * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
 - * the current restart point; we update them only when we have reached a
 - * suitable place to restart if a suspension occurs.
 - */
 -
 -/* Declare and initialize local copies of input pointer/count */
 -#define INPUT_VARS(cinfo)  \
 -	struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
 -	const JOCTET * next_input_byte = datasrc->next_input_byte;  \
 -	size_t bytes_in_buffer = datasrc->bytes_in_buffer
 -
 -/* Unload the local copies --- do this only at a restart boundary */
 -#define INPUT_SYNC(cinfo)  \
 -	( 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 */
 -#define INPUT_RELOAD(cinfo)  \
 -	( next_input_byte = datasrc->next_input_byte,  \
 -	  bytes_in_buffer = datasrc->bytes_in_buffer )
 -
 -/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
 - * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
 - * but we must reload the local copies after a successful fill.
 - */
 -#define MAKE_BYTE_AVAIL(cinfo,action)  \
 -	if (bytes_in_buffer == 0) {  \
 -	  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); \
 -		  V = GETJOCTET(*next_input_byte++); )
 -
 -/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
 - * V should be declared unsigned int or perhaps INT32.
 - */
 -#define INPUT_2BYTES(cinfo,V,action)  \
 -	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
 -		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
 -		  MAKE_BYTE_AVAIL(cinfo,action); \
 -		  V += GETJOCTET(*next_input_byte++); )
 -
 -
 -/*
 - * Routines to process JPEG markers.
 - *
 - * Entry condition: JPEG marker itself has been read and its code saved
 - *   in cinfo->unread_marker; input restart point is just after the marker.
 - *
 - * Exit: if return TRUE, have read and processed any parameters, and have
 - *   updated the restart point to point after the parameters.
 - *   If return FALSE, was forced to suspend before reaching end of
 - *   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.
 - *
 - * Note that we don't bother to avoid duplicate trace messages if a
 - * suspension occurs within marker parameters.  Other side effects
 - * require more care.
 - */
 -
 -
 -LOCAL boolean
 -get_soi (j_decompress_ptr cinfo)
 -/* Process an SOI marker */
 -{
 -  int i;
 -  
 -  TRACEMS(cinfo, 1, JTRC_SOI);
 -
 -  if (cinfo->marker->saw_SOI)
 -    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
 -
 -  /* Reset all parameters that are defined to be reset by SOI */
 -
 -  for (i = 0; i < NUM_ARITH_TBLS; i++) {
 -    cinfo->arith_dc_L[i] = 0;
 -    cinfo->arith_dc_U[i] = 1;
 -    cinfo->arith_ac_K[i] = 5;
 -  }
 -  cinfo->restart_interval = 0;
 -
 -  /* Set initial assumptions for colorspace etc */
 -
 -  cinfo->jpeg_color_space = JCS_UNKNOWN;
 -  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
 -
 -  cinfo->saw_JFIF_marker = FALSE;
 -  cinfo->density_unit = 0;	/* set default JFIF APP0 values */
 -  cinfo->X_density = 1;
 -  cinfo->Y_density = 1;
 -  cinfo->saw_Adobe_marker = FALSE;
 -  cinfo->Adobe_transform = 0;
 -
 -  cinfo->marker->saw_SOI = TRUE;
 -
 -  return TRUE;
 -}
 -
 -
 -LOCAL boolean
 -get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
 -/* Process a SOFn marker */
 -{
 -  INT32 length;
 -  int c, ci;
 -  jpeg_component_info * compptr;
 -  INPUT_VARS(cinfo);
 -
 -  cinfo->progressive_mode = is_prog;
 -  cinfo->arith_code = is_arith;
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -
 -  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
 -  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
 -  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
 -  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
 -
 -  length -= 8;
 -
 -  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
 -	   (int) cinfo->image_width, (int) cinfo->image_height,
 -	   cinfo->num_components);
 -
 -  if (cinfo->marker->saw_SOF)
 -    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
 -
 -  /* We don't support files in which the image height is initially specified */
 -  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
 -  /* might as well have a general sanity check. */
 -  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
 -      || cinfo->num_components <= 0)
 -    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
 -
 -  if (length != (cinfo->num_components * 3))
 -    ERREXIT(cinfo, JERR_BAD_LENGTH);
 -
 -  if (cinfo->comp_info == NULL)	/* do only once, even if suspend */
 -    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
 -			((j_common_ptr) cinfo, JPOOL_IMAGE,
 -			 cinfo->num_components * SIZEOF(jpeg_component_info));
 -  
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    compptr->component_index = ci;
 -    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
 -    INPUT_BYTE(cinfo, c, return FALSE);
 -    compptr->h_samp_factor = (c >> 4) & 15;
 -    compptr->v_samp_factor = (c     ) & 15;
 -    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
 -
 -    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
 -	     compptr->component_id, compptr->h_samp_factor,
 -	     compptr->v_samp_factor, compptr->quant_tbl_no);
 -  }
 -
 -  cinfo->marker->saw_SOF = TRUE;
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -LOCAL boolean
 -get_sos (j_decompress_ptr cinfo)
 -/* Process a SOS marker */
 -{
 -  INT32 length;
 -  int i, ci, n, c, cc;
 -  jpeg_component_info * compptr;
 -  INPUT_VARS(cinfo);
 -
 -  if (! cinfo->marker->saw_SOF)
 -    ERREXIT(cinfo, JERR_SOS_NO_SOF);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -
 -  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
 -
 -  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 */
 -
 -  for (i = 0; i < n; i++) {
 -    INPUT_BYTE(cinfo, cc, return FALSE);
 -    INPUT_BYTE(cinfo, c, return FALSE);
 -    
 -    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -	 ci++, compptr++) {
 -      if (cc == compptr->component_id)
 -	goto id_found;
 -    }
 -
 -    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
 -
 -  id_found:
 -
 -    cinfo->cur_comp_info[i] = compptr;
 -    compptr->dc_tbl_no = (c >> 4) & 15;
 -    compptr->ac_tbl_no = (c     ) & 15;
 -    
 -    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
 -	     compptr->dc_tbl_no, compptr->ac_tbl_no);
 -  }
 -
 -  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
 -  INPUT_BYTE(cinfo, c, return FALSE);
 -  cinfo->Ss = c;
 -  INPUT_BYTE(cinfo, c, return FALSE);
 -  cinfo->Se = c;
 -  INPUT_BYTE(cinfo, c, return FALSE);
 -  cinfo->Ah = (c >> 4) & 15;
 -  cinfo->Al = (c     ) & 15;
 -
 -  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
 -	   cinfo->Ah, cinfo->Al);
 -
 -  /* Prepare to scan data & restart markers */
 -  cinfo->marker->next_restart_num = 0;
 -
 -  /* Count another SOS marker */
 -  cinfo->input_scan_number++;
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -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;
 -
 -  /* 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
 -get_dac (j_decompress_ptr cinfo)
 -/* Process a DAC marker */
 -{
 -  INT32 length;
 -  int index, val;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -  length -= 2;
 -  
 -  while (length > 0) {
 -    INPUT_BYTE(cinfo, index, return FALSE);
 -    INPUT_BYTE(cinfo, val, return FALSE);
 -
 -    length -= 2;
 -
 -    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
 -
 -    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
 -      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
 -
 -    if (index >= NUM_ARITH_TBLS) { /* define AC table */
 -      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
 -    } else {			/* define DC table */
 -      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
 -      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
 -      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
 -	ERREXIT1(cinfo, JERR_DAC_VALUE, val);
 -    }
 -  }
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -LOCAL boolean
 -get_dht (j_decompress_ptr cinfo)
 -/* Process a DHT marker */
 -{
 -  INT32 length;
 -  UINT8 bits[17];
 -  UINT8 huffval[256];
 -  int i, index, count;
 -  JHUFF_TBL **htblptr;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -  length -= 2;
 -  
 -  while (length > 0) {
 -    INPUT_BYTE(cinfo, index, return FALSE);
 -
 -    TRACEMS1(cinfo, 1, JTRC_DHT, index);
 -      
 -    bits[0] = 0;
 -    count = 0;
 -    for (i = 1; i <= 16; i++) {
 -      INPUT_BYTE(cinfo, bits[i], return FALSE);
 -      count += bits[i];
 -    }
 -
 -    length -= 1 + 16;
 -
 -    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
 -	     bits[1], bits[2], bits[3], bits[4],
 -	     bits[5], bits[6], bits[7], bits[8]);
 -    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
 -	     bits[9], bits[10], bits[11], bits[12],
 -	     bits[13], bits[14], bits[15], bits[16]);
 -
 -    if (count > 256 || ((INT32) count) > length)
 -      ERREXIT(cinfo, JERR_DHT_COUNTS);
 -
 -    for (i = 0; i < count; i++)
 -      INPUT_BYTE(cinfo, huffval[i], return FALSE);
 -
 -    length -= count;
 -
 -    if (index & 0x10) {		/* AC table definition */
 -      index -= 0x10;
 -      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
 -    } else {			/* DC table definition */
 -      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
 -    }
 -
 -    if (index < 0 || index >= NUM_HUFF_TBLS)
 -      ERREXIT1(cinfo, JERR_DHT_INDEX, index);
 -
 -    if (*htblptr == NULL)
 -      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
 -  
 -    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
 -    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
 -  }
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -LOCAL boolean
 -get_dqt (j_decompress_ptr cinfo)
 -/* Process a DQT marker */
 -{
 -  INT32 length;
 -  int n, i, prec;
 -  unsigned int tmp;
 -  JQUANT_TBL *quant_ptr;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -  length -= 2;
 -
 -  while (length > 0) {
 -    INPUT_BYTE(cinfo, n, return FALSE);
 -    prec = n >> 4;
 -    n &= 0x0F;
 -
 -    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
 -
 -    if (n >= NUM_QUANT_TBLS)
 -      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
 -      
 -    if (cinfo->quant_tbl_ptrs[n] == NULL)
 -      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
 -    quant_ptr = cinfo->quant_tbl_ptrs[n];
 -
 -    for (i = 0; i < DCTSIZE2; i++) {
 -      if (prec)
 -	INPUT_2BYTES(cinfo, tmp, return FALSE);
 -      else
 -	INPUT_BYTE(cinfo, tmp, return FALSE);
 -      quant_ptr->quantval[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]);
 -    }
 -
 -    length -= DCTSIZE2+1;
 -    if (prec) length -= DCTSIZE2;
 -  }
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -LOCAL boolean
 -get_dri (j_decompress_ptr cinfo)
 -/* Process a DRI marker */
 -{
 -  INT32 length;
 -  unsigned int tmp;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -  
 -  if (length != 4)
 -    ERREXIT(cinfo, JERR_BAD_LENGTH);
 -
 -  INPUT_2BYTES(cinfo, tmp, return FALSE);
 -
 -  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
 -
 -  cinfo->restart_interval = tmp;
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -METHODDEF boolean
 -skip_variable (j_decompress_ptr cinfo)
 -/* Skip over an unknown or uninteresting variable-length marker */
 -{
 -  INT32 length;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_2BYTES(cinfo, length, return FALSE);
 -  
 -  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);
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Find the next JPEG marker, save it in cinfo->unread_marker.
 - * Returns FALSE if had to suspend before reaching a marker;
 - * in that case cinfo->unread_marker is unchanged.
 - *
 - * Note that the result might not be a valid marker code,
 - * but it will never be 0 or FF.
 - */
 -
 -LOCAL boolean
 -next_marker (j_decompress_ptr cinfo)
 -{
 -  int c;
 -  INPUT_VARS(cinfo);
 -
 -  for (;;) {
 -    INPUT_BYTE(cinfo, c, return FALSE);
 -    /* Skip any non-FF bytes.
 -     * This may look a bit inefficient, but it will not occur in a valid file.
 -     * We sync after each discarded byte so that a suspending data source
 -     * can discard the byte from its buffer.
 -     */
 -    while (c != 0xFF) {
 -      cinfo->marker->discarded_bytes++;
 -      INPUT_SYNC(cinfo);
 -      INPUT_BYTE(cinfo, c, return FALSE);
 -    }
 -    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
 -     * pad bytes, so don't count them in discarded_bytes.  We assume there
 -     * will not be so many consecutive FF bytes as to overflow a suspending
 -     * data source's input buffer.
 -     */
 -    do {
 -      INPUT_BYTE(cinfo, c, return FALSE);
 -    } while (c == 0xFF);
 -    if (c != 0)
 -      break;			/* found a valid marker, exit loop */
 -    /* Reach here if we found a stuffed-zero data sequence (FF/00).
 -     * Discard it and loop back to try again.
 -     */
 -    cinfo->marker->discarded_bytes += 2;
 -    INPUT_SYNC(cinfo);
 -  }
 -
 -  if (cinfo->marker->discarded_bytes != 0) {
 -    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
 -    cinfo->marker->discarded_bytes = 0;
 -  }
 -
 -  cinfo->unread_marker = c;
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -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,
 - * we might well scan an entire input file before realizing it ain't JPEG.
 - * If an application wants to process non-JFIF files, it must seek to the
 - * SOI before calling the JPEG library.
 - */
 -{
 -  int c, c2;
 -  INPUT_VARS(cinfo);
 -
 -  INPUT_BYTE(cinfo, c, return FALSE);
 -  INPUT_BYTE(cinfo, c2, return FALSE);
 -  if (c != 0xFF || c2 != (int) M_SOI)
 -    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
 -
 -  cinfo->unread_marker = c2;
 -
 -  INPUT_SYNC(cinfo);
 -  return TRUE;
 -}
 -
 -
 -/*
 - * Read markers until SOS or EOI.
 - *
 - * Returns same codes as are defined for jpeg_consume_input:
 - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 - */
 -
 -METHODDEF int
 -read_markers (j_decompress_ptr cinfo)
 -{
 -  /* Outer loop repeats once for each marker. */
 -  for (;;) {
 -    /* Collect the marker proper, unless we already did. */
 -    /* NB: first_marker() enforces the requirement that SOI appear first. */
 -    if (cinfo->unread_marker == 0) {
 -      if (! cinfo->marker->saw_SOI) {
 -	if (! first_marker(cinfo))
 -	  return JPEG_SUSPENDED;
 -      } else {
 -	if (! next_marker(cinfo))
 -	  return JPEG_SUSPENDED;
 -      }
 -    }
 -    /* At this point cinfo->unread_marker contains the marker code and the
 -     * input point is just past the marker proper, but before any parameters.
 -     * A suspension will cause us to return with this state still true.
 -     */
 -    switch (cinfo->unread_marker) {
 -    case M_SOI:
 -      if (! get_soi(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    case M_SOF0:		/* Baseline */
 -    case M_SOF1:		/* Extended sequential, Huffman */
 -      if (! get_sof(cinfo, FALSE, FALSE))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    case M_SOF2:		/* Progressive, Huffman */
 -      if (! get_sof(cinfo, TRUE, FALSE))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    case M_SOF9:		/* Extended sequential, arithmetic */
 -      if (! get_sof(cinfo, FALSE, TRUE))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    case M_SOF10:		/* Progressive, arithmetic */
 -      if (! get_sof(cinfo, TRUE, TRUE))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    /* Currently unsupported SOFn types */
 -    case M_SOF3:		/* Lossless, Huffman */
 -    case M_SOF5:		/* Differential sequential, Huffman */
 -    case M_SOF6:		/* Differential progressive, Huffman */
 -    case M_SOF7:		/* Differential lossless, Huffman */
 -    case M_JPG:			/* Reserved for JPEG extensions */
 -    case M_SOF11:		/* Lossless, arithmetic */
 -    case M_SOF13:		/* Differential sequential, arithmetic */
 -    case M_SOF14:		/* Differential progressive, arithmetic */
 -    case M_SOF15:		/* Differential lossless, arithmetic */
 -      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
 -      break;
 -
 -    case M_SOS:
 -      if (! get_sos(cinfo))
 -	return JPEG_SUSPENDED;
 -      cinfo->unread_marker = 0;	/* processed the marker */
 -      return JPEG_REACHED_SOS;
 -    
 -    case M_EOI:
 -      TRACEMS(cinfo, 1, JTRC_EOI);
 -      cinfo->unread_marker = 0;	/* processed the marker */
 -      return JPEG_REACHED_EOI;
 -      
 -    case M_DAC:
 -      if (! get_dac(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -      
 -    case M_DHT:
 -      if (! get_dht(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -      
 -    case M_DQT:
 -      if (! get_dqt(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -      
 -    case M_DRI:
 -      if (! get_dri(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -      
 -    case M_APP0:
 -    case M_APP1:
 -    case M_APP2:
 -    case M_APP3:
 -    case M_APP4:
 -    case M_APP5:
 -    case M_APP6:
 -    case M_APP7:
 -    case M_APP8:
 -    case M_APP9:
 -    case M_APP10:
 -    case M_APP11:
 -    case M_APP12:
 -    case M_APP13:
 -    case M_APP14:
 -    case M_APP15:
 -      if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -      
 -    case M_COM:
 -      if (! (*cinfo->marker->process_COM) (cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    case M_RST0:		/* these are all parameterless */
 -    case M_RST1:
 -    case M_RST2:
 -    case M_RST3:
 -    case M_RST4:
 -    case M_RST5:
 -    case M_RST6:
 -    case M_RST7:
 -    case M_TEM:
 -      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
 -      break;
 -
 -    case M_DNL:			/* Ignore DNL ... perhaps the wrong thing */
 -      if (! skip_variable(cinfo))
 -	return JPEG_SUSPENDED;
 -      break;
 -
 -    default:			/* must be DHP, EXP, JPGn, or RESn */
 -      /* For now, we treat the reserved markers as fatal errors since they are
 -       * likely to be used to signal incompatible JPEG Part 3 extensions.
 -       * Once the JPEG 3 version-number marker is well defined, this code
 -       * ought to change!
 -       */
 -      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
 -      break;
 -    }
 -    /* Successfully processed marker, so reset state variable */
 -    cinfo->unread_marker = 0;
 -  } /* end loop */
 -}
 -
 -
 -/*
 - * Read a restart marker, which is expected to appear next in the datastream;
 - * if the marker is not there, take appropriate recovery action.
 - * Returns FALSE if suspension is required.
 - *
 - * This is called by the entropy decoder after it has read an appropriate
 - * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
 - * has already read a marker from the data source.  Under normal conditions
 - * cinfo->unread_marker will be reset to 0 before returning; if not reset,
 - * it holds a marker which the decoder will be unable to read past.
 - */
 -
 -METHODDEF boolean
 -read_restart_marker (j_decompress_ptr cinfo)
 -{
 -  /* Obtain a marker unless we already did. */
 -  /* Note that next_marker will complain if it skips any data. */
 -  if (cinfo->unread_marker == 0) {
 -    if (! next_marker(cinfo))
 -      return FALSE;
 -  }
 -
 -  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);
 -    cinfo->unread_marker = 0;
 -  } else {
 -    /* Uh-oh, the restart markers have been messed up. */
 -    /* Let the data source manager determine how to resync. */
 -    if (! (*cinfo->src->resync_to_restart) (cinfo,
 -					    cinfo->marker->next_restart_num))
 -      return FALSE;
 -  }
 -
 -  /* Update next-restart state */
 -  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
 -
 -  return TRUE;
 -}
 -
 -
 -/*
 - * This is the default resync_to_restart method for data source managers
 - * to use if they don't have any better approach.  Some data source managers
 - * may be able to back up, or may have additional knowledge about the data
 - * which permits a more intelligent recovery strategy; such managers would
 - * presumably supply their own resync method.
 - *
 - * read_restart_marker calls resync_to_restart if it finds a marker other than
 - * the restart marker it was expecting.  (This code is *not* used unless
 - * a nonzero restart interval has been declared.)  cinfo->unread_marker is
 - * the marker code actually found (might be anything, except 0 or FF).
 - * The desired restart marker number (0..7) is passed as a parameter.
 - * This routine is supposed to apply whatever error recovery strategy seems
 - * appropriate in order to position the input stream to the next data segment.
 - * Note that cinfo->unread_marker is treated as a marker appearing before
 - * the current data-source input point; usually it should be reset to zero
 - * before returning.
 - * Returns FALSE if suspension is required.
 - *
 - * This implementation is substantially constrained by wanting to treat the
 - * input as a data stream; this means we can't back up.  Therefore, we have
 - * only the following actions to work with:
 - *   1. Simply discard the marker and let the entropy decoder resume at next
 - *      byte of file.
 - *   2. Read forward until we find another marker, discarding intervening
 - *      data.  (In theory we could look ahead within the current bufferload,
 - *      without having to discard data if we don't find the desired marker.
 - *      This idea is not implemented here, in part because it makes behavior
 - *      dependent on buffer size and chance buffer-boundary positions.)
 - *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
 - *      This will cause the entropy decoder to process an empty data segment,
 - *      inserting dummy zeroes, and then we will reprocess the marker.
 - *
 - * #2 is appropriate if we think the desired marker lies ahead, while #3 is
 - * appropriate if the found marker is a future restart marker (indicating
 - * that we have missed the desired restart marker, probably because it got
 - * corrupted).
 - * We apply #2 or #3 if the found marker is a restart marker no more than
 - * two counts behind or ahead of the expected one.  We also apply #2 if the
 - * found marker is not a legal JPEG marker code (it's certainly bogus data).
 - * If the found marker is a restart marker more than 2 counts away, we do #1
 - * (too much risk that the marker is erroneous; with luck we will be able to
 - * resync at some future point).
 - * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
 - * overrunning the end of a scan.  An implementation limited to single-scan
 - * files might find it better to apply #2 for markers other than EOI, since
 - * any other marker would have to be bogus data in that case.
 - */
 -
 -GLOBAL boolean
 -jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
 -{
 -  int marker = cinfo->unread_marker;
 -  int action = 1;
 -  
 -  /* Always put up a warning. */
 -  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
 -  
 -  /* Outer loop handles repeated decision after scanning forward. */
 -  for (;;) {
 -    if (marker < (int) M_SOF0)
 -      action = 2;		/* invalid marker */
 -    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
 -      action = 3;		/* valid non-restart marker */
 -    else {
 -      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
 -	  marker == ((int) M_RST0 + ((desired+2) & 7)))
 -	action = 3;		/* one of the next two expected restarts */
 -      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
 -	       marker == ((int) M_RST0 + ((desired-2) & 7)))
 -	action = 2;		/* a prior restart, so advance */
 -      else
 -	action = 1;		/* desired restart or too far away */
 -    }
 -    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
 -    switch (action) {
 -    case 1:
 -      /* Discard marker and let entropy decoder resume processing. */
 -      cinfo->unread_marker = 0;
 -      return TRUE;
 -    case 2:
 -      /* Scan to the next marker, and repeat the decision loop. */
 -      if (! next_marker(cinfo))
 -	return FALSE;
 -      marker = cinfo->unread_marker;
 -      break;
 -    case 3:
 -      /* Return without advancing past this marker. */
 -      /* Entropy decoder will be forced to process an empty segment. */
 -      return TRUE;
 -    }
 -  } /* end loop */
 -}
 -
 -
 -/*
 - * Reset marker processing state to begin a fresh datastream.
 - */
 -
 -METHODDEF void
 -reset_marker_reader (j_decompress_ptr cinfo)
 -{
 -  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;
 -}
 -
 -
 -/*
 - * Initialize the marker reader module.
 - * This is called only once, when the decompression object is created.
 - */
 -
 -GLOBAL void
 -jinit_marker_reader (j_decompress_ptr cinfo)
 -{
 -  int i;
 -
 -  /* Create subobject in permanent pool */
 -  cinfo->marker = (struct jpeg_marker_reader *)
 -    (*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;
 -  /* Reset marker processing state */
 -  reset_marker_reader(cinfo);
 -}
 +/* + * jdmarker.c + * + * Copyright (C) 1991-1995, 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 routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application.  On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum {			/* JPEG marker codes */ +  M_SOF0  = 0xc0, +  M_SOF1  = 0xc1, +  M_SOF2  = 0xc2, +  M_SOF3  = 0xc3, +   +  M_SOF5  = 0xc5, +  M_SOF6  = 0xc6, +  M_SOF7  = 0xc7, +   +  M_JPG   = 0xc8, +  M_SOF9  = 0xc9, +  M_SOF10 = 0xca, +  M_SOF11 = 0xcb, +   +  M_SOF13 = 0xcd, +  M_SOF14 = 0xce, +  M_SOF15 = 0xcf, +   +  M_DHT   = 0xc4, +   +  M_DAC   = 0xcc, +   +  M_RST0  = 0xd0, +  M_RST1  = 0xd1, +  M_RST2  = 0xd2, +  M_RST3  = 0xd3, +  M_RST4  = 0xd4, +  M_RST5  = 0xd5, +  M_RST6  = 0xd6, +  M_RST7  = 0xd7, +   +  M_SOI   = 0xd8, +  M_EOI   = 0xd9, +  M_SOS   = 0xda, +  M_DQT   = 0xdb, +  M_DNL   = 0xdc, +  M_DRI   = 0xdd, +  M_DHP   = 0xde, +  M_EXP   = 0xdf, +   +  M_APP0  = 0xe0, +  M_APP1  = 0xe1, +  M_APP2  = 0xe2, +  M_APP3  = 0xe3, +  M_APP4  = 0xe4, +  M_APP5  = 0xe5, +  M_APP6  = 0xe6, +  M_APP7  = 0xe7, +  M_APP8  = 0xe8, +  M_APP9  = 0xe9, +  M_APP10 = 0xea, +  M_APP11 = 0xeb, +  M_APP12 = 0xec, +  M_APP13 = 0xed, +  M_APP14 = 0xee, +  M_APP15 = 0xef, +   +  M_JPG0  = 0xf0, +  M_JPG13 = 0xfd, +  M_COM   = 0xfe, +   +  M_TEM   = 0x01, +   +  M_ERROR = 0x100 +} JPEG_MARKER; + + +/* + * Macros for fetching data from the data source module. + * + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect + * the current restart point; we update them only when we have reached a + * suitable place to restart if a suspension occurs. + */ + +/* Declare and initialize local copies of input pointer/count */ +#define INPUT_VARS(cinfo)  \ +	struct jpeg_source_mgr * datasrc = (cinfo)->src;  \ +	const JOCTET * next_input_byte = datasrc->next_input_byte;  \ +	size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo)  \ +	( 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 */ +#define INPUT_RELOAD(cinfo)  \ +	( next_input_byte = datasrc->next_input_byte,  \ +	  bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action)  \ +	if (bytes_in_buffer == 0) {  \ +	  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); \ +		  V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action)  \ +	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ +		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ +		  MAKE_BYTE_AVAIL(cinfo,action); \ +		  V += GETJOCTET(*next_input_byte++); ) + + +/* + * Routines to process JPEG markers. + * + * Entry condition: JPEG marker itself has been read and its code saved + *   in cinfo->unread_marker; input restart point is just after the marker. + * + * Exit: if return TRUE, have read and processed any parameters, and have + *   updated the restart point to point after the parameters. + *   If return FALSE, was forced to suspend before reaching end of + *   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. + * + * Note that we don't bother to avoid duplicate trace messages if a + * suspension occurs within marker parameters.  Other side effects + * require more care. + */ + + +LOCAL boolean +get_soi (j_decompress_ptr cinfo) +/* Process an SOI marker */ +{ +  int i; +   +  TRACEMS(cinfo, 1, JTRC_SOI); + +  if (cinfo->marker->saw_SOI) +    ERREXIT(cinfo, JERR_SOI_DUPLICATE); + +  /* Reset all parameters that are defined to be reset by SOI */ + +  for (i = 0; i < NUM_ARITH_TBLS; i++) { +    cinfo->arith_dc_L[i] = 0; +    cinfo->arith_dc_U[i] = 1; +    cinfo->arith_ac_K[i] = 5; +  } +  cinfo->restart_interval = 0; + +  /* Set initial assumptions for colorspace etc */ + +  cinfo->jpeg_color_space = JCS_UNKNOWN; +  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ + +  cinfo->saw_JFIF_marker = FALSE; +  cinfo->density_unit = 0;	/* set default JFIF APP0 values */ +  cinfo->X_density = 1; +  cinfo->Y_density = 1; +  cinfo->saw_Adobe_marker = FALSE; +  cinfo->Adobe_transform = 0; + +  cinfo->marker->saw_SOI = TRUE; + +  return TRUE; +} + + +LOCAL boolean +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +/* Process a SOFn marker */ +{ +  INT32 length; +  int c, ci; +  jpeg_component_info * compptr; +  INPUT_VARS(cinfo); + +  cinfo->progressive_mode = is_prog; +  cinfo->arith_code = is_arith; + +  INPUT_2BYTES(cinfo, length, return FALSE); + +  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); +  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); +  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); +  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); + +  length -= 8; + +  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, +	   (int) cinfo->image_width, (int) cinfo->image_height, +	   cinfo->num_components); + +  if (cinfo->marker->saw_SOF) +    ERREXIT(cinfo, JERR_SOF_DUPLICATE); + +  /* We don't support files in which the image height is initially specified */ +  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */ +  /* might as well have a general sanity check. */ +  if (cinfo->image_height <= 0 || cinfo->image_width <= 0 +      || cinfo->num_components <= 0) +    ERREXIT(cinfo, JERR_EMPTY_IMAGE); + +  if (length != (cinfo->num_components * 3)) +    ERREXIT(cinfo, JERR_BAD_LENGTH); + +  if (cinfo->comp_info == NULL)	/* do only once, even if suspend */ +    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) +			((j_common_ptr) cinfo, JPOOL_IMAGE, +			 cinfo->num_components * SIZEOF(jpeg_component_info)); +   +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    compptr->component_index = ci; +    INPUT_BYTE(cinfo, compptr->component_id, return FALSE); +    INPUT_BYTE(cinfo, c, return FALSE); +    compptr->h_samp_factor = (c >> 4) & 15; +    compptr->v_samp_factor = (c     ) & 15; +    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); + +    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, +	     compptr->component_id, compptr->h_samp_factor, +	     compptr->v_samp_factor, compptr->quant_tbl_no); +  } + +  cinfo->marker->saw_SOF = TRUE; + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +LOCAL boolean +get_sos (j_decompress_ptr cinfo) +/* Process a SOS marker */ +{ +  INT32 length; +  int i, ci, n, c, cc; +  jpeg_component_info * compptr; +  INPUT_VARS(cinfo); + +  if (! cinfo->marker->saw_SOF) +    ERREXIT(cinfo, JERR_SOS_NO_SOF); + +  INPUT_2BYTES(cinfo, length, return FALSE); + +  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + +  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 */ + +  for (i = 0; i < n; i++) { +    INPUT_BYTE(cinfo, cc, return FALSE); +    INPUT_BYTE(cinfo, c, return FALSE); +     +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +	 ci++, compptr++) { +      if (cc == compptr->component_id) +	goto id_found; +    } + +    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + +  id_found: + +    cinfo->cur_comp_info[i] = compptr; +    compptr->dc_tbl_no = (c >> 4) & 15; +    compptr->ac_tbl_no = (c     ) & 15; +     +    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, +	     compptr->dc_tbl_no, compptr->ac_tbl_no); +  } + +  /* Collect the additional scan parameters Ss, Se, Ah/Al. */ +  INPUT_BYTE(cinfo, c, return FALSE); +  cinfo->Ss = c; +  INPUT_BYTE(cinfo, c, return FALSE); +  cinfo->Se = c; +  INPUT_BYTE(cinfo, c, return FALSE); +  cinfo->Ah = (c >> 4) & 15; +  cinfo->Al = (c     ) & 15; + +  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, +	   cinfo->Ah, cinfo->Al); + +  /* Prepare to scan data & restart markers */ +  cinfo->marker->next_restart_num = 0; + +  /* Count another SOS marker */ +  cinfo->input_scan_number++; + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +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; + +  /* 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 +get_dac (j_decompress_ptr cinfo) +/* Process a DAC marker */ +{ +  INT32 length; +  int index, val; +  INPUT_VARS(cinfo); + +  INPUT_2BYTES(cinfo, length, return FALSE); +  length -= 2; +   +  while (length > 0) { +    INPUT_BYTE(cinfo, index, return FALSE); +    INPUT_BYTE(cinfo, val, return FALSE); + +    length -= 2; + +    TRACEMS2(cinfo, 1, JTRC_DAC, index, val); + +    if (index < 0 || index >= (2*NUM_ARITH_TBLS)) +      ERREXIT1(cinfo, JERR_DAC_INDEX, index); + +    if (index >= NUM_ARITH_TBLS) { /* define AC table */ +      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; +    } else {			/* define DC table */ +      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); +      cinfo->arith_dc_U[index] = (UINT8) (val >> 4); +      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) +	ERREXIT1(cinfo, JERR_DAC_VALUE, val); +    } +  } + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +LOCAL boolean +get_dht (j_decompress_ptr cinfo) +/* Process a DHT marker */ +{ +  INT32 length; +  UINT8 bits[17]; +  UINT8 huffval[256]; +  int i, index, count; +  JHUFF_TBL **htblptr; +  INPUT_VARS(cinfo); + +  INPUT_2BYTES(cinfo, length, return FALSE); +  length -= 2; +   +  while (length > 0) { +    INPUT_BYTE(cinfo, index, return FALSE); + +    TRACEMS1(cinfo, 1, JTRC_DHT, index); +       +    bits[0] = 0; +    count = 0; +    for (i = 1; i <= 16; i++) { +      INPUT_BYTE(cinfo, bits[i], return FALSE); +      count += bits[i]; +    } + +    length -= 1 + 16; + +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS, +	     bits[1], bits[2], bits[3], bits[4], +	     bits[5], bits[6], bits[7], bits[8]); +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS, +	     bits[9], bits[10], bits[11], bits[12], +	     bits[13], bits[14], bits[15], bits[16]); + +    if (count > 256 || ((INT32) count) > length) +      ERREXIT(cinfo, JERR_DHT_COUNTS); + +    for (i = 0; i < count; i++) +      INPUT_BYTE(cinfo, huffval[i], return FALSE); + +    length -= count; + +    if (index & 0x10) {		/* AC table definition */ +      index -= 0x10; +      htblptr = &cinfo->ac_huff_tbl_ptrs[index]; +    } else {			/* DC table definition */ +      htblptr = &cinfo->dc_huff_tbl_ptrs[index]; +    } + +    if (index < 0 || index >= NUM_HUFF_TBLS) +      ERREXIT1(cinfo, JERR_DHT_INDEX, index); + +    if (*htblptr == NULL) +      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); +   +    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); +    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); +  } + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +LOCAL boolean +get_dqt (j_decompress_ptr cinfo) +/* Process a DQT marker */ +{ +  INT32 length; +  int n, i, prec; +  unsigned int tmp; +  JQUANT_TBL *quant_ptr; +  INPUT_VARS(cinfo); + +  INPUT_2BYTES(cinfo, length, return FALSE); +  length -= 2; + +  while (length > 0) { +    INPUT_BYTE(cinfo, n, return FALSE); +    prec = n >> 4; +    n &= 0x0F; + +    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); + +    if (n >= NUM_QUANT_TBLS) +      ERREXIT1(cinfo, JERR_DQT_INDEX, n); +       +    if (cinfo->quant_tbl_ptrs[n] == NULL) +      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); +    quant_ptr = cinfo->quant_tbl_ptrs[n]; + +    for (i = 0; i < DCTSIZE2; i++) { +      if (prec) +	INPUT_2BYTES(cinfo, tmp, return FALSE); +      else +	INPUT_BYTE(cinfo, tmp, return FALSE); +      quant_ptr->quantval[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]); +    } + +    length -= DCTSIZE2+1; +    if (prec) length -= DCTSIZE2; +  } + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +LOCAL boolean +get_dri (j_decompress_ptr cinfo) +/* Process a DRI marker */ +{ +  INT32 length; +  unsigned int tmp; +  INPUT_VARS(cinfo); + +  INPUT_2BYTES(cinfo, length, return FALSE); +   +  if (length != 4) +    ERREXIT(cinfo, JERR_BAD_LENGTH); + +  INPUT_2BYTES(cinfo, tmp, return FALSE); + +  TRACEMS1(cinfo, 1, JTRC_DRI, tmp); + +  cinfo->restart_interval = tmp; + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +METHODDEF boolean +skip_variable (j_decompress_ptr cinfo) +/* Skip over an unknown or uninteresting variable-length marker */ +{ +  INT32 length; +  INPUT_VARS(cinfo); + +  INPUT_2BYTES(cinfo, length, return FALSE); +   +  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); + +  return TRUE; +} + + +/* + * Find the next JPEG marker, save it in cinfo->unread_marker. + * Returns FALSE if had to suspend before reaching a marker; + * in that case cinfo->unread_marker is unchanged. + * + * Note that the result might not be a valid marker code, + * but it will never be 0 or FF. + */ + +LOCAL boolean +next_marker (j_decompress_ptr cinfo) +{ +  int c; +  INPUT_VARS(cinfo); + +  for (;;) { +    INPUT_BYTE(cinfo, c, return FALSE); +    /* Skip any non-FF bytes. +     * This may look a bit inefficient, but it will not occur in a valid file. +     * We sync after each discarded byte so that a suspending data source +     * can discard the byte from its buffer. +     */ +    while (c != 0xFF) { +      cinfo->marker->discarded_bytes++; +      INPUT_SYNC(cinfo); +      INPUT_BYTE(cinfo, c, return FALSE); +    } +    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as +     * pad bytes, so don't count them in discarded_bytes.  We assume there +     * will not be so many consecutive FF bytes as to overflow a suspending +     * data source's input buffer. +     */ +    do { +      INPUT_BYTE(cinfo, c, return FALSE); +    } while (c == 0xFF); +    if (c != 0) +      break;			/* found a valid marker, exit loop */ +    /* Reach here if we found a stuffed-zero data sequence (FF/00). +     * Discard it and loop back to try again. +     */ +    cinfo->marker->discarded_bytes += 2; +    INPUT_SYNC(cinfo); +  } + +  if (cinfo->marker->discarded_bytes != 0) { +    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); +    cinfo->marker->discarded_bytes = 0; +  } + +  cinfo->unread_marker = c; + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +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, + * we might well scan an entire input file before realizing it ain't JPEG. + * If an application wants to process non-JFIF files, it must seek to the + * SOI before calling the JPEG library. + */ +{ +  int c, c2; +  INPUT_VARS(cinfo); + +  INPUT_BYTE(cinfo, c, return FALSE); +  INPUT_BYTE(cinfo, c2, return FALSE); +  if (c != 0xFF || c2 != (int) M_SOI) +    ERREXIT2(cinfo, JERR_NO_SOI, c, c2); + +  cinfo->unread_marker = c2; + +  INPUT_SYNC(cinfo); +  return TRUE; +} + + +/* + * Read markers until SOS or EOI. + * + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + +METHODDEF int +read_markers (j_decompress_ptr cinfo) +{ +  /* Outer loop repeats once for each marker. */ +  for (;;) { +    /* Collect the marker proper, unless we already did. */ +    /* NB: first_marker() enforces the requirement that SOI appear first. */ +    if (cinfo->unread_marker == 0) { +      if (! cinfo->marker->saw_SOI) { +	if (! first_marker(cinfo)) +	  return JPEG_SUSPENDED; +      } else { +	if (! next_marker(cinfo)) +	  return JPEG_SUSPENDED; +      } +    } +    /* At this point cinfo->unread_marker contains the marker code and the +     * input point is just past the marker proper, but before any parameters. +     * A suspension will cause us to return with this state still true. +     */ +    switch (cinfo->unread_marker) { +    case M_SOI: +      if (! get_soi(cinfo)) +	return JPEG_SUSPENDED; +      break; + +    case M_SOF0:		/* Baseline */ +    case M_SOF1:		/* Extended sequential, Huffman */ +      if (! get_sof(cinfo, FALSE, FALSE)) +	return JPEG_SUSPENDED; +      break; + +    case M_SOF2:		/* Progressive, Huffman */ +      if (! get_sof(cinfo, TRUE, FALSE)) +	return JPEG_SUSPENDED; +      break; + +    case M_SOF9:		/* Extended sequential, arithmetic */ +      if (! get_sof(cinfo, FALSE, TRUE)) +	return JPEG_SUSPENDED; +      break; + +    case M_SOF10:		/* Progressive, arithmetic */ +      if (! get_sof(cinfo, TRUE, TRUE)) +	return JPEG_SUSPENDED; +      break; + +    /* Currently unsupported SOFn types */ +    case M_SOF3:		/* Lossless, Huffman */ +    case M_SOF5:		/* Differential sequential, Huffman */ +    case M_SOF6:		/* Differential progressive, Huffman */ +    case M_SOF7:		/* Differential lossless, Huffman */ +    case M_JPG:			/* Reserved for JPEG extensions */ +    case M_SOF11:		/* Lossless, arithmetic */ +    case M_SOF13:		/* Differential sequential, arithmetic */ +    case M_SOF14:		/* Differential progressive, arithmetic */ +    case M_SOF15:		/* Differential lossless, arithmetic */ +      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); +      break; + +    case M_SOS: +      if (! get_sos(cinfo)) +	return JPEG_SUSPENDED; +      cinfo->unread_marker = 0;	/* processed the marker */ +      return JPEG_REACHED_SOS; +     +    case M_EOI: +      TRACEMS(cinfo, 1, JTRC_EOI); +      cinfo->unread_marker = 0;	/* processed the marker */ +      return JPEG_REACHED_EOI; +       +    case M_DAC: +      if (! get_dac(cinfo)) +	return JPEG_SUSPENDED; +      break; +       +    case M_DHT: +      if (! get_dht(cinfo)) +	return JPEG_SUSPENDED; +      break; +       +    case M_DQT: +      if (! get_dqt(cinfo)) +	return JPEG_SUSPENDED; +      break; +       +    case M_DRI: +      if (! get_dri(cinfo)) +	return JPEG_SUSPENDED; +      break; +       +    case M_APP0: +    case M_APP1: +    case M_APP2: +    case M_APP3: +    case M_APP4: +    case M_APP5: +    case M_APP6: +    case M_APP7: +    case M_APP8: +    case M_APP9: +    case M_APP10: +    case M_APP11: +    case M_APP12: +    case M_APP13: +    case M_APP14: +    case M_APP15: +      if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo)) +	return JPEG_SUSPENDED; +      break; +       +    case M_COM: +      if (! (*cinfo->marker->process_COM) (cinfo)) +	return JPEG_SUSPENDED; +      break; + +    case M_RST0:		/* these are all parameterless */ +    case M_RST1: +    case M_RST2: +    case M_RST3: +    case M_RST4: +    case M_RST5: +    case M_RST6: +    case M_RST7: +    case M_TEM: +      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); +      break; + +    case M_DNL:			/* Ignore DNL ... perhaps the wrong thing */ +      if (! skip_variable(cinfo)) +	return JPEG_SUSPENDED; +      break; + +    default:			/* must be DHP, EXP, JPGn, or RESn */ +      /* For now, we treat the reserved markers as fatal errors since they are +       * likely to be used to signal incompatible JPEG Part 3 extensions. +       * Once the JPEG 3 version-number marker is well defined, this code +       * ought to change! +       */ +      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); +      break; +    } +    /* Successfully processed marker, so reset state variable */ +    cinfo->unread_marker = 0; +  } /* end loop */ +} + + +/* + * Read a restart marker, which is expected to appear next in the datastream; + * if the marker is not there, take appropriate recovery action. + * Returns FALSE if suspension is required. + * + * This is called by the entropy decoder after it has read an appropriate + * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder + * has already read a marker from the data source.  Under normal conditions + * cinfo->unread_marker will be reset to 0 before returning; if not reset, + * it holds a marker which the decoder will be unable to read past. + */ + +METHODDEF boolean +read_restart_marker (j_decompress_ptr cinfo) +{ +  /* Obtain a marker unless we already did. */ +  /* Note that next_marker will complain if it skips any data. */ +  if (cinfo->unread_marker == 0) { +    if (! next_marker(cinfo)) +      return FALSE; +  } + +  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); +    cinfo->unread_marker = 0; +  } else { +    /* Uh-oh, the restart markers have been messed up. */ +    /* Let the data source manager determine how to resync. */ +    if (! (*cinfo->src->resync_to_restart) (cinfo, +					    cinfo->marker->next_restart_num)) +      return FALSE; +  } + +  /* Update next-restart state */ +  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; + +  return TRUE; +} + + +/* + * This is the default resync_to_restart method for data source managers + * to use if they don't have any better approach.  Some data source managers + * may be able to back up, or may have additional knowledge about the data + * which permits a more intelligent recovery strategy; such managers would + * presumably supply their own resync method. + * + * read_restart_marker calls resync_to_restart if it finds a marker other than + * the restart marker it was expecting.  (This code is *not* used unless + * a nonzero restart interval has been declared.)  cinfo->unread_marker is + * the marker code actually found (might be anything, except 0 or FF). + * The desired restart marker number (0..7) is passed as a parameter. + * This routine is supposed to apply whatever error recovery strategy seems + * appropriate in order to position the input stream to the next data segment. + * Note that cinfo->unread_marker is treated as a marker appearing before + * the current data-source input point; usually it should be reset to zero + * before returning. + * Returns FALSE if suspension is required. + * + * This implementation is substantially constrained by wanting to treat the + * input as a data stream; this means we can't back up.  Therefore, we have + * only the following actions to work with: + *   1. Simply discard the marker and let the entropy decoder resume at next + *      byte of file. + *   2. Read forward until we find another marker, discarding intervening + *      data.  (In theory we could look ahead within the current bufferload, + *      without having to discard data if we don't find the desired marker. + *      This idea is not implemented here, in part because it makes behavior + *      dependent on buffer size and chance buffer-boundary positions.) + *   3. Leave the marker unread (by failing to zero cinfo->unread_marker). + *      This will cause the entropy decoder to process an empty data segment, + *      inserting dummy zeroes, and then we will reprocess the marker. + * + * #2 is appropriate if we think the desired marker lies ahead, while #3 is + * appropriate if the found marker is a future restart marker (indicating + * that we have missed the desired restart marker, probably because it got + * corrupted). + * We apply #2 or #3 if the found marker is a restart marker no more than + * two counts behind or ahead of the expected one.  We also apply #2 if the + * found marker is not a legal JPEG marker code (it's certainly bogus data). + * If the found marker is a restart marker more than 2 counts away, we do #1 + * (too much risk that the marker is erroneous; with luck we will be able to + * resync at some future point). + * For any valid non-restart JPEG marker, we apply #3.  This keeps us from + * overrunning the end of a scan.  An implementation limited to single-scan + * files might find it better to apply #2 for markers other than EOI, since + * any other marker would have to be bogus data in that case. + */ + +GLOBAL boolean +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ +  int marker = cinfo->unread_marker; +  int action = 1; +   +  /* Always put up a warning. */ +  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); +   +  /* Outer loop handles repeated decision after scanning forward. */ +  for (;;) { +    if (marker < (int) M_SOF0) +      action = 2;		/* invalid marker */ +    else if (marker < (int) M_RST0 || marker > (int) M_RST7) +      action = 3;		/* valid non-restart marker */ +    else { +      if (marker == ((int) M_RST0 + ((desired+1) & 7)) || +	  marker == ((int) M_RST0 + ((desired+2) & 7))) +	action = 3;		/* one of the next two expected restarts */ +      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || +	       marker == ((int) M_RST0 + ((desired-2) & 7))) +	action = 2;		/* a prior restart, so advance */ +      else +	action = 1;		/* desired restart or too far away */ +    } +    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); +    switch (action) { +    case 1: +      /* Discard marker and let entropy decoder resume processing. */ +      cinfo->unread_marker = 0; +      return TRUE; +    case 2: +      /* Scan to the next marker, and repeat the decision loop. */ +      if (! next_marker(cinfo)) +	return FALSE; +      marker = cinfo->unread_marker; +      break; +    case 3: +      /* Return without advancing past this marker. */ +      /* Entropy decoder will be forced to process an empty segment. */ +      return TRUE; +    } +  } /* end loop */ +} + + +/* + * Reset marker processing state to begin a fresh datastream. + */ + +METHODDEF void +reset_marker_reader (j_decompress_ptr cinfo) +{ +  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; +} + + +/* + * Initialize the marker reader module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL void +jinit_marker_reader (j_decompress_ptr cinfo) +{ +  int i; + +  /* Create subobject in permanent pool */ +  cinfo->marker = (struct jpeg_marker_reader *) +    (*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; +  /* Reset marker processing state */ +  reset_marker_reader(cinfo); +} diff --git a/libs/jpeg6/jdmaster.cpp b/libs/jpeg6/jdmaster.cpp index 64f730f..18e0880 100755 --- a/libs/jpeg6/jdmaster.cpp +++ b/libs/jpeg6/jdmaster.cpp @@ -1,557 +1,557 @@ -/*
 - * jdmaster.c
 - *
 - * Copyright (C) 1991-1995, 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 master control logic for the JPEG decompressor.
 - * These routines are concerned with selecting the modules to be executed
 - * and with determining the number of passes and the work to be done in each
 - * pass.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Private state */
 -
 -typedef struct {
 -  struct jpeg_decomp_master pub; /* public fields */
 -
 -  int pass_number;		/* # of passes completed */
 -
 -  boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
 -
 -  /* Saved references to initialized quantizer modules,
 -   * in case we need to switch modes.
 -   */
 -  struct jpeg_color_quantizer * quantizer_1pass;
 -  struct jpeg_color_quantizer * quantizer_2pass;
 -} my_decomp_master;
 -
 -typedef my_decomp_master * my_master_ptr;
 -
 -
 -/*
 - * Determine whether merged upsample/color conversion should be used.
 - * CRUCIAL: this must match the actual capabilities of jdmerge.c!
 - */
 -
 -LOCAL boolean
 -use_merged_upsample (j_decompress_ptr cinfo)
 -{
 -#ifdef UPSAMPLE_MERGING_SUPPORTED
 -  /* Merging is the equivalent of plain box-filter upsampling */
 -  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
 -    return FALSE;
 -  /* jdmerge.c only supports YCC=>RGB color conversion */
 -  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
 -      cinfo->out_color_space != JCS_RGB ||
 -      cinfo->out_color_components != RGB_PIXELSIZE)
 -    return FALSE;
 -  /* and it only handles 2h1v or 2h2v sampling ratios */
 -  if (cinfo->comp_info[0].h_samp_factor != 2 ||
 -      cinfo->comp_info[1].h_samp_factor != 1 ||
 -      cinfo->comp_info[2].h_samp_factor != 1 ||
 -      cinfo->comp_info[0].v_samp_factor >  2 ||
 -      cinfo->comp_info[1].v_samp_factor != 1 ||
 -      cinfo->comp_info[2].v_samp_factor != 1)
 -    return FALSE;
 -  /* furthermore, it doesn't work if we've scaled the IDCTs differently */
 -  if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
 -      cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
 -      cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
 -    return FALSE;
 -  /* ??? also need to test for upsample-time rescaling, when & if supported */
 -  return TRUE;			/* by golly, it'll work... */
 -#else
 -  return FALSE;
 -#endif
 -}
 -
 -
 -/*
 - * Compute output image dimensions and related values.
 - * NOTE: this is exported for possible use by application.
 - * Hence it mustn't do anything that can't be done twice.
 - * Also note that it may be called before the master module is initialized!
 - */
 -
 -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
 -  int ci;
 -  jpeg_component_info *compptr;
 -#endif
 -
 -  /* Prevent application from calling me at wrong times */
 -  if (cinfo->global_state != DSTATE_READY)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -
 -#ifdef IDCT_SCALING_SUPPORTED
 -
 -  /* Compute actual output image dimensions and DCT scaling choices. */
 -  if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
 -    /* Provide 1/8 scaling */
 -    cinfo->output_width = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width, 8L);
 -    cinfo->output_height = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height, 8L);
 -    cinfo->min_DCT_scaled_size = 1;
 -  } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
 -    /* Provide 1/4 scaling */
 -    cinfo->output_width = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width, 4L);
 -    cinfo->output_height = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height, 4L);
 -    cinfo->min_DCT_scaled_size = 2;
 -  } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
 -    /* Provide 1/2 scaling */
 -    cinfo->output_width = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width, 2L);
 -    cinfo->output_height = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height, 2L);
 -    cinfo->min_DCT_scaled_size = 4;
 -  } else {
 -    /* Provide 1/1 scaling */
 -    cinfo->output_width = cinfo->image_width;
 -    cinfo->output_height = cinfo->image_height;
 -    cinfo->min_DCT_scaled_size = DCTSIZE;
 -  }
 -  /* In selecting the actual DCT scaling for each component, we try to
 -   * scale up the chroma components via IDCT scaling rather than upsampling.
 -   * This saves time if the upsampler gets to use 1:1 scaling.
 -   * Note this code assumes that the supported DCT scalings are powers of 2.
 -   */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    int ssize = cinfo->min_DCT_scaled_size;
 -    while (ssize < DCTSIZE &&
 -	   (compptr->h_samp_factor * ssize * 2 <=
 -	    cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
 -	   (compptr->v_samp_factor * ssize * 2 <=
 -	    cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
 -      ssize = ssize * 2;
 -    }
 -    compptr->DCT_scaled_size = ssize;
 -  }
 -
 -  /* Recompute downsampled dimensions of components;
 -   * application needs to know these if using raw downsampled data.
 -   */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Size in samples, after IDCT scaling */
 -    compptr->downsampled_width = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_width *
 -		    (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
 -		    (long) (cinfo->max_h_samp_factor * DCTSIZE));
 -    compptr->downsampled_height = (JDIMENSION)
 -      jdiv_round_up((long) cinfo->image_height *
 -		    (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
 -		    (long) (cinfo->max_v_samp_factor * DCTSIZE));
 -  }
 -
 -#else /* !IDCT_SCALING_SUPPORTED */
 -
 -  /* Hardwire it to "no scaling" */
 -  cinfo->output_width = cinfo->image_width;
 -  cinfo->output_height = cinfo->image_height;
 -  /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
 -   * and has computed unscaled downsampled_width and downsampled_height.
 -   */
 -
 -#endif /* IDCT_SCALING_SUPPORTED */
 -
 -  /* Report number of components in selected colorspace. */
 -  /* Probably this should be in the color conversion module... */
 -  switch (cinfo->out_color_space) {
 -  case JCS_GRAYSCALE:
 -    cinfo->out_color_components = 1;
 -    break;
 -  case JCS_RGB:
 -#if RGB_PIXELSIZE != 3
 -    cinfo->out_color_components = RGB_PIXELSIZE;
 -    break;
 -#endif /* else share code with YCbCr */
 -  case JCS_YCbCr:
 -    cinfo->out_color_components = 3;
 -    break;
 -  case JCS_CMYK:
 -  case JCS_YCCK:
 -    cinfo->out_color_components = 4;
 -    break;
 -  default:			/* else must be same colorspace as in file */
 -    cinfo->out_color_components = cinfo->num_components;
 -    break;
 -  }
 -  cinfo->output_components = (cinfo->quantize_colors ? 1 :
 -			      cinfo->out_color_components);
 -
 -  /* See if upsampler will want to emit more than one row at a time */
 -  if (use_merged_upsample(cinfo))
 -    cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
 -  else
 -    cinfo->rec_outbuf_height = 1;
 -}
 -
 -
 -/*
 - * Several decompression processes need to range-limit values to the range
 - * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
 - * due to noise introduced by quantization, roundoff error, etc.  These
 - * processes are inner loops and need to be as fast as possible.  On most
 - * machines, particularly CPUs with pipelines or instruction prefetch,
 - * a (subscript-check-less) C table lookup
 - *		x = sample_range_limit[x];
 - * is faster than explicit tests
 - *		if (x < 0)  x = 0;
 - *		else if (x > MAXJSAMPLE)  x = MAXJSAMPLE;
 - * These processes all use a common table prepared by the routine below.
 - *
 - * For most steps we can mathematically guarantee that the initial value
 - * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
 - * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient.  But for the initial
 - * limiting step (just after the IDCT), a wildly out-of-range value is 
 - * possible if the input data is corrupt.  To avoid any chance of indexing
 - * off the end of memory and getting a bad-pointer trap, we perform the
 - * post-IDCT limiting thus:
 - *		x = range_limit[x & MASK];
 - * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
 - * samples.  Under normal circumstances this is more than enough range and
 - * a correct output will be generated; with bogus input data the mask will
 - * cause wraparound, and we will safely generate a bogus-but-in-range output.
 - * For the post-IDCT step, we want to convert the data from signed to unsigned
 - * representation by adding CENTERJSAMPLE at the same time that we limit it.
 - * So the post-IDCT limiting table ends up looking like this:
 - *   CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
 - *   MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
 - *   0          (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
 - *   0,1,...,CENTERJSAMPLE-1
 - * Negative inputs select values from the upper half of the table after
 - * masking.
 - *
 - * We can save some space by overlapping the start of the post-IDCT table
 - * with the simpler range limiting table.  The post-IDCT table begins at
 - * sample_range_limit + CENTERJSAMPLE.
 - *
 - * Note that the table is allocated in near data space on PCs; it's small
 - * enough and used often enough to justify this.
 - */
 -
 -LOCAL void
 -prepare_range_limit_table (j_decompress_ptr cinfo)
 -/* Allocate and fill in the sample_range_limit table */
 -{
 -  JSAMPLE * table;
 -  int i;
 -
 -  table = (JSAMPLE *)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
 -  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */
 -  cinfo->sample_range_limit = table;
 -  /* First segment of "simple" table: limit[x] = 0 for x < 0 */
 -  MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
 -  /* Main part of "simple" table: limit[x] = x */
 -  for (i = 0; i <= MAXJSAMPLE; i++)
 -    table[i] = (JSAMPLE) i;
 -  table += CENTERJSAMPLE;	/* Point to where post-IDCT table starts */
 -  /* End of simple table, rest of first half of post-IDCT table */
 -  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
 -    table[i] = MAXJSAMPLE;
 -  /* Second half of post-IDCT table */
 -  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
 -	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
 -  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
 -	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
 -}
 -
 -
 -/*
 - * Master selection of decompression modules.
 - * This is done once at jpeg_start_decompress time.  We determine
 - * which modules will be used and give them appropriate initialization calls.
 - * We also initialize the decompressor input side to begin consuming data.
 - *
 - * Since jpeg_read_header has finished, we know what is in the SOF
 - * and (first) SOS markers.  We also have all the application parameter
 - * settings.
 - */
 -
 -LOCAL void
 -master_selection (j_decompress_ptr cinfo)
 -{
 -  my_master_ptr master = (my_master_ptr) cinfo->master;
 -  boolean use_c_buffer;
 -  long samplesperrow;
 -  JDIMENSION jd_samplesperrow;
 -
 -  /* Initialize dimensions and other stuff */
 -  jpeg_calc_output_dimensions(cinfo);
 -  prepare_range_limit_table(cinfo);
 -
 -  /* Width of an output scanline must be representable as JDIMENSION. */
 -  samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
 -  jd_samplesperrow = (JDIMENSION) samplesperrow;
 -  if ((long) jd_samplesperrow != samplesperrow)
 -    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 -
 -  /* Initialize my private state */
 -  master->pass_number = 0;
 -  master->using_merged_upsample = use_merged_upsample(cinfo);
 -
 -  /* Color quantizer selection */
 -  master->quantizer_1pass = NULL;
 -  master->quantizer_2pass = NULL;
 -  /* No mode changes if not using buffered-image mode. */
 -  if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
 -    cinfo->enable_1pass_quant = FALSE;
 -    cinfo->enable_external_quant = FALSE;
 -    cinfo->enable_2pass_quant = FALSE;
 -  }
 -  if (cinfo->quantize_colors) {
 -    if (cinfo->raw_data_out)
 -      ERREXIT(cinfo, JERR_NOTIMPL);
 -    /* 2-pass quantizer only works in 3-component color space. */
 -    if (cinfo->out_color_components != 3) {
 -      cinfo->enable_1pass_quant = TRUE;
 -      cinfo->enable_external_quant = FALSE;
 -      cinfo->enable_2pass_quant = FALSE;
 -      cinfo->colormap = NULL;
 -    } else if (cinfo->colormap != NULL) {
 -      cinfo->enable_external_quant = TRUE;
 -    } else if (cinfo->two_pass_quantize) {
 -      cinfo->enable_2pass_quant = TRUE;
 -    } else {
 -      cinfo->enable_1pass_quant = TRUE;
 -    }
 -
 -    if (cinfo->enable_1pass_quant) {
 -#ifdef QUANT_1PASS_SUPPORTED
 -      jinit_1pass_quantizer(cinfo);
 -      master->quantizer_1pass = cinfo->cquantize;
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -    }
 -
 -    /* We use the 2-pass code to map to external colormaps. */
 -    if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
 -#ifdef QUANT_2PASS_SUPPORTED
 -      jinit_2pass_quantizer(cinfo);
 -      master->quantizer_2pass = cinfo->cquantize;
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -    }
 -    /* If both quantizers are initialized, the 2-pass one is left active;
 -     * this is necessary for starting with quantization to an external map.
 -     */
 -  }
 -
 -  /* Post-processing: in particular, color conversion first */
 -  if (! cinfo->raw_data_out) {
 -    if (master->using_merged_upsample) {
 -#ifdef UPSAMPLE_MERGING_SUPPORTED
 -      jinit_merged_upsampler(cinfo); /* does color conversion too */
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -    } else {
 -      jinit_color_deconverter(cinfo);
 -      jinit_upsampler(cinfo);
 -    }
 -    jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
 -  }
 -  /* Inverse DCT */
 -  jinit_inverse_dct(cinfo);
 -  /* Entropy decoding: either Huffman or arithmetic coding. */
 -  if (cinfo->arith_code) {
 -    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 -  } else {
 -    if (cinfo->progressive_mode) {
 -#ifdef D_PROGRESSIVE_SUPPORTED
 -      jinit_phuff_decoder(cinfo);
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -    } else
 -      jinit_huff_decoder(cinfo);
 -  }
 -
 -  /* Initialize principal buffer controllers. */
 -  use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
 -  jinit_d_coef_controller(cinfo, use_c_buffer);
 -
 -  if (! cinfo->raw_data_out)
 -    jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
 -
 -  /* We can now tell the memory manager to allocate virtual arrays. */
 -  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 -
 -  /* Initialize input side of decompressor to consume first scan. */
 -  (*cinfo->inputctl->start_input_pass) (cinfo);
 -
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -  /* If jpeg_start_decompress will read the whole file, initialize
 -   * progress monitoring appropriately.  The input step is counted
 -   * as one pass.
 -   */
 -  if (cinfo->progress != NULL && ! cinfo->buffered_image &&
 -      cinfo->inputctl->has_multiple_scans) {
 -    int nscans;
 -    /* Estimate number of scans to set pass_limit. */
 -    if (cinfo->progressive_mode) {
 -      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
 -      nscans = 2 + 3 * cinfo->num_components;
 -    } else {
 -      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
 -      nscans = cinfo->num_components;
 -    }
 -    cinfo->progress->pass_counter = 0L;
 -    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
 -    cinfo->progress->completed_passes = 0;
 -    cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
 -    /* Count the input pass as done */
 -    master->pass_number++;
 -  }
 -#endif /* D_MULTISCAN_FILES_SUPPORTED */
 -}
 -
 -
 -/*
 - * Per-pass setup.
 - * This is called at the beginning of each output pass.  We determine which
 - * 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.)
 - */
 -
 -METHODDEF void
 -prepare_for_output_pass (j_decompress_ptr cinfo)
 -{
 -  my_master_ptr master = (my_master_ptr) cinfo->master;
 -
 -  if (master->pub.is_dummy_pass) {
 -#ifdef QUANT_2PASS_SUPPORTED
 -    /* Final pass of 2-pass quantization */
 -    master->pub.is_dummy_pass = FALSE;
 -    (*cinfo->cquantize->start_pass) (cinfo, FALSE);
 -    (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
 -    (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
 -#else
 -    ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif /* QUANT_2PASS_SUPPORTED */
 -  } else {
 -    if (cinfo->quantize_colors && cinfo->colormap == NULL) {
 -      /* Select new quantization method */
 -      if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
 -	cinfo->cquantize = master->quantizer_2pass;
 -	master->pub.is_dummy_pass = TRUE;
 -      } else if (cinfo->enable_1pass_quant) {
 -	cinfo->cquantize = master->quantizer_1pass;
 -      } else {
 -	ERREXIT(cinfo, JERR_MODE_CHANGE);
 -      }
 -    }
 -    (*cinfo->idct->start_pass) (cinfo);
 -    (*cinfo->coef->start_output_pass) (cinfo);
 -    if (! cinfo->raw_data_out) {
 -      if (! master->using_merged_upsample)
 -	(*cinfo->cconvert->start_pass) (cinfo);
 -      (*cinfo->upsample->start_pass) (cinfo);
 -      if (cinfo->quantize_colors)
 -	(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
 -      (*cinfo->post->start_pass) (cinfo,
 -	    (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
 -      (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
 -    }
 -  }
 -
 -  /* Set up progress monitor's pass info if present */
 -  if (cinfo->progress != NULL) {
 -    cinfo->progress->completed_passes = master->pass_number;
 -    cinfo->progress->total_passes = master->pass_number +
 -				    (master->pub.is_dummy_pass ? 2 : 1);
 -    /* In buffered-image mode, we assume one more output pass if EOI not
 -     * yet reached, but no more passes if EOI has been reached.
 -     */
 -    if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
 -      cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Finish up at end of an output pass.
 - */
 -
 -METHODDEF void
 -finish_output_pass (j_decompress_ptr cinfo)
 -{
 -  my_master_ptr master = (my_master_ptr) cinfo->master;
 -
 -  if (cinfo->quantize_colors)
 -    (*cinfo->cquantize->finish_pass) (cinfo);
 -  master->pass_number++;
 -}
 -
 -
 -#ifdef D_MULTISCAN_FILES_SUPPORTED
 -
 -/*
 - * Switch to a new external colormap between output passes.
 - */
 -
 -GLOBAL void
 -jpeg_new_colormap (j_decompress_ptr cinfo)
 -{
 -  my_master_ptr master = (my_master_ptr) cinfo->master;
 -
 -  /* Prevent application from calling me at wrong times */
 -  if (cinfo->global_state != DSTATE_BUFIMAGE)
 -    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 -
 -  if (cinfo->quantize_colors && cinfo->enable_external_quant &&
 -      cinfo->colormap != NULL) {
 -    /* Select 2-pass quantizer for external colormap use */
 -    cinfo->cquantize = master->quantizer_2pass;
 -    /* Notify quantizer of colormap change */
 -    (*cinfo->cquantize->new_color_map) (cinfo);
 -    master->pub.is_dummy_pass = FALSE; /* just in case */
 -  } else
 -    ERREXIT(cinfo, JERR_MODE_CHANGE);
 -}
 -
 -#endif /* D_MULTISCAN_FILES_SUPPORTED */
 -
 -
 -/*
 - * Initialize master decompression control and select active modules.
 - * This is performed at the start of jpeg_start_decompress.
 - */
 -
 -GLOBAL void
 -jinit_master_decompress (j_decompress_ptr cinfo)
 -{
 -  my_master_ptr master;
 -
 -  master = (my_master_ptr)
 -      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				  SIZEOF(my_decomp_master));
 -  cinfo->master = (struct jpeg_decomp_master *) master;
 -  master->pub.prepare_for_output_pass = prepare_for_output_pass;
 -  master->pub.finish_output_pass = finish_output_pass;
 -
 -  master->pub.is_dummy_pass = FALSE;
 -
 -  master_selection(cinfo);
 -}
 +/* + * jdmaster.c + * + * Copyright (C) 1991-1995, 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 master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { +  struct jpeg_decomp_master pub; /* public fields */ + +  int pass_number;		/* # of passes completed */ + +  boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ + +  /* Saved references to initialized quantizer modules, +   * in case we need to switch modes. +   */ +  struct jpeg_color_quantizer * quantizer_1pass; +  struct jpeg_color_quantizer * quantizer_2pass; +} my_decomp_master; + +typedef my_decomp_master * my_master_ptr; + + +/* + * Determine whether merged upsample/color conversion should be used. + * CRUCIAL: this must match the actual capabilities of jdmerge.c! + */ + +LOCAL boolean +use_merged_upsample (j_decompress_ptr cinfo) +{ +#ifdef UPSAMPLE_MERGING_SUPPORTED +  /* Merging is the equivalent of plain box-filter upsampling */ +  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) +    return FALSE; +  /* jdmerge.c only supports YCC=>RGB color conversion */ +  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || +      cinfo->out_color_space != JCS_RGB || +      cinfo->out_color_components != RGB_PIXELSIZE) +    return FALSE; +  /* and it only handles 2h1v or 2h2v sampling ratios */ +  if (cinfo->comp_info[0].h_samp_factor != 2 || +      cinfo->comp_info[1].h_samp_factor != 1 || +      cinfo->comp_info[2].h_samp_factor != 1 || +      cinfo->comp_info[0].v_samp_factor >  2 || +      cinfo->comp_info[1].v_samp_factor != 1 || +      cinfo->comp_info[2].v_samp_factor != 1) +    return FALSE; +  /* furthermore, it doesn't work if we've scaled the IDCTs differently */ +  if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || +      cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || +      cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) +    return FALSE; +  /* ??? also need to test for upsample-time rescaling, when & if supported */ +  return TRUE;			/* by golly, it'll work... */ +#else +  return FALSE; +#endif +} + + +/* + * Compute output image dimensions and related values. + * NOTE: this is exported for possible use by application. + * Hence it mustn't do anything that can't be done twice. + * Also note that it may be called before the master module is initialized! + */ + +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 +  int ci; +  jpeg_component_info *compptr; +#endif + +  /* Prevent application from calling me at wrong times */ +  if (cinfo->global_state != DSTATE_READY) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +#ifdef IDCT_SCALING_SUPPORTED + +  /* Compute actual output image dimensions and DCT scaling choices. */ +  if (cinfo->scale_num * 8 <= cinfo->scale_denom) { +    /* Provide 1/8 scaling */ +    cinfo->output_width = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width, 8L); +    cinfo->output_height = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height, 8L); +    cinfo->min_DCT_scaled_size = 1; +  } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { +    /* Provide 1/4 scaling */ +    cinfo->output_width = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width, 4L); +    cinfo->output_height = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height, 4L); +    cinfo->min_DCT_scaled_size = 2; +  } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { +    /* Provide 1/2 scaling */ +    cinfo->output_width = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width, 2L); +    cinfo->output_height = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height, 2L); +    cinfo->min_DCT_scaled_size = 4; +  } else { +    /* Provide 1/1 scaling */ +    cinfo->output_width = cinfo->image_width; +    cinfo->output_height = cinfo->image_height; +    cinfo->min_DCT_scaled_size = DCTSIZE; +  } +  /* In selecting the actual DCT scaling for each component, we try to +   * scale up the chroma components via IDCT scaling rather than upsampling. +   * This saves time if the upsampler gets to use 1:1 scaling. +   * Note this code assumes that the supported DCT scalings are powers of 2. +   */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    int ssize = cinfo->min_DCT_scaled_size; +    while (ssize < DCTSIZE && +	   (compptr->h_samp_factor * ssize * 2 <= +	    cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && +	   (compptr->v_samp_factor * ssize * 2 <= +	    cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { +      ssize = ssize * 2; +    } +    compptr->DCT_scaled_size = ssize; +  } + +  /* Recompute downsampled dimensions of components; +   * application needs to know these if using raw downsampled data. +   */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Size in samples, after IDCT scaling */ +    compptr->downsampled_width = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_width * +		    (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), +		    (long) (cinfo->max_h_samp_factor * DCTSIZE)); +    compptr->downsampled_height = (JDIMENSION) +      jdiv_round_up((long) cinfo->image_height * +		    (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), +		    (long) (cinfo->max_v_samp_factor * DCTSIZE)); +  } + +#else /* !IDCT_SCALING_SUPPORTED */ + +  /* Hardwire it to "no scaling" */ +  cinfo->output_width = cinfo->image_width; +  cinfo->output_height = cinfo->image_height; +  /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, +   * and has computed unscaled downsampled_width and downsampled_height. +   */ + +#endif /* IDCT_SCALING_SUPPORTED */ + +  /* Report number of components in selected colorspace. */ +  /* Probably this should be in the color conversion module... */ +  switch (cinfo->out_color_space) { +  case JCS_GRAYSCALE: +    cinfo->out_color_components = 1; +    break; +  case JCS_RGB: +#if RGB_PIXELSIZE != 3 +    cinfo->out_color_components = RGB_PIXELSIZE; +    break; +#endif /* else share code with YCbCr */ +  case JCS_YCbCr: +    cinfo->out_color_components = 3; +    break; +  case JCS_CMYK: +  case JCS_YCCK: +    cinfo->out_color_components = 4; +    break; +  default:			/* else must be same colorspace as in file */ +    cinfo->out_color_components = cinfo->num_components; +    break; +  } +  cinfo->output_components = (cinfo->quantize_colors ? 1 : +			      cinfo->out_color_components); + +  /* See if upsampler will want to emit more than one row at a time */ +  if (use_merged_upsample(cinfo)) +    cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; +  else +    cinfo->rec_outbuf_height = 1; +} + + +/* + * Several decompression processes need to range-limit values to the range + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range + * due to noise introduced by quantization, roundoff error, etc.  These + * processes are inner loops and need to be as fast as possible.  On most + * machines, particularly CPUs with pipelines or instruction prefetch, + * a (subscript-check-less) C table lookup + *		x = sample_range_limit[x]; + * is faster than explicit tests + *		if (x < 0)  x = 0; + *		else if (x > MAXJSAMPLE)  x = MAXJSAMPLE; + * These processes all use a common table prepared by the routine below. + * + * For most steps we can mathematically guarantee that the initial value + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient.  But for the initial + * limiting step (just after the IDCT), a wildly out-of-range value is  + * possible if the input data is corrupt.  To avoid any chance of indexing + * off the end of memory and getting a bad-pointer trap, we perform the + * post-IDCT limiting thus: + *		x = range_limit[x & MASK]; + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + * samples.  Under normal circumstances this is more than enough range and + * a correct output will be generated; with bogus input data the mask will + * cause wraparound, and we will safely generate a bogus-but-in-range output. + * For the post-IDCT step, we want to convert the data from signed to unsigned + * representation by adding CENTERJSAMPLE at the same time that we limit it. + * So the post-IDCT limiting table ends up looking like this: + *   CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + *   MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + *   0          (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + *   0,1,...,CENTERJSAMPLE-1 + * Negative inputs select values from the upper half of the table after + * masking. + * + * We can save some space by overlapping the start of the post-IDCT table + * with the simpler range limiting table.  The post-IDCT table begins at + * sample_range_limit + CENTERJSAMPLE. + * + * Note that the table is allocated in near data space on PCs; it's small + * enough and used often enough to justify this. + */ + +LOCAL void +prepare_range_limit_table (j_decompress_ptr cinfo) +/* Allocate and fill in the sample_range_limit table */ +{ +  JSAMPLE * table; +  int i; + +  table = (JSAMPLE *) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); +  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */ +  cinfo->sample_range_limit = table; +  /* First segment of "simple" table: limit[x] = 0 for x < 0 */ +  MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); +  /* Main part of "simple" table: limit[x] = x */ +  for (i = 0; i <= MAXJSAMPLE; i++) +    table[i] = (JSAMPLE) i; +  table += CENTERJSAMPLE;	/* Point to where post-IDCT table starts */ +  /* End of simple table, rest of first half of post-IDCT table */ +  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) +    table[i] = MAXJSAMPLE; +  /* Second half of post-IDCT table */ +  MEMZERO(table + (2 * (MAXJSAMPLE+1)), +	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); +  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), +	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); +} + + +/* + * Master selection of decompression modules. + * This is done once at jpeg_start_decompress time.  We determine + * which modules will be used and give them appropriate initialization calls. + * We also initialize the decompressor input side to begin consuming data. + * + * Since jpeg_read_header has finished, we know what is in the SOF + * and (first) SOS markers.  We also have all the application parameter + * settings. + */ + +LOCAL void +master_selection (j_decompress_ptr cinfo) +{ +  my_master_ptr master = (my_master_ptr) cinfo->master; +  boolean use_c_buffer; +  long samplesperrow; +  JDIMENSION jd_samplesperrow; + +  /* Initialize dimensions and other stuff */ +  jpeg_calc_output_dimensions(cinfo); +  prepare_range_limit_table(cinfo); + +  /* Width of an output scanline must be representable as JDIMENSION. */ +  samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; +  jd_samplesperrow = (JDIMENSION) samplesperrow; +  if ((long) jd_samplesperrow != samplesperrow) +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + +  /* Initialize my private state */ +  master->pass_number = 0; +  master->using_merged_upsample = use_merged_upsample(cinfo); + +  /* Color quantizer selection */ +  master->quantizer_1pass = NULL; +  master->quantizer_2pass = NULL; +  /* No mode changes if not using buffered-image mode. */ +  if (! cinfo->quantize_colors || ! cinfo->buffered_image) { +    cinfo->enable_1pass_quant = FALSE; +    cinfo->enable_external_quant = FALSE; +    cinfo->enable_2pass_quant = FALSE; +  } +  if (cinfo->quantize_colors) { +    if (cinfo->raw_data_out) +      ERREXIT(cinfo, JERR_NOTIMPL); +    /* 2-pass quantizer only works in 3-component color space. */ +    if (cinfo->out_color_components != 3) { +      cinfo->enable_1pass_quant = TRUE; +      cinfo->enable_external_quant = FALSE; +      cinfo->enable_2pass_quant = FALSE; +      cinfo->colormap = NULL; +    } else if (cinfo->colormap != NULL) { +      cinfo->enable_external_quant = TRUE; +    } else if (cinfo->two_pass_quantize) { +      cinfo->enable_2pass_quant = TRUE; +    } else { +      cinfo->enable_1pass_quant = TRUE; +    } + +    if (cinfo->enable_1pass_quant) { +#ifdef QUANT_1PASS_SUPPORTED +      jinit_1pass_quantizer(cinfo); +      master->quantizer_1pass = cinfo->cquantize; +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +    } + +    /* We use the 2-pass code to map to external colormaps. */ +    if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { +#ifdef QUANT_2PASS_SUPPORTED +      jinit_2pass_quantizer(cinfo); +      master->quantizer_2pass = cinfo->cquantize; +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +    } +    /* If both quantizers are initialized, the 2-pass one is left active; +     * this is necessary for starting with quantization to an external map. +     */ +  } + +  /* Post-processing: in particular, color conversion first */ +  if (! cinfo->raw_data_out) { +    if (master->using_merged_upsample) { +#ifdef UPSAMPLE_MERGING_SUPPORTED +      jinit_merged_upsampler(cinfo); /* does color conversion too */ +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +    } else { +      jinit_color_deconverter(cinfo); +      jinit_upsampler(cinfo); +    } +    jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); +  } +  /* Inverse DCT */ +  jinit_inverse_dct(cinfo); +  /* Entropy decoding: either Huffman or arithmetic coding. */ +  if (cinfo->arith_code) { +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL); +  } else { +    if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED +      jinit_phuff_decoder(cinfo); +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +    } else +      jinit_huff_decoder(cinfo); +  } + +  /* Initialize principal buffer controllers. */ +  use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; +  jinit_d_coef_controller(cinfo, use_c_buffer); + +  if (! cinfo->raw_data_out) +    jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); + +  /* We can now tell the memory manager to allocate virtual arrays. */ +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + +  /* Initialize input side of decompressor to consume first scan. */ +  (*cinfo->inputctl->start_input_pass) (cinfo); + +#ifdef D_MULTISCAN_FILES_SUPPORTED +  /* If jpeg_start_decompress will read the whole file, initialize +   * progress monitoring appropriately.  The input step is counted +   * as one pass. +   */ +  if (cinfo->progress != NULL && ! cinfo->buffered_image && +      cinfo->inputctl->has_multiple_scans) { +    int nscans; +    /* Estimate number of scans to set pass_limit. */ +    if (cinfo->progressive_mode) { +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ +      nscans = 2 + 3 * cinfo->num_components; +    } else { +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */ +      nscans = cinfo->num_components; +    } +    cinfo->progress->pass_counter = 0L; +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; +    cinfo->progress->completed_passes = 0; +    cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); +    /* Count the input pass as done */ +    master->pass_number++; +  } +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +} + + +/* + * Per-pass setup. + * This is called at the beginning of each output pass.  We determine which + * 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.) + */ + +METHODDEF void +prepare_for_output_pass (j_decompress_ptr cinfo) +{ +  my_master_ptr master = (my_master_ptr) cinfo->master; + +  if (master->pub.is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED +    /* Final pass of 2-pass quantization */ +    master->pub.is_dummy_pass = FALSE; +    (*cinfo->cquantize->start_pass) (cinfo, FALSE); +    (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); +    (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); +#else +    ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ +  } else { +    if (cinfo->quantize_colors && cinfo->colormap == NULL) { +      /* Select new quantization method */ +      if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { +	cinfo->cquantize = master->quantizer_2pass; +	master->pub.is_dummy_pass = TRUE; +      } else if (cinfo->enable_1pass_quant) { +	cinfo->cquantize = master->quantizer_1pass; +      } else { +	ERREXIT(cinfo, JERR_MODE_CHANGE); +      } +    } +    (*cinfo->idct->start_pass) (cinfo); +    (*cinfo->coef->start_output_pass) (cinfo); +    if (! cinfo->raw_data_out) { +      if (! master->using_merged_upsample) +	(*cinfo->cconvert->start_pass) (cinfo); +      (*cinfo->upsample->start_pass) (cinfo); +      if (cinfo->quantize_colors) +	(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); +      (*cinfo->post->start_pass) (cinfo, +	    (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); +      (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); +    } +  } + +  /* Set up progress monitor's pass info if present */ +  if (cinfo->progress != NULL) { +    cinfo->progress->completed_passes = master->pass_number; +    cinfo->progress->total_passes = master->pass_number + +				    (master->pub.is_dummy_pass ? 2 : 1); +    /* In buffered-image mode, we assume one more output pass if EOI not +     * yet reached, but no more passes if EOI has been reached. +     */ +    if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { +      cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); +    } +  } +} + + +/* + * Finish up at end of an output pass. + */ + +METHODDEF void +finish_output_pass (j_decompress_ptr cinfo) +{ +  my_master_ptr master = (my_master_ptr) cinfo->master; + +  if (cinfo->quantize_colors) +    (*cinfo->cquantize->finish_pass) (cinfo); +  master->pass_number++; +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Switch to a new external colormap between output passes. + */ + +GLOBAL void +jpeg_new_colormap (j_decompress_ptr cinfo) +{ +  my_master_ptr master = (my_master_ptr) cinfo->master; + +  /* Prevent application from calling me at wrong times */ +  if (cinfo->global_state != DSTATE_BUFIMAGE) +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +  if (cinfo->quantize_colors && cinfo->enable_external_quant && +      cinfo->colormap != NULL) { +    /* Select 2-pass quantizer for external colormap use */ +    cinfo->cquantize = master->quantizer_2pass; +    /* Notify quantizer of colormap change */ +    (*cinfo->cquantize->new_color_map) (cinfo); +    master->pub.is_dummy_pass = FALSE; /* just in case */ +  } else +    ERREXIT(cinfo, JERR_MODE_CHANGE); +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize master decompression control and select active modules. + * This is performed at the start of jpeg_start_decompress. + */ + +GLOBAL void +jinit_master_decompress (j_decompress_ptr cinfo) +{ +  my_master_ptr master; + +  master = (my_master_ptr) +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				  SIZEOF(my_decomp_master)); +  cinfo->master = (struct jpeg_decomp_master *) master; +  master->pub.prepare_for_output_pass = prepare_for_output_pass; +  master->pub.finish_output_pass = finish_output_pass; + +  master->pub.is_dummy_pass = FALSE; + +  master_selection(cinfo); +} diff --git a/libs/jpeg6/jdpostct.cpp b/libs/jpeg6/jdpostct.cpp index e3283b0..f612002 100755 --- a/libs/jpeg6/jdpostct.cpp +++ b/libs/jpeg6/jdpostct.cpp @@ -1,290 +1,290 @@ -/*
 - * jdpostct.c
 - *
 - * Copyright (C) 1994-1995, 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 the decompression postprocessing controller.
 - * This controller manages the upsampling, color conversion, and color
 - * quantization/reduction steps; specifically, it controls the buffering
 - * between upsample/color conversion and color quantization/reduction.
 - *
 - * If no color quantization/reduction is required, then this module has no
 - * work to do, and it just hands off to the upsample/color conversion code.
 - * An integrated upsample/convert/quantize process would replace this module
 - * entirely.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Private buffer controller object */
 -
 -typedef struct {
 -  struct jpeg_d_post_controller pub; /* public fields */
 -
 -  /* Color quantization source buffer: this holds output data from
 -   * the upsample/color conversion step to be passed to the quantizer.
 -   * For two-pass color quantization, we need a full-image buffer;
 -   * for one-pass operation, a strip buffer is sufficient.
 -   */
 -  jvirt_sarray_ptr whole_image;	/* virtual array, or NULL if one-pass */
 -  JSAMPARRAY buffer;		/* strip buffer, or current strip of virtual */
 -  JDIMENSION strip_height;	/* buffer size in rows */
 -  /* for two-pass mode only: */
 -  JDIMENSION starting_row;	/* row # of first row in current strip */
 -  JDIMENSION next_row;		/* index of next row to fill/empty in strip */
 -} my_post_controller;
 -
 -typedef my_post_controller * my_post_ptr;
 -
 -
 -/* Forward declarations */
 -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
 -	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
 -	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));
 -#endif
 -
 -
 -/*
 - * Initialize for a processing pass.
 - */
 -
 -METHODDEF void
 -start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
 -{
 -  my_post_ptr post = (my_post_ptr) cinfo->post;
 -
 -  switch (pass_mode) {
 -  case JBUF_PASS_THRU:
 -    if (cinfo->quantize_colors) {
 -      /* Single-pass processing with color quantization. */
 -      post->pub.post_process_data = post_process_1pass;
 -      /* We could be doing buffered-image output before starting a 2-pass
 -       * color quantization; in that case, jinit_d_post_controller did not
 -       * allocate a strip buffer.  Use the virtual-array buffer as workspace.
 -       */
 -      if (post->buffer == NULL) {
 -	post->buffer = (*cinfo->mem->access_virt_sarray)
 -	  ((j_common_ptr) cinfo, post->whole_image,
 -	   (JDIMENSION) 0, post->strip_height, TRUE);
 -      }
 -    } else {
 -      /* For single-pass processing without color quantization,
 -       * I have no work to do; just call the upsampler directly.
 -       */
 -      post->pub.post_process_data = cinfo->upsample->upsample;
 -    }
 -    break;
 -#ifdef QUANT_2PASS_SUPPORTED
 -  case JBUF_SAVE_AND_PASS:
 -    /* First pass of 2-pass quantization */
 -    if (post->whole_image == NULL)
 -      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -    post->pub.post_process_data = post_process_prepass;
 -    break;
 -  case JBUF_CRANK_DEST:
 -    /* Second pass of 2-pass quantization */
 -    if (post->whole_image == NULL)
 -      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -    post->pub.post_process_data = post_process_2pass;
 -    break;
 -#endif /* QUANT_2PASS_SUPPORTED */
 -  default:
 -    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -    break;
 -  }
 -  post->starting_row = post->next_row = 0;
 -}
 -
 -
 -/*
 - * Process some data in the one-pass (strip buffer) case.
 - * This is used for color precision reduction as well as one-pass quantization.
 - */
 -
 -METHODDEF void
 -post_process_1pass (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)
 -{
 -  my_post_ptr post = (my_post_ptr) cinfo->post;
 -  JDIMENSION num_rows, max_rows;
 -
 -  /* Fill the buffer, but not more than what we can dump out in one go. */
 -  /* Note we rely on the upsampler to detect bottom of image. */
 -  max_rows = out_rows_avail - *out_row_ctr;
 -  if (max_rows > post->strip_height)
 -    max_rows = post->strip_height;
 -  num_rows = 0;
 -  (*cinfo->upsample->upsample) (cinfo,
 -		input_buf, in_row_group_ctr, in_row_groups_avail,
 -		post->buffer, &num_rows, max_rows);
 -  /* Quantize and emit data. */
 -  (*cinfo->cquantize->color_quantize) (cinfo,
 -		post->buffer, output_buf + *out_row_ctr, (int) num_rows);
 -  *out_row_ctr += num_rows;
 -}
 -
 -
 -#ifdef QUANT_2PASS_SUPPORTED
 -
 -/*
 - * Process some data in the first pass of 2-pass quantization.
 - */
 -
 -METHODDEF void
 -post_process_prepass (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)
 -{
 -  my_post_ptr post = (my_post_ptr) cinfo->post;
 -  JDIMENSION old_next_row, num_rows;
 -
 -  /* Reposition virtual buffer if at start of strip. */
 -  if (post->next_row == 0) {
 -    post->buffer = (*cinfo->mem->access_virt_sarray)
 -	((j_common_ptr) cinfo, post->whole_image,
 -	 post->starting_row, post->strip_height, TRUE);
 -  }
 -
 -  /* Upsample some data (up to a strip height's worth). */
 -  old_next_row = post->next_row;
 -  (*cinfo->upsample->upsample) (cinfo,
 -		input_buf, in_row_group_ctr, in_row_groups_avail,
 -		post->buffer, &post->next_row, post->strip_height);
 -
 -  /* Allow quantizer to scan new data.  No data is emitted, */
 -  /* but we advance out_row_ctr so outer loop can tell when we're done. */
 -  if (post->next_row > old_next_row) {
 -    num_rows = post->next_row - old_next_row;
 -    (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
 -					 (JSAMPARRAY) NULL, (int) num_rows);
 -    *out_row_ctr += num_rows;
 -  }
 -
 -  /* Advance if we filled the strip. */
 -  if (post->next_row >= post->strip_height) {
 -    post->starting_row += post->strip_height;
 -    post->next_row = 0;
 -  }
 -}
 -
 -
 -/*
 - * Process some data in the second pass of 2-pass quantization.
 - */
 -
 -METHODDEF void
 -post_process_2pass (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)
 -{
 -  my_post_ptr post = (my_post_ptr) cinfo->post;
 -  JDIMENSION num_rows, max_rows;
 -
 -  /* Reposition virtual buffer if at start of strip. */
 -  if (post->next_row == 0) {
 -    post->buffer = (*cinfo->mem->access_virt_sarray)
 -	((j_common_ptr) cinfo, post->whole_image,
 -	 post->starting_row, post->strip_height, FALSE);
 -  }
 -
 -  /* Determine number of rows to emit. */
 -  num_rows = post->strip_height - post->next_row; /* available in strip */
 -  max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
 -  if (num_rows > max_rows)
 -    num_rows = max_rows;
 -  /* We have to check bottom of image here, can't depend on upsampler. */
 -  max_rows = cinfo->output_height - post->starting_row;
 -  if (num_rows > max_rows)
 -    num_rows = max_rows;
 -
 -  /* Quantize and emit data. */
 -  (*cinfo->cquantize->color_quantize) (cinfo,
 -		post->buffer + post->next_row, output_buf + *out_row_ctr,
 -		(int) num_rows);
 -  *out_row_ctr += num_rows;
 -
 -  /* Advance if we filled the strip. */
 -  post->next_row += num_rows;
 -  if (post->next_row >= post->strip_height) {
 -    post->starting_row += post->strip_height;
 -    post->next_row = 0;
 -  }
 -}
 -
 -#endif /* QUANT_2PASS_SUPPORTED */
 -
 -
 -/*
 - * Initialize postprocessing controller.
 - */
 -
 -GLOBAL void
 -jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
 -{
 -  my_post_ptr post;
 -
 -  post = (my_post_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(my_post_controller));
 -  cinfo->post = (struct jpeg_d_post_controller *) post;
 -  post->pub.start_pass = start_pass_dpost;
 -  post->whole_image = NULL;	/* flag for no virtual arrays */
 -  post->buffer = NULL;		/* flag for no strip buffer */
 -
 -  /* Create the quantization buffer, if needed */
 -  if (cinfo->quantize_colors) {
 -    /* The buffer strip height is max_v_samp_factor, which is typically
 -     * an efficient number of rows for upsampling to return.
 -     * (In the presence of output rescaling, we might want to be smarter?)
 -     */
 -    post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
 -    if (need_full_buffer) {
 -      /* Two-pass color quantization: need full-image storage. */
 -      /* We round up the number of rows to a multiple of the strip height. */
 -#ifdef QUANT_2PASS_SUPPORTED
 -      post->whole_image = (*cinfo->mem->request_virt_sarray)
 -	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
 -	 cinfo->output_width * cinfo->out_color_components,
 -	 (JDIMENSION) jround_up((long) cinfo->output_height,
 -				(long) post->strip_height),
 -	 post->strip_height);
 -#else
 -      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 -#endif /* QUANT_2PASS_SUPPORTED */
 -    } else {
 -      /* One-pass color quantization: just make a strip buffer. */
 -      post->buffer = (*cinfo->mem->alloc_sarray)
 -	((j_common_ptr) cinfo, JPOOL_IMAGE,
 -	 cinfo->output_width * cinfo->out_color_components,
 -	 post->strip_height);
 -    }
 -  }
 -}
 +/* + * jdpostct.c + * + * Copyright (C) 1994-1995, 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 the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private buffer controller object */ + +typedef struct { +  struct jpeg_d_post_controller pub; /* public fields */ + +  /* Color quantization source buffer: this holds output data from +   * the upsample/color conversion step to be passed to the quantizer. +   * For two-pass color quantization, we need a full-image buffer; +   * for one-pass operation, a strip buffer is sufficient. +   */ +  jvirt_sarray_ptr whole_image;	/* virtual array, or NULL if one-pass */ +  JSAMPARRAY buffer;		/* strip buffer, or current strip of virtual */ +  JDIMENSION strip_height;	/* buffer size in rows */ +  /* for two-pass mode only: */ +  JDIMENSION starting_row;	/* row # of first row in current strip */ +  JDIMENSION next_row;		/* index of next row to fill/empty in strip */ +} my_post_controller; + +typedef my_post_controller * my_post_ptr; + + +/* Forward declarations */ +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 +	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 +	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)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF void +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ +  my_post_ptr post = (my_post_ptr) cinfo->post; + +  switch (pass_mode) { +  case JBUF_PASS_THRU: +    if (cinfo->quantize_colors) { +      /* Single-pass processing with color quantization. */ +      post->pub.post_process_data = post_process_1pass; +      /* We could be doing buffered-image output before starting a 2-pass +       * color quantization; in that case, jinit_d_post_controller did not +       * allocate a strip buffer.  Use the virtual-array buffer as workspace. +       */ +      if (post->buffer == NULL) { +	post->buffer = (*cinfo->mem->access_virt_sarray) +	  ((j_common_ptr) cinfo, post->whole_image, +	   (JDIMENSION) 0, post->strip_height, TRUE); +      } +    } else { +      /* For single-pass processing without color quantization, +       * I have no work to do; just call the upsampler directly. +       */ +      post->pub.post_process_data = cinfo->upsample->upsample; +    } +    break; +#ifdef QUANT_2PASS_SUPPORTED +  case JBUF_SAVE_AND_PASS: +    /* First pass of 2-pass quantization */ +    if (post->whole_image == NULL) +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +    post->pub.post_process_data = post_process_prepass; +    break; +  case JBUF_CRANK_DEST: +    /* Second pass of 2-pass quantization */ +    if (post->whole_image == NULL) +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +    post->pub.post_process_data = post_process_2pass; +    break; +#endif /* QUANT_2PASS_SUPPORTED */ +  default: +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +    break; +  } +  post->starting_row = post->next_row = 0; +} + + +/* + * Process some data in the one-pass (strip buffer) case. + * This is used for color precision reduction as well as one-pass quantization. + */ + +METHODDEF void +post_process_1pass (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) +{ +  my_post_ptr post = (my_post_ptr) cinfo->post; +  JDIMENSION num_rows, max_rows; + +  /* Fill the buffer, but not more than what we can dump out in one go. */ +  /* Note we rely on the upsampler to detect bottom of image. */ +  max_rows = out_rows_avail - *out_row_ctr; +  if (max_rows > post->strip_height) +    max_rows = post->strip_height; +  num_rows = 0; +  (*cinfo->upsample->upsample) (cinfo, +		input_buf, in_row_group_ctr, in_row_groups_avail, +		post->buffer, &num_rows, max_rows); +  /* Quantize and emit data. */ +  (*cinfo->cquantize->color_quantize) (cinfo, +		post->buffer, output_buf + *out_row_ctr, (int) num_rows); +  *out_row_ctr += num_rows; +} + + +#ifdef QUANT_2PASS_SUPPORTED + +/* + * Process some data in the first pass of 2-pass quantization. + */ + +METHODDEF void +post_process_prepass (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) +{ +  my_post_ptr post = (my_post_ptr) cinfo->post; +  JDIMENSION old_next_row, num_rows; + +  /* Reposition virtual buffer if at start of strip. */ +  if (post->next_row == 0) { +    post->buffer = (*cinfo->mem->access_virt_sarray) +	((j_common_ptr) cinfo, post->whole_image, +	 post->starting_row, post->strip_height, TRUE); +  } + +  /* Upsample some data (up to a strip height's worth). */ +  old_next_row = post->next_row; +  (*cinfo->upsample->upsample) (cinfo, +		input_buf, in_row_group_ctr, in_row_groups_avail, +		post->buffer, &post->next_row, post->strip_height); + +  /* Allow quantizer to scan new data.  No data is emitted, */ +  /* but we advance out_row_ctr so outer loop can tell when we're done. */ +  if (post->next_row > old_next_row) { +    num_rows = post->next_row - old_next_row; +    (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, +					 (JSAMPARRAY) NULL, (int) num_rows); +    *out_row_ctr += num_rows; +  } + +  /* Advance if we filled the strip. */ +  if (post->next_row >= post->strip_height) { +    post->starting_row += post->strip_height; +    post->next_row = 0; +  } +} + + +/* + * Process some data in the second pass of 2-pass quantization. + */ + +METHODDEF void +post_process_2pass (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) +{ +  my_post_ptr post = (my_post_ptr) cinfo->post; +  JDIMENSION num_rows, max_rows; + +  /* Reposition virtual buffer if at start of strip. */ +  if (post->next_row == 0) { +    post->buffer = (*cinfo->mem->access_virt_sarray) +	((j_common_ptr) cinfo, post->whole_image, +	 post->starting_row, post->strip_height, FALSE); +  } + +  /* Determine number of rows to emit. */ +  num_rows = post->strip_height - post->next_row; /* available in strip */ +  max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ +  if (num_rows > max_rows) +    num_rows = max_rows; +  /* We have to check bottom of image here, can't depend on upsampler. */ +  max_rows = cinfo->output_height - post->starting_row; +  if (num_rows > max_rows) +    num_rows = max_rows; + +  /* Quantize and emit data. */ +  (*cinfo->cquantize->color_quantize) (cinfo, +		post->buffer + post->next_row, output_buf + *out_row_ctr, +		(int) num_rows); +  *out_row_ctr += num_rows; + +  /* Advance if we filled the strip. */ +  post->next_row += num_rows; +  if (post->next_row >= post->strip_height) { +    post->starting_row += post->strip_height; +    post->next_row = 0; +  } +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize postprocessing controller. + */ + +GLOBAL void +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ +  my_post_ptr post; + +  post = (my_post_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(my_post_controller)); +  cinfo->post = (struct jpeg_d_post_controller *) post; +  post->pub.start_pass = start_pass_dpost; +  post->whole_image = NULL;	/* flag for no virtual arrays */ +  post->buffer = NULL;		/* flag for no strip buffer */ + +  /* Create the quantization buffer, if needed */ +  if (cinfo->quantize_colors) { +    /* The buffer strip height is max_v_samp_factor, which is typically +     * an efficient number of rows for upsampling to return. +     * (In the presence of output rescaling, we might want to be smarter?) +     */ +    post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; +    if (need_full_buffer) { +      /* Two-pass color quantization: need full-image storage. */ +      /* We round up the number of rows to a multiple of the strip height. */ +#ifdef QUANT_2PASS_SUPPORTED +      post->whole_image = (*cinfo->mem->request_virt_sarray) +	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, +	 cinfo->output_width * cinfo->out_color_components, +	 (JDIMENSION) jround_up((long) cinfo->output_height, +				(long) post->strip_height), +	 post->strip_height); +#else +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif /* QUANT_2PASS_SUPPORTED */ +    } else { +      /* One-pass color quantization: just make a strip buffer. */ +      post->buffer = (*cinfo->mem->alloc_sarray) +	((j_common_ptr) cinfo, JPOOL_IMAGE, +	 cinfo->output_width * cinfo->out_color_components, +	 post->strip_height); +    } +  } +} diff --git a/libs/jpeg6/jdsample.cpp b/libs/jpeg6/jdsample.cpp index bc171f4..661e198 100755 --- a/libs/jpeg6/jdsample.cpp +++ b/libs/jpeg6/jdsample.cpp @@ -1,478 +1,478 @@ -/*
 - * jdsample.c
 - *
 - * Copyright (C) 1991-1994, 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 upsampling routines.
 - *
 - * Upsampling input data is counted in "row groups".  A row group
 - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
 - * sample rows of each component.  Upsampling will normally produce
 - * max_v_samp_factor pixel rows from each row group (but this could vary
 - * if the upsampler is applying a scale factor of its own).
 - *
 - * An excellent reference for image resampling is
 - *   Digital Image Warping, George Wolberg, 1990.
 - *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Pointer to routine to upsample a single component */
 -typedef JMETHOD(void, upsample1_ptr,
 -		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
 -
 -/* Private subobject */
 -
 -typedef struct {
 -  struct jpeg_upsampler pub;	/* public fields */
 -
 -  /* Color conversion buffer.  When using separate upsampling and color
 -   * conversion steps, this buffer holds one upsampled row group until it
 -   * has been color converted and output.
 -   * Note: we do not allocate any storage for component(s) which are full-size,
 -   * ie do not need rescaling.  The corresponding entry of color_buf[] is
 -   * simply set to point to the input data array, thereby avoiding copying.
 -   */
 -  JSAMPARRAY color_buf[MAX_COMPONENTS];
 -
 -  /* Per-component upsampling method pointers */
 -  upsample1_ptr methods[MAX_COMPONENTS];
 -
 -  int next_row_out;		/* counts rows emitted from color_buf */
 -  JDIMENSION rows_to_go;	/* counts rows remaining in image */
 -
 -  /* Height of an input row group for each component. */
 -  int rowgroup_height[MAX_COMPONENTS];
 -
 -  /* These arrays save pixel expansion factors so that int_expand need not
 -   * recompute them each time.  They are unused for other upsampling methods.
 -   */
 -  UINT8 h_expand[MAX_COMPONENTS];
 -  UINT8 v_expand[MAX_COMPONENTS];
 -} my_upsampler;
 -
 -typedef my_upsampler * my_upsample_ptr;
 -
 -
 -/*
 - * Initialize for an upsampling pass.
 - */
 -
 -METHODDEF void
 -start_pass_upsample (j_decompress_ptr cinfo)
 -{
 -  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 -
 -  /* Mark the conversion buffer empty */
 -  upsample->next_row_out = cinfo->max_v_samp_factor;
 -  /* Initialize total-height counter for detecting bottom of image */
 -  upsample->rows_to_go = cinfo->output_height;
 -}
 -
 -
 -/*
 - * Control routine to do upsampling (and color conversion).
 - *
 - * In this version we upsample each component independently.
 - * We upsample one row group into the conversion buffer, then apply
 - * color conversion a row at a time.
 - */
 -
 -METHODDEF void
 -sep_upsample (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)
 -{
 -  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 -  int ci;
 -  jpeg_component_info * compptr;
 -  JDIMENSION num_rows;
 -
 -  /* Fill the conversion buffer, if it's empty */
 -  if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
 -    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -	 ci++, compptr++) {
 -      /* Invoke per-component upsample method.  Notice we pass a POINTER
 -       * to color_buf[ci], so that fullsize_upsample can change it.
 -       */
 -      (*upsample->methods[ci]) (cinfo, compptr,
 -	input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
 -	upsample->color_buf + ci);
 -    }
 -    upsample->next_row_out = 0;
 -  }
 -
 -  /* Color-convert and emit rows */
 -
 -  /* How many we have in the buffer: */
 -  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
 -  /* Not more than the distance to the end of the image.  Need this test
 -   * in case the image height is not a multiple of max_v_samp_factor:
 -   */
 -  if (num_rows > upsample->rows_to_go) 
 -    num_rows = upsample->rows_to_go;
 -  /* And not more than what the client can accept: */
 -  out_rows_avail -= *out_row_ctr;
 -  if (num_rows > out_rows_avail)
 -    num_rows = out_rows_avail;
 -
 -  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
 -				     (JDIMENSION) upsample->next_row_out,
 -				     output_buf + *out_row_ctr,
 -				     (int) num_rows);
 -
 -  /* Adjust counts */
 -  *out_row_ctr += num_rows;
 -  upsample->rows_to_go -= num_rows;
 -  upsample->next_row_out += num_rows;
 -  /* When the buffer is emptied, declare this input row group consumed */
 -  if (upsample->next_row_out >= cinfo->max_v_samp_factor)
 -    (*in_row_group_ctr)++;
 -}
 -
 -
 -/*
 - * These are the routines invoked by sep_upsample to upsample pixel values
 - * of a single component.  One row group is processed per call.
 - */
 -
 -
 -/*
 - * For full-size components, we just make color_buf[ci] point at the
 - * input buffer, and thus avoid copying any data.  Note that this is
 - * safe only because sep_upsample doesn't declare the input row group
 - * "consumed" until we are done color converting and emitting it.
 - */
 -
 -METHODDEF void
 -fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  *output_data_ptr = input_data;
 -}
 -
 -
 -/*
 - * This is a no-op version used for "uninteresting" components.
 - * These components will not be referenced by color conversion.
 - */
 -
 -METHODDEF void
 -noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  *output_data_ptr = NULL;	/* safety check */
 -}
 -
 -
 -/*
 - * This version handles any integral sampling ratios.
 - * This is not used for typical JPEG files, so it need not be fast.
 - * Nor, for that matter, is it particularly accurate: the algorithm is
 - * simple replication of the input pixel onto the corresponding output
 - * pixels.  The hi-falutin sampling literature refers to this as a
 - * "box filter".  A box filter tends to introduce visible artifacts,
 - * so if you are actually going to use 3:1 or 4:1 sampling ratios
 - * you would be well advised to improve this code.
 - */
 -
 -METHODDEF void
 -int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
 -  JSAMPARRAY output_data = *output_data_ptr;
 -  register JSAMPROW inptr, outptr;
 -  register JSAMPLE invalue;
 -  register int h;
 -  JSAMPROW outend;
 -  int h_expand, v_expand;
 -  int inrow, outrow;
 -
 -  h_expand = upsample->h_expand[compptr->component_index];
 -  v_expand = upsample->v_expand[compptr->component_index];
 -
 -  inrow = outrow = 0;
 -  while (outrow < cinfo->max_v_samp_factor) {
 -    /* Generate one output row with proper horizontal expansion */
 -    inptr = input_data[inrow];
 -    outptr = output_data[outrow];
 -    outend = outptr + cinfo->output_width;
 -    while (outptr < outend) {
 -      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 -      for (h = h_expand; h > 0; h--) {
 -	*outptr++ = invalue;
 -      }
 -    }
 -    /* Generate any additional output rows by duplicating the first one */
 -    if (v_expand > 1) {
 -      jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
 -			v_expand-1, cinfo->output_width);
 -    }
 -    inrow++;
 -    outrow += v_expand;
 -  }
 -}
 -
 -
 -/*
 - * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
 - * It's still a box filter.
 - */
 -
 -METHODDEF void
 -h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  JSAMPARRAY output_data = *output_data_ptr;
 -  register JSAMPROW inptr, outptr;
 -  register JSAMPLE invalue;
 -  JSAMPROW outend;
 -  int inrow;
 -
 -  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
 -    inptr = input_data[inrow];
 -    outptr = output_data[inrow];
 -    outend = outptr + cinfo->output_width;
 -    while (outptr < outend) {
 -      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 -      *outptr++ = invalue;
 -      *outptr++ = invalue;
 -    }
 -  }
 -}
 -
 -
 -/*
 - * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
 - * It's still a box filter.
 - */
 -
 -METHODDEF void
 -h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  JSAMPARRAY output_data = *output_data_ptr;
 -  register JSAMPROW inptr, outptr;
 -  register JSAMPLE invalue;
 -  JSAMPROW outend;
 -  int inrow, outrow;
 -
 -  inrow = outrow = 0;
 -  while (outrow < cinfo->max_v_samp_factor) {
 -    inptr = input_data[inrow];
 -    outptr = output_data[outrow];
 -    outend = outptr + cinfo->output_width;
 -    while (outptr < outend) {
 -      invalue = *inptr++;	/* don't need GETJSAMPLE() here */
 -      *outptr++ = invalue;
 -      *outptr++ = invalue;
 -    }
 -    jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
 -		      1, cinfo->output_width);
 -    inrow++;
 -    outrow += 2;
 -  }
 -}
 -
 -
 -/*
 - * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
 - *
 - * The upsampling algorithm is linear interpolation between pixel centers,
 - * also known as a "triangle filter".  This is a good compromise between
 - * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
 - * of the way between input pixel centers.
 - *
 - * A note about the "bias" calculations: when rounding fractional values to
 - * integer, we do not want to always round 0.5 up to the next integer.
 - * If we did that, we'd introduce a noticeable bias towards larger values.
 - * Instead, this code is arranged so that 0.5 will be rounded up or down at
 - * alternate pixel locations (a simple ordered dither pattern).
 - */
 -
 -METHODDEF void
 -h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  JSAMPARRAY output_data = *output_data_ptr;
 -  register JSAMPROW inptr, outptr;
 -  register int invalue;
 -  register JDIMENSION colctr;
 -  int inrow;
 -
 -  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
 -    inptr = input_data[inrow];
 -    outptr = output_data[inrow];
 -    /* Special case for first column */
 -    invalue = GETJSAMPLE(*inptr++);
 -    *outptr++ = (JSAMPLE) invalue;
 -    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
 -
 -    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
 -      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
 -      invalue = GETJSAMPLE(*inptr++) * 3;
 -      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
 -      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
 -    }
 -
 -    /* Special case for last column */
 -    invalue = GETJSAMPLE(*inptr);
 -    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
 -    *outptr++ = (JSAMPLE) invalue;
 -  }
 -}
 -
 -
 -/*
 - * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
 - * Again a triangle filter; see comments for h2v1 case, above.
 - *
 - * It is OK for us to reference the adjacent input rows because we demanded
 - * context from the main buffer controller (see initialization code).
 - */
 -
 -METHODDEF void
 -h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
 -{
 -  JSAMPARRAY output_data = *output_data_ptr;
 -  register JSAMPROW inptr0, inptr1, outptr;
 -#if BITS_IN_JSAMPLE == 8
 -  register int thiscolsum, lastcolsum, nextcolsum;
 -#else
 -  register INT32 thiscolsum, lastcolsum, nextcolsum;
 -#endif
 -  register JDIMENSION colctr;
 -  int inrow, outrow, v;
 -
 -  inrow = outrow = 0;
 -  while (outrow < cinfo->max_v_samp_factor) {
 -    for (v = 0; v < 2; v++) {
 -      /* inptr0 points to nearest input row, inptr1 points to next nearest */
 -      inptr0 = input_data[inrow];
 -      if (v == 0)		/* next nearest is row above */
 -	inptr1 = input_data[inrow-1];
 -      else			/* next nearest is row below */
 -	inptr1 = input_data[inrow+1];
 -      outptr = output_data[outrow++];
 -
 -      /* Special case for first column */
 -      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 -      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 -      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
 -      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
 -      lastcolsum = thiscolsum; thiscolsum = nextcolsum;
 -
 -      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
 -	/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
 -	/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
 -	nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
 -	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
 -	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
 -	lastcolsum = thiscolsum; thiscolsum = nextcolsum;
 -      }
 -
 -      /* Special case for last column */
 -      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
 -      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
 -    }
 -    inrow++;
 -  }
 -}
 -
 -
 -/*
 - * Module initialization routine for upsampling.
 - */
 -
 -GLOBAL void
 -jinit_upsampler (j_decompress_ptr cinfo)
 -{
 -  my_upsample_ptr upsample;
 -  int ci;
 -  jpeg_component_info * compptr;
 -  boolean need_buffer, do_fancy;
 -  int h_in_group, v_in_group, h_out_group, v_out_group;
 -
 -  upsample = (my_upsample_ptr)
 -    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 -				SIZEOF(my_upsampler));
 -  cinfo->upsample = (struct jpeg_upsampler *) upsample;
 -  upsample->pub.start_pass = start_pass_upsample;
 -  upsample->pub.upsample = sep_upsample;
 -  upsample->pub.need_context_rows = FALSE; /* until we find out differently */
 -
 -  if (cinfo->CCIR601_sampling)	/* this isn't supported */
 -    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
 -
 -  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
 -   * so don't ask for it.
 -   */
 -  do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
 -
 -  /* Verify we can handle the sampling factors, select per-component methods,
 -   * and create storage as needed.
 -   */
 -  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 -       ci++, compptr++) {
 -    /* Compute size of an "input group" after IDCT scaling.  This many samples
 -     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
 -     */
 -    h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
 -		 cinfo->min_DCT_scaled_size;
 -    v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
 -		 cinfo->min_DCT_scaled_size;
 -    h_out_group = cinfo->max_h_samp_factor;
 -    v_out_group = cinfo->max_v_samp_factor;
 -    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
 -    need_buffer = TRUE;
 -    if (! compptr->component_needed) {
 -      /* Don't bother to upsample an uninteresting component. */
 -      upsample->methods[ci] = noop_upsample;
 -      need_buffer = FALSE;
 -    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
 -      /* Fullsize components can be processed without any work. */
 -      upsample->methods[ci] = fullsize_upsample;
 -      need_buffer = FALSE;
 -    } else if (h_in_group * 2 == h_out_group &&
 -	       v_in_group == v_out_group) {
 -      /* Special cases for 2h1v upsampling */
 -      if (do_fancy && compptr->downsampled_width > 2)
 -	upsample->methods[ci] = h2v1_fancy_upsample;
 -      else
 -	upsample->methods[ci] = h2v1_upsample;
 -    } else if (h_in_group * 2 == h_out_group &&
 -	       v_in_group * 2 == v_out_group) {
 -      /* Special cases for 2h2v upsampling */
 -      if (do_fancy && compptr->downsampled_width > 2) {
 -	upsample->methods[ci] = h2v2_fancy_upsample;
 -	upsample->pub.need_context_rows = TRUE;
 -      } else
 -	upsample->methods[ci] = h2v2_upsample;
 -    } else if ((h_out_group % h_in_group) == 0 &&
 -	       (v_out_group % v_in_group) == 0) {
 -      /* Generic integral-factors upsampling method */
 -      upsample->methods[ci] = int_upsample;
 -      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
 -      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
 -    } else
 -      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
 -    if (need_buffer) {
 -      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
 -	((j_common_ptr) cinfo, JPOOL_IMAGE,
 -	 (JDIMENSION) jround_up((long) cinfo->output_width,
 -				(long) cinfo->max_h_samp_factor),
 -	 (JDIMENSION) cinfo->max_v_samp_factor);
 -    }
 -  }
 -}
 +/* + * jdsample.c + * + * Copyright (C) 1991-1994, 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 upsampling routines. + * + * Upsampling input data is counted in "row groups".  A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component.  Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + *   Digital Image Warping, George Wolberg, 1990. + *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to upsample a single component */ +typedef JMETHOD(void, upsample1_ptr, +		(j_decompress_ptr cinfo, jpeg_component_info * compptr, +		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + +/* Private subobject */ + +typedef struct { +  struct jpeg_upsampler pub;	/* public fields */ + +  /* Color conversion buffer.  When using separate upsampling and color +   * conversion steps, this buffer holds one upsampled row group until it +   * has been color converted and output. +   * Note: we do not allocate any storage for component(s) which are full-size, +   * ie do not need rescaling.  The corresponding entry of color_buf[] is +   * simply set to point to the input data array, thereby avoiding copying. +   */ +  JSAMPARRAY color_buf[MAX_COMPONENTS]; + +  /* Per-component upsampling method pointers */ +  upsample1_ptr methods[MAX_COMPONENTS]; + +  int next_row_out;		/* counts rows emitted from color_buf */ +  JDIMENSION rows_to_go;	/* counts rows remaining in image */ + +  /* Height of an input row group for each component. */ +  int rowgroup_height[MAX_COMPONENTS]; + +  /* These arrays save pixel expansion factors so that int_expand need not +   * recompute them each time.  They are unused for other upsampling methods. +   */ +  UINT8 h_expand[MAX_COMPONENTS]; +  UINT8 v_expand[MAX_COMPONENTS]; +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF void +start_pass_upsample (j_decompress_ptr cinfo) +{ +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + +  /* Mark the conversion buffer empty */ +  upsample->next_row_out = cinfo->max_v_samp_factor; +  /* Initialize total-height counter for detecting bottom of image */ +  upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * In this version we upsample each component independently. + * We upsample one row group into the conversion buffer, then apply + * color conversion a row at a time. + */ + +METHODDEF void +sep_upsample (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) +{ +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; +  int ci; +  jpeg_component_info * compptr; +  JDIMENSION num_rows; + +  /* Fill the conversion buffer, if it's empty */ +  if (upsample->next_row_out >= cinfo->max_v_samp_factor) { +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +	 ci++, compptr++) { +      /* Invoke per-component upsample method.  Notice we pass a POINTER +       * to color_buf[ci], so that fullsize_upsample can change it. +       */ +      (*upsample->methods[ci]) (cinfo, compptr, +	input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), +	upsample->color_buf + ci); +    } +    upsample->next_row_out = 0; +  } + +  /* Color-convert and emit rows */ + +  /* How many we have in the buffer: */ +  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); +  /* Not more than the distance to the end of the image.  Need this test +   * in case the image height is not a multiple of max_v_samp_factor: +   */ +  if (num_rows > upsample->rows_to_go)  +    num_rows = upsample->rows_to_go; +  /* And not more than what the client can accept: */ +  out_rows_avail -= *out_row_ctr; +  if (num_rows > out_rows_avail) +    num_rows = out_rows_avail; + +  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, +				     (JDIMENSION) upsample->next_row_out, +				     output_buf + *out_row_ctr, +				     (int) num_rows); + +  /* Adjust counts */ +  *out_row_ctr += num_rows; +  upsample->rows_to_go -= num_rows; +  upsample->next_row_out += num_rows; +  /* When the buffer is emptied, declare this input row group consumed */ +  if (upsample->next_row_out >= cinfo->max_v_samp_factor) +    (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by sep_upsample to upsample pixel values + * of a single component.  One row group is processed per call. + */ + + +/* + * For full-size components, we just make color_buf[ci] point at the + * input buffer, and thus avoid copying any data.  Note that this is + * safe only because sep_upsample doesn't declare the input row group + * "consumed" until we are done color converting and emitting it. + */ + +METHODDEF void +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +		   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  *output_data_ptr = input_data; +} + + +/* + * This is a no-op version used for "uninteresting" components. + * These components will not be referenced by color conversion. + */ + +METHODDEF void +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  *output_data_ptr = NULL;	/* safety check */ +} + + +/* + * This version handles any integral sampling ratios. + * This is not used for typical JPEG files, so it need not be fast. + * Nor, for that matter, is it particularly accurate: the algorithm is + * simple replication of the input pixel onto the corresponding output + * pixels.  The hi-falutin sampling literature refers to this as a + * "box filter".  A box filter tends to introduce visible artifacts, + * so if you are actually going to use 3:1 or 4:1 sampling ratios + * you would be well advised to improve this code. + */ + +METHODDEF void +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +	      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; +  JSAMPARRAY output_data = *output_data_ptr; +  register JSAMPROW inptr, outptr; +  register JSAMPLE invalue; +  register int h; +  JSAMPROW outend; +  int h_expand, v_expand; +  int inrow, outrow; + +  h_expand = upsample->h_expand[compptr->component_index]; +  v_expand = upsample->v_expand[compptr->component_index]; + +  inrow = outrow = 0; +  while (outrow < cinfo->max_v_samp_factor) { +    /* Generate one output row with proper horizontal expansion */ +    inptr = input_data[inrow]; +    outptr = output_data[outrow]; +    outend = outptr + cinfo->output_width; +    while (outptr < outend) { +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */ +      for (h = h_expand; h > 0; h--) { +	*outptr++ = invalue; +      } +    } +    /* Generate any additional output rows by duplicating the first one */ +    if (v_expand > 1) { +      jcopy_sample_rows(output_data, outrow, output_data, outrow+1, +			v_expand-1, cinfo->output_width); +    } +    inrow++; +    outrow += v_expand; +  } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + * It's still a box filter. + */ + +METHODDEF void +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  JSAMPARRAY output_data = *output_data_ptr; +  register JSAMPROW inptr, outptr; +  register JSAMPLE invalue; +  JSAMPROW outend; +  int inrow; + +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { +    inptr = input_data[inrow]; +    outptr = output_data[inrow]; +    outend = outptr + cinfo->output_width; +    while (outptr < outend) { +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */ +      *outptr++ = invalue; +      *outptr++ = invalue; +    } +  } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + * It's still a box filter. + */ + +METHODDEF void +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +	       JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  JSAMPARRAY output_data = *output_data_ptr; +  register JSAMPROW inptr, outptr; +  register JSAMPLE invalue; +  JSAMPROW outend; +  int inrow, outrow; + +  inrow = outrow = 0; +  while (outrow < cinfo->max_v_samp_factor) { +    inptr = input_data[inrow]; +    outptr = output_data[outrow]; +    outend = outptr + cinfo->output_width; +    while (outptr < outend) { +      invalue = *inptr++;	/* don't need GETJSAMPLE() here */ +      *outptr++ = invalue; +      *outptr++ = invalue; +    } +    jcopy_sample_rows(output_data, outrow, output_data, outrow+1, +		      1, cinfo->output_width); +    inrow++; +    outrow += 2; +  } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + * + * The upsampling algorithm is linear interpolation between pixel centers, + * also known as a "triangle filter".  This is a good compromise between + * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4 + * of the way between input pixel centers. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF void +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  JSAMPARRAY output_data = *output_data_ptr; +  register JSAMPROW inptr, outptr; +  register int invalue; +  register JDIMENSION colctr; +  int inrow; + +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { +    inptr = input_data[inrow]; +    outptr = output_data[inrow]; +    /* Special case for first column */ +    invalue = GETJSAMPLE(*inptr++); +    *outptr++ = (JSAMPLE) invalue; +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + +    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { +      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ +      invalue = GETJSAMPLE(*inptr++) * 3; +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); +    } + +    /* Special case for last column */ +    invalue = GETJSAMPLE(*inptr); +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); +    *outptr++ = (JSAMPLE) invalue; +  } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + * Again a triangle filter; see comments for h2v1 case, above. + * + * It is OK for us to reference the adjacent input rows because we demanded + * context from the main buffer controller (see initialization code). + */ + +METHODDEF void +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, +		     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ +  JSAMPARRAY output_data = *output_data_ptr; +  register JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 +  register int thiscolsum, lastcolsum, nextcolsum; +#else +  register INT32 thiscolsum, lastcolsum, nextcolsum; +#endif +  register JDIMENSION colctr; +  int inrow, outrow, v; + +  inrow = outrow = 0; +  while (outrow < cinfo->max_v_samp_factor) { +    for (v = 0; v < 2; v++) { +      /* inptr0 points to nearest input row, inptr1 points to next nearest */ +      inptr0 = input_data[inrow]; +      if (v == 0)		/* next nearest is row above */ +	inptr1 = input_data[inrow-1]; +      else			/* next nearest is row below */ +	inptr1 = input_data[inrow+1]; +      outptr = output_data[outrow++]; + +      /* Special case for first column */ +      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); +      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); +      lastcolsum = thiscolsum; thiscolsum = nextcolsum; + +      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { +	/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ +	/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ +	nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); +	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); +	*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); +	lastcolsum = thiscolsum; thiscolsum = nextcolsum; +      } + +      /* Special case for last column */ +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); +    } +    inrow++; +  } +} + + +/* + * Module initialization routine for upsampling. + */ + +GLOBAL void +jinit_upsampler (j_decompress_ptr cinfo) +{ +  my_upsample_ptr upsample; +  int ci; +  jpeg_component_info * compptr; +  boolean need_buffer, do_fancy; +  int h_in_group, v_in_group, h_out_group, v_out_group; + +  upsample = (my_upsample_ptr) +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, +				SIZEOF(my_upsampler)); +  cinfo->upsample = (struct jpeg_upsampler *) upsample; +  upsample->pub.start_pass = start_pass_upsample; +  upsample->pub.upsample = sep_upsample; +  upsample->pub.need_context_rows = FALSE; /* until we find out differently */ + +  if (cinfo->CCIR601_sampling)	/* this isn't supported */ +    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + +  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, +   * so don't ask for it. +   */ +  do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + +  /* Verify we can handle the sampling factors, select per-component methods, +   * and create storage as needed. +   */ +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; +       ci++, compptr++) { +    /* Compute size of an "input group" after IDCT scaling.  This many samples +     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. +     */ +    h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / +		 cinfo->min_DCT_scaled_size; +    v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / +		 cinfo->min_DCT_scaled_size; +    h_out_group = cinfo->max_h_samp_factor; +    v_out_group = cinfo->max_v_samp_factor; +    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ +    need_buffer = TRUE; +    if (! compptr->component_needed) { +      /* Don't bother to upsample an uninteresting component. */ +      upsample->methods[ci] = noop_upsample; +      need_buffer = FALSE; +    } else if (h_in_group == h_out_group && v_in_group == v_out_group) { +      /* Fullsize components can be processed without any work. */ +      upsample->methods[ci] = fullsize_upsample; +      need_buffer = FALSE; +    } else if (h_in_group * 2 == h_out_group && +	       v_in_group == v_out_group) { +      /* Special cases for 2h1v upsampling */ +      if (do_fancy && compptr->downsampled_width > 2) +	upsample->methods[ci] = h2v1_fancy_upsample; +      else +	upsample->methods[ci] = h2v1_upsample; +    } else if (h_in_group * 2 == h_out_group && +	       v_in_group * 2 == v_out_group) { +      /* Special cases for 2h2v upsampling */ +      if (do_fancy && compptr->downsampled_width > 2) { +	upsample->methods[ci] = h2v2_fancy_upsample; +	upsample->pub.need_context_rows = TRUE; +      } else +	upsample->methods[ci] = h2v2_upsample; +    } else if ((h_out_group % h_in_group) == 0 && +	       (v_out_group % v_in_group) == 0) { +      /* Generic integral-factors upsampling method */ +      upsample->methods[ci] = int_upsample; +      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); +      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); +    } else +      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); +    if (need_buffer) { +      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) +	((j_common_ptr) cinfo, JPOOL_IMAGE, +	 (JDIMENSION) jround_up((long) cinfo->output_width, +				(long) cinfo->max_h_samp_factor), +	 (JDIMENSION) cinfo->max_v_samp_factor); +    } +  } +} diff --git a/libs/jpeg6/jdtrans.cpp b/libs/jpeg6/jdtrans.cpp index eb873e0..5c14adc 100755 --- a/libs/jpeg6/jdtrans.cpp +++ b/libs/jpeg6/jdtrans.cpp @@ -1,122 +1,122 @@ -/*
 - * jdtrans.c
 - *
 - * Copyright (C) 1995, 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 library routines for transcoding decompression,
 - * that is, reading raw DCT coefficient arrays from an input JPEG file.
 - * The routines in jdapimin.c will also be needed by a transcoder.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/* Forward declarations */
 -LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo));
 -
 -
 -/*
 - * Read the coefficient arrays from a JPEG file.
 - * jpeg_read_header must be completed before calling this.
 - *
 - * The entire image is read into a set of virtual coefficient-block arrays,
 - * one per component.  The return value is a pointer to the array of
 - * virtual-array descriptors.  These can be manipulated directly via the
 - * JPEG memory manager, or handed off to jpeg_write_coefficients().
 - * To release the memory occupied by the virtual arrays, call
 - * jpeg_finish_decompress() when done with the data.
 - *
 - * Returns NULL if suspended.  This case need be checked only if
 - * a suspending data source is used.
 - */
 -
 -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;
 -      }
 -    }
 -  }
 -  /* Set state so that jpeg_finish_decompress does the right thing */
 -  cinfo->global_state = DSTATE_STOPPING;
 -  return cinfo->coef->coef_arrays;
 -}
 -
 -
 -/*
 - * Master selection of decompression modules for transcoding.
 - * This substitutes for jdmaster.c's initialization of the full decompressor.
 - */
 -
 -LOCAL void
 -transdecode_master_selection (j_decompress_ptr cinfo)
 -{
 -  /* Entropy decoding: either Huffman or arithmetic coding. */
 -  if (cinfo->arith_code) {
 -    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
 -  } else {
 -    if (cinfo->progressive_mode) {
 -#ifdef D_PROGRESSIVE_SUPPORTED
 -      jinit_phuff_decoder(cinfo);
 -#else
 -      ERREXIT(cinfo, JERR_NOT_COMPILED);
 -#endif
 -    } else
 -      jinit_huff_decoder(cinfo);
 -  }
 -
 -  /* Always get a full-image coefficient buffer. */
 -  jinit_d_coef_controller(cinfo, TRUE);
 -
 -  /* We can now tell the memory manager to allocate virtual arrays. */
 -  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 -
 -  /* Initialize input side of decompressor to consume first scan. */
 -  (*cinfo->inputctl->start_input_pass) (cinfo);
 -
 -  /* Initialize progress monitoring. */
 -  if (cinfo->progress != NULL) {
 -    int nscans;
 -    /* Estimate number of scans to set pass_limit. */
 -    if (cinfo->progressive_mode) {
 -      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
 -      nscans = 2 + 3 * cinfo->num_components;
 -    } else if (cinfo->inputctl->has_multiple_scans) {
 -      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
 -      nscans = cinfo->num_components;
 -    } else {
 -      nscans = 1;
 -    }
 -    cinfo->progress->pass_counter = 0L;
 -    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
 -    cinfo->progress->completed_passes = 0;
 -    cinfo->progress->total_passes = 1;
 -  }
 -}
 +/* + * jdtrans.c + * + * Copyright (C) 1995, 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 library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); + + +/* + * Read the coefficient arrays from a JPEG file. + * jpeg_read_header must be completed before calling this. + * + * The entire image is read into a set of virtual coefficient-block arrays, + * one per component.  The return value is a pointer to the array of + * virtual-array descriptors.  These can be manipulated directly via the + * JPEG memory manager, or handed off to jpeg_write_coefficients(). + * To release the memory occupied by the virtual arrays, call + * jpeg_finish_decompress() when done with the data. + * + * Returns NULL if suspended.  This case need be checked only if + * a suspending data source is used. + */ + +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; +      } +    } +  } +  /* Set state so that jpeg_finish_decompress does the right thing */ +  cinfo->global_state = DSTATE_STOPPING; +  return cinfo->coef->coef_arrays; +} + + +/* + * Master selection of decompression modules for transcoding. + * This substitutes for jdmaster.c's initialization of the full decompressor. + */ + +LOCAL void +transdecode_master_selection (j_decompress_ptr cinfo) +{ +  /* Entropy decoding: either Huffman or arithmetic coding. */ +  if (cinfo->arith_code) { +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL); +  } else { +    if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED +      jinit_phuff_decoder(cinfo); +#else +      ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif +    } else +      jinit_huff_decoder(cinfo); +  } + +  /* Always get a full-image coefficient buffer. */ +  jinit_d_coef_controller(cinfo, TRUE); + +  /* We can now tell the memory manager to allocate virtual arrays. */ +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + +  /* Initialize input side of decompressor to consume first scan. */ +  (*cinfo->inputctl->start_input_pass) (cinfo); + +  /* Initialize progress monitoring. */ +  if (cinfo->progress != NULL) { +    int nscans; +    /* Estimate number of scans to set pass_limit. */ +    if (cinfo->progressive_mode) { +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ +      nscans = 2 + 3 * cinfo->num_components; +    } else if (cinfo->inputctl->has_multiple_scans) { +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */ +      nscans = cinfo->num_components; +    } else { +      nscans = 1; +    } +    cinfo->progress->pass_counter = 0L; +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; +    cinfo->progress->completed_passes = 0; +    cinfo->progress->total_passes = 1; +  } +} diff --git a/libs/jpeg6/jerror.cpp b/libs/jpeg6/jerror.cpp index 09027d8..595f371 100755 --- a/libs/jpeg6/jerror.cpp +++ b/libs/jpeg6/jerror.cpp @@ -1,231 +1,231 @@ -/*
 - * jerror.c
 - *
 - * Copyright (C) 1991-1994, 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 simple error-reporting and trace-message routines.
 - * These are suitable for Unix-like systems and others where writing to
 - * stderr is the right thing to do.  Many applications will want to replace
 - * some or all of these routines.
 - *
 - * These routines are used by both the compression and decompression code.
 - */
 -
 -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jversion.h"
 -#include "jerror.h"
 -
 -#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
 -#define EXIT_FAILURE  1
 -#endif
 -
 -
 -/*
 - * Create the message string table.
 - * We do this from the master message list in jerror.h by re-reading
 - * jerror.h with a suitable definition for macro JMESSAGE.
 - * The message table is made an external symbol just in case any applications
 - * want to refer to it directly.
 - */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_std_message_table	jMsgTable
 -#endif
 -
 -#define JMESSAGE(code,string)	string ,
 -
 -const char * const jpeg_std_message_table[] = {
 -#include "jerror.h"
 -  NULL
 -};
 -
 -
 -/*
 - * Error exit handler: must not return to caller.
 - *
 - * Applications may override this if they want to get control back after
 - * an error.  Typically one would longjmp somewhere instead of exiting.
 - * The setjmp buffer can be made a private field within an expanded error
 - * handler object.  Note that the info needed to generate an error message
 - * is stored in the error object, so you can generate the message now or
 - * later, at your convenience.
 - * You should make sure that the JPEG object is cleaned up (with jpeg_abort
 - * or jpeg_destroy) at some point.
 - */
 -
 -METHODDEF void
 -error_exit (j_common_ptr 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);
 -
 -  // FIXME: need to get this setup with an error handler
 -  //Error("%s\n", buffer );
 -}
 -
 -
 -/*
 - * Actual output of an error or trace message.
 - * Applications may override this method to send JPEG messages somewhere
 - * other than stderr.
 - */
 -
 -METHODDEF void
 -output_message (j_common_ptr cinfo)
 -{
 -  char buffer[JMSG_LENGTH_MAX];
 -
 -  /* Create the message */
 -  (*cinfo->err->format_message) (cinfo, buffer);
 -
 -  /* Send it to stderr, adding a newline */
 -  printf("%s\n", buffer);
 -}
 -
 -
 -/*
 - * Decide whether to emit a trace or warning message.
 - * msg_level is one of:
 - *   -1: recoverable corrupt-data warning, may want to abort.
 - *    0: important advisory messages (always display to user).
 - *    1: first level of tracing detail.
 - *    2,3,...: successively more detailed tracing messages.
 - * An application might override this method if it wanted to abort on warnings
 - * or change the policy about which messages to display.
 - */
 -
 -METHODDEF void
 -emit_message (j_common_ptr cinfo, int msg_level)
 -{
 -  struct jpeg_error_mgr * err = cinfo->err;
 -
 -  if (msg_level < 0) {
 -    /* It's a warning message.  Since corrupt files may generate many warnings,
 -     * the policy implemented here is to show only the first warning,
 -     * unless trace_level >= 3.
 -     */
 -    if (err->num_warnings == 0 || err->trace_level >= 3)
 -      (*err->output_message) (cinfo);
 -    /* Always count warnings in num_warnings. */
 -    err->num_warnings++;
 -  } else {
 -    /* It's a trace message.  Show it if trace_level >= msg_level. */
 -    if (err->trace_level >= msg_level)
 -      (*err->output_message) (cinfo);
 -  }
 -}
 -
 -
 -/*
 - * Format a message string for the most recent JPEG error or message.
 - * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
 - * characters.  Note that no '\n' character is added to the string.
 - * Few applications should need to override this method.
 - */
 -
 -METHODDEF void
 -format_message (j_common_ptr cinfo, char * buffer)
 -{
 -  struct jpeg_error_mgr * err = cinfo->err;
 -  int msg_code = err->msg_code;
 -  const char * msgtext = NULL;
 -  const char * msgptr;
 -  char ch;
 -  boolean isstring;
 -
 -  /* Look up message string in proper table */
 -  if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
 -    msgtext = err->jpeg_message_table[msg_code];
 -  } else if (err->addon_message_table != NULL &&
 -	     msg_code >= err->first_addon_message &&
 -	     msg_code <= err->last_addon_message) {
 -    msgtext = err->addon_message_table[msg_code - err->first_addon_message];
 -  }
 -
 -  /* Defend against bogus message number */
 -  if (msgtext == NULL) {
 -    err->msg_parm.i[0] = msg_code;
 -    msgtext = err->jpeg_message_table[0];
 -  }
 -
 -  /* Check for string parameter, as indicated by %s in the message text */
 -  isstring = FALSE;
 -  msgptr = msgtext;
 -  while ((ch = *msgptr++) != '\0') {
 -    if (ch == '%') {
 -      if (*msgptr == 's') isstring = TRUE;
 -      break;
 -    }
 -  }
 -
 -  /* Format the message into the passed buffer */
 -  if (isstring)
 -    sprintf(buffer, msgtext, err->msg_parm.s);
 -  else
 -    sprintf(buffer, msgtext,
 -	    err->msg_parm.i[0], err->msg_parm.i[1],
 -	    err->msg_parm.i[2], err->msg_parm.i[3],
 -	    err->msg_parm.i[4], err->msg_parm.i[5],
 -	    err->msg_parm.i[6], err->msg_parm.i[7]);
 -}
 -
 -
 -/*
 - * Reset error state variables at start of a new image.
 - * This is called during compression startup to reset trace/error
 - * processing to default state, without losing any application-specific
 - * method pointers.  An application might possibly want to override
 - * this method if it has additional error processing state.
 - */
 -
 -METHODDEF void
 -reset_error_mgr (j_common_ptr cinfo)
 -{
 -  cinfo->err->num_warnings = 0;
 -  /* trace_level is not reset since it is an application-supplied parameter */
 -  cinfo->err->msg_code = 0;	/* may be useful as a flag for "no error" */
 -}
 -
 -
 -/*
 - * Fill in the standard error-handling methods in a jpeg_error_mgr object.
 - * Typical call is:
 - *	struct jpeg_compress_struct cinfo;
 - *	struct jpeg_error_mgr err;
 - *
 - *	cinfo.err = jpeg_std_error(&err);
 - * after which the application may override some of the methods.
 - */
 -
 -GLOBAL struct jpeg_error_mgr *
 -jpeg_std_error (struct jpeg_error_mgr * err)
 -{
 -  err->error_exit = error_exit;
 -  err->emit_message = emit_message;
 -  err->output_message = output_message;
 -  err->format_message = format_message;
 -  err->reset_error_mgr = reset_error_mgr;
 -
 -  err->trace_level = 0;		/* default = no tracing */
 -  err->num_warnings = 0;	/* no warnings emitted yet */
 -  err->msg_code = 0;		/* may be useful as a flag for "no error" */
 -
 -  /* Initialize message table pointers */
 -  err->jpeg_message_table = jpeg_std_message_table;
 -  err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
 -
 -  err->addon_message_table = NULL;
 -  err->first_addon_message = 0;	/* for safety */
 -  err->last_addon_message = 0;
 -
 -  return err;
 -}
 +/* + * jerror.c + * + * Copyright (C) 1991-1994, 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 simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do.  Many applications will want to replace + * some or all of these routines. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" + +#ifndef EXIT_FAILURE		/* define exit() codes if not provided */ +#define EXIT_FAILURE  1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table	jMsgTable +#endif + +#define JMESSAGE(code,string)	string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" +  NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error.  Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object.  Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF void +error_exit (j_common_ptr 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); + +  // FIXME: need to get this setup with an error handler +  //Error("%s\n", buffer ); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + */ + +METHODDEF void +output_message (j_common_ptr cinfo) +{ +  char buffer[JMSG_LENGTH_MAX]; + +  /* Create the message */ +  (*cinfo->err->format_message) (cinfo, buffer); + +  /* Send it to stderr, adding a newline */ +  printf("%s\n", buffer); +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + *   -1: recoverable corrupt-data warning, may want to abort. + *    0: important advisory messages (always display to user). + *    1: first level of tracing detail. + *    2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF void +emit_message (j_common_ptr cinfo, int msg_level) +{ +  struct jpeg_error_mgr * err = cinfo->err; + +  if (msg_level < 0) { +    /* It's a warning message.  Since corrupt files may generate many warnings, +     * the policy implemented here is to show only the first warning, +     * unless trace_level >= 3. +     */ +    if (err->num_warnings == 0 || err->trace_level >= 3) +      (*err->output_message) (cinfo); +    /* Always count warnings in num_warnings. */ +    err->num_warnings++; +  } else { +    /* It's a trace message.  Show it if trace_level >= msg_level. */ +    if (err->trace_level >= msg_level) +      (*err->output_message) (cinfo); +  } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters.  Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF void +format_message (j_common_ptr cinfo, char * buffer) +{ +  struct jpeg_error_mgr * err = cinfo->err; +  int msg_code = err->msg_code; +  const char * msgtext = NULL; +  const char * msgptr; +  char ch; +  boolean isstring; + +  /* Look up message string in proper table */ +  if (msg_code > 0 && msg_code <= err->last_jpeg_message) { +    msgtext = err->jpeg_message_table[msg_code]; +  } else if (err->addon_message_table != NULL && +	     msg_code >= err->first_addon_message && +	     msg_code <= err->last_addon_message) { +    msgtext = err->addon_message_table[msg_code - err->first_addon_message]; +  } + +  /* Defend against bogus message number */ +  if (msgtext == NULL) { +    err->msg_parm.i[0] = msg_code; +    msgtext = err->jpeg_message_table[0]; +  } + +  /* Check for string parameter, as indicated by %s in the message text */ +  isstring = FALSE; +  msgptr = msgtext; +  while ((ch = *msgptr++) != '\0') { +    if (ch == '%') { +      if (*msgptr == 's') isstring = TRUE; +      break; +    } +  } + +  /* Format the message into the passed buffer */ +  if (isstring) +    sprintf(buffer, msgtext, err->msg_parm.s); +  else +    sprintf(buffer, msgtext, +	    err->msg_parm.i[0], err->msg_parm.i[1], +	    err->msg_parm.i[2], err->msg_parm.i[3], +	    err->msg_parm.i[4], err->msg_parm.i[5], +	    err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers.  An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF void +reset_error_mgr (j_common_ptr cinfo) +{ +  cinfo->err->num_warnings = 0; +  /* trace_level is not reset since it is an application-supplied parameter */ +  cinfo->err->msg_code = 0;	/* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + *	struct jpeg_compress_struct cinfo; + *	struct jpeg_error_mgr err; + * + *	cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL struct jpeg_error_mgr * +jpeg_std_error (struct jpeg_error_mgr * err) +{ +  err->error_exit = error_exit; +  err->emit_message = emit_message; +  err->output_message = output_message; +  err->format_message = format_message; +  err->reset_error_mgr = reset_error_mgr; + +  err->trace_level = 0;		/* default = no tracing */ +  err->num_warnings = 0;	/* no warnings emitted yet */ +  err->msg_code = 0;		/* may be useful as a flag for "no error" */ + +  /* Initialize message table pointers */ +  err->jpeg_message_table = jpeg_std_message_table; +  err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + +  err->addon_message_table = NULL; +  err->first_addon_message = 0;	/* for safety */ +  err->last_addon_message = 0; + +  return err; +} diff --git a/libs/jpeg6/jerror.h b/libs/jpeg6/jerror.h index 0ffb8b4..bf60e7e 100755 --- a/libs/jpeg6/jerror.h +++ b/libs/jpeg6/jerror.h @@ -1,273 +1,273 @@ -/*
 - * jerror.h
 - *
 - * Copyright (C) 1994-1995, 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 defines the error and message codes for the JPEG library.
 - * Edit this file to add new codes, or to translate the message strings to
 - * some other language.
 - * A set of error-reporting macros are defined too.  Some applications using
 - * the JPEG library may wish to include this file to get the error codes
 - * and/or the macros.
 - */
 -
 -/*
 - * To define the enum list of message codes, include this file without
 - * defining macro JMESSAGE.  To create a message string table, include it
 - * again with a suitable JMESSAGE definition (see jerror.c for an example).
 - */
 -#ifndef JMESSAGE
 -#ifndef JERROR_H
 -/* First time through, define the enum list */
 -#define JMAKE_ENUM_LIST
 -#else
 -/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
 -#define JMESSAGE(code,string)
 -#endif /* JERROR_H */
 -#endif /* JMESSAGE */
 -
 -#ifdef JMAKE_ENUM_LIST
 -
 -typedef enum {
 -
 -#define JMESSAGE(code,string)	code ,
 -
 -#endif /* JMAKE_ENUM_LIST */
 -
 -JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
 -
 -/* For maintenance convenience, list is alphabetical by message code name */
 -JMESSAGE(JERR_ARITH_NOTIMPL,
 -	 "Sorry, there are legal restrictions on arithmetic coding")
 -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_DCTSIZE, "IDCT output block size %d not supported")
 -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_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")
 -JMESSAGE(JERR_BAD_PROGRESSION,
 -	 "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
 -JMESSAGE(JERR_BAD_PROG_SCRIPT,
 -	 "Invalid progressive parameters at scan script entry %d")
 -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_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")
 -JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
 -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)")
 -JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
 -JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
 -JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
 -JMESSAGE(JERR_FILE_READ, "Input file read error")
 -JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
 -JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
 -JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
 -JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
 -JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
 -JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
 -JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
 -JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
 -	 "Cannot transcode due to multiple use of quantization table %d")
 -JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
 -JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
 -JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
 -JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
 -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
 -JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
 -JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
 -JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
 -JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
 -JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
 -JMESSAGE(JERR_QUANT_COMPONENTS,
 -	 "Cannot quantize more than %d color components")
 -JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
 -JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
 -JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
 -JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
 -JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
 -JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
 -JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
 -JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
 -JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
 -JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
 -JMESSAGE(JERR_TFILE_WRITE,
 -	 "Write failed on temporary file --- out of disk space?")
 -JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
 -JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
 -JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
 -JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
 -JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
 -JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
 -JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
 -JMESSAGE(JMSG_VERSION, JVERSION)
 -JMESSAGE(JTRC_16BIT_TABLES,
 -	 "Caution: quantization tables are too coarse for baseline JPEG")
 -JMESSAGE(JTRC_ADOBE,
 -	 "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
 -JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
 -JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
 -JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
 -JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
 -JMESSAGE(JTRC_DQT, "Define Quantization Table %d  precision %d")
 -JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
 -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_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_THUMBNAIL, "    with %d x %d thumbnail image")
 -JMESSAGE(JTRC_MISC_MARKER, "Skipping 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")
 -JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
 -JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
 -JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
 -JMESSAGE(JTRC_RST, "RST%d")
 -JMESSAGE(JTRC_SMOOTH_NOTIMPL,
 -	 "Smoothing not supported with nonstandard sampling ratios")
 -JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
 -JMESSAGE(JTRC_SOF_COMPONENT, "    Component %d: %dhx%dv q=%d")
 -JMESSAGE(JTRC_SOI, "Start of Image")
 -JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
 -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_UNKNOWN_IDS,
 -	 "Unrecognized component IDs %d %d %d, assuming YCbCr")
 -JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
 -JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
 -JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
 -JMESSAGE(JWRN_BOGUS_PROGRESSION,
 -	 "Inconsistent progression sequence for component %d coefficient %d")
 -JMESSAGE(JWRN_EXTRANEOUS_DATA,
 -	 "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
 -JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
 -JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
 -JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
 -JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
 -JMESSAGE(JWRN_MUST_RESYNC,
 -	 "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
 -JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
 -JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
 -
 -#ifdef JMAKE_ENUM_LIST
 -
 -  JMSG_LASTMSGCODE
 -} J_MESSAGE_CODE;
 -
 -#undef JMAKE_ENUM_LIST
 -#endif /* JMAKE_ENUM_LIST */
 -
 -/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
 -#undef JMESSAGE
 -
 -
 -#ifndef JERROR_H
 -#define JERROR_H
 -
 -/* Macros to simplify using the error and trace message stuff */
 -/* The first parameter is either type of cinfo pointer */
 -
 -/* Fatal errors (print message and exit) */
 -#define ERREXIT(cinfo,code)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -#define ERREXIT1(cinfo,code,p1)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -#define ERREXIT2(cinfo,code,p1,p2)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (cinfo)->err->msg_parm.i[1] = (p2), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -#define ERREXIT3(cinfo,code,p1,p2,p3)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (cinfo)->err->msg_parm.i[1] = (p2), \
 -   (cinfo)->err->msg_parm.i[2] = (p3), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -#define ERREXIT4(cinfo,code,p1,p2,p3,p4)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (cinfo)->err->msg_parm.i[1] = (p2), \
 -   (cinfo)->err->msg_parm.i[2] = (p3), \
 -   (cinfo)->err->msg_parm.i[3] = (p4), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -#define ERREXITS(cinfo,code,str)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
 -   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
 -
 -#define MAKESTMT(stuff)		do { stuff } while (0)
 -
 -/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
 -#define WARNMS(cinfo,code)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 -#define WARNMS1(cinfo,code,p1)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 -#define WARNMS2(cinfo,code,p1,p2)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (cinfo)->err->msg_parm.i[1] = (p2), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
 -
 -/* Informational/debugging messages */
 -#define TRACEMS(cinfo,lvl,code)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 -#define TRACEMS1(cinfo,lvl,code,p1)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 -#define TRACEMS2(cinfo,lvl,code,p1,p2)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   (cinfo)->err->msg_parm.i[0] = (p1), \
 -   (cinfo)->err->msg_parm.i[1] = (p2), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 -#define TRACEMS3(cinfo,lvl,code,p1,p2,p3)  \
 -  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 -	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
 -	   (cinfo)->err->msg_code = (code); \
 -	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 -#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4)  \
 -  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 -	   _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 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); \
 -	   _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
 -	   (cinfo)->err->msg_code = (code); \
 -	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 -#define TRACEMSS(cinfo,lvl,code,str)  \
 -  ((cinfo)->err->msg_code = (code), \
 -   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
 -   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
 -
 -#endif /* JERROR_H */
 +/* + * jerror.h + * + * Copyright (C) 1994-1995, 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 defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too.  Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE.  To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string)	code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, +	 "Sorry, there are legal restrictions on arithmetic coding") +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_DCTSIZE, "IDCT output block size %d not supported") +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_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") +JMESSAGE(JERR_BAD_PROGRESSION, +	 "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, +	 "Invalid progressive parameters at scan script entry %d") +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_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") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +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)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, +	 "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, +	 "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, +	 "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, +	 "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, +	 "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d  precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +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_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_THUMBNAIL, "    with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Skipping 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") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, +	 "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, "    Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +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_UNKNOWN_IDS, +	 "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, +	 "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, +	 "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, +	 "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + +  JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code)  \ +  ((cinfo)->err->msg_code = (code), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (cinfo)->err->msg_parm.i[1] = (p2), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (cinfo)->err->msg_parm.i[1] = (p2), \ +   (cinfo)->err->msg_parm.i[2] = (p3), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (cinfo)->err->msg_parm.i[1] = (p2), \ +   (cinfo)->err->msg_parm.i[2] = (p3), \ +   (cinfo)->err->msg_parm.i[3] = (p4), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str)  \ +  ((cinfo)->err->msg_code = (code), \ +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff)		do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code)  \ +  ((cinfo)->err->msg_code = (code), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (cinfo)->err->msg_parm.i[1] = (p2), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code)  \ +  ((cinfo)->err->msg_code = (code), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2)  \ +  ((cinfo)->err->msg_code = (code), \ +   (cinfo)->err->msg_parm.i[0] = (p1), \ +   (cinfo)->err->msg_parm.i[1] = (p2), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3)  \ +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ +	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ +	   (cinfo)->err->msg_code = (code); \ +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4)  \ +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ +	   _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 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); \ +	   _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ +	   (cinfo)->err->msg_code = (code); \ +	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str)  \ +  ((cinfo)->err->msg_code = (code), \ +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/libs/jpeg6/jfdctflt.cpp b/libs/jpeg6/jfdctflt.cpp index 1509b88..21371eb 100755 --- a/libs/jpeg6/jfdctflt.cpp +++ b/libs/jpeg6/jfdctflt.cpp @@ -1,168 +1,168 @@ -/*
 - * jfdctflt.c
 - *
 - * Copyright (C) 1994, 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 floating-point implementation of the
 - * forward DCT (Discrete Cosine Transform).
 - *
 - * This implementation should be more accurate than either of the integer
 - * DCT implementations.  However, it may not give the same results on all
 - * machines because of differences in roundoff behavior.  Speed will depend
 - * on the hardware's floating point capacity.
 - *
 - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
 - * on each column.  Direct algorithms are also available, but they are
 - * much more complex and seem not to be any faster when reduced to code.
 - *
 - * This implementation is based on Arai, Agui, and Nakajima's algorithm for
 - * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
 - * Japanese, but the algorithm is described in the Pennebaker & Mitchell
 - * JPEG textbook (see REFERENCES section in file README).  The following code
 - * is based directly on figure 4-8 in P&M.
 - * While an 8-point DCT cannot be done in less than 11 multiplies, it is
 - * possible to arrange the computation so that many of the multiplies are
 - * simple scalings of the final outputs.  These multiplies can then be
 - * folded into the multiplications or divisions by the JPEG quantization
 - * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
 - * to be done in the DCT itself.
 - * The primary disadvantage of this method is that with a fixed-point
 - * implementation, accuracy is lost due to imprecise representation of the
 - * scaled quantization values.  However, that problem does not arise if
 - * we use floating point arithmetic.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jdct.h"		/* Private declarations for DCT subsystem */
 -
 -#ifdef DCT_FLOAT_SUPPORTED
 -
 -
 -/*
 - * This module is specialized to the case DCTSIZE = 8.
 - */
 -
 -#if DCTSIZE != 8
 -  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
 -#endif
 -
 -
 -/*
 - * Perform the forward DCT on one block of samples.
 - */
 -
 -GLOBAL void
 -jpeg_fdct_float (FAST_FLOAT * data)
 -{
 -  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
 -  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
 -  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
 -  FAST_FLOAT *dataptr;
 -  int ctr;
 -
 -  /* Pass 1: process rows. */
 -
 -  dataptr = data;
 -  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 -    tmp0 = dataptr[0] + dataptr[7];
 -    tmp7 = dataptr[0] - dataptr[7];
 -    tmp1 = dataptr[1] + dataptr[6];
 -    tmp6 = dataptr[1] - dataptr[6];
 -    tmp2 = dataptr[2] + dataptr[5];
 -    tmp5 = dataptr[2] - dataptr[5];
 -    tmp3 = dataptr[3] + dataptr[4];
 -    tmp4 = dataptr[3] - dataptr[4];
 -    
 -    /* Even part */
 -    
 -    tmp10 = tmp0 + tmp3;	/* phase 2 */
 -    tmp13 = tmp0 - tmp3;
 -    tmp11 = tmp1 + tmp2;
 -    tmp12 = tmp1 - tmp2;
 -    
 -    dataptr[0] = tmp10 + tmp11; /* phase 3 */
 -    dataptr[4] = tmp10 - tmp11;
 -    
 -    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
 -    dataptr[2] = tmp13 + z1;	/* phase 5 */
 -    dataptr[6] = tmp13 - z1;
 -    
 -    /* Odd part */
 -
 -    tmp10 = tmp4 + tmp5;	/* phase 2 */
 -    tmp11 = tmp5 + tmp6;
 -    tmp12 = tmp6 + tmp7;
 -
 -    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 -    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
 -    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
 -    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
 -    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
 -
 -    z11 = tmp7 + z3;		/* phase 5 */
 -    z13 = tmp7 - z3;
 -
 -    dataptr[5] = z13 + z2;	/* phase 6 */
 -    dataptr[3] = z13 - z2;
 -    dataptr[1] = z11 + z4;
 -    dataptr[7] = z11 - z4;
 -
 -    dataptr += DCTSIZE;		/* advance pointer to next row */
 -  }
 -
 -  /* Pass 2: process columns. */
 -
 -  dataptr = data;
 -  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
 -    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
 -    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
 -    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
 -    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
 -    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
 -    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
 -    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
 -    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
 -    
 -    /* Even part */
 -    
 -    tmp10 = tmp0 + tmp3;	/* phase 2 */
 -    tmp13 = tmp0 - tmp3;
 -    tmp11 = tmp1 + tmp2;
 -    tmp12 = tmp1 - tmp2;
 -    
 -    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
 -    dataptr[DCTSIZE*4] = tmp10 - tmp11;
 -    
 -    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
 -    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
 -    dataptr[DCTSIZE*6] = tmp13 - z1;
 -    
 -    /* Odd part */
 -
 -    tmp10 = tmp4 + tmp5;	/* phase 2 */
 -    tmp11 = tmp5 + tmp6;
 -    tmp12 = tmp6 + tmp7;
 -
 -    /* The rotator is modified from fig 4-8 to avoid extra negations. */
 -    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
 -    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
 -    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
 -    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
 -
 -    z11 = tmp7 + z3;		/* phase 5 */
 -    z13 = tmp7 - z3;
 -
 -    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
 -    dataptr[DCTSIZE*3] = z13 - z2;
 -    dataptr[DCTSIZE*1] = z11 + z4;
 -    dataptr[DCTSIZE*7] = z11 - z4;
 -
 -    dataptr++;			/* advance pointer to next column */
 -  }
 -}
 -
 -#endif /* DCT_FLOAT_SUPPORTED */
 +/* + * jfdctflt.c + * + * Copyright (C) 1994, 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 floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations.  However, it may not give the same results on all + * machines because of differences in roundoff behavior.  Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column.  Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README).  The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs.  These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values.  However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h"		/* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL void +jpeg_fdct_float (FAST_FLOAT * data) +{ +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13; +  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; +  FAST_FLOAT *dataptr; +  int ctr; + +  /* Pass 1: process rows. */ + +  dataptr = data; +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { +    tmp0 = dataptr[0] + dataptr[7]; +    tmp7 = dataptr[0] - dataptr[7]; +    tmp1 = dataptr[1] + dataptr[6]; +    tmp6 = dataptr[1] - dataptr[6]; +    tmp2 = dataptr[2] + dataptr[5]; +    tmp5 = dataptr[2] - dataptr[5]; +    tmp3 = dataptr[3] + dataptr[4]; +    tmp4 = dataptr[3] - dataptr[4]; +     +    /* Even part */ +     +    tmp10 = tmp0 + tmp3;	/* phase 2 */ +    tmp13 = tmp0 - tmp3; +    tmp11 = tmp1 + tmp2; +    tmp12 = tmp1 - tmp2; +     +    dataptr[0] = tmp10 + tmp11; /* phase 3 */ +    dataptr[4] = tmp10 - tmp11; +     +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ +    dataptr[2] = tmp13 + z1;	/* phase 5 */ +    dataptr[6] = tmp13 - z1; +     +    /* Odd part */ + +    tmp10 = tmp4 + tmp5;	/* phase 2 */ +    tmp11 = tmp5 + tmp6; +    tmp12 = tmp6 + tmp7; + +    /* The rotator is modified from fig 4-8 to avoid extra negations. */ +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + +    z11 = tmp7 + z3;		/* phase 5 */ +    z13 = tmp7 - z3; + +    dataptr[5] = z13 + z2;	/* phase 6 */ +    dataptr[3] = z13 - z2; +    dataptr[1] = z11 + z4; +    dataptr[7] = z11 - z4; + +    dataptr += DCTSIZE;		/* advance pointer to next row */ +  } + +  /* Pass 2: process columns. */ + +  dataptr = data; +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; +     +    /* Even part */ +     +    tmp10 = tmp0 + tmp3;	/* phase 2 */ +    tmp13 = tmp0 - tmp3; +    tmp11 = tmp1 + tmp2; +    tmp12 = tmp1 - tmp2; +     +    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ +    dataptr[DCTSIZE*4] = tmp10 - tmp11; +     +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ +    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ +    dataptr[DCTSIZE*6] = tmp13 - z1; +     +    /* Odd part */ + +    tmp10 = tmp4 + tmp5;	/* phase 2 */ +    tmp11 = tmp5 + tmp6; +    tmp12 = tmp6 + tmp7; + +    /* The rotator is modified from fig 4-8 to avoid extra negations. */ +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + +    z11 = tmp7 + z3;		/* phase 5 */ +    z13 = tmp7 - z3; + +    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ +    dataptr[DCTSIZE*3] = z13 - z2; +    dataptr[DCTSIZE*1] = z11 + z4; +    dataptr[DCTSIZE*7] = z11 - z4; + +    dataptr++;			/* advance pointer to next column */ +  } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/libs/jpeg6/jidctflt.cpp b/libs/jpeg6/jidctflt.cpp index 2e25c44..847919e 100755 --- a/libs/jpeg6/jidctflt.cpp +++ b/libs/jpeg6/jidctflt.cpp @@ -1,241 +1,241 @@ -/*
 - * jidctflt.c
 - *
 - * Copyright (C) 1994, 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 floating-point implementation of the
 - * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
 - * must also perform dequantization of the input coefficients.
 - *
 - * This implementation should be more accurate than either of the integer
 - * IDCT implementations.  However, it may not give the same results on all
 - * machines because of differences in roundoff behavior.  Speed will depend
 - * on the hardware's floating point capacity.
 - *
 - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
 - * on each row (or vice versa, but it's more convenient to emit a row at
 - * a time).  Direct algorithms are also available, but they are much more
 - * complex and seem not to be any faster when reduced to code.
 - *
 - * This implementation is based on Arai, Agui, and Nakajima's algorithm for
 - * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
 - * Japanese, but the algorithm is described in the Pennebaker & Mitchell
 - * JPEG textbook (see REFERENCES section in file README).  The following code
 - * is based directly on figure 4-8 in P&M.
 - * While an 8-point DCT cannot be done in less than 11 multiplies, it is
 - * possible to arrange the computation so that many of the multiplies are
 - * simple scalings of the final outputs.  These multiplies can then be
 - * folded into the multiplications or divisions by the JPEG quantization
 - * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
 - * to be done in the DCT itself.
 - * The primary disadvantage of this method is that with a fixed-point
 - * implementation, accuracy is lost due to imprecise representation of the
 - * scaled quantization values.  However, that problem does not arise if
 - * we use floating point arithmetic.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jdct.h"		/* Private declarations for DCT subsystem */
 -
 -#ifdef DCT_FLOAT_SUPPORTED
 -
 -
 -/*
 - * This module is specialized to the case DCTSIZE = 8.
 - */
 -
 -#if DCTSIZE != 8
 -  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
 -#endif
 -
 -
 -/* Dequantize a coefficient by multiplying it by the multiplier-table
 - * entry; produce a float result.
 - */
 -
 -#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval))
 -
 -
 -/*
 - * Perform dequantization and inverse DCT on one block of coefficients.
 - */
 -
 -GLOBAL void
 -jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		 JCOEFPTR coef_block,
 -		 JSAMPARRAY output_buf, JDIMENSION output_col)
 -{
 -  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
 -  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
 -  FAST_FLOAT z5, z10, z11, z12, z13;
 -  JCOEFPTR inptr;
 -  FLOAT_MULT_TYPE * quantptr;
 -  FAST_FLOAT * wsptr;
 -  JSAMPROW outptr;
 -  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
 -  int ctr;
 -  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
 -  SHIFT_TEMPS
 -
 -  /* Pass 1: process columns from input, store into work array. */
 -
 -  inptr = coef_block;
 -  quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
 -  wsptr = workspace;
 -  for (ctr = DCTSIZE; ctr > 0; ctr--) {
 -    /* Due to quantization, we will usually find that many of the input
 -     * coefficients are zero, especially the AC terms.  We can exploit this
 -     * by short-circuiting the IDCT calculation for any column in which all
 -     * the AC terms are zero.  In that case each output is equal to the
 -     * DC coefficient (with scale factor as needed).
 -     * With typical images and quantization tables, half or more of the
 -     * 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) {
 -      /* AC terms all zero */
 -      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 -      
 -      wsptr[DCTSIZE*0] = dcval;
 -      wsptr[DCTSIZE*1] = dcval;
 -      wsptr[DCTSIZE*2] = dcval;
 -      wsptr[DCTSIZE*3] = dcval;
 -      wsptr[DCTSIZE*4] = dcval;
 -      wsptr[DCTSIZE*5] = dcval;
 -      wsptr[DCTSIZE*6] = dcval;
 -      wsptr[DCTSIZE*7] = dcval;
 -      
 -      inptr++;			/* advance pointers to next column */
 -      quantptr++;
 -      wsptr++;
 -      continue;
 -    }
 -    
 -    /* Even part */
 -
 -    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 -    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
 -    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
 -    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
 -
 -    tmp10 = tmp0 + tmp2;	/* phase 3 */
 -    tmp11 = tmp0 - tmp2;
 -
 -    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
 -    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
 -
 -    tmp0 = tmp10 + tmp13;	/* phase 2 */
 -    tmp3 = tmp10 - tmp13;
 -    tmp1 = tmp11 + tmp12;
 -    tmp2 = tmp11 - tmp12;
 -    
 -    /* Odd part */
 -
 -    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
 -    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
 -    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
 -    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
 -
 -    z13 = tmp6 + tmp5;		/* phase 6 */
 -    z10 = tmp6 - tmp5;
 -    z11 = tmp4 + tmp7;
 -    z12 = tmp4 - tmp7;
 -
 -    tmp7 = z11 + z13;		/* phase 5 */
 -    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
 -
 -    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
 -    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
 -    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
 -
 -    tmp6 = tmp12 - tmp7;	/* phase 2 */
 -    tmp5 = tmp11 - tmp6;
 -    tmp4 = tmp10 + tmp5;
 -
 -    wsptr[DCTSIZE*0] = tmp0 + tmp7;
 -    wsptr[DCTSIZE*7] = tmp0 - tmp7;
 -    wsptr[DCTSIZE*1] = tmp1 + tmp6;
 -    wsptr[DCTSIZE*6] = tmp1 - tmp6;
 -    wsptr[DCTSIZE*2] = tmp2 + tmp5;
 -    wsptr[DCTSIZE*5] = tmp2 - tmp5;
 -    wsptr[DCTSIZE*4] = tmp3 + tmp4;
 -    wsptr[DCTSIZE*3] = tmp3 - tmp4;
 -
 -    inptr++;			/* advance pointers to next column */
 -    quantptr++;
 -    wsptr++;
 -  }
 -  
 -  /* Pass 2: process rows from work array, store into output array. */
 -  /* Note that we must descale the results by a factor of 8 == 2**3. */
 -
 -  wsptr = workspace;
 -  for (ctr = 0; ctr < DCTSIZE; ctr++) {
 -    outptr = output_buf[ctr] + output_col;
 -    /* Rows of zeroes can be exploited in the same way as we did with columns.
 -     * However, the column calculation has created many nonzero AC terms, so
 -     * the simplification applies less often (typically 5% to 10% of the time).
 -     * And testing floats for zero is relatively expensive, so we don't bother.
 -     */
 -    
 -    /* Even part */
 -
 -    tmp10 = wsptr[0] + wsptr[4];
 -    tmp11 = wsptr[0] - wsptr[4];
 -
 -    tmp13 = wsptr[2] + wsptr[6];
 -    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
 -
 -    tmp0 = tmp10 + tmp13;
 -    tmp3 = tmp10 - tmp13;
 -    tmp1 = tmp11 + tmp12;
 -    tmp2 = tmp11 - tmp12;
 -
 -    /* Odd part */
 -
 -    z13 = wsptr[5] + wsptr[3];
 -    z10 = wsptr[5] - wsptr[3];
 -    z11 = wsptr[1] + wsptr[7];
 -    z12 = wsptr[1] - wsptr[7];
 -
 -    tmp7 = z11 + z13;
 -    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
 -
 -    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
 -    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
 -    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
 -
 -    tmp6 = tmp12 - tmp7;
 -    tmp5 = tmp11 - tmp6;
 -    tmp4 = tmp10 + tmp5;
 -
 -    /* Final output stage: scale down by a factor of 8 and range-limit */
 -
 -    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
 -			    & RANGE_MASK];
 -    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
 -			    & RANGE_MASK];
 -    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
 -			    & RANGE_MASK];
 -    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
 -			    & RANGE_MASK];
 -    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
 -			    & RANGE_MASK];
 -    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
 -			    & RANGE_MASK];
 -    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
 -			    & RANGE_MASK];
 -    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
 -			    & RANGE_MASK];
 -    
 -    wsptr += DCTSIZE;		/* advance pointer to next row */
 -  }
 -}
 -
 -#endif /* DCT_FLOAT_SUPPORTED */
 +/* + * jidctflt.c + * + * Copyright (C) 1994, 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 floating-point implementation of the + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations.  However, it may not give the same results on all + * machines because of differences in roundoff behavior.  Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time).  Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README).  The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs.  These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values.  However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h"		/* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a float result. + */ + +#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL void +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, +		 JCOEFPTR coef_block, +		 JSAMPARRAY output_buf, JDIMENSION output_col) +{ +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13; +  FAST_FLOAT z5, z10, z11, z12, z13; +  JCOEFPTR inptr; +  FLOAT_MULT_TYPE * quantptr; +  FAST_FLOAT * wsptr; +  JSAMPROW outptr; +  JSAMPLE *range_limit = IDCT_range_limit(cinfo); +  int ctr; +  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ +  SHIFT_TEMPS + +  /* Pass 1: process columns from input, store into work array. */ + +  inptr = coef_block; +  quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; +  wsptr = workspace; +  for (ctr = DCTSIZE; ctr > 0; ctr--) { +    /* Due to quantization, we will usually find that many of the input +     * coefficients are zero, especially the AC terms.  We can exploit this +     * by short-circuiting the IDCT calculation for any column in which all +     * the AC terms are zero.  In that case each output is equal to the +     * DC coefficient (with scale factor as needed). +     * With typical images and quantization tables, half or more of the +     * 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) { +      /* AC terms all zero */ +      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); +       +      wsptr[DCTSIZE*0] = dcval; +      wsptr[DCTSIZE*1] = dcval; +      wsptr[DCTSIZE*2] = dcval; +      wsptr[DCTSIZE*3] = dcval; +      wsptr[DCTSIZE*4] = dcval; +      wsptr[DCTSIZE*5] = dcval; +      wsptr[DCTSIZE*6] = dcval; +      wsptr[DCTSIZE*7] = dcval; +       +      inptr++;			/* advance pointers to next column */ +      quantptr++; +      wsptr++; +      continue; +    } +     +    /* Even part */ + +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + +    tmp10 = tmp0 + tmp2;	/* phase 3 */ +    tmp11 = tmp0 - tmp2; + +    tmp13 = tmp1 + tmp3;	/* phases 5-3 */ +    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + +    tmp0 = tmp10 + tmp13;	/* phase 2 */ +    tmp3 = tmp10 - tmp13; +    tmp1 = tmp11 + tmp12; +    tmp2 = tmp11 - tmp12; +     +    /* Odd part */ + +    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); +    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); +    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); +    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + +    z13 = tmp6 + tmp5;		/* phase 6 */ +    z10 = tmp6 - tmp5; +    z11 = tmp4 + tmp7; +    z12 = tmp4 - tmp7; + +    tmp7 = z11 + z13;		/* phase 5 */ +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + +    tmp6 = tmp12 - tmp7;	/* phase 2 */ +    tmp5 = tmp11 - tmp6; +    tmp4 = tmp10 + tmp5; + +    wsptr[DCTSIZE*0] = tmp0 + tmp7; +    wsptr[DCTSIZE*7] = tmp0 - tmp7; +    wsptr[DCTSIZE*1] = tmp1 + tmp6; +    wsptr[DCTSIZE*6] = tmp1 - tmp6; +    wsptr[DCTSIZE*2] = tmp2 + tmp5; +    wsptr[DCTSIZE*5] = tmp2 - tmp5; +    wsptr[DCTSIZE*4] = tmp3 + tmp4; +    wsptr[DCTSIZE*3] = tmp3 - tmp4; + +    inptr++;			/* advance pointers to next column */ +    quantptr++; +    wsptr++; +  } +   +  /* Pass 2: process rows from work array, store into output array. */ +  /* Note that we must descale the results by a factor of 8 == 2**3. */ + +  wsptr = workspace; +  for (ctr = 0; ctr < DCTSIZE; ctr++) { +    outptr = output_buf[ctr] + output_col; +    /* Rows of zeroes can be exploited in the same way as we did with columns. +     * However, the column calculation has created many nonzero AC terms, so +     * the simplification applies less often (typically 5% to 10% of the time). +     * And testing floats for zero is relatively expensive, so we don't bother. +     */ +     +    /* Even part */ + +    tmp10 = wsptr[0] + wsptr[4]; +    tmp11 = wsptr[0] - wsptr[4]; + +    tmp13 = wsptr[2] + wsptr[6]; +    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + +    tmp0 = tmp10 + tmp13; +    tmp3 = tmp10 - tmp13; +    tmp1 = tmp11 + tmp12; +    tmp2 = tmp11 - tmp12; + +    /* Odd part */ + +    z13 = wsptr[5] + wsptr[3]; +    z10 = wsptr[5] - wsptr[3]; +    z11 = wsptr[1] + wsptr[7]; +    z12 = wsptr[1] - wsptr[7]; + +    tmp7 = z11 + z13; +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + +    tmp6 = tmp12 - tmp7; +    tmp5 = tmp11 - tmp6; +    tmp4 = tmp10 + tmp5; + +    /* Final output stage: scale down by a factor of 8 and range-limit */ + +    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) +			    & RANGE_MASK]; +    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) +			    & RANGE_MASK]; +    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) +			    & RANGE_MASK]; +    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) +			    & RANGE_MASK]; +    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) +			    & RANGE_MASK]; +    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) +			    & RANGE_MASK]; +    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) +			    & RANGE_MASK]; +    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) +			    & RANGE_MASK]; +     +    wsptr += DCTSIZE;		/* advance pointer to next row */ +  } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/libs/jpeg6/jinclude.h b/libs/jpeg6/jinclude.h index 5ff60fe..0a4f151 100755 --- a/libs/jpeg6/jinclude.h +++ b/libs/jpeg6/jinclude.h @@ -1,91 +1,91 @@ -/*
 - * jinclude.h
 - *
 - * Copyright (C) 1991-1994, 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 exists to provide a single place to fix any problems with
 - * including the wrong system include files.  (Common problems are taken
 - * care of by the standard jconfig symbols, but on really weird systems
 - * you may have to edit this file.)
 - *
 - * NOTE: this file is NOT intended to be included by applications using the
 - * JPEG library.  Most applications need only include jpeglib.h.
 - */
 -
 -
 -/* Include auto-config file to find out which system include files we need. */
 -
 -#include "jconfig.h"		/* auto configuration options */
 -#define JCONFIG_INCLUDED	/* so that jpeglib.h doesn't do it again */
 -
 -/*
 - * We need the NULL macro and size_t typedef.
 - * On an ANSI-conforming system it is sufficient to include <stddef.h>.
 - * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
 - * pull in <sys/types.h> as well.
 - * Note that the core JPEG library does not require <stdio.h>;
 - * only the default error handler and data source/destination modules do.
 - * But we must pull it in because of the references to FILE in jpeglib.h.
 - * You can remove those references if you want to compile without <stdio.h>.
 - */
 -
 -#ifdef HAVE_STDDEF_H
 -#include <stddef.h>
 -#endif
 -
 -#ifdef HAVE_STDLIB_H
 -#include <stdlib.h>
 -#endif
 -
 -#ifdef NEED_SYS_TYPES_H
 -#include <sys/types.h>
 -#endif
 -
 -#include <stdio.h>
 -
 -/*
 - * We need memory copying and zeroing functions, plus strncpy().
 - * ANSI and System V implementations declare these in <string.h>.
 - * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
 - * Some systems may declare memset and memcpy in <memory.h>.
 - *
 - * NOTE: we assume the size parameters to these functions are of type size_t.
 - * Change the casts in these macros if not!
 - */
 -
 -#ifdef NEED_BSD_STRINGS
 -
 -#include <strings.h>
 -#define MEMZERO(target,size)	bzero((void *)(target), (size_t)(size))
 -#define MEMCOPY(dest,src,size)	bcopy((const void *)(src), (void *)(dest), (size_t)(size))
 -
 -#else /* not BSD, assume ANSI/SysV string lib */
 -
 -#include <string.h>
 -#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size))
 -#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size))
 -
 -#endif
 -
 -/*
 - * In ANSI C, and indeed any rational implementation, size_t is also the
 - * type returned by sizeof().  However, it seems there are some irrational
 - * implementations out there, in which sizeof() returns an int even though
 - * size_t is defined as long or unsigned long.  To ensure consistent results
 - * we always use this SIZEOF() macro in place of using sizeof() directly.
 - */
 -
 -#define SIZEOF(object)	((size_t) sizeof(object))
 -
 -/*
 - * The modules that use fread() and fwrite() always invoke them through
 - * these macros.  On some systems you may need to twiddle the argument casts.
 - * CAUTION: argument order is different from underlying functions!
 - */
 -
 -#define JFREAD(file,buf,sizeofbuf)  \
 -  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
 -#define JFWRITE(file,buf,sizeofbuf)  \
 -  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
 +/* + * jinclude.h + * + * Copyright (C) 1991-1994, 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 exists to provide a single place to fix any problems with + * including the wrong system include files.  (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library.  Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "jconfig.h"		/* auto configuration options */ +#define JCONFIG_INCLUDED	/* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include <stddef.h>. + * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to + * pull in <sys/types.h> as well. + * Note that the core JPEG library does not require <stdio.h>; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without <stdio.h>. + */ + +#ifdef HAVE_STDDEF_H +#include <stddef.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef NEED_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <stdio.h> + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in <string.h>. + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in <memory.h>. + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include <strings.h> +#define MEMZERO(target,size)	bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size)	bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include <string.h> +#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof().  However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long.  To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object)	((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros.  On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +#define JFREAD(file,buf,sizeofbuf)  \ +  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf)  \ +  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/libs/jpeg6/jmemmgr.cpp b/libs/jpeg6/jmemmgr.cpp index 61045f9..dc3e1c7 100755 --- a/libs/jpeg6/jmemmgr.cpp +++ b/libs/jpeg6/jmemmgr.cpp @@ -1,1115 +1,1115 @@ -/*
 - * jmemmgr.c
 - *
 - * Copyright (C) 1991-1995, 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 the JPEG system-independent memory management
 - * routines.  This code is usable across a wide variety of machines; most
 - * of the system dependencies have been isolated in a separate file.
 - * The major functions provided here are:
 - *   * pool-based allocation and freeing of memory;
 - *   * policy decisions about how to divide available memory among the
 - *     virtual arrays;
 - *   * control logic for swapping virtual arrays between main memory and
 - *     backing storage.
 - * The separate system-dependent file provides the actual backing-storage
 - * access code, and it contains the policy decision about how much total
 - * main memory to use.
 - * This file is system-dependent in the sense that some of its functions
 - * are unnecessary in some systems.  For example, if there is enough virtual
 - * memory so that backing storage will never be used, much of the virtual
 - * array control logic could be removed.  (Of course, if you have that much
 - * memory then you shouldn't care about a little bit of unused code...)
 - */
 -
 -#define JPEG_INTERNALS
 -#define AM_MEMORY_MANAGER	/* we define jvirt_Xarray_control structs */
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jmemsys.h"		/* import the system-dependent declarations */
 -
 -#ifndef NO_GETENV
 -#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare getenv() */
 -extern char * getenv JPP((const char * name));
 -#endif
 -#endif
 -
 -
 -/*
 - * Some important notes:
 - *   The allocation routines provided here must never return NULL.
 - *   They should exit to error_exit if unsuccessful.
 - *
 - *   It's not a good idea to try to merge the sarray and barray routines,
 - *   even though they are textually almost the same, because samples are
 - *   usually stored as bytes while coefficients are shorts or ints.  Thus,
 - *   in machines where byte pointers have a different representation from
 - *   word pointers, the resulting machine code could not be the same.
 - */
 -
 -
 -/*
 - * Many machines require storage alignment: longs must start on 4-byte
 - * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
 - * always returns pointers that are multiples of the worst-case alignment
 - * requirement, and we had better do so too.
 - * There isn't any really portable way to determine the worst-case alignment
 - * requirement.  This module assumes that the alignment requirement is
 - * multiples of sizeof(ALIGN_TYPE).
 - * By default, we define ALIGN_TYPE as double.  This is necessary on some
 - * workstations (where doubles really do need 8-byte alignment) and will work
 - * fine on nearly everything.  If your machine has lesser alignment needs,
 - * you can save a few bytes by making ALIGN_TYPE smaller.
 - * The only place I know of where this will NOT work is certain Macintosh
 - * 680x0 compilers that define double as a 10-byte IEEE extended float.
 - * Doing 10-byte alignment is counterproductive because longwords won't be
 - * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have
 - * such a compiler.
 - */
 -
 -#ifndef ALIGN_TYPE		/* so can override from jconfig.h */
 -#define ALIGN_TYPE  double
 -#endif
 -
 -
 -/*
 - * We allocate objects from "pools", where each pool is gotten with a single
 - * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
 - * overhead within a pool, except for alignment padding.  Each pool has a
 - * header with a link to the next pool of the same class.
 - * Small and large pool headers are identical except that the latter's
 - * link pointer must be FAR on 80x86 machines.
 - * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
 - * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
 - * of the alignment requirement of ALIGN_TYPE.
 - */
 -
 -typedef union small_pool_struct * small_pool_ptr;
 -
 -typedef union small_pool_struct {
 -  struct {
 -    small_pool_ptr next;	/* next in list of pools */
 -    size_t bytes_used;		/* how many bytes already used within pool */
 -    size_t bytes_left;		/* bytes still available in this pool */
 -  } hdr;
 -  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
 -} small_pool_hdr;
 -
 -typedef union large_pool_struct FAR * large_pool_ptr;
 -
 -typedef union large_pool_struct {
 -  struct {
 -    large_pool_ptr next;	/* next in list of pools */
 -    size_t bytes_used;		/* how many bytes already used within pool */
 -    size_t bytes_left;		/* bytes still available in this pool */
 -  } hdr;
 -  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
 -} large_pool_hdr;
 -
 -
 -/*
 - * Here is the full definition of a memory manager object.
 - */
 -
 -typedef struct {
 -  struct jpeg_memory_mgr pub;	/* public fields */
 -
 -  /* Each pool identifier (lifetime class) names a linked list of pools. */
 -  small_pool_ptr small_list[JPOOL_NUMPOOLS];
 -  large_pool_ptr large_list[JPOOL_NUMPOOLS];
 -
 -  /* Since we only have one lifetime class of virtual arrays, only one
 -   * linked list is necessary (for each datatype).  Note that the virtual
 -   * array control blocks being linked together are actually stored somewhere
 -   * in the small-pool list.
 -   */
 -  jvirt_sarray_ptr virt_sarray_list;
 -  jvirt_barray_ptr virt_barray_list;
 -
 -  /* This counts total space obtained from jpeg_get_small/large */
 -  long total_space_allocated;
 -
 -  /* alloc_sarray and alloc_barray set this value for use by virtual
 -   * array routines.
 -   */
 -  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */
 -} my_memory_mgr;
 -
 -typedef my_memory_mgr * my_mem_ptr;
 -
 -
 -/*
 - * The control blocks for virtual arrays.
 - * Note that these blocks are allocated in the "small" pool area.
 - * System-dependent info for the associated backing store (if any) is hidden
 - * inside the backing_store_info struct.
 - */
 -
 -struct jvirt_sarray_control {
 -  JSAMPARRAY mem_buffer;	/* => the in-memory buffer */
 -  JDIMENSION rows_in_array;	/* total virtual array height */
 -  JDIMENSION samplesperrow;	/* width of array (and of memory buffer) */
 -  JDIMENSION maxaccess;		/* max rows accessed by access_virt_sarray */
 -  JDIMENSION rows_in_mem;	/* height of memory buffer */
 -  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
 -  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
 -  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
 -  boolean pre_zero;		/* pre-zero mode requested? */
 -  boolean dirty;		/* do current buffer contents need written? */
 -  boolean b_s_open;		/* is backing-store data valid? */
 -  jvirt_sarray_ptr next;	/* link to next virtual sarray control block */
 -  backing_store_info b_s_info;	/* System-dependent control info */
 -};
 -
 -struct jvirt_barray_control {
 -  JBLOCKARRAY mem_buffer;	/* => the in-memory buffer */
 -  JDIMENSION rows_in_array;	/* total virtual array height */
 -  JDIMENSION blocksperrow;	/* width of array (and of memory buffer) */
 -  JDIMENSION maxaccess;		/* max rows accessed by access_virt_barray */
 -  JDIMENSION rows_in_mem;	/* height of memory buffer */
 -  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */
 -  JDIMENSION cur_start_row;	/* first logical row # in the buffer */
 -  JDIMENSION first_undef_row;	/* row # of first uninitialized row */
 -  boolean pre_zero;		/* pre-zero mode requested? */
 -  boolean dirty;		/* do current buffer contents need written? */
 -  boolean b_s_open;		/* is backing-store data valid? */
 -  jvirt_barray_ptr next;	/* link to next virtual barray control block */
 -  backing_store_info b_s_info;	/* System-dependent control info */
 -};
 -
 -
 -#ifdef MEM_STATS		/* optional extra stuff for statistics */
 -
 -LOCAL void
 -print_mem_stats (j_common_ptr cinfo, int pool_id)
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  small_pool_ptr shdr_ptr;
 -  large_pool_ptr lhdr_ptr;
 -
 -  /* Since this is only a debugging stub, we can cheat a little by using
 -   * fprintf directly rather than going through the trace message code.
 -   * This is helpful because message parm array can't handle longs.
 -   */
 -  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
 -	  pool_id, mem->total_space_allocated);
 -
 -  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
 -       lhdr_ptr = lhdr_ptr->hdr.next) {
 -    fprintf(stderr, "  Large chunk used %ld\n",
 -	    (long) lhdr_ptr->hdr.bytes_used);
 -  }
 -
 -  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
 -       shdr_ptr = shdr_ptr->hdr.next) {
 -    fprintf(stderr, "  Small chunk used %ld free %ld\n",
 -	    (long) shdr_ptr->hdr.bytes_used,
 -	    (long) shdr_ptr->hdr.bytes_left);
 -  }
 -}
 -
 -#endif /* MEM_STATS */
 -
 -
 -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 */
 -{
 -#ifdef MEM_STATS
 -  cinfo->err->trace_level = 2;	/* force self_destruct to report stats */
 -#endif
 -  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
 -}
 -
 -
 -/*
 - * Allocation of "small" objects.
 - *
 - * For these, we use pooled storage.  When a new pool must be created,
 - * we try to get enough space for the current request plus a "slop" factor,
 - * where the slop will be the amount of leftover space in the new pool.
 - * The speed vs. space tradeoff is largely determined by the slop values.
 - * A different slop value is provided for each pool class (lifetime),
 - * and we also distinguish the first pool of a class from later ones.
 - * NOTE: the values given work fairly well on both 16- and 32-bit-int
 - * machines, but may be too small if longs are 64 bits or more.
 - */
 -
 -static const size_t first_pool_slop[JPOOL_NUMPOOLS] = 
 -{
 -	1600,			/* first PERMANENT pool */
 -	16000			/* first IMAGE pool */
 -};
 -
 -static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = 
 -{
 -	0,			/* additional PERMANENT pools */
 -	5000			/* additional IMAGE pools */
 -};
 -
 -#define MIN_SLOP  50		/* greater than 0 to avoid futile looping */
 -
 -
 -METHODDEF void *
 -alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
 -/* Allocate a "small" object */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  small_pool_ptr hdr_ptr, prev_hdr_ptr;
 -  char * data_ptr;
 -  size_t odd_bytes, min_request, slop;
 -
 -  /* Check for unsatisfiable request (do now to ensure no overflow below) */
 -  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
 -    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */
 -
 -  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
 -  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
 -  if (odd_bytes > 0)
 -    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
 -
 -  /* See if space is available in any existing pool */
 -  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 -    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 -  prev_hdr_ptr = NULL;
 -  hdr_ptr = mem->small_list[pool_id];
 -  while (hdr_ptr != NULL) {
 -    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
 -      break;			/* found pool with enough space */
 -    prev_hdr_ptr = hdr_ptr;
 -    hdr_ptr = hdr_ptr->hdr.next;
 -  }
 -
 -  /* Time to make a new pool? */
 -  if (hdr_ptr == NULL) {
 -    /* min_request is what we need now, slop is what will be leftover */
 -    min_request = sizeofobject + SIZEOF(small_pool_hdr);
 -    if (prev_hdr_ptr == NULL)	/* first pool in class? */
 -      slop = first_pool_slop[pool_id];
 -    else
 -      slop = extra_pool_slop[pool_id];
 -    /* Don't ask for more than MAX_ALLOC_CHUNK */
 -    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
 -      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
 -    /* Try to get space, if fail reduce slop and try again */
 -    for (;;) {
 -      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
 -      if (hdr_ptr != NULL)
 -	break;
 -      slop /= 2;
 -      if (slop < MIN_SLOP)	/* give up when it gets real small */
 -	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
 -    }
 -    mem->total_space_allocated += min_request + slop;
 -    /* Success, initialize the new pool header and add to end of list */
 -    hdr_ptr->hdr.next = NULL;
 -    hdr_ptr->hdr.bytes_used = 0;
 -    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
 -    if (prev_hdr_ptr == NULL)	/* first pool in class? */
 -      mem->small_list[pool_id] = hdr_ptr;
 -    else
 -      prev_hdr_ptr->hdr.next = hdr_ptr;
 -  }
 -
 -  /* OK, allocate the object from the current pool */
 -  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
 -  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
 -  hdr_ptr->hdr.bytes_used += sizeofobject;
 -  hdr_ptr->hdr.bytes_left -= sizeofobject;
 -
 -  return (void *) data_ptr;
 -}
 -
 -
 -/*
 - * Allocation of "large" objects.
 - *
 - * The external semantics of these are the same as "small" objects,
 - * except that FAR pointers are used on 80x86.  However the pool
 - * management heuristics are quite different.  We assume that each
 - * request is large enough that it may as well be passed directly to
 - * jpeg_get_large; the pool management just links everything together
 - * so that we can free it all on demand.
 - * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
 - * structures.  The routines that create these structures (see below)
 - * deliberately bunch rows together to ensure a large request size.
 - */
 -
 -METHODDEF void FAR *
 -alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
 -/* Allocate a "large" object */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  large_pool_ptr hdr_ptr;
 -  size_t odd_bytes;
 -
 -  /* Check for unsatisfiable request (do now to ensure no overflow below) */
 -  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
 -    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */
 -
 -  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
 -  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
 -  if (odd_bytes > 0)
 -    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
 -
 -  /* Always make a new pool */
 -  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 -    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 -
 -  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
 -					    SIZEOF(large_pool_hdr));
 -  if (hdr_ptr == NULL)
 -    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */
 -  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
 -
 -  /* Success, initialize the new pool header and add to list */
 -  hdr_ptr->hdr.next = mem->large_list[pool_id];
 -  /* We maintain space counts in each pool header for statistical purposes,
 -   * even though they are not needed for allocation.
 -   */
 -  hdr_ptr->hdr.bytes_used = sizeofobject;
 -  hdr_ptr->hdr.bytes_left = 0;
 -  mem->large_list[pool_id] = hdr_ptr;
 -
 -  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
 -}
 -
 -
 -/*
 - * Creation of 2-D sample arrays.
 - * The pointers are in near heap, the samples themselves in FAR heap.
 - *
 - * To minimize allocation overhead and to allow I/O of large contiguous
 - * blocks, we allocate the sample rows in groups of as many rows as possible
 - * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
 - * NB: the virtual array control routines, later in this file, know about
 - * this chunking of rows.  The rowsperchunk value is left in the mem manager
 - * object so that it can be saved away if this sarray is the workspace for
 - * a virtual array.
 - */
 -
 -METHODDEF JSAMPARRAY
 -alloc_sarray (j_common_ptr cinfo, int pool_id,
 -	      JDIMENSION samplesperrow, JDIMENSION numrows)
 -/* Allocate a 2-D sample array */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  JSAMPARRAY result;
 -  JSAMPROW workspace;
 -  JDIMENSION rowsperchunk, currow, i;
 -  long ltemp;
 -
 -  /* Calculate max # of rows allowed in one allocation chunk */
 -  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
 -	  ((long) samplesperrow * SIZEOF(JSAMPLE));
 -  if (ltemp <= 0)
 -    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 -  if (ltemp < (long) numrows)
 -    rowsperchunk = (JDIMENSION) ltemp;
 -  else
 -    rowsperchunk = numrows;
 -  mem->last_rowsperchunk = rowsperchunk;
 -
 -  /* Get space for row pointers (small object) */
 -  result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
 -				    (size_t) (numrows * SIZEOF(JSAMPROW)));
 -
 -  /* Get the rows themselves (large objects) */
 -  currow = 0;
 -  while (currow < numrows) {
 -    rowsperchunk = MIN(rowsperchunk, numrows - currow);
 -    workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
 -	(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
 -		  * SIZEOF(JSAMPLE)));
 -    for (i = rowsperchunk; i > 0; i--) {
 -      result[currow++] = workspace;
 -      workspace += samplesperrow;
 -    }
 -  }
 -
 -  return result;
 -}
 -
 -
 -/*
 - * Creation of 2-D coefficient-block arrays.
 - * This is essentially the same as the code for sample arrays, above.
 - */
 -
 -METHODDEF JBLOCKARRAY
 -alloc_barray (j_common_ptr cinfo, int pool_id,
 -	      JDIMENSION blocksperrow, JDIMENSION numrows)
 -/* Allocate a 2-D coefficient-block array */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  JBLOCKARRAY result;
 -  JBLOCKROW workspace;
 -  JDIMENSION rowsperchunk, currow, i;
 -  long ltemp;
 -
 -  /* Calculate max # of rows allowed in one allocation chunk */
 -  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
 -	  ((long) blocksperrow * SIZEOF(JBLOCK));
 -  if (ltemp <= 0)
 -    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 -  if (ltemp < (long) numrows)
 -    rowsperchunk = (JDIMENSION) ltemp;
 -  else
 -    rowsperchunk = numrows;
 -  mem->last_rowsperchunk = rowsperchunk;
 -
 -  /* Get space for row pointers (small object) */
 -  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
 -				     (size_t) (numrows * SIZEOF(JBLOCKROW)));
 -
 -  /* Get the rows themselves (large objects) */
 -  currow = 0;
 -  while (currow < numrows) {
 -    rowsperchunk = MIN(rowsperchunk, numrows - currow);
 -    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
 -	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
 -		  * SIZEOF(JBLOCK)));
 -    for (i = rowsperchunk; i > 0; i--) {
 -      result[currow++] = workspace;
 -      workspace += blocksperrow;
 -    }
 -  }
 -
 -  return result;
 -}
 -
 -
 -/*
 - * About virtual array management:
 - *
 - * The above "normal" array routines are only used to allocate strip buffers
 - * (as wide as the image, but just a few rows high).  Full-image-sized buffers
 - * are handled as "virtual" arrays.  The array is still accessed a strip at a
 - * time, but the memory manager must save the whole array for repeated
 - * accesses.  The intended implementation is that there is a strip buffer in
 - * memory (as high as is possible given the desired memory limit), plus a
 - * backing file that holds the rest of the array.
 - *
 - * The request_virt_array routines are told the total size of the image and
 - * the maximum number of rows that will be accessed at once.  The in-memory
 - * buffer must be at least as large as the maxaccess value.
 - *
 - * The request routines create control blocks but not the in-memory buffers.
 - * That is postponed until realize_virt_arrays is called.  At that time the
 - * total amount of space needed is known (approximately, anyway), so free
 - * memory can be divided up fairly.
 - *
 - * The access_virt_array routines are responsible for making a specific strip
 - * area accessible (after reading or writing the backing file, if necessary).
 - * Note that the access routines are told whether the caller intends to modify
 - * the accessed strip; during a read-only pass this saves having to rewrite
 - * data to disk.  The access routines are also responsible for pre-zeroing
 - * any newly accessed rows, if pre-zeroing was requested.
 - *
 - * In current usage, the access requests are usually for nonoverlapping
 - * strips; that is, successive access start_row numbers differ by exactly
 - * num_rows = maxaccess.  This means we can get good performance with simple
 - * buffer dump/reload logic, by making the in-memory buffer be a multiple
 - * of the access height; then there will never be accesses across bufferload
 - * boundaries.  The code will still work with overlapping access requests,
 - * but it doesn't handle bufferload overlaps very efficiently.
 - */
 -
 -
 -METHODDEF jvirt_sarray_ptr
 -request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
 -		     JDIMENSION samplesperrow, JDIMENSION numrows,
 -		     JDIMENSION maxaccess)
 -/* Request a virtual 2-D sample array */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  jvirt_sarray_ptr result;
 -
 -  /* Only IMAGE-lifetime virtual arrays are currently supported */
 -  if (pool_id != JPOOL_IMAGE)
 -    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 -
 -  /* get control block */
 -  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
 -					  SIZEOF(struct jvirt_sarray_control));
 -
 -  result->mem_buffer = NULL;	/* marks array not yet realized */
 -  result->rows_in_array = numrows;
 -  result->samplesperrow = samplesperrow;
 -  result->maxaccess = maxaccess;
 -  result->pre_zero = pre_zero;
 -  result->b_s_open = FALSE;	/* no associated backing-store object */
 -  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
 -  mem->virt_sarray_list = result;
 -
 -  return result;
 -}
 -
 -
 -METHODDEF jvirt_barray_ptr
 -request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
 -		     JDIMENSION blocksperrow, JDIMENSION numrows,
 -		     JDIMENSION maxaccess)
 -/* Request a virtual 2-D coefficient-block array */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  jvirt_barray_ptr result;
 -
 -  /* Only IMAGE-lifetime virtual arrays are currently supported */
 -  if (pool_id != JPOOL_IMAGE)
 -    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 -
 -  /* get control block */
 -  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
 -					  SIZEOF(struct jvirt_barray_control));
 -
 -  result->mem_buffer = NULL;	/* marks array not yet realized */
 -  result->rows_in_array = numrows;
 -  result->blocksperrow = blocksperrow;
 -  result->maxaccess = maxaccess;
 -  result->pre_zero = pre_zero;
 -  result->b_s_open = FALSE;	/* no associated backing-store object */
 -  result->next = mem->virt_barray_list; /* add to list of virtual arrays */
 -  mem->virt_barray_list = result;
 -
 -  return result;
 -}
 -
 -
 -METHODDEF void
 -realize_virt_arrays (j_common_ptr cinfo)
 -/* Allocate the in-memory buffers for any unrealized virtual arrays */
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  long space_per_minheight, maximum_space, avail_mem;
 -  long minheights, max_minheights;
 -  jvirt_sarray_ptr sptr;
 -  jvirt_barray_ptr bptr;
 -
 -  /* Compute the minimum space needed (maxaccess rows in each buffer)
 -   * and the maximum space needed (full image height in each buffer).
 -   * These may be of use to the system-dependent jpeg_mem_available routine.
 -   */
 -  space_per_minheight = 0;
 -  maximum_space = 0;
 -  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 -    if (sptr->mem_buffer == NULL) { /* if not realized yet */
 -      space_per_minheight += (long) sptr->maxaccess *
 -			     (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
 -      maximum_space += (long) sptr->rows_in_array *
 -		       (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
 -    }
 -  }
 -  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 -    if (bptr->mem_buffer == NULL) { /* if not realized yet */
 -      space_per_minheight += (long) bptr->maxaccess *
 -			     (long) bptr->blocksperrow * SIZEOF(JBLOCK);
 -      maximum_space += (long) bptr->rows_in_array *
 -		       (long) bptr->blocksperrow * SIZEOF(JBLOCK);
 -    }
 -  }
 -
 -  if (space_per_minheight <= 0)
 -    return;			/* no unrealized arrays, no work */
 -
 -  /* Determine amount of memory to actually use; this is system-dependent. */
 -  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
 -				 mem->total_space_allocated);
 -
 -  /* If the maximum space needed is available, make all the buffers full
 -   * height; otherwise parcel it out with the same number of minheights
 -   * in each buffer.
 -   */
 -  if (avail_mem >= maximum_space)
 -    max_minheights = 1000000000L;
 -  else {
 -    max_minheights = avail_mem / space_per_minheight;
 -    /* If there doesn't seem to be enough space, try to get the minimum
 -     * anyway.  This allows a "stub" implementation of jpeg_mem_available().
 -     */
 -    if (max_minheights <= 0)
 -      max_minheights = 1;
 -  }
 -
 -  /* Allocate the in-memory buffers and initialize backing store as needed. */
 -
 -  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 -    if (sptr->mem_buffer == NULL) { /* if not realized yet */
 -      minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
 -      if (minheights <= max_minheights) {
 -	/* This buffer fits in memory */
 -	sptr->rows_in_mem = sptr->rows_in_array;
 -      } else {
 -	/* It doesn't fit in memory, create backing store. */
 -	sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
 -	jpeg_open_backing_store(cinfo, & sptr->b_s_info,
 -				(long) sptr->rows_in_array *
 -				(long) sptr->samplesperrow *
 -				(long) SIZEOF(JSAMPLE));
 -	sptr->b_s_open = TRUE;
 -      }
 -      sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
 -				      sptr->samplesperrow, sptr->rows_in_mem);
 -      sptr->rowsperchunk = mem->last_rowsperchunk;
 -      sptr->cur_start_row = 0;
 -      sptr->first_undef_row = 0;
 -      sptr->dirty = FALSE;
 -    }
 -  }
 -
 -  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 -    if (bptr->mem_buffer == NULL) { /* if not realized yet */
 -      minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
 -      if (minheights <= max_minheights) {
 -	/* This buffer fits in memory */
 -	bptr->rows_in_mem = bptr->rows_in_array;
 -      } else {
 -	/* It doesn't fit in memory, create backing store. */
 -	bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
 -	jpeg_open_backing_store(cinfo, & bptr->b_s_info,
 -				(long) bptr->rows_in_array *
 -				(long) bptr->blocksperrow *
 -				(long) SIZEOF(JBLOCK));
 -	bptr->b_s_open = TRUE;
 -      }
 -      bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
 -				      bptr->blocksperrow, bptr->rows_in_mem);
 -      bptr->rowsperchunk = mem->last_rowsperchunk;
 -      bptr->cur_start_row = 0;
 -      bptr->first_undef_row = 0;
 -      bptr->dirty = FALSE;
 -    }
 -  }
 -}
 -
 -
 -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 */
 -{
 -  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
 -
 -  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
 -  file_offset = ptr->cur_start_row * bytesperrow;
 -  /* Loop to read or write each allocation chunk in mem_buffer */
 -  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
 -    /* One chunk, but check for short chunk at end of buffer */
 -    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
 -    /* Transfer no more than is currently defined */
 -    thisrow = (long) ptr->cur_start_row + i;
 -    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
 -    /* Transfer no more than fits in file */
 -    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
 -    if (rows <= 0)		/* this chunk might be past end of file! */
 -      break;
 -    byte_count = rows * bytesperrow;
 -    if (writing)
 -      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
 -					    (void FAR *) ptr->mem_buffer[i],
 -					    file_offset, byte_count);
 -    else
 -      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
 -					   (void FAR *) ptr->mem_buffer[i],
 -					   file_offset, byte_count);
 -    file_offset += byte_count;
 -  }
 -}
 -
 -
 -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 */
 -{
 -  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
 -
 -  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
 -  file_offset = ptr->cur_start_row * bytesperrow;
 -  /* Loop to read or write each allocation chunk in mem_buffer */
 -  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
 -    /* One chunk, but check for short chunk at end of buffer */
 -    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
 -    /* Transfer no more than is currently defined */
 -    thisrow = (long) ptr->cur_start_row + i;
 -    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
 -    /* Transfer no more than fits in file */
 -    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
 -    if (rows <= 0)		/* this chunk might be past end of file! */
 -      break;
 -    byte_count = rows * bytesperrow;
 -    if (writing)
 -      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
 -					    (void FAR *) ptr->mem_buffer[i],
 -					    file_offset, byte_count);
 -    else
 -      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
 -					   (void FAR *) ptr->mem_buffer[i],
 -					   file_offset, byte_count);
 -    file_offset += byte_count;
 -  }
 -}
 -
 -
 -METHODDEF JSAMPARRAY
 -access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
 -		    JDIMENSION start_row, JDIMENSION num_rows,
 -		    boolean writable)
 -/* Access the part of a virtual sample array starting at start_row */
 -/* and extending for num_rows rows.  writable is true if  */
 -/* caller intends to modify the accessed area. */
 -{
 -  JDIMENSION end_row = start_row + num_rows;
 -  JDIMENSION undef_row;
 -
 -  /* debugging check */
 -  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
 -      ptr->mem_buffer == NULL)
 -    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -
 -  /* Make the desired part of the virtual array accessible */
 -  if (start_row < ptr->cur_start_row ||
 -      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
 -    if (! ptr->b_s_open)
 -      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
 -    /* Flush old buffer contents if necessary */
 -    if (ptr->dirty) {
 -      do_sarray_io(cinfo, ptr, TRUE);
 -      ptr->dirty = FALSE;
 -    }
 -    /* Decide what part of virtual array to access.
 -     * Algorithm: if target address > current window, assume forward scan,
 -     * load starting at target address.  If target address < current window,
 -     * assume backward scan, load so that target area is top of window.
 -     * Note that when switching from forward write to forward read, will have
 -     * start_row = 0, so the limiting case applies and we load from 0 anyway.
 -     */
 -    if (start_row > ptr->cur_start_row) {
 -      ptr->cur_start_row = start_row;
 -    } else {
 -      /* use long arithmetic here to avoid overflow & unsigned problems */
 -      long ltemp;
 -
 -      ltemp = (long) end_row - (long) ptr->rows_in_mem;
 -      if (ltemp < 0)
 -	ltemp = 0;		/* don't fall off front end of file */
 -      ptr->cur_start_row = (JDIMENSION) ltemp;
 -    }
 -    /* Read in the selected part of the array.
 -     * During the initial write pass, we will do no actual read
 -     * because the selected part is all undefined.
 -     */
 -    do_sarray_io(cinfo, ptr, FALSE);
 -  }
 -  /* Ensure the accessed part of the array is defined; prezero if needed.
 -   * To improve locality of access, we only prezero the part of the array
 -   * that the caller is about to access, not the entire in-memory array.
 -   */
 -  if (ptr->first_undef_row < end_row) {
 -    if (ptr->first_undef_row < start_row) {
 -      if (writable)		/* writer skipped over a section of array */
 -	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -      undef_row = start_row;	/* but reader is allowed to read ahead */
 -    } else {
 -      undef_row = ptr->first_undef_row;
 -    }
 -    if (writable)
 -      ptr->first_undef_row = end_row;
 -    if (ptr->pre_zero) {
 -      size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
 -      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
 -      end_row -= ptr->cur_start_row;
 -      while (undef_row < end_row) {
 -	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
 -	undef_row++;
 -      }
 -    } else {
 -      if (! writable)		/* reader looking at undefined data */
 -	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -    }
 -  }
 -  /* Flag the buffer dirty if caller will write in it */
 -  if (writable)
 -    ptr->dirty = TRUE;
 -  /* Return address of proper part of the buffer */
 -  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
 -}
 -
 -
 -METHODDEF JBLOCKARRAY
 -access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
 -		    JDIMENSION start_row, JDIMENSION num_rows,
 -		    boolean writable)
 -/* Access the part of a virtual block array starting at start_row */
 -/* and extending for num_rows rows.  writable is true if  */
 -/* caller intends to modify the accessed area. */
 -{
 -  JDIMENSION end_row = start_row + num_rows;
 -  JDIMENSION undef_row;
 -
 -  /* debugging check */
 -  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
 -      ptr->mem_buffer == NULL)
 -    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -
 -  /* Make the desired part of the virtual array accessible */
 -  if (start_row < ptr->cur_start_row ||
 -      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
 -    if (! ptr->b_s_open)
 -      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
 -    /* Flush old buffer contents if necessary */
 -    if (ptr->dirty) {
 -      do_barray_io(cinfo, ptr, TRUE);
 -      ptr->dirty = FALSE;
 -    }
 -    /* Decide what part of virtual array to access.
 -     * Algorithm: if target address > current window, assume forward scan,
 -     * load starting at target address.  If target address < current window,
 -     * assume backward scan, load so that target area is top of window.
 -     * Note that when switching from forward write to forward read, will have
 -     * start_row = 0, so the limiting case applies and we load from 0 anyway.
 -     */
 -    if (start_row > ptr->cur_start_row) {
 -      ptr->cur_start_row = start_row;
 -    } else {
 -      /* use long arithmetic here to avoid overflow & unsigned problems */
 -      long ltemp;
 -
 -      ltemp = (long) end_row - (long) ptr->rows_in_mem;
 -      if (ltemp < 0)
 -	ltemp = 0;		/* don't fall off front end of file */
 -      ptr->cur_start_row = (JDIMENSION) ltemp;
 -    }
 -    /* Read in the selected part of the array.
 -     * During the initial write pass, we will do no actual read
 -     * because the selected part is all undefined.
 -     */
 -    do_barray_io(cinfo, ptr, FALSE);
 -  }
 -  /* Ensure the accessed part of the array is defined; prezero if needed.
 -   * To improve locality of access, we only prezero the part of the array
 -   * that the caller is about to access, not the entire in-memory array.
 -   */
 -  if (ptr->first_undef_row < end_row) {
 -    if (ptr->first_undef_row < start_row) {
 -      if (writable)		/* writer skipped over a section of array */
 -	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -      undef_row = start_row;	/* but reader is allowed to read ahead */
 -    } else {
 -      undef_row = ptr->first_undef_row;
 -    }
 -    if (writable)
 -      ptr->first_undef_row = end_row;
 -    if (ptr->pre_zero) {
 -      size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
 -      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
 -      end_row -= ptr->cur_start_row;
 -      while (undef_row < end_row) {
 -	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
 -	undef_row++;
 -      }
 -    } else {
 -      if (! writable)		/* reader looking at undefined data */
 -	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
 -    }
 -  }
 -  /* Flag the buffer dirty if caller will write in it */
 -  if (writable)
 -    ptr->dirty = TRUE;
 -  /* Return address of proper part of the buffer */
 -  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
 -}
 -
 -
 -/*
 - * Release all objects belonging to a specified pool.
 - */
 -
 -METHODDEF void
 -free_pool (j_common_ptr cinfo, int pool_id)
 -{
 -  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
 -  small_pool_ptr shdr_ptr;
 -  large_pool_ptr lhdr_ptr;
 -  size_t space_freed;
 -
 -  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
 -    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
 -
 -#ifdef MEM_STATS
 -  if (cinfo->err->trace_level > 1)
 -    print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
 -#endif
 -
 -  /* If freeing IMAGE pool, close any virtual arrays first */
 -  if (pool_id == JPOOL_IMAGE) {
 -    jvirt_sarray_ptr sptr;
 -    jvirt_barray_ptr bptr;
 -
 -    for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
 -      if (sptr->b_s_open) {	/* there may be no backing store */
 -	sptr->b_s_open = FALSE;	/* prevent recursive close if error */
 -	(*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
 -      }
 -    }
 -    mem->virt_sarray_list = NULL;
 -    for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
 -      if (bptr->b_s_open) {	/* there may be no backing store */
 -	bptr->b_s_open = FALSE;	/* prevent recursive close if error */
 -	(*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
 -      }
 -    }
 -    mem->virt_barray_list = NULL;
 -  }
 -
 -  /* Release large objects */
 -  lhdr_ptr = mem->large_list[pool_id];
 -  mem->large_list[pool_id] = NULL;
 -
 -  while (lhdr_ptr != NULL) {
 -    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
 -    space_freed = lhdr_ptr->hdr.bytes_used +
 -		  lhdr_ptr->hdr.bytes_left +
 -		  SIZEOF(large_pool_hdr);
 -    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
 -    mem->total_space_allocated -= space_freed;
 -    lhdr_ptr = next_lhdr_ptr;
 -  }
 -
 -  /* Release small objects */
 -  shdr_ptr = mem->small_list[pool_id];
 -  mem->small_list[pool_id] = NULL;
 -
 -  while (shdr_ptr != NULL) {
 -    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
 -    space_freed = shdr_ptr->hdr.bytes_used +
 -		  shdr_ptr->hdr.bytes_left +
 -		  SIZEOF(small_pool_hdr);
 -    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
 -    mem->total_space_allocated -= space_freed;
 -    shdr_ptr = next_shdr_ptr;
 -  }
 -}
 -
 -
 -/*
 - * Close up shop entirely.
 - * Note that this cannot be called unless cinfo->mem is non-NULL.
 - */
 -
 -METHODDEF void
 -self_destruct (j_common_ptr cinfo)
 -{
 -  int pool;
 -
 -  /* Close all backing store, release all memory.
 -   * Releasing pools in reverse order might help avoid fragmentation
 -   * with some (brain-damaged) malloc libraries.
 -   */
 -  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
 -    free_pool(cinfo, pool);
 -  }
 -
 -  /* Release the memory manager control block too. */
 -  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
 -  cinfo->mem = NULL;		/* ensures I will be called only once */
 -
 -  jpeg_mem_term(cinfo);		/* system-dependent cleanup */
 -}
 -
 -
 -/*
 - * Memory manager initialization.
 - * When this is called, only the error manager pointer is valid in cinfo!
 - */
 -
 -GLOBAL void
 -jinit_memory_mgr (j_common_ptr cinfo)
 -{
 -  my_mem_ptr mem;
 -  long max_to_use;
 -  int pool;
 -  size_t test_mac;
 -
 -  cinfo->mem = NULL;		/* for safety if init fails */
 -
 -  /* Check for configuration errors.
 -   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
 -   * doesn't reflect any real hardware alignment requirement.
 -   * The test is a little tricky: for X>0, X and X-1 have no one-bits
 -   * in common if and only if X is a power of 2, ie has only one one-bit.
 -   * Some compilers may give an "unreachable code" warning here; ignore it.
 -   */
 -  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
 -    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
 -  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
 -   * a multiple of SIZEOF(ALIGN_TYPE).
 -   * Again, an "unreachable code" warning may be ignored here.
 -   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
 -   */
 -  test_mac = (size_t) MAX_ALLOC_CHUNK;
 -  if ((long) test_mac != MAX_ALLOC_CHUNK ||
 -      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
 -    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
 -
 -  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
 -
 -  /* Attempt to allocate memory manager's control block */
 -  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
 -
 -  if (mem == NULL) {
 -    jpeg_mem_term(cinfo);	/* system-dependent cleanup */
 -    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
 -  }
 -
 -  /* OK, fill in the method pointers */
 -  mem->pub.alloc_small = alloc_small;
 -  mem->pub.alloc_large = alloc_large;
 -  mem->pub.alloc_sarray = alloc_sarray;
 -  mem->pub.alloc_barray = alloc_barray;
 -  mem->pub.request_virt_sarray = request_virt_sarray;
 -  mem->pub.request_virt_barray = request_virt_barray;
 -  mem->pub.realize_virt_arrays = realize_virt_arrays;
 -  mem->pub.access_virt_sarray = access_virt_sarray;
 -  mem->pub.access_virt_barray = access_virt_barray;
 -  mem->pub.free_pool = free_pool;
 -  mem->pub.self_destruct = self_destruct;
 -
 -  /* Initialize working state */
 -  mem->pub.max_memory_to_use = max_to_use;
 -
 -  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
 -    mem->small_list[pool] = NULL;
 -    mem->large_list[pool] = NULL;
 -  }
 -  mem->virt_sarray_list = NULL;
 -  mem->virt_barray_list = NULL;
 -
 -  mem->total_space_allocated = SIZEOF(my_memory_mgr);
 -
 -  /* Declare ourselves open for business */
 -  cinfo->mem = & mem->pub;
 -
 -  /* Check for an environment variable JPEGMEM; if found, override the
 -   * default max_memory setting from jpeg_mem_init.  Note that the
 -   * surrounding application may again override this value.
 -   * If your system doesn't support getenv(), define NO_GETENV to disable
 -   * this feature.
 -   */
 -#ifndef NO_GETENV
 -  { char * memenv;
 -
 -    if ((memenv = getenv("JPEGMEM")) != NULL) {
 -      char ch = 'x';
 -
 -      if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
 -	if (ch == 'm' || ch == 'M')
 -	  max_to_use *= 1000L;
 -	mem->pub.max_memory_to_use = max_to_use * 1000L;
 -      }
 -    }
 -  }
 -#endif
 -
 -}
 +/* + * jmemmgr.c + * + * Copyright (C) 1991-1995, 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 the JPEG system-independent memory management + * routines.  This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + *   * pool-based allocation and freeing of memory; + *   * policy decisions about how to divide available memory among the + *     virtual arrays; + *   * control logic for swapping virtual arrays between main memory and + *     backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems.  For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed.  (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER	/* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h"		/* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + + +/* + * Some important notes: + *   The allocation routines provided here must never return NULL. + *   They should exit to error_exit if unsuccessful. + * + *   It's not a good idea to try to merge the sarray and barray routines, + *   even though they are textually almost the same, because samples are + *   usually stored as bytes while coefficients are shorts or ints.  Thus, + *   in machines where byte pointers have a different representation from + *   word pointers, the resulting machine code could not be the same. + */ + + +/* + * Many machines require storage alignment: longs must start on 4-byte + * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc() + * always returns pointers that are multiples of the worst-case alignment + * requirement, and we had better do so too. + * There isn't any really portable way to determine the worst-case alignment + * requirement.  This module assumes that the alignment requirement is + * multiples of sizeof(ALIGN_TYPE). + * By default, we define ALIGN_TYPE as double.  This is necessary on some + * workstations (where doubles really do need 8-byte alignment) and will work + * fine on nearly everything.  If your machine has lesser alignment needs, + * you can save a few bytes by making ALIGN_TYPE smaller. + * The only place I know of where this will NOT work is certain Macintosh + * 680x0 compilers that define double as a 10-byte IEEE extended float. + * Doing 10-byte alignment is counterproductive because longwords won't be + * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have + * such a compiler. + */ + +#ifndef ALIGN_TYPE		/* so can override from jconfig.h */ +#define ALIGN_TYPE  double +#endif + + +/* + * We allocate objects from "pools", where each pool is gotten with a single + * request to jpeg_get_small() or jpeg_get_large().  There is no per-object + * overhead within a pool, except for alignment padding.  Each pool has a + * header with a link to the next pool of the same class. + * Small and large pool headers are identical except that the latter's + * link pointer must be FAR on 80x86 machines. + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + * of the alignment requirement of ALIGN_TYPE. + */ + +typedef union small_pool_struct * small_pool_ptr; + +typedef union small_pool_struct { +  struct { +    small_pool_ptr next;	/* next in list of pools */ +    size_t bytes_used;		/* how many bytes already used within pool */ +    size_t bytes_left;		/* bytes still available in this pool */ +  } hdr; +  ALIGN_TYPE dummy;		/* included in union to ensure alignment */ +} small_pool_hdr; + +typedef union large_pool_struct FAR * large_pool_ptr; + +typedef union large_pool_struct { +  struct { +    large_pool_ptr next;	/* next in list of pools */ +    size_t bytes_used;		/* how many bytes already used within pool */ +    size_t bytes_left;		/* bytes still available in this pool */ +  } hdr; +  ALIGN_TYPE dummy;		/* included in union to ensure alignment */ +} large_pool_hdr; + + +/* + * Here is the full definition of a memory manager object. + */ + +typedef struct { +  struct jpeg_memory_mgr pub;	/* public fields */ + +  /* Each pool identifier (lifetime class) names a linked list of pools. */ +  small_pool_ptr small_list[JPOOL_NUMPOOLS]; +  large_pool_ptr large_list[JPOOL_NUMPOOLS]; + +  /* Since we only have one lifetime class of virtual arrays, only one +   * linked list is necessary (for each datatype).  Note that the virtual +   * array control blocks being linked together are actually stored somewhere +   * in the small-pool list. +   */ +  jvirt_sarray_ptr virt_sarray_list; +  jvirt_barray_ptr virt_barray_list; + +  /* This counts total space obtained from jpeg_get_small/large */ +  long total_space_allocated; + +  /* alloc_sarray and alloc_barray set this value for use by virtual +   * array routines. +   */ +  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */ +} my_memory_mgr; + +typedef my_memory_mgr * my_mem_ptr; + + +/* + * The control blocks for virtual arrays. + * Note that these blocks are allocated in the "small" pool area. + * System-dependent info for the associated backing store (if any) is hidden + * inside the backing_store_info struct. + */ + +struct jvirt_sarray_control { +  JSAMPARRAY mem_buffer;	/* => the in-memory buffer */ +  JDIMENSION rows_in_array;	/* total virtual array height */ +  JDIMENSION samplesperrow;	/* width of array (and of memory buffer) */ +  JDIMENSION maxaccess;		/* max rows accessed by access_virt_sarray */ +  JDIMENSION rows_in_mem;	/* height of memory buffer */ +  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */ +  JDIMENSION cur_start_row;	/* first logical row # in the buffer */ +  JDIMENSION first_undef_row;	/* row # of first uninitialized row */ +  boolean pre_zero;		/* pre-zero mode requested? */ +  boolean dirty;		/* do current buffer contents need written? */ +  boolean b_s_open;		/* is backing-store data valid? */ +  jvirt_sarray_ptr next;	/* link to next virtual sarray control block */ +  backing_store_info b_s_info;	/* System-dependent control info */ +}; + +struct jvirt_barray_control { +  JBLOCKARRAY mem_buffer;	/* => the in-memory buffer */ +  JDIMENSION rows_in_array;	/* total virtual array height */ +  JDIMENSION blocksperrow;	/* width of array (and of memory buffer) */ +  JDIMENSION maxaccess;		/* max rows accessed by access_virt_barray */ +  JDIMENSION rows_in_mem;	/* height of memory buffer */ +  JDIMENSION rowsperchunk;	/* allocation chunk size in mem_buffer */ +  JDIMENSION cur_start_row;	/* first logical row # in the buffer */ +  JDIMENSION first_undef_row;	/* row # of first uninitialized row */ +  boolean pre_zero;		/* pre-zero mode requested? */ +  boolean dirty;		/* do current buffer contents need written? */ +  boolean b_s_open;		/* is backing-store data valid? */ +  jvirt_barray_ptr next;	/* link to next virtual barray control block */ +  backing_store_info b_s_info;	/* System-dependent control info */ +}; + + +#ifdef MEM_STATS		/* optional extra stuff for statistics */ + +LOCAL void +print_mem_stats (j_common_ptr cinfo, int pool_id) +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  small_pool_ptr shdr_ptr; +  large_pool_ptr lhdr_ptr; + +  /* Since this is only a debugging stub, we can cheat a little by using +   * fprintf directly rather than going through the trace message code. +   * This is helpful because message parm array can't handle longs. +   */ +  fprintf(stderr, "Freeing pool %d, total space = %ld\n", +	  pool_id, mem->total_space_allocated); + +  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; +       lhdr_ptr = lhdr_ptr->hdr.next) { +    fprintf(stderr, "  Large chunk used %ld\n", +	    (long) lhdr_ptr->hdr.bytes_used); +  } + +  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; +       shdr_ptr = shdr_ptr->hdr.next) { +    fprintf(stderr, "  Small chunk used %ld free %ld\n", +	    (long) shdr_ptr->hdr.bytes_used, +	    (long) shdr_ptr->hdr.bytes_left); +  } +} + +#endif /* MEM_STATS */ + + +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 */ +{ +#ifdef MEM_STATS +  cinfo->err->trace_level = 2;	/* force self_destruct to report stats */ +#endif +  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +} + + +/* + * Allocation of "small" objects. + * + * For these, we use pooled storage.  When a new pool must be created, + * we try to get enough space for the current request plus a "slop" factor, + * where the slop will be the amount of leftover space in the new pool. + * The speed vs. space tradeoff is largely determined by the slop values. + * A different slop value is provided for each pool class (lifetime), + * and we also distinguish the first pool of a class from later ones. + * NOTE: the values given work fairly well on both 16- and 32-bit-int + * machines, but may be too small if longs are 64 bits or more. + */ + +static const size_t first_pool_slop[JPOOL_NUMPOOLS] =  +{ +	1600,			/* first PERMANENT pool */ +	16000			/* first IMAGE pool */ +}; + +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =  +{ +	0,			/* additional PERMANENT pools */ +	5000			/* additional IMAGE pools */ +}; + +#define MIN_SLOP  50		/* greater than 0 to avoid futile looping */ + + +METHODDEF void * +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "small" object */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  small_pool_ptr hdr_ptr, prev_hdr_ptr; +  char * data_ptr; +  size_t odd_bytes, min_request, slop; + +  /* Check for unsatisfiable request (do now to ensure no overflow below) */ +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) +    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */ + +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); +  if (odd_bytes > 0) +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + +  /* See if space is available in any existing pool */ +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */ +  prev_hdr_ptr = NULL; +  hdr_ptr = mem->small_list[pool_id]; +  while (hdr_ptr != NULL) { +    if (hdr_ptr->hdr.bytes_left >= sizeofobject) +      break;			/* found pool with enough space */ +    prev_hdr_ptr = hdr_ptr; +    hdr_ptr = hdr_ptr->hdr.next; +  } + +  /* Time to make a new pool? */ +  if (hdr_ptr == NULL) { +    /* min_request is what we need now, slop is what will be leftover */ +    min_request = sizeofobject + SIZEOF(small_pool_hdr); +    if (prev_hdr_ptr == NULL)	/* first pool in class? */ +      slop = first_pool_slop[pool_id]; +    else +      slop = extra_pool_slop[pool_id]; +    /* Don't ask for more than MAX_ALLOC_CHUNK */ +    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) +      slop = (size_t) (MAX_ALLOC_CHUNK-min_request); +    /* Try to get space, if fail reduce slop and try again */ +    for (;;) { +      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); +      if (hdr_ptr != NULL) +	break; +      slop /= 2; +      if (slop < MIN_SLOP)	/* give up when it gets real small */ +	out_of_memory(cinfo, 2); /* jpeg_get_small failed */ +    } +    mem->total_space_allocated += min_request + slop; +    /* Success, initialize the new pool header and add to end of list */ +    hdr_ptr->hdr.next = NULL; +    hdr_ptr->hdr.bytes_used = 0; +    hdr_ptr->hdr.bytes_left = sizeofobject + slop; +    if (prev_hdr_ptr == NULL)	/* first pool in class? */ +      mem->small_list[pool_id] = hdr_ptr; +    else +      prev_hdr_ptr->hdr.next = hdr_ptr; +  } + +  /* OK, allocate the object from the current pool */ +  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ +  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ +  hdr_ptr->hdr.bytes_used += sizeofobject; +  hdr_ptr->hdr.bytes_left -= sizeofobject; + +  return (void *) data_ptr; +} + + +/* + * Allocation of "large" objects. + * + * The external semantics of these are the same as "small" objects, + * except that FAR pointers are used on 80x86.  However the pool + * management heuristics are quite different.  We assume that each + * request is large enough that it may as well be passed directly to + * jpeg_get_large; the pool management just links everything together + * so that we can free it all on demand. + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + * structures.  The routines that create these structures (see below) + * deliberately bunch rows together to ensure a large request size. + */ + +METHODDEF void FAR * +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "large" object */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  large_pool_ptr hdr_ptr; +  size_t odd_bytes; + +  /* Check for unsatisfiable request (do now to ensure no overflow below) */ +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) +    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */ + +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); +  if (odd_bytes > 0) +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + +  /* Always make a new pool */ +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */ + +  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + +					    SIZEOF(large_pool_hdr)); +  if (hdr_ptr == NULL) +    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */ +  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); + +  /* Success, initialize the new pool header and add to list */ +  hdr_ptr->hdr.next = mem->large_list[pool_id]; +  /* We maintain space counts in each pool header for statistical purposes, +   * even though they are not needed for allocation. +   */ +  hdr_ptr->hdr.bytes_used = sizeofobject; +  hdr_ptr->hdr.bytes_left = 0; +  mem->large_list[pool_id] = hdr_ptr; + +  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ +} + + +/* + * Creation of 2-D sample arrays. + * The pointers are in near heap, the samples themselves in FAR heap. + * + * To minimize allocation overhead and to allow I/O of large contiguous + * blocks, we allocate the sample rows in groups of as many rows as possible + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + * NB: the virtual array control routines, later in this file, know about + * this chunking of rows.  The rowsperchunk value is left in the mem manager + * object so that it can be saved away if this sarray is the workspace for + * a virtual array. + */ + +METHODDEF JSAMPARRAY +alloc_sarray (j_common_ptr cinfo, int pool_id, +	      JDIMENSION samplesperrow, JDIMENSION numrows) +/* Allocate a 2-D sample array */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  JSAMPARRAY result; +  JSAMPROW workspace; +  JDIMENSION rowsperchunk, currow, i; +  long ltemp; + +  /* Calculate max # of rows allowed in one allocation chunk */ +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / +	  ((long) samplesperrow * SIZEOF(JSAMPLE)); +  if (ltemp <= 0) +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); +  if (ltemp < (long) numrows) +    rowsperchunk = (JDIMENSION) ltemp; +  else +    rowsperchunk = numrows; +  mem->last_rowsperchunk = rowsperchunk; + +  /* Get space for row pointers (small object) */ +  result = (JSAMPARRAY) alloc_small(cinfo, pool_id, +				    (size_t) (numrows * SIZEOF(JSAMPROW))); + +  /* Get the rows themselves (large objects) */ +  currow = 0; +  while (currow < numrows) { +    rowsperchunk = MIN(rowsperchunk, numrows - currow); +    workspace = (JSAMPROW) alloc_large(cinfo, pool_id, +	(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow +		  * SIZEOF(JSAMPLE))); +    for (i = rowsperchunk; i > 0; i--) { +      result[currow++] = workspace; +      workspace += samplesperrow; +    } +  } + +  return result; +} + + +/* + * Creation of 2-D coefficient-block arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF JBLOCKARRAY +alloc_barray (j_common_ptr cinfo, int pool_id, +	      JDIMENSION blocksperrow, JDIMENSION numrows) +/* Allocate a 2-D coefficient-block array */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  JBLOCKARRAY result; +  JBLOCKROW workspace; +  JDIMENSION rowsperchunk, currow, i; +  long ltemp; + +  /* Calculate max # of rows allowed in one allocation chunk */ +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / +	  ((long) blocksperrow * SIZEOF(JBLOCK)); +  if (ltemp <= 0) +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); +  if (ltemp < (long) numrows) +    rowsperchunk = (JDIMENSION) ltemp; +  else +    rowsperchunk = numrows; +  mem->last_rowsperchunk = rowsperchunk; + +  /* Get space for row pointers (small object) */ +  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, +				     (size_t) (numrows * SIZEOF(JBLOCKROW))); + +  /* Get the rows themselves (large objects) */ +  currow = 0; +  while (currow < numrows) { +    rowsperchunk = MIN(rowsperchunk, numrows - currow); +    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, +	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow +		  * SIZEOF(JBLOCK))); +    for (i = rowsperchunk; i > 0; i--) { +      result[currow++] = workspace; +      workspace += blocksperrow; +    } +  } + +  return result; +} + + +/* + * About virtual array management: + * + * The above "normal" array routines are only used to allocate strip buffers + * (as wide as the image, but just a few rows high).  Full-image-sized buffers + * are handled as "virtual" arrays.  The array is still accessed a strip at a + * time, but the memory manager must save the whole array for repeated + * accesses.  The intended implementation is that there is a strip buffer in + * memory (as high as is possible given the desired memory limit), plus a + * backing file that holds the rest of the array. + * + * The request_virt_array routines are told the total size of the image and + * the maximum number of rows that will be accessed at once.  The in-memory + * buffer must be at least as large as the maxaccess value. + * + * The request routines create control blocks but not the in-memory buffers. + * That is postponed until realize_virt_arrays is called.  At that time the + * total amount of space needed is known (approximately, anyway), so free + * memory can be divided up fairly. + * + * The access_virt_array routines are responsible for making a specific strip + * area accessible (after reading or writing the backing file, if necessary). + * Note that the access routines are told whether the caller intends to modify + * the accessed strip; during a read-only pass this saves having to rewrite + * data to disk.  The access routines are also responsible for pre-zeroing + * any newly accessed rows, if pre-zeroing was requested. + * + * In current usage, the access requests are usually for nonoverlapping + * strips; that is, successive access start_row numbers differ by exactly + * num_rows = maxaccess.  This means we can get good performance with simple + * buffer dump/reload logic, by making the in-memory buffer be a multiple + * of the access height; then there will never be accesses across bufferload + * boundaries.  The code will still work with overlapping access requests, + * but it doesn't handle bufferload overlaps very efficiently. + */ + + +METHODDEF jvirt_sarray_ptr +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, +		     JDIMENSION samplesperrow, JDIMENSION numrows, +		     JDIMENSION maxaccess) +/* Request a virtual 2-D sample array */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  jvirt_sarray_ptr result; + +  /* Only IMAGE-lifetime virtual arrays are currently supported */ +  if (pool_id != JPOOL_IMAGE) +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */ + +  /* get control block */ +  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, +					  SIZEOF(struct jvirt_sarray_control)); + +  result->mem_buffer = NULL;	/* marks array not yet realized */ +  result->rows_in_array = numrows; +  result->samplesperrow = samplesperrow; +  result->maxaccess = maxaccess; +  result->pre_zero = pre_zero; +  result->b_s_open = FALSE;	/* no associated backing-store object */ +  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ +  mem->virt_sarray_list = result; + +  return result; +} + + +METHODDEF jvirt_barray_ptr +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, +		     JDIMENSION blocksperrow, JDIMENSION numrows, +		     JDIMENSION maxaccess) +/* Request a virtual 2-D coefficient-block array */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  jvirt_barray_ptr result; + +  /* Only IMAGE-lifetime virtual arrays are currently supported */ +  if (pool_id != JPOOL_IMAGE) +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */ + +  /* get control block */ +  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, +					  SIZEOF(struct jvirt_barray_control)); + +  result->mem_buffer = NULL;	/* marks array not yet realized */ +  result->rows_in_array = numrows; +  result->blocksperrow = blocksperrow; +  result->maxaccess = maxaccess; +  result->pre_zero = pre_zero; +  result->b_s_open = FALSE;	/* no associated backing-store object */ +  result->next = mem->virt_barray_list; /* add to list of virtual arrays */ +  mem->virt_barray_list = result; + +  return result; +} + + +METHODDEF void +realize_virt_arrays (j_common_ptr cinfo) +/* Allocate the in-memory buffers for any unrealized virtual arrays */ +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  long space_per_minheight, maximum_space, avail_mem; +  long minheights, max_minheights; +  jvirt_sarray_ptr sptr; +  jvirt_barray_ptr bptr; + +  /* Compute the minimum space needed (maxaccess rows in each buffer) +   * and the maximum space needed (full image height in each buffer). +   * These may be of use to the system-dependent jpeg_mem_available routine. +   */ +  space_per_minheight = 0; +  maximum_space = 0; +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { +    if (sptr->mem_buffer == NULL) { /* if not realized yet */ +      space_per_minheight += (long) sptr->maxaccess * +			     (long) sptr->samplesperrow * SIZEOF(JSAMPLE); +      maximum_space += (long) sptr->rows_in_array * +		       (long) sptr->samplesperrow * SIZEOF(JSAMPLE); +    } +  } +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { +    if (bptr->mem_buffer == NULL) { /* if not realized yet */ +      space_per_minheight += (long) bptr->maxaccess * +			     (long) bptr->blocksperrow * SIZEOF(JBLOCK); +      maximum_space += (long) bptr->rows_in_array * +		       (long) bptr->blocksperrow * SIZEOF(JBLOCK); +    } +  } + +  if (space_per_minheight <= 0) +    return;			/* no unrealized arrays, no work */ + +  /* Determine amount of memory to actually use; this is system-dependent. */ +  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, +				 mem->total_space_allocated); + +  /* If the maximum space needed is available, make all the buffers full +   * height; otherwise parcel it out with the same number of minheights +   * in each buffer. +   */ +  if (avail_mem >= maximum_space) +    max_minheights = 1000000000L; +  else { +    max_minheights = avail_mem / space_per_minheight; +    /* If there doesn't seem to be enough space, try to get the minimum +     * anyway.  This allows a "stub" implementation of jpeg_mem_available(). +     */ +    if (max_minheights <= 0) +      max_minheights = 1; +  } + +  /* Allocate the in-memory buffers and initialize backing store as needed. */ + +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { +    if (sptr->mem_buffer == NULL) { /* if not realized yet */ +      minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; +      if (minheights <= max_minheights) { +	/* This buffer fits in memory */ +	sptr->rows_in_mem = sptr->rows_in_array; +      } else { +	/* It doesn't fit in memory, create backing store. */ +	sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); +	jpeg_open_backing_store(cinfo, & sptr->b_s_info, +				(long) sptr->rows_in_array * +				(long) sptr->samplesperrow * +				(long) SIZEOF(JSAMPLE)); +	sptr->b_s_open = TRUE; +      } +      sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, +				      sptr->samplesperrow, sptr->rows_in_mem); +      sptr->rowsperchunk = mem->last_rowsperchunk; +      sptr->cur_start_row = 0; +      sptr->first_undef_row = 0; +      sptr->dirty = FALSE; +    } +  } + +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { +    if (bptr->mem_buffer == NULL) { /* if not realized yet */ +      minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; +      if (minheights <= max_minheights) { +	/* This buffer fits in memory */ +	bptr->rows_in_mem = bptr->rows_in_array; +      } else { +	/* It doesn't fit in memory, create backing store. */ +	bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); +	jpeg_open_backing_store(cinfo, & bptr->b_s_info, +				(long) bptr->rows_in_array * +				(long) bptr->blocksperrow * +				(long) SIZEOF(JBLOCK)); +	bptr->b_s_open = TRUE; +      } +      bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, +				      bptr->blocksperrow, bptr->rows_in_mem); +      bptr->rowsperchunk = mem->last_rowsperchunk; +      bptr->cur_start_row = 0; +      bptr->first_undef_row = 0; +      bptr->dirty = FALSE; +    } +  } +} + + +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 */ +{ +  long bytesperrow, file_offset, byte_count, rows, thisrow, i; + +  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); +  file_offset = ptr->cur_start_row * bytesperrow; +  /* Loop to read or write each allocation chunk in mem_buffer */ +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { +    /* One chunk, but check for short chunk at end of buffer */ +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); +    /* Transfer no more than is currently defined */ +    thisrow = (long) ptr->cur_start_row + i; +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow); +    /* Transfer no more than fits in file */ +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow); +    if (rows <= 0)		/* this chunk might be past end of file! */ +      break; +    byte_count = rows * bytesperrow; +    if (writing) +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, +					    (void FAR *) ptr->mem_buffer[i], +					    file_offset, byte_count); +    else +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, +					   (void FAR *) ptr->mem_buffer[i], +					   file_offset, byte_count); +    file_offset += byte_count; +  } +} + + +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 */ +{ +  long bytesperrow, file_offset, byte_count, rows, thisrow, i; + +  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); +  file_offset = ptr->cur_start_row * bytesperrow; +  /* Loop to read or write each allocation chunk in mem_buffer */ +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { +    /* One chunk, but check for short chunk at end of buffer */ +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); +    /* Transfer no more than is currently defined */ +    thisrow = (long) ptr->cur_start_row + i; +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow); +    /* Transfer no more than fits in file */ +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow); +    if (rows <= 0)		/* this chunk might be past end of file! */ +      break; +    byte_count = rows * bytesperrow; +    if (writing) +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, +					    (void FAR *) ptr->mem_buffer[i], +					    file_offset, byte_count); +    else +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, +					   (void FAR *) ptr->mem_buffer[i], +					   file_offset, byte_count); +    file_offset += byte_count; +  } +} + + +METHODDEF JSAMPARRAY +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, +		    JDIMENSION start_row, JDIMENSION num_rows, +		    boolean writable) +/* Access the part of a virtual sample array starting at start_row */ +/* and extending for num_rows rows.  writable is true if  */ +/* caller intends to modify the accessed area. */ +{ +  JDIMENSION end_row = start_row + num_rows; +  JDIMENSION undef_row; + +  /* debugging check */ +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || +      ptr->mem_buffer == NULL) +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + +  /* Make the desired part of the virtual array accessible */ +  if (start_row < ptr->cur_start_row || +      end_row > ptr->cur_start_row+ptr->rows_in_mem) { +    if (! ptr->b_s_open) +      ERREXIT(cinfo, JERR_VIRTUAL_BUG); +    /* Flush old buffer contents if necessary */ +    if (ptr->dirty) { +      do_sarray_io(cinfo, ptr, TRUE); +      ptr->dirty = FALSE; +    } +    /* Decide what part of virtual array to access. +     * Algorithm: if target address > current window, assume forward scan, +     * load starting at target address.  If target address < current window, +     * assume backward scan, load so that target area is top of window. +     * Note that when switching from forward write to forward read, will have +     * start_row = 0, so the limiting case applies and we load from 0 anyway. +     */ +    if (start_row > ptr->cur_start_row) { +      ptr->cur_start_row = start_row; +    } else { +      /* use long arithmetic here to avoid overflow & unsigned problems */ +      long ltemp; + +      ltemp = (long) end_row - (long) ptr->rows_in_mem; +      if (ltemp < 0) +	ltemp = 0;		/* don't fall off front end of file */ +      ptr->cur_start_row = (JDIMENSION) ltemp; +    } +    /* Read in the selected part of the array. +     * During the initial write pass, we will do no actual read +     * because the selected part is all undefined. +     */ +    do_sarray_io(cinfo, ptr, FALSE); +  } +  /* Ensure the accessed part of the array is defined; prezero if needed. +   * To improve locality of access, we only prezero the part of the array +   * that the caller is about to access, not the entire in-memory array. +   */ +  if (ptr->first_undef_row < end_row) { +    if (ptr->first_undef_row < start_row) { +      if (writable)		/* writer skipped over a section of array */ +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); +      undef_row = start_row;	/* but reader is allowed to read ahead */ +    } else { +      undef_row = ptr->first_undef_row; +    } +    if (writable) +      ptr->first_undef_row = end_row; +    if (ptr->pre_zero) { +      size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ +      end_row -= ptr->cur_start_row; +      while (undef_row < end_row) { +	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); +	undef_row++; +      } +    } else { +      if (! writable)		/* reader looking at undefined data */ +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); +    } +  } +  /* Flag the buffer dirty if caller will write in it */ +  if (writable) +    ptr->dirty = TRUE; +  /* Return address of proper part of the buffer */ +  return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +METHODDEF JBLOCKARRAY +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, +		    JDIMENSION start_row, JDIMENSION num_rows, +		    boolean writable) +/* Access the part of a virtual block array starting at start_row */ +/* and extending for num_rows rows.  writable is true if  */ +/* caller intends to modify the accessed area. */ +{ +  JDIMENSION end_row = start_row + num_rows; +  JDIMENSION undef_row; + +  /* debugging check */ +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || +      ptr->mem_buffer == NULL) +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + +  /* Make the desired part of the virtual array accessible */ +  if (start_row < ptr->cur_start_row || +      end_row > ptr->cur_start_row+ptr->rows_in_mem) { +    if (! ptr->b_s_open) +      ERREXIT(cinfo, JERR_VIRTUAL_BUG); +    /* Flush old buffer contents if necessary */ +    if (ptr->dirty) { +      do_barray_io(cinfo, ptr, TRUE); +      ptr->dirty = FALSE; +    } +    /* Decide what part of virtual array to access. +     * Algorithm: if target address > current window, assume forward scan, +     * load starting at target address.  If target address < current window, +     * assume backward scan, load so that target area is top of window. +     * Note that when switching from forward write to forward read, will have +     * start_row = 0, so the limiting case applies and we load from 0 anyway. +     */ +    if (start_row > ptr->cur_start_row) { +      ptr->cur_start_row = start_row; +    } else { +      /* use long arithmetic here to avoid overflow & unsigned problems */ +      long ltemp; + +      ltemp = (long) end_row - (long) ptr->rows_in_mem; +      if (ltemp < 0) +	ltemp = 0;		/* don't fall off front end of file */ +      ptr->cur_start_row = (JDIMENSION) ltemp; +    } +    /* Read in the selected part of the array. +     * During the initial write pass, we will do no actual read +     * because the selected part is all undefined. +     */ +    do_barray_io(cinfo, ptr, FALSE); +  } +  /* Ensure the accessed part of the array is defined; prezero if needed. +   * To improve locality of access, we only prezero the part of the array +   * that the caller is about to access, not the entire in-memory array. +   */ +  if (ptr->first_undef_row < end_row) { +    if (ptr->first_undef_row < start_row) { +      if (writable)		/* writer skipped over a section of array */ +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); +      undef_row = start_row;	/* but reader is allowed to read ahead */ +    } else { +      undef_row = ptr->first_undef_row; +    } +    if (writable) +      ptr->first_undef_row = end_row; +    if (ptr->pre_zero) { +      size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ +      end_row -= ptr->cur_start_row; +      while (undef_row < end_row) { +	jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); +	undef_row++; +      } +    } else { +      if (! writable)		/* reader looking at undefined data */ +	ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); +    } +  } +  /* Flag the buffer dirty if caller will write in it */ +  if (writable) +    ptr->dirty = TRUE; +  /* Return address of proper part of the buffer */ +  return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +/* + * Release all objects belonging to a specified pool. + */ + +METHODDEF void +free_pool (j_common_ptr cinfo, int pool_id) +{ +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem; +  small_pool_ptr shdr_ptr; +  large_pool_ptr lhdr_ptr; +  size_t space_freed; + +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */ + +#ifdef MEM_STATS +  if (cinfo->err->trace_level > 1) +    print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ +#endif + +  /* If freeing IMAGE pool, close any virtual arrays first */ +  if (pool_id == JPOOL_IMAGE) { +    jvirt_sarray_ptr sptr; +    jvirt_barray_ptr bptr; + +    for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { +      if (sptr->b_s_open) {	/* there may be no backing store */ +	sptr->b_s_open = FALSE;	/* prevent recursive close if error */ +	(*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); +      } +    } +    mem->virt_sarray_list = NULL; +    for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { +      if (bptr->b_s_open) {	/* there may be no backing store */ +	bptr->b_s_open = FALSE;	/* prevent recursive close if error */ +	(*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); +      } +    } +    mem->virt_barray_list = NULL; +  } + +  /* Release large objects */ +  lhdr_ptr = mem->large_list[pool_id]; +  mem->large_list[pool_id] = NULL; + +  while (lhdr_ptr != NULL) { +    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; +    space_freed = lhdr_ptr->hdr.bytes_used + +		  lhdr_ptr->hdr.bytes_left + +		  SIZEOF(large_pool_hdr); +    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); +    mem->total_space_allocated -= space_freed; +    lhdr_ptr = next_lhdr_ptr; +  } + +  /* Release small objects */ +  shdr_ptr = mem->small_list[pool_id]; +  mem->small_list[pool_id] = NULL; + +  while (shdr_ptr != NULL) { +    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; +    space_freed = shdr_ptr->hdr.bytes_used + +		  shdr_ptr->hdr.bytes_left + +		  SIZEOF(small_pool_hdr); +    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); +    mem->total_space_allocated -= space_freed; +    shdr_ptr = next_shdr_ptr; +  } +} + + +/* + * Close up shop entirely. + * Note that this cannot be called unless cinfo->mem is non-NULL. + */ + +METHODDEF void +self_destruct (j_common_ptr cinfo) +{ +  int pool; + +  /* Close all backing store, release all memory. +   * Releasing pools in reverse order might help avoid fragmentation +   * with some (brain-damaged) malloc libraries. +   */ +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { +    free_pool(cinfo, pool); +  } + +  /* Release the memory manager control block too. */ +  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); +  cinfo->mem = NULL;		/* ensures I will be called only once */ + +  jpeg_mem_term(cinfo);		/* system-dependent cleanup */ +} + + +/* + * Memory manager initialization. + * When this is called, only the error manager pointer is valid in cinfo! + */ + +GLOBAL void +jinit_memory_mgr (j_common_ptr cinfo) +{ +  my_mem_ptr mem; +  long max_to_use; +  int pool; +  size_t test_mac; + +  cinfo->mem = NULL;		/* for safety if init fails */ + +  /* Check for configuration errors. +   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably +   * doesn't reflect any real hardware alignment requirement. +   * The test is a little tricky: for X>0, X and X-1 have no one-bits +   * in common if and only if X is a power of 2, ie has only one one-bit. +   * Some compilers may give an "unreachable code" warning here; ignore it. +   */ +  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) +    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); +  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be +   * a multiple of SIZEOF(ALIGN_TYPE). +   * Again, an "unreachable code" warning may be ignored here. +   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. +   */ +  test_mac = (size_t) MAX_ALLOC_CHUNK; +  if ((long) test_mac != MAX_ALLOC_CHUNK || +      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) +    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + +  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ + +  /* Attempt to allocate memory manager's control block */ +  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); + +  if (mem == NULL) { +    jpeg_mem_term(cinfo);	/* system-dependent cleanup */ +    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); +  } + +  /* OK, fill in the method pointers */ +  mem->pub.alloc_small = alloc_small; +  mem->pub.alloc_large = alloc_large; +  mem->pub.alloc_sarray = alloc_sarray; +  mem->pub.alloc_barray = alloc_barray; +  mem->pub.request_virt_sarray = request_virt_sarray; +  mem->pub.request_virt_barray = request_virt_barray; +  mem->pub.realize_virt_arrays = realize_virt_arrays; +  mem->pub.access_virt_sarray = access_virt_sarray; +  mem->pub.access_virt_barray = access_virt_barray; +  mem->pub.free_pool = free_pool; +  mem->pub.self_destruct = self_destruct; + +  /* Initialize working state */ +  mem->pub.max_memory_to_use = max_to_use; + +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { +    mem->small_list[pool] = NULL; +    mem->large_list[pool] = NULL; +  } +  mem->virt_sarray_list = NULL; +  mem->virt_barray_list = NULL; + +  mem->total_space_allocated = SIZEOF(my_memory_mgr); + +  /* Declare ourselves open for business */ +  cinfo->mem = & mem->pub; + +  /* Check for an environment variable JPEGMEM; if found, override the +   * default max_memory setting from jpeg_mem_init.  Note that the +   * surrounding application may again override this value. +   * If your system doesn't support getenv(), define NO_GETENV to disable +   * this feature. +   */ +#ifndef NO_GETENV +  { char * memenv; + +    if ((memenv = getenv("JPEGMEM")) != NULL) { +      char ch = 'x'; + +      if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { +	if (ch == 'm' || ch == 'M') +	  max_to_use *= 1000L; +	mem->pub.max_memory_to_use = max_to_use * 1000L; +      } +    } +  } +#endif + +} diff --git a/libs/jpeg6/jmemnobs.cpp b/libs/jpeg6/jmemnobs.cpp index e63e5e4..9bafed5 100755 --- a/libs/jpeg6/jmemnobs.cpp +++ b/libs/jpeg6/jmemnobs.cpp @@ -1,103 +1,103 @@ -/*
 - * jmemnobs.c
 - *
 - * Copyright (C) 1992-1994, 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 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 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.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -#include "jmemsys.h"		/* import the system-dependent declarations */
 -
 -/*
 - * Memory allocation and ri.Freeing are controlled by the regular library
 - * routines ri.Malloc() and ri.Free().
 - */
 -
 -GLOBAL void *
 -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
 -{
 -  return (void *) malloc(sizeofobject);
 -}
 -
 -GLOBAL void
 -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
 -{
 -  free(object);
 -}
 -
 -
 -/*
 - * "Large" objects are treated the same as "small" ones.
 - * NB: although we include FAR keywords in the routine declarations,
 - * this file won't actually work in 80x86 small/medium model; at least,
 - * you probably won't be able to process useful-size images in only 64KB.
 - */
 -
 -GLOBAL void FAR *
 -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
 -{
 -  return (void FAR *) malloc(sizeofobject);
 -}
 -
 -GLOBAL void
 -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
 -{
 -  free(object);
 -}
 -
 -
 -/*
 - * This routine computes the total memory space available for allocation.
 - * Here we always say, "we got all you want bud!"
 - */
 -
 -GLOBAL long
 -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
 -		    long max_bytes_needed, long already_allocated)
 -{
 -  return max_bytes_needed;
 -}
 -
 -
 -/*
 - * Backing store (temporary file) management.
 - * Since jpeg_mem_available always promised the moon,
 - * this should never be called and we can just error out.
 - */
 -
 -GLOBAL void
 -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
 -			 long total_bytes_needed)
 -{
 -  ERREXIT(cinfo, JERR_NO_BACKING_STORE);
 -}
 -
 -
 -/*
 - * These routines take care of any system-dependent initialization and
 - * cleanup required.  Here, there isn't any.
 - */
 -
 -GLOBAL long
 -jpeg_mem_init (j_common_ptr cinfo)
 -{
 -  return 0;			/* just set max_memory_to_use to 0 */
 -}
 -
 -GLOBAL void
 -jpeg_mem_term (j_common_ptr cinfo)
 -{
 -  /* no work */
 -}
 +/* + * jmemnobs.c + * + * Copyright (C) 1992-1994, 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 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 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. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h"		/* import the system-dependent declarations */ + +/* + * Memory allocation and ri.Freeing are controlled by the regular library + * routines ri.Malloc() and ri.Free(). + */ + +GLOBAL void * +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ +  return (void *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ +  free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL void FAR * +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ +  return (void FAR *) malloc(sizeofobject); +} + +GLOBAL void +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ +  free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL long +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, +		    long max_bytes_needed, long already_allocated) +{ +  return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL void +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, +			 long total_bytes_needed) +{ +  ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required.  Here, there isn't any. + */ + +GLOBAL long +jpeg_mem_init (j_common_ptr cinfo) +{ +  return 0;			/* just set max_memory_to_use to 0 */ +} + +GLOBAL void +jpeg_mem_term (j_common_ptr cinfo) +{ +  /* no work */ +} diff --git a/libs/jpeg6/jmemsys.h b/libs/jpeg6/jmemsys.h index 0c7d7c1..033d29a 100755 --- a/libs/jpeg6/jmemsys.h +++ b/libs/jpeg6/jmemsys.h @@ -1,182 +1,182 @@ -/*
 - * jmemsys.h
 - *
 - * Copyright (C) 1992-1994, 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 include file defines the interface between the system-independent
 - * and system-dependent portions of the JPEG memory manager.  No other
 - * modules need include it.  (The system-independent portion is jmemmgr.c;
 - * there are several different versions of the system-dependent portion.)
 - *
 - * This file works as-is for the system-dependent memory managers supplied
 - * 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.
 - */
 -
 -
 -/* Short forms of external names for systems with brain-damaged linkers. */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_get_small		jGetSmall
 -#define jpeg_free_small		jFreeSmall
 -#define jpeg_get_large		jGetLarge
 -#define jpeg_free_large		jFreeLarge
 -#define jpeg_mem_available	jMemAvail
 -#define jpeg_open_backing_store	jOpenBackStore
 -#define jpeg_mem_init		jMemInit
 -#define jpeg_mem_term		jMemTerm
 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
 -
 -
 -/*
 - * These two functions are used to allocate and release small chunks of
 - * memory.  (Typically the total amount requested through jpeg_get_small is
 - * no more than 20K or so; this will be requested in chunks of a few K each.)
 - * Behavior should be the same as for the standard library functions malloc
 - * and free; in particular, jpeg_get_small must return NULL on failure.
 - * On most systems, these ARE malloc and free.  jpeg_free_small is passed the
 - * size of the object being freed, just in case it's needed.
 - * 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));
 -
 -/*
 - * These two functions are used to allocate and release large chunks of
 - * memory (up to the total free space designated by jpeg_mem_available).
 - * The interface is the same as above, except that on an 80x86 machine,
 - * far pointers are used.  On most other machines these are identical to
 - * the jpeg_get/free_small routines; but we keep them separate anyway,
 - * 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));
 -
 -/*
 - * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
 - * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
 - * matter, but that case should never come into play).  This macro is needed
 - * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
 - * On those machines, we expect that jconfig.h will provide a proper value.
 - * On machines with 32-bit flat address spaces, any large constant may be used.
 - *
 - * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
 - * size_t and will be a multiple of sizeof(align_type).
 - */
 -
 -#ifndef MAX_ALLOC_CHUNK		/* may be overridden in jconfig.h */
 -#define MAX_ALLOC_CHUNK  1000000000L
 -#endif
 -
 -/*
 - * This routine computes the total space still available for allocation by
 - * jpeg_get_large.  If more space than this is needed, backing store will be
 - * used.  NOTE: any memory already allocated must not be counted.
 - *
 - * There is a minimum space requirement, corresponding to the minimum
 - * feasible buffer sizes; jmemmgr.c will request that much space even if
 - * jpeg_mem_available returns zero.  The maximum space needed, enough to hold
 - * all working storage in memory, is also passed in case it is useful.
 - * Finally, the total space already allocated is passed.  If no better
 - * method is available, cinfo->mem->max_memory_to_use - already_allocated
 - * is often a suitable calculation.
 - *
 - * It is OK for jpeg_mem_available to underestimate the space available
 - * (that'll just lead to more backing-store access than is really necessary).
 - * However, an overestimate will lead to failure.  Hence it's wise to subtract
 - * a slop factor from the true available space.  5% should be enough.
 - *
 - * On machines with lots of virtual memory, any large constant may be returned.
 - * 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));
 -
 -
 -/*
 - * This structure holds whatever state is needed to access a single
 - * backing-store object.  The read/write/close method pointers are called
 - * by jmemmgr.c to manipulate the backing-store object; all other fields
 - * are private to the system-dependent backing store routines.
 - */
 -
 -#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 */
 -typedef unsigned short EMSH;	/* type of expanded-memory handles */
 -
 -typedef union {
 -  short file_handle;		/* DOS file handle if it's a temp file */
 -  XMSH xms_handle;		/* handle if it's a chunk of XMS */
 -  EMSH ems_handle;		/* handle if it's a chunk of EMS */
 -} handle_union;
 -
 -#endif /* USE_MSDOS_MEMMGR */
 -
 -typedef struct backing_store_struct * backing_store_ptr;
 -
 -typedef struct backing_store_struct {
 -  /* Methods for reading/writing/closing this backing-store object */
 -  JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
 -				     backing_store_ptr info,
 -				     void FAR * buffer_address,
 -				     long file_offset, long byte_count));
 -  JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
 -				      backing_store_ptr info,
 -				      void FAR * buffer_address,
 -				      long file_offset, long byte_count));
 -  JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
 -				      backing_store_ptr info));
 -
 -  /* Private fields for system-dependent backing-store management */
 -#ifdef USE_MSDOS_MEMMGR
 -  /* For the MS-DOS manager (jmemdos.c), we need: */
 -  handle_union handle;		/* reference to backing-store storage object */
 -  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
 -} 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
 - * may take an error exit if the specified maximum file size is exceeded.
 - * (If jpeg_mem_available always returns a large value, this routine can
 - * just take an error exit.)
 - */
 -
 -EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo,
 -					 backing_store_ptr info,
 -					 long total_bytes_needed));
 -
 -
 -/*
 - * These routines take care of any system-dependent initialization and
 - * cleanup required.  jpeg_mem_init will be called before anything is
 - * allocated (and, therefore, nothing in cinfo is of use except the error
 - * manager pointer).  It should return a suitable default value for
 - * max_memory_to_use; this may subsequently be overridden by the surrounding
 - * application.  (Note that max_memory_to_use is only important if
 - * jpeg_mem_available chooses to consult it ... no one else will.)
 - * jpeg_mem_term may assume that all requested memory has been freed and that
 - * 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));
 +/* + * jmemsys.h + * + * Copyright (C) 1992-1994, 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 include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager.  No other + * modules need include it.  (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * 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. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small		jGetSmall +#define jpeg_free_small		jFreeSmall +#define jpeg_get_large		jGetLarge +#define jpeg_free_large		jFreeLarge +#define jpeg_mem_available	jMemAvail +#define jpeg_open_backing_store	jOpenBackStore +#define jpeg_mem_init		jMemInit +#define jpeg_mem_term		jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory.  (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free.  jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * 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)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used.  On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * 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)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play).  This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK		/* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK  1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large.  If more space than this is needed, backing store will be + * used.  NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero.  The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed.  If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure.  Hence it's wise to subtract + * a slop factor from the true available space.  5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * 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)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object.  The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#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 */ +typedef unsigned short EMSH;	/* type of expanded-memory handles */ + +typedef union { +  short file_handle;		/* DOS file handle if it's a temp file */ +  XMSH xms_handle;		/* handle if it's a chunk of XMS */ +  EMSH ems_handle;		/* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { +  /* Methods for reading/writing/closing this backing-store object */ +  JMETHOD(void, read_backing_store, (j_common_ptr cinfo, +				     backing_store_ptr info, +				     void FAR * buffer_address, +				     long file_offset, long byte_count)); +  JMETHOD(void, write_backing_store, (j_common_ptr cinfo, +				      backing_store_ptr info, +				      void FAR * buffer_address, +				      long file_offset, long byte_count)); +  JMETHOD(void, close_backing_store, (j_common_ptr cinfo, +				      backing_store_ptr info)); + +  /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR +  /* For the MS-DOS manager (jmemdos.c), we need: */ +  handle_union handle;		/* reference to backing-store storage object */ +  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 +} 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 + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, +					 backing_store_ptr info, +					 long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required.  jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer).  It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application.  (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * 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)); diff --git a/libs/jpeg6/jmorecfg.h b/libs/jpeg6/jmorecfg.h index d451399..7e83fec 100755 --- a/libs/jpeg6/jmorecfg.h +++ b/libs/jpeg6/jmorecfg.h @@ -1,346 +1,346 @@ -/*
 - * jmorecfg.h
 - *
 - * Copyright (C) 1991-1995, 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 additional configuration options that customize the
 - * JPEG software for special applications or support machine-dependent
 - * optimizations.  Most users will not need to touch this file.
 - */
 -
 -
 -/*
 - * Define BITS_IN_JSAMPLE as either
 - *   8   for 8-bit sample values (the usual setting)
 - *   12  for 12-bit sample values
 - * Only 8 and 12 are legal data precisions for lossy JPEG according to the
 - * JPEG standard, and the IJG code does not support anything else!
 - * We do not support run-time selection of data precision, sorry.
 - */
 -
 -#define BITS_IN_JSAMPLE  8	/* use 8 or 12 */
 -
 -
 -/*
 - * Maximum number of components (color channels) allowed in JPEG image.
 - * To meet the letter of the JPEG spec, set this to 255.  However, darn
 - * few applications need more than 4 channels (maybe 5 for CMYK + alpha
 - * mask).  We recommend 10 as a reasonable compromise; use 4 if you are
 - * really short on memory.  (Each allowed component costs a hundred or so
 - * bytes of storage, whether actually used in an image or not.)
 - */
 -
 -#define MAX_COMPONENTS  10	/* maximum number of image components */
 -
 -
 -/*
 - * Basic data types.
 - * You may need to change these if you have a machine with unusual data
 - * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
 - * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits,
 - * but it had better be at least 16.
 - */
 -
 -/* Representation of a single sample (pixel element value).
 - * We frequently allocate large arrays of these, so it's important to keep
 - * them small.  But if you have memory to burn and access to char or short
 - * arrays is very slow on your hardware, you might want to change these.
 - */
 -
 -#if BITS_IN_JSAMPLE == 8
 -/* JSAMPLE should be the smallest type that will hold the values 0..255.
 - * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
 - */
 -
 -#ifdef HAVE_UNSIGNED_CHAR
 -
 -typedef unsigned char JSAMPLE;
 -#define GETJSAMPLE(value)  ((int) (value))
 -
 -#else /* not HAVE_UNSIGNED_CHAR */
 -
 -typedef char JSAMPLE;
 -#ifdef CHAR_IS_UNSIGNED
 -#define GETJSAMPLE(value)  ((int) (value))
 -#else
 -#define GETJSAMPLE(value)  ((int) (value) & 0xFF)
 -#endif /* CHAR_IS_UNSIGNED */
 -
 -#endif /* HAVE_UNSIGNED_CHAR */
 -
 -#define MAXJSAMPLE	255
 -#define CENTERJSAMPLE	128
 -
 -#endif /* BITS_IN_JSAMPLE == 8 */
 -
 -
 -#if BITS_IN_JSAMPLE == 12
 -/* JSAMPLE should be the smallest type that will hold the values 0..4095.
 - * On nearly all machines "short" will do nicely.
 - */
 -
 -typedef short JSAMPLE;
 -#define GETJSAMPLE(value)  ((int) (value))
 -
 -#define MAXJSAMPLE	4095
 -#define CENTERJSAMPLE	2048
 -
 -#endif /* BITS_IN_JSAMPLE == 12 */
 -
 -
 -/* Representation of a DCT frequency coefficient.
 - * This should be a signed value of at least 16 bits; "short" is usually OK.
 - * Again, we allocate large arrays of these, but you can change to int
 - * if you have memory to burn and "short" is really slow.
 - */
 -
 -typedef short JCOEF;
 -
 -
 -/* Compressed datastreams are represented as arrays of JOCTET.
 - * These must be EXACTLY 8 bits wide, at least once they are written to
 - * external storage.  Note that when using the stdio data source/destination
 - * managers, this is also the data type passed to fread/fwrite.
 - */
 -
 -#ifdef HAVE_UNSIGNED_CHAR
 -
 -typedef unsigned char JOCTET;
 -#define GETJOCTET(value)  (value)
 -
 -#else /* not HAVE_UNSIGNED_CHAR */
 -
 -typedef char JOCTET;
 -#ifdef CHAR_IS_UNSIGNED
 -#define GETJOCTET(value)  (value)
 -#else
 -#define GETJOCTET(value)  ((value) & 0xFF)
 -#endif /* CHAR_IS_UNSIGNED */
 -
 -#endif /* HAVE_UNSIGNED_CHAR */
 -
 -
 -/* These typedefs are used for various table entries and so forth.
 - * They must be at least as wide as specified; but making them too big
 - * won't cost a huge amount of memory, so we don't provide special
 - * extraction code like we did for JSAMPLE.  (In other words, these
 - * typedefs live at a different point on the speed/space tradeoff curve.)
 - */
 -
 -/* UINT8 must hold at least the values 0..255. */
 -
 -#ifdef HAVE_UNSIGNED_CHAR
 -typedef unsigned char UINT8;
 -#else /* not HAVE_UNSIGNED_CHAR */
 -#ifdef CHAR_IS_UNSIGNED
 -typedef char UINT8;
 -#else /* not CHAR_IS_UNSIGNED */
 -typedef short UINT8;
 -#endif /* CHAR_IS_UNSIGNED */
 -#endif /* HAVE_UNSIGNED_CHAR */
 -
 -/* UINT16 must hold at least the values 0..65535. */
 -
 -#ifdef HAVE_UNSIGNED_SHORT
 -typedef unsigned short UINT16;
 -#else /* not HAVE_UNSIGNED_SHORT */
 -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. */
 -
 -//#ifndef XMD_H			/* X11/xmd.h correctly defines INT32 */
 -//typedef long INT32;
 -//#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
 - * handle larger images and you don't mind deviating from the spec, you
 - * can change this datatype.
 - */
 -
 -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.
 - * 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 */
 -
 -
 -/* Here is the pseudo-keyword for declaring pointers that must be "far"
 - * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
 - * by just saying "FAR *" where such a pointer is needed.  In a few places
 - * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
 - */
 -
 -#ifdef NEED_FAR_POINTERS
 -#undef FAR
 -#define FAR  far
 -#else
 -#undef FAR
 -#define FAR
 -#endif
 -
 -
 -/*
 - * On a few systems, type boolean and/or its values FALSE, TRUE may appear
 - * in standard header files.  Or you may have conflicts with application-
 - * specific header files that you want to include together with these files.
 - * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
 - */
 -
 -//#ifndef HAVE_BOOLEAN
 -//typedef int boolean;
 -//#endif
 -#ifndef FALSE			/* in case these macros already exist */
 -#define FALSE	0		/* values of boolean */
 -#endif
 -#ifndef TRUE
 -#define TRUE	1
 -#endif
 -
 -
 -/*
 - * The remaining options affect code selection within the JPEG library,
 - * but they don't need to be visible to most applications using the library.
 - * To minimize application namespace pollution, the symbols won't be
 - * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
 - */
 -
 -#ifdef JPEG_INTERNALS
 -#define JPEG_INTERNAL_OPTIONS
 -#endif
 -
 -#ifdef JPEG_INTERNAL_OPTIONS
 -
 -
 -/*
 - * These defines indicate whether to include various optional functions.
 - * Undefining some of these symbols will produce a smaller but less capable
 - * library.  Note that you can leave certain source files out of the
 - * compilation/linking process if you've #undef'd the corresponding symbols.
 - * (You may HAVE to do that if your compiler doesn't like null source files.)
 - */
 -
 -/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
 -
 -/* Capability options common to encoder and decoder: */
 -
 -#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: */
 -
 -#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
 -#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
 -#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
 -#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
 -/* Note: if you selected 12-bit data precision, it is dangerous to turn off
 - * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
 - * precision, so jchuff.c normally uses entropy optimization to compute
 - * usable tables for higher precision.  If you don't want to do optimization,
 - * you'll have to supply different default Huffman tables.
 - * The exact same statements apply for progressive JPEG: the default tables
 - * don't work for progressive mode.  (This may get fixed, however.)
 - */
 -#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
 -
 -/* Decoder capability options: */
 -
 -#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 BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
 -#undef IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
 -#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
 -#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 */
 -
 -
 -/*
 - * Ordering of RGB data in scanlines passed to or from the application.
 - * If your application wants to deal with data in the order B,G,R, just
 - * change these macros.  You can also deal with formats such as R,G,B,X
 - * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing
 - * the offsets will also change the order in which colormap data is organized.
 - * RESTRICTIONS:
 - * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
 - * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
 - *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
 - * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
 - *    is not 3 (they don't understand about dummy color components!).  So you
 - *    can't use color quantization if you change that value.
 - */
 -
 -#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	4	/* JSAMPLEs per RGB scanline element */
 -
 -
 -/* Definitions for speed-related optimizations. */
 -
 -
 -/* If your compiler supports inline functions, define INLINE
 - * as the inline keyword; otherwise define it as empty.
 - */
 -
 -#ifndef INLINE
 -#ifdef __GNUC__			/* for instance, GNU C knows about inline */
 -#define INLINE __inline__
 -#endif
 -#ifndef INLINE
 -#define INLINE			/* default is to define it as empty */
 -#endif
 -#endif
 -
 -
 -/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
 - * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
 - * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
 - */
 -
 -#ifndef MULTIPLIER
 -#define MULTIPLIER  int		/* type for fastest integer multiply */
 -#endif
 -
 -
 -/* FAST_FLOAT should be either float or double, whichever is done faster
 - * by your compiler.  (Note that this type is only used in the floating point
 - * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
 - * Typically, float is faster in ANSI C compilers, while double is faster in
 - * pre-ANSI compilers (because they insist on converting to double anyway).
 - * The code below therefore chooses float if we have ANSI-style prototypes.
 - */
 -
 -#ifndef FAST_FLOAT
 -#ifdef HAVE_PROTOTYPES
 -#define FAST_FLOAT  float
 -#else
 -#define FAST_FLOAT  double
 -#endif
 -#endif
 -
 -#endif /* JPEG_INTERNAL_OPTIONS */
 +/* + * jmorecfg.h + * + * Copyright (C) 1991-1995, 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 additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations.  Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + *   8   for 8-bit sample values (the usual setting) + *   12  for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE  8	/* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255.  However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask).  We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory.  (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS  10	/* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small.  But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value)  ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value)  ((int) (value)) +#else +#define GETJSAMPLE(value)  ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE	255 +#define CENTERJSAMPLE	128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value)  ((int) (value)) + +#define MAXJSAMPLE	4095 +#define CENTERJSAMPLE	2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage.  Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value)  (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value)  (value) +#else +#define GETJOCTET(value)  ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE.  (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +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. */ + +//#ifndef XMD_H			/* X11/xmd.h correctly defines INT32 */ +//typedef long INT32; +//#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 + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +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. + * 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 */ + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines.  Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed.  In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#undef FAR +#define FAR  far +#else +#undef FAR +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files.  Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +//#ifndef HAVE_BOOLEAN +//typedef int boolean; +//#endif +#ifndef FALSE			/* in case these macros already exist */ +#define FALSE	0		/* values of boolean */ +#endif +#ifndef TRUE +#define TRUE	1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library.  Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#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: */ + +#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision.  If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode.  (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#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 BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */ +#undef IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */ +#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */ +#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 */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros.  You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + *    useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + *    is not 3 (they don't understand about dummy color components!).  So you + *    can't use color quantization if you change that value. + */ + +#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	4	/* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__			/* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE			/* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER + * as short on such a machine.  MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER  int		/* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler.  (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT  float +#else +#define FAST_FLOAT  double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/libs/jpeg6/jpeg6.vcproj b/libs/jpeg6/jpeg6.vcproj index f17e134..ef6f2ab 100755 --- a/libs/jpeg6/jpeg6.vcproj +++ b/libs/jpeg6/jpeg6.vcproj @@ -1,603 +1,603 @@ -<?xml version="1.0" encoding="Windows-1252"?>
 -<VisualStudioProject
 -	ProjectType="Visual C++"
 -	Version="7.10"
 -	Name="jpeg6"
 -	SccProjectName=""$/source/q3radiant", FEFAAAAA"
 -	SccLocalPath="..\..\q3radiant">
 -	<Platforms>
 -		<Platform
 -			Name="Win32"/>
 -	</Platforms>
 -	<Configurations>
 -		<Configuration
 -			Name="Release|Win32"
 -			OutputDirectory=".\Release"
 -			IntermediateDirectory=".\Release"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="2"
 -				InlineFunctionExpansion="1"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
 -				StringPooling="TRUE"
 -				RuntimeLibrary="0"
 -				EnableFunctionLevelLinking="TRUE"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Release/jpeg6.pch"
 -				AssemblerListingLocation=".\Release/"
 -				ObjectFile=".\Release/"
 -				ProgramDataBaseFileName=".\Release/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\jpeg6.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="NDEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -		<Configuration
 -			Name="Debug|Win32"
 -			OutputDirectory=".\Debug"
 -			IntermediateDirectory=".\Debug"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="0"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
 -				BasicRuntimeChecks="3"
 -				RuntimeLibrary="1"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Debug/jpeg6.pch"
 -				AssemblerListingLocation=".\Debug/"
 -				ObjectFile=".\Debug/"
 -				ProgramDataBaseFileName=".\Debug/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				DebugInformationFormat="4"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\jpeg6d.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="_DEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -	</Configurations>
 -	<References>
 -	</References>
 -	<Files>
 -		<Filter
 -			Name="Source Files"
 -			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
 -			<File
 -				RelativePath="jcomapi.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdapimin.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdapistd.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdatasrc.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdcoefct.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdcolor.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jddctmgr.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdhuff.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdinput.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdmainct.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdmarker.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdmaster.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdpostct.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdsample.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jdtrans.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jerror.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jfdctflt.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jidctflt.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jmemmgr.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jmemnobs.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jpgload.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="jutils.cpp">
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="2"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -			</File>
 -		</Filter>
 -		<Filter
 -			Name="Header Files"
 -			Filter="h;hpp;hxx;hm;inl">
 -			<File
 -				RelativePath="jchuff.h">
 -			</File>
 -			<File
 -				RelativePath="jconfig.h">
 -			</File>
 -			<File
 -				RelativePath="jdct.h">
 -			</File>
 -			<File
 -				RelativePath="jdhuff.h">
 -			</File>
 -			<File
 -				RelativePath="jerror.h">
 -			</File>
 -			<File
 -				RelativePath="jinclude.h">
 -			</File>
 -			<File
 -				RelativePath="jmemsys.h">
 -			</File>
 -			<File
 -				RelativePath="jmorecfg.h">
 -			</File>
 -			<File
 -				RelativePath="jpegint.h">
 -			</File>
 -			<File
 -				RelativePath="jversion.h">
 -			</File>
 -		</Filter>
 -	</Files>
 -	<Globals>
 -	</Globals>
 -</VisualStudioProject>
 +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject +	ProjectType="Visual C++" +	Version="7.10" +	Name="jpeg6" +	SccProjectName=""$/source/q3radiant", FEFAAAAA" +	SccLocalPath="..\..\q3radiant"> +	<Platforms> +		<Platform +			Name="Win32"/> +	</Platforms> +	<Configurations> +		<Configuration +			Name="Release|Win32" +			OutputDirectory=".\Release" +			IntermediateDirectory=".\Release" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="2" +				InlineFunctionExpansion="1" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;NDEBUG;_LIB" +				StringPooling="TRUE" +				RuntimeLibrary="0" +				EnableFunctionLevelLinking="TRUE" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Release/jpeg6.pch" +				AssemblerListingLocation=".\Release/" +				ObjectFile=".\Release/" +				ProgramDataBaseFileName=".\Release/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\jpeg6.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="NDEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Debug|Win32" +			OutputDirectory=".\Debug" +			IntermediateDirectory=".\Debug" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;_DEBUG;_LIB" +				BasicRuntimeChecks="3" +				RuntimeLibrary="1" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Debug/jpeg6.pch" +				AssemblerListingLocation=".\Debug/" +				ObjectFile=".\Debug/" +				ProgramDataBaseFileName=".\Debug/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				DebugInformationFormat="4" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\jpeg6d.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="_DEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +	</Configurations> +	<References> +	</References> +	<Files> +		<Filter +			Name="Source Files" +			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> +			<File +				RelativePath="jcomapi.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdapimin.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdapistd.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdatasrc.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdcoefct.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdcolor.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jddctmgr.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdhuff.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdinput.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdmainct.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdmarker.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdmaster.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdpostct.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdsample.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jdtrans.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jerror.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jfdctflt.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jidctflt.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jmemmgr.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jmemnobs.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jpgload.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="jutils.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +			</File> +		</Filter> +		<Filter +			Name="Header Files" +			Filter="h;hpp;hxx;hm;inl"> +			<File +				RelativePath="jchuff.h"> +			</File> +			<File +				RelativePath="jconfig.h"> +			</File> +			<File +				RelativePath="jdct.h"> +			</File> +			<File +				RelativePath="jdhuff.h"> +			</File> +			<File +				RelativePath="jerror.h"> +			</File> +			<File +				RelativePath="jinclude.h"> +			</File> +			<File +				RelativePath="jmemsys.h"> +			</File> +			<File +				RelativePath="jmorecfg.h"> +			</File> +			<File +				RelativePath="jpegint.h"> +			</File> +			<File +				RelativePath="jversion.h"> +			</File> +		</Filter> +	</Files> +	<Globals> +	</Globals> +</VisualStudioProject> diff --git a/libs/jpeg6/jpegint.h b/libs/jpeg6/jpegint.h index b3b6a6d..ab5bee2 100755 --- a/libs/jpeg6/jpegint.h +++ b/libs/jpeg6/jpegint.h @@ -1,388 +1,388 @@ -/*
 - * jpegint.h
 - *
 - * Copyright (C) 1991-1995, 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 provides common declarations for the various JPEG modules.
 - * These declarations are considered internal to the JPEG library; most
 - * applications using the library shouldn't need to include this file.
 - */
 -
 -
 -/* Declarations for both compression & decompression */
 -
 -typedef enum {			/* Operating modes for buffer controllers */
 -	JBUF_PASS_THRU,		/* Plain stripwise operation */
 -	/* Remaining modes require a full-image buffer to have been created */
 -	JBUF_SAVE_SOURCE,	/* Run source subobject only, save output */
 -	JBUF_CRANK_DEST,	/* Run dest subobject only, using saved data */
 -	JBUF_SAVE_AND_PASS	/* Run both subobjects, save output */
 -} J_BUF_MODE;
 -
 -/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
 -#define CSTATE_START	100	/* after create_compress */
 -#define CSTATE_SCANNING	101	/* start_compress done, write_scanlines OK */
 -#define CSTATE_RAW_OK	102	/* start_compress done, write_raw_data OK */
 -#define CSTATE_WRCOEFS	103	/* jpeg_write_coefficients done */
 -#define DSTATE_START	200	/* after create_decompress */
 -#define DSTATE_INHEADER	201	/* reading header markers, no SOS yet */
 -#define DSTATE_READY	202	/* found SOS, ready for start_decompress */
 -#define DSTATE_PRELOAD	203	/* reading multiscan file in start_decompress*/
 -#define DSTATE_PRESCAN	204	/* performing dummy pass for 2-pass quant */
 -#define DSTATE_SCANNING	205	/* start_decompress done, read_scanlines OK */
 -#define DSTATE_RAW_OK	206	/* start_decompress done, read_raw_data OK */
 -#define DSTATE_BUFIMAGE	207	/* expecting jpeg_start_output */
 -#define DSTATE_BUFPOST	208	/* looking for SOS/EOI in jpeg_finish_output */
 -#define DSTATE_RDCOEFS	209	/* reading file in jpeg_read_coefficients */
 -#define DSTATE_STOPPING	210	/* looking for EOI in jpeg_finish_decompress */
 -
 -
 -/* Declarations for compression modules */
 -
 -/* Master control module */
 -struct jpeg_comp_master {
 -  JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
 -  JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
 -  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
 -
 -  /* State variables made visible to other modules */
 -  boolean call_pass_startup;	/* True if pass_startup must be called */
 -  boolean is_last_pass;		/* True during last pass */
 -};
 -
 -/* Main buffer control (downsampled-data buffer) */
 -struct jpeg_c_main_controller {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
 -  JMETHOD(void, process_data, (j_compress_ptr cinfo,
 -			       JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 -			       JDIMENSION in_rows_avail));
 -};
 -
 -/* Compression preprocessing (downsampling input buffer control) */
 -struct jpeg_c_prep_controller {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
 -  JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
 -				   JSAMPARRAY input_buf,
 -				   JDIMENSION *in_row_ctr,
 -				   JDIMENSION in_rows_avail,
 -				   JSAMPIMAGE output_buf,
 -				   JDIMENSION *out_row_group_ctr,
 -				   JDIMENSION out_row_groups_avail));
 -};
 -
 -/* Coefficient buffer control */
 -struct jpeg_c_coef_controller {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
 -  JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
 -				   JSAMPIMAGE input_buf));
 -};
 -
 -/* Colorspace conversion */
 -struct jpeg_color_converter {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
 -  JMETHOD(void, color_convert, (j_compress_ptr cinfo,
 -				JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 -				JDIMENSION output_row, int num_rows));
 -};
 -
 -/* Downsampling */
 -struct jpeg_downsampler {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
 -  JMETHOD(void, downsample, (j_compress_ptr cinfo,
 -			     JSAMPIMAGE input_buf, JDIMENSION in_row_index,
 -			     JSAMPIMAGE output_buf,
 -			     JDIMENSION out_row_group_index));
 -
 -  boolean need_context_rows;	/* TRUE if need rows above & below */
 -};
 -
 -/* Forward DCT (also controls coefficient quantization) */
 -struct jpeg_forward_dct {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
 -  /* perhaps this should be an array??? */
 -  JMETHOD(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));
 -};
 -
 -/* Entropy encoding */
 -struct jpeg_entropy_encoder {
 -  JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
 -  JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
 -  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
 -};
 -
 -/* 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));
 -};
 -
 -
 -/* Declarations for decompression modules */
 -
 -/* Master control module */
 -struct jpeg_decomp_master {
 -  JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
 -
 -  /* State variables made visible to other modules */
 -  boolean is_dummy_pass;	/* True during 1st pass for 2-pass quant */
 -};
 -
 -/* Input control module */
 -struct jpeg_input_controller {
 -  JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
 -  JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
 -  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
 -
 -  /* State variables made visible to other modules */
 -  boolean has_multiple_scans;	/* True if file has multiple scans */
 -  boolean eoi_reached;		/* True when EOI has been consumed */
 -};
 -
 -/* Main buffer control (downsampled-data buffer) */
 -struct jpeg_d_main_controller {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
 -  JMETHOD(void, process_data, (j_decompress_ptr cinfo,
 -			       JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
 -			       JDIMENSION out_rows_avail));
 -};
 -
 -/* Coefficient buffer control */
 -struct jpeg_d_coef_controller {
 -  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
 -  JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
 -				 JSAMPIMAGE output_buf));
 -  /* Pointer to array of coefficient virtual arrays, or NULL if none */
 -  jvirt_barray_ptr *coef_arrays;
 -};
 -
 -/* Decompression postprocessing (color quantization buffer control) */
 -struct jpeg_d_post_controller {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
 -  JMETHOD(void, post_process_data, (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));
 -};
 -
 -/* Marker reading & parsing */
 -struct jpeg_marker_reader {
 -  JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
 -  /* Read markers until SOS or EOI.
 -   * Returns same codes as are defined for jpeg_consume_input:
 -   * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
 -   */
 -  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.
 -   */
 -  boolean saw_SOI;		/* found SOI? */
 -  boolean saw_SOF;		/* found SOF? */
 -  int next_restart_num;		/* next restart number expected (0-7) */
 -  unsigned int discarded_bytes;	/* # of bytes skipped looking for a marker */
 -};
 -
 -/* Entropy decoding */
 -struct jpeg_entropy_decoder {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
 -				JBLOCKROW *MCU_data));
 -};
 -
 -/* Inverse DCT (also performs dequantization) */
 -typedef JMETHOD(void, inverse_DCT_method_ptr,
 -		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
 -		 JCOEFPTR coef_block,
 -		 JSAMPARRAY output_buf, JDIMENSION output_col));
 -
 -struct jpeg_inverse_dct {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 -  /* It is useful to allow each component to have a separate IDCT method. */
 -  inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
 -};
 -
 -/* Upsampling (note that upsampler must also call color converter) */
 -struct jpeg_upsampler {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(void, upsample, (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));
 -
 -  boolean need_context_rows;	/* TRUE if need rows above & below */
 -};
 -
 -/* Colorspace conversion */
 -struct jpeg_color_deconverter {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
 -				JSAMPIMAGE input_buf, JDIMENSION input_row,
 -				JSAMPARRAY output_buf, int num_rows));
 -};
 -
 -/* Color quantization or color precision reduction */
 -struct jpeg_color_quantizer {
 -  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
 -  JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
 -				 JSAMPARRAY input_buf, JSAMPARRAY output_buf,
 -				 int num_rows));
 -  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
 -  JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
 -};
 -
 -
 -/* Miscellaneous useful macros */
 -
 -#undef MAX
 -#define MAX(a,b)	((a) > (b) ? (a) : (b))
 -#undef MIN
 -#define MIN(a,b)	((a) < (b) ? (a) : (b))
 -
 -
 -/* We assume that right shift corresponds to signed division by 2 with
 - * rounding towards minus infinity.  This is correct for typical "arithmetic
 - * shift" instructions that shift in copies of the sign bit.  But some
 - * C compilers implement >> with an unsigned shift.  For these machines you
 - * must define RIGHT_SHIFT_IS_UNSIGNED.
 - * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
 - * It is only applied with constant shift counts.  SHIFT_TEMPS must be
 - * included in the variables of any routine using RIGHT_SHIFT.
 - */
 -
 -#ifdef RIGHT_SHIFT_IS_UNSIGNED
 -#define SHIFT_TEMPS	INT32 shift_temp;
 -#define RIGHT_SHIFT(x,shft)  \
 -	((shift_temp = (x)) < 0 ? \
 -	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
 -	 (shift_temp >> (shft)))
 -#else
 -#define SHIFT_TEMPS
 -#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
 -#endif
 -
 -
 -/* Short forms of external names for systems with brain-damaged linkers. */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jinit_compress_master	jICompress
 -#define jinit_c_master_control	jICMaster
 -#define jinit_c_main_controller	jICMainC
 -#define jinit_c_prep_controller	jICPrepC
 -#define jinit_c_coef_controller	jICCoefC
 -#define jinit_color_converter	jICColor
 -#define jinit_downsampler	jIDownsampler
 -#define jinit_forward_dct	jIFDCT
 -#define jinit_huff_encoder	jIHEncoder
 -#define jinit_phuff_encoder	jIPHEncoder
 -#define jinit_marker_writer	jIMWriter
 -#define jinit_master_decompress	jIDMaster
 -#define jinit_d_main_controller	jIDMainC
 -#define jinit_d_coef_controller	jIDCoefC
 -#define jinit_d_post_controller	jIDPostC
 -#define jinit_input_controller	jIInCtlr
 -#define jinit_marker_reader	jIMReader
 -#define jinit_huff_decoder	jIHDecoder
 -#define jinit_phuff_decoder	jIPHDecoder
 -#define jinit_inverse_dct	jIIDCT
 -#define jinit_upsampler		jIUpsampler
 -#define jinit_color_deconverter	jIDColor
 -#define jinit_1pass_quantizer	jI1Quant
 -#define jinit_2pass_quantizer	jI2Quant
 -#define jinit_merged_upsampler	jIMUpsampler
 -#define jinit_memory_mgr	jIMemMgr
 -#define jdiv_round_up		jDivRound
 -#define jround_up		jRound
 -#define jcopy_sample_rows	jCopySamples
 -#define jcopy_block_row		jCopyBlocks
 -#define jzero_far		jZeroFar
 -#define jpeg_zigzag_order	jZIGTable
 -#define jpeg_natural_order	jZAGTable
 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
 -
 -
 -/* 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));
 -/* 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));
 -/* Memory manager initialization */
 -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));
 -/* Constant tables in jutils.c */
 -extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
 -extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
 -
 -/* Suppress undefined-structure complaints if necessary. */
 -
 -#ifdef INCOMPLETE_TYPES_BROKEN
 -#ifndef AM_MEMORY_MANAGER	/* only jmemmgr.c defines these */
 -struct jvirt_sarray_control { long dummy; };
 -struct jvirt_barray_control { long dummy; };
 -#endif
 -#endif /* INCOMPLETE_TYPES_BROKEN */
 +/* + * jpegint.h + * + * Copyright (C) 1991-1995, 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 provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum {			/* Operating modes for buffer controllers */ +	JBUF_PASS_THRU,		/* Plain stripwise operation */ +	/* Remaining modes require a full-image buffer to have been created */ +	JBUF_SAVE_SOURCE,	/* Run source subobject only, save output */ +	JBUF_CRANK_DEST,	/* Run dest subobject only, using saved data */ +	JBUF_SAVE_AND_PASS	/* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START	100	/* after create_compress */ +#define CSTATE_SCANNING	101	/* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK	102	/* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS	103	/* jpeg_write_coefficients done */ +#define DSTATE_START	200	/* after create_decompress */ +#define DSTATE_INHEADER	201	/* reading header markers, no SOS yet */ +#define DSTATE_READY	202	/* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD	203	/* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN	204	/* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING	205	/* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK	206	/* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE	207	/* expecting jpeg_start_output */ +#define DSTATE_BUFPOST	208	/* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS	209	/* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING	210	/* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { +  JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); +  JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + +  /* State variables made visible to other modules */ +  boolean call_pass_startup;	/* True if pass_startup must be called */ +  boolean is_last_pass;		/* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); +  JMETHOD(void, process_data, (j_compress_ptr cinfo, +			       JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, +			       JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); +  JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, +				   JSAMPARRAY input_buf, +				   JDIMENSION *in_row_ctr, +				   JDIMENSION in_rows_avail, +				   JSAMPIMAGE output_buf, +				   JDIMENSION *out_row_group_ctr, +				   JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); +  JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, +				   JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo)); +  JMETHOD(void, color_convert, (j_compress_ptr cinfo, +				JSAMPARRAY input_buf, JSAMPIMAGE output_buf, +				JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo)); +  JMETHOD(void, downsample, (j_compress_ptr cinfo, +			     JSAMPIMAGE input_buf, JDIMENSION in_row_index, +			     JSAMPIMAGE output_buf, +			     JDIMENSION out_row_group_index)); + +  boolean need_context_rows;	/* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo)); +  /* perhaps this should be an array??? */ +  JMETHOD(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)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); +  JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* 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)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { +  JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); +  JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + +  /* State variables made visible to other modules */ +  boolean is_dummy_pass;	/* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { +  JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); +  JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); +  JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + +  /* State variables made visible to other modules */ +  boolean has_multiple_scans;	/* True if file has multiple scans */ +  boolean eoi_reached;		/* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); +  JMETHOD(void, process_data, (j_decompress_ptr cinfo, +			       JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, +			       JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); +  JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); +  JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); +  JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, +				 JSAMPIMAGE output_buf)); +  /* Pointer to array of coefficient virtual arrays, or NULL if none */ +  jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); +  JMETHOD(void, post_process_data, (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)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { +  JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); +  /* Read markers until SOS or EOI. +   * Returns same codes as are defined for jpeg_consume_input: +   * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. +   */ +  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. +   */ +  boolean saw_SOI;		/* found SOI? */ +  boolean saw_SOF;		/* found SOF? */ +  int next_restart_num;		/* next restart number expected (0-7) */ +  unsigned int discarded_bytes;	/* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); +  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, +				JBLOCKROW *MCU_data)); +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, +		(j_decompress_ptr cinfo, jpeg_component_info * compptr, +		 JCOEFPTR coef_block, +		 JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); +  /* It is useful to allow each component to have a separate IDCT method. */ +  inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); +  JMETHOD(void, upsample, (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)); + +  boolean need_context_rows;	/* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); +  JMETHOD(void, color_convert, (j_decompress_ptr cinfo, +				JSAMPIMAGE input_buf, JDIMENSION input_row, +				JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); +  JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, +				 JSAMPARRAY input_buf, JSAMPARRAY output_buf, +				 int num_rows)); +  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); +  JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b)	((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b)	((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity.  This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit.  But some + * C compilers implement >> with an unsigned shift.  For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts.  SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS	INT32 shift_temp; +#define RIGHT_SHIFT(x,shft)  \ +	((shift_temp = (x)) < 0 ? \ +	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ +	 (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft)	((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master	jICompress +#define jinit_c_master_control	jICMaster +#define jinit_c_main_controller	jICMainC +#define jinit_c_prep_controller	jICPrepC +#define jinit_c_coef_controller	jICCoefC +#define jinit_color_converter	jICColor +#define jinit_downsampler	jIDownsampler +#define jinit_forward_dct	jIFDCT +#define jinit_huff_encoder	jIHEncoder +#define jinit_phuff_encoder	jIPHEncoder +#define jinit_marker_writer	jIMWriter +#define jinit_master_decompress	jIDMaster +#define jinit_d_main_controller	jIDMainC +#define jinit_d_coef_controller	jIDCoefC +#define jinit_d_post_controller	jIDPostC +#define jinit_input_controller	jIInCtlr +#define jinit_marker_reader	jIMReader +#define jinit_huff_decoder	jIHDecoder +#define jinit_phuff_decoder	jIPHDecoder +#define jinit_inverse_dct	jIIDCT +#define jinit_upsampler		jIUpsampler +#define jinit_color_deconverter	jIDColor +#define jinit_1pass_quantizer	jI1Quant +#define jinit_2pass_quantizer	jI2Quant +#define jinit_merged_upsampler	jIMUpsampler +#define jinit_memory_mgr	jIMemMgr +#define jdiv_round_up		jDivRound +#define jround_up		jRound +#define jcopy_sample_rows	jCopySamples +#define jcopy_block_row		jCopyBlocks +#define jzero_far		jZeroFar +#define jpeg_zigzag_order	jZIGTable +#define jpeg_natural_order	jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* 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)); +/* 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)); +/* Memory manager initialization */ +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)); +/* Constant tables in jutils.c */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER	/* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/libs/jpeg6/jpgload.cpp b/libs/jpeg6/jpgload.cpp index 1006b99..ca64685 100755 --- a/libs/jpeg6/jpgload.cpp +++ b/libs/jpeg6/jpgload.cpp @@ -1,142 +1,142 @@ -
 -    
 -#include "jpeglib.h"
 -#include <memory.h>
 -
 -GLOBAL void LoadJPGBuff(unsigned char *fbuffer, unsigned char **pic, int *width, int *height ) 
 -{
 -  /* This struct contains the JPEG decompression parameters and pointers to
 -   * working space (which is allocated as needed by the JPEG library).
 -   */
 -  struct jpeg_decompress_struct cinfo;
 -  /* We use our private extension JPEG error handler.
 -   * Note that this struct must live as long as the main JPEG parameter
 -   * struct, to avoid dangling-pointer problems.
 -   */
 -  /* This struct represents a JPEG error handler.  It is declared separately
 -   * because applications often want to supply a specialized error handler
 -   * (see the second half of this file for an example).  But here we just
 -   * take the easy way out and use the standard error handler, which will
 -   * print a message on stderr and call exit() if compression fails.
 -   * Note that this struct must live as long as the main JPEG parameter
 -   * struct, to avoid dangling-pointer problems.
 -   */
 -
 -  struct jpeg_error_mgr jerr;
 -  /* More stuff */
 -  JSAMPARRAY buffer;		/* Output row buffer */
 -  int row_stride;		/* physical row width in output buffer */
 -  unsigned char *out;
 -  byte  *bbuf;
 -  int nSize;
 -
 -  /* Step 1: allocate and initialize JPEG decompression object */
 -
 -  /* We have to set up the error handler first, in case the initialization
 -   * step fails.  (Unlikely, but it could happen if you are out of memory.)
 -   * This routine fills in the contents of struct jerr, and returns jerr's
 -   * address which we place into the link field in cinfo.
 -   */
 -  cinfo.err = jpeg_std_error(&jerr);
 -
 -  /* Now we can initialize the JPEG decompression object. */
 -  jpeg_create_decompress(&cinfo);
 -
 -  /* Step 2: specify data source (eg, a file) */
 -
 -  jpeg_stdio_src(&cinfo, fbuffer);
 -
 -  /* Step 3: read file parameters with jpeg_read_header() */
 -
 -  (void) jpeg_read_header(&cinfo, TRUE);
 -  /* We can ignore the return value from jpeg_read_header since
 -   *   (a) suspension is not possible with the stdio data source, and
 -   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
 -   * See libjpeg.doc for more info.
 -   */
 -
 -  /* Step 4: set parameters for decompression */
 -
 -  /* In this example, we don't need to change any of the defaults set by
 -   * jpeg_read_header(), so we do nothing here.
 -   */
 -
 -  /* Step 5: Start decompressor */
 -
 -  (void) jpeg_start_decompress(&cinfo);
 -  /* We can ignore the return value since suspension is not possible
 -   * with the stdio data source.
 -   */
 -
 -  /* We may need to do some setup of our own at this point before reading
 -   * the data.  After jpeg_start_decompress() we have the correct scaled
 -   * output image dimensions available, as well as the output colormap
 -   * if we asked for color quantization.
 -   * In this example, we need to make an output work buffer of the right size.
 -   */ 
 -  /* JSAMPLEs per row in output buffer */
 -  row_stride = cinfo.output_width * cinfo.output_components;
 -
 -  nSize = cinfo.output_width*cinfo.output_height*cinfo.output_components;
 -  out = reinterpret_cast<unsigned char*>(malloc(nSize+1));
 -  memset(out, 0, nSize+1);
 -
 -  *pic = out;
 -  *width = cinfo.output_width;
 -  *height = cinfo.output_height;
 -
 -  /* Step 6: while (scan lines remain to be read) */
 -  /*           jpeg_read_scanlines(...); */
 -
 -  /* Here we use the library's state variable cinfo.output_scanline as the
 -   * loop counter, so that we don't have to keep track ourselves.
 -   */
 -  while (cinfo.output_scanline < cinfo.output_height) {
 -    /* jpeg_read_scanlines expects an array of pointers to scanlines.
 -     * Here the array is only one element long, but you could ask for
 -     * more than one scanline at a time if that's more convenient.
 -     */
 -	  bbuf = ((out+(row_stride*cinfo.output_scanline)));
 -  	buffer = &bbuf;
 -    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
 -  }
 -
 -  // clear all the alphas to 255
 -  {
 -	  int	i, j;
 -		byte	*buf;
 -
 -		buf = *pic;
 -
 -	  j = cinfo.output_width * cinfo.output_height * 4;
 -	  for ( i = 3 ; i < j ; i+=4 ) {
 -		  buf[i] = 255;
 -	  }
 -  }
 -
 -  /* Step 7: Finish decompression */
 -
 -  (void) jpeg_finish_decompress(&cinfo);
 -  /* We can ignore the return value since suspension is not possible
 -   * with the stdio data source.
 -   */
 -
 -  /* Step 8: Release JPEG decompression object */
 -
 -  /* This is an important step since it will release a good deal of memory. */
 -  jpeg_destroy_decompress(&cinfo);
 -
 -  /* After finish_decompress, we can close the input file.
 -   * Here we postpone it until after no more JPEG errors are possible,
 -   * so as to simplify the setjmp error logic above.  (Actually, I don't
 -   * think that jpeg_destroy can do an error exit, but why assume anything...)
 -   */
 -  //free (fbuffer);
 -
 -  /* At this point you may want to check to see whether any corrupt-data
 -   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
 -   */
 -
 -  /* And we're done! */
 -}
 -
 + +     +#include "jpeglib.h" +#include <memory.h> + +GLOBAL void LoadJPGBuff(unsigned char *fbuffer, unsigned char **pic, int *width, int *height )  +{ +  /* This struct contains the JPEG decompression parameters and pointers to +   * working space (which is allocated as needed by the JPEG library). +   */ +  struct jpeg_decompress_struct cinfo; +  /* We use our private extension JPEG error handler. +   * Note that this struct must live as long as the main JPEG parameter +   * struct, to avoid dangling-pointer problems. +   */ +  /* This struct represents a JPEG error handler.  It is declared separately +   * because applications often want to supply a specialized error handler +   * (see the second half of this file for an example).  But here we just +   * take the easy way out and use the standard error handler, which will +   * print a message on stderr and call exit() if compression fails. +   * Note that this struct must live as long as the main JPEG parameter +   * struct, to avoid dangling-pointer problems. +   */ + +  struct jpeg_error_mgr jerr; +  /* More stuff */ +  JSAMPARRAY buffer;		/* Output row buffer */ +  int row_stride;		/* physical row width in output buffer */ +  unsigned char *out; +  byte  *bbuf; +  int nSize; + +  /* Step 1: allocate and initialize JPEG decompression object */ + +  /* We have to set up the error handler first, in case the initialization +   * step fails.  (Unlikely, but it could happen if you are out of memory.) +   * This routine fills in the contents of struct jerr, and returns jerr's +   * address which we place into the link field in cinfo. +   */ +  cinfo.err = jpeg_std_error(&jerr); + +  /* Now we can initialize the JPEG decompression object. */ +  jpeg_create_decompress(&cinfo); + +  /* Step 2: specify data source (eg, a file) */ + +  jpeg_stdio_src(&cinfo, fbuffer); + +  /* Step 3: read file parameters with jpeg_read_header() */ + +  (void) jpeg_read_header(&cinfo, TRUE); +  /* We can ignore the return value from jpeg_read_header since +   *   (a) suspension is not possible with the stdio data source, and +   *   (b) we passed TRUE to reject a tables-only JPEG file as an error. +   * See libjpeg.doc for more info. +   */ + +  /* Step 4: set parameters for decompression */ + +  /* In this example, we don't need to change any of the defaults set by +   * jpeg_read_header(), so we do nothing here. +   */ + +  /* Step 5: Start decompressor */ + +  (void) jpeg_start_decompress(&cinfo); +  /* We can ignore the return value since suspension is not possible +   * with the stdio data source. +   */ + +  /* We may need to do some setup of our own at this point before reading +   * the data.  After jpeg_start_decompress() we have the correct scaled +   * output image dimensions available, as well as the output colormap +   * if we asked for color quantization. +   * In this example, we need to make an output work buffer of the right size. +   */  +  /* JSAMPLEs per row in output buffer */ +  row_stride = cinfo.output_width * cinfo.output_components; + +  nSize = cinfo.output_width*cinfo.output_height*cinfo.output_components; +  out = reinterpret_cast<unsigned char*>(malloc(nSize+1)); +  memset(out, 0, nSize+1); + +  *pic = out; +  *width = cinfo.output_width; +  *height = cinfo.output_height; + +  /* Step 6: while (scan lines remain to be read) */ +  /*           jpeg_read_scanlines(...); */ + +  /* Here we use the library's state variable cinfo.output_scanline as the +   * loop counter, so that we don't have to keep track ourselves. +   */ +  while (cinfo.output_scanline < cinfo.output_height) { +    /* jpeg_read_scanlines expects an array of pointers to scanlines. +     * Here the array is only one element long, but you could ask for +     * more than one scanline at a time if that's more convenient. +     */ +	  bbuf = ((out+(row_stride*cinfo.output_scanline))); +  	buffer = &bbuf; +    (void) jpeg_read_scanlines(&cinfo, buffer, 1); +  } + +  // clear all the alphas to 255 +  { +	  int	i, j; +		byte	*buf; + +		buf = *pic; + +	  j = cinfo.output_width * cinfo.output_height * 4; +	  for ( i = 3 ; i < j ; i+=4 ) { +		  buf[i] = 255; +	  } +  } + +  /* Step 7: Finish decompression */ + +  (void) jpeg_finish_decompress(&cinfo); +  /* We can ignore the return value since suspension is not possible +   * with the stdio data source. +   */ + +  /* Step 8: Release JPEG decompression object */ + +  /* This is an important step since it will release a good deal of memory. */ +  jpeg_destroy_decompress(&cinfo); + +  /* After finish_decompress, we can close the input file. +   * Here we postpone it until after no more JPEG errors are possible, +   * so as to simplify the setjmp error logic above.  (Actually, I don't +   * think that jpeg_destroy can do an error exit, but why assume anything...) +   */ +  //free (fbuffer); + +  /* At this point you may want to check to see whether any corrupt-data +   * warnings occurred (test whether jerr.pub.num_warnings is nonzero). +   */ + +  /* And we're done! */ +} + diff --git a/libs/jpeg6/jutils.cpp b/libs/jpeg6/jutils.cpp index 8e8dc13..4ba2a54 100755 --- a/libs/jpeg6/jutils.cpp +++ b/libs/jpeg6/jutils.cpp @@ -1,175 +1,175 @@ -/*
 - * jutils.c
 - *
 - * Copyright (C) 1991-1995, 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 tables and miscellaneous utility routines needed
 - * for both compression and decompression.
 - * Note we prefix all global names with "j" to minimize conflicts with
 - * a surrounding application.
 - */
 -
 -#define JPEG_INTERNALS
 -#include "jinclude.h"
 -#include "jpeglib.h"
 -
 -
 -/*
 - * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
 - * of a DCT block read in natural order (left to right, top to bottom).
 - */
 -
 -const int jpeg_zigzag_order[DCTSIZE2] = {
 -   0,  1,  5,  6, 14, 15, 27, 28,
 -   2,  4,  7, 13, 16, 26, 29, 42,
 -   3,  8, 12, 17, 25, 30, 41, 43,
 -   9, 11, 18, 24, 31, 40, 44, 53,
 -  10, 19, 23, 32, 39, 45, 52, 54,
 -  20, 22, 33, 38, 46, 51, 55, 60,
 -  21, 34, 37, 47, 50, 56, 59, 61,
 -  35, 36, 48, 49, 57, 58, 62, 63
 -};
 -
 -/*
 - * jpeg_natural_order[i] is the natural-order position of the i'th element
 - * of zigzag order.
 - *
 - * When reading corrupted data, the Huffman decoders could attempt
 - * to reference an entry beyond the end of this array (if the decoded
 - * zero run length reaches past the end of the block).  To prevent
 - * wild stores without adding an inner-loop test, we put some extra
 - * "63"s after the real entries.  This will cause the extra coefficient
 - * to be stored in location 63 of the block, not somewhere random.
 - * The worst case would be a run-length of 15, which means we need 16
 - * fake entries.
 - */
 -
 -const int jpeg_natural_order[DCTSIZE2+16] = {
 -  0,  1,  8, 16,  9,  2,  3, 10,
 - 17, 24, 32, 25, 18, 11,  4,  5,
 - 12, 19, 26, 33, 40, 48, 41, 34,
 - 27, 20, 13,  6,  7, 14, 21, 28,
 - 35, 42, 49, 56, 57, 50, 43, 36,
 - 29, 22, 15, 23, 30, 37, 44, 51,
 - 58, 59, 52, 45, 38, 31, 39, 46,
 - 53, 60, 61, 54, 47, 55, 62, 63,
 - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
 - 63, 63, 63, 63, 63, 63, 63, 63
 -};
 -
 -
 -/*
 - * Arithmetic utilities
 - */
 -
 -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 */
 -{
 -  return (a + b - 1L) / b;
 -}
 -
 -
 -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 */
 -{
 -  a += b - 1L;
 -  return a - (a % b);
 -}
 -
 -
 -/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
 - * and coefficient-block arrays.  This won't work on 80x86 because the arrays
 - * are FAR and we're assuming a small-pointer memory model.  However, some
 - * DOS compilers provide far-pointer versions of memcpy() and memset() even
 - * in the small-model libraries.  These will be used if USE_FMEM is defined.
 - * Otherwise, the routines below do it the hard way.  (The performance cost
 - * is not all that great, because these routines aren't very heavily used.)
 - */
 -
 -#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */
 -#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size)
 -#define FMEMZERO(target,size)	MEMZERO(target,size)
 -#else				/* 80x86 case, define if we can */
 -#ifdef USE_FMEM
 -#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
 -#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size))
 -#endif
 -#endif
 -
 -
 -GLOBAL void
 -jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
 -		   JSAMPARRAY output_array, int dest_row,
 -		   int num_rows, JDIMENSION num_cols)
 -/* Copy some rows of samples from one place to another.
 - * num_rows rows are copied from input_array[source_row++]
 - * to output_array[dest_row++]; these areas may overlap for duplication.
 - * The source and destination arrays must be at least as wide as num_cols.
 - */
 -{
 -  register JSAMPROW inptr, outptr;
 -#ifdef FMEMCOPY
 -  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
 -#else
 -  register JDIMENSION count;
 -#endif
 -  register int row;
 -
 -  input_array += source_row;
 -  output_array += dest_row;
 -
 -  for (row = num_rows; row > 0; row--) {
 -    inptr = *input_array++;
 -    outptr = *output_array++;
 -#ifdef FMEMCOPY
 -    FMEMCOPY(outptr, inptr, count);
 -#else
 -    for (count = num_cols; count > 0; count--)
 -      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */
 -#endif
 -  }
 -}
 -
 -
 -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. */
 -{
 -#ifdef FMEMCOPY
 -  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
 -#else
 -  register JCOEFPTR inptr, outptr;
 -  register long count;
 -
 -  inptr = (JCOEFPTR) input_row;
 -  outptr = (JCOEFPTR) output_row;
 -  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
 -    *outptr++ = *inptr++;
 -  }
 -#endif
 -}
 -
 -
 -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. */
 -{
 -#ifdef FMEMZERO
 -  FMEMZERO(target, bytestozero);
 -#else
 -  register char FAR * ptr = (char FAR *) target;
 -  register size_t count;
 -
 -  for (count = bytestozero; count > 0; count--) {
 -    *ptr++ = 0;
 -  }
 -#endif
 -}
 +/* + * jutils.c + * + * Copyright (C) 1991-1995, 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 tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + * of a DCT block read in natural order (left to right, top to bottom). + */ + +const int jpeg_zigzag_order[DCTSIZE2] = { +   0,  1,  5,  6, 14, 15, 27, 28, +   2,  4,  7, 13, 16, 26, 29, 42, +   3,  8, 12, 17, 25, 30, 41, 43, +   9, 11, 18, 24, 31, 40, 44, 53, +  10, 19, 23, 32, 39, 45, 52, 54, +  20, 22, 33, 38, 46, 51, 55, 60, +  21, 34, 37, 47, 50, 56, 59, 61, +  35, 36, 48, 49, 57, 58, 62, 63 +}; + +/* + * jpeg_natural_order[i] is the natural-order position of the i'th element + * of zigzag order. + * + * When reading corrupted data, the Huffman decoders could attempt + * to reference an entry beyond the end of this array (if the decoded + * zero run length reaches past the end of the block).  To prevent + * wild stores without adding an inner-loop test, we put some extra + * "63"s after the real entries.  This will cause the extra coefficient + * to be stored in location 63 of the block, not somewhere random. + * The worst case would be a run-length of 15, which means we need 16 + * fake entries. + */ + +const int jpeg_natural_order[DCTSIZE2+16] = { +  0,  1,  8, 16,  9,  2,  3, 10, + 17, 24, 32, 25, 18, 11,  4,  5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13,  6,  7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 +}; + + +/* + * Arithmetic utilities + */ + +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 */ +{ +  return (a + b - 1L) / b; +} + + +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 */ +{ +  a += b - 1L; +  return a - (a % b); +} + + +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + * and coefficient-block arrays.  This won't work on 80x86 because the arrays + * are FAR and we're assuming a small-pointer memory model.  However, some + * DOS compilers provide far-pointer versions of memcpy() and memset() even + * in the small-model libraries.  These will be used if USE_FMEM is defined. + * Otherwise, the routines below do it the hard way.  (The performance cost + * is not all that great, because these routines aren't very heavily used.) + */ + +#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size) +#define FMEMZERO(target,size)	MEMZERO(target,size) +#else				/* 80x86 case, define if we can */ +#ifdef USE_FMEM +#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size)) +#endif +#endif + + +GLOBAL void +jcopy_sample_rows (JSAMPARRAY input_array, int source_row, +		   JSAMPARRAY output_array, int dest_row, +		   int num_rows, JDIMENSION num_cols) +/* Copy some rows of samples from one place to another. + * num_rows rows are copied from input_array[source_row++] + * to output_array[dest_row++]; these areas may overlap for duplication. + * The source and destination arrays must be at least as wide as num_cols. + */ +{ +  register JSAMPROW inptr, outptr; +#ifdef FMEMCOPY +  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); +#else +  register JDIMENSION count; +#endif +  register int row; + +  input_array += source_row; +  output_array += dest_row; + +  for (row = num_rows; row > 0; row--) { +    inptr = *input_array++; +    outptr = *output_array++; +#ifdef FMEMCOPY +    FMEMCOPY(outptr, inptr, count); +#else +    for (count = num_cols; count > 0; count--) +      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */ +#endif +  } +} + + +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. */ +{ +#ifdef FMEMCOPY +  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +#else +  register JCOEFPTR inptr, outptr; +  register long count; + +  inptr = (JCOEFPTR) input_row; +  outptr = (JCOEFPTR) output_row; +  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { +    *outptr++ = *inptr++; +  } +#endif +} + + +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. */ +{ +#ifdef FMEMZERO +  FMEMZERO(target, bytestozero); +#else +  register char FAR * ptr = (char FAR *) target; +  register size_t count; + +  for (count = bytestozero; count > 0; count--) { +    *ptr++ = 0; +  } +#endif +} diff --git a/libs/jpeg6/jversion.h b/libs/jpeg6/jversion.h index 02083ac..f2f1b8d 100755 --- a/libs/jpeg6/jversion.h +++ b/libs/jpeg6/jversion.h @@ -1,14 +1,14 @@ -/*
 - * jversion.h
 - *
 - * Copyright (C) 1991-1995, 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 software version identification.
 - */
 -
 -
 -#define JVERSION	"6  2-Aug-95"
 -
 -#define JCOPYRIGHT	"Copyright (C) 1995, Thomas G. Lane"
 +/* + * jversion.h + * + * Copyright (C) 1991-1995, 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 software version identification. + */ + + +#define JVERSION	"6  2-Aug-95" + +#define JCOPYRIGHT	"Copyright (C) 1995, Thomas G. Lane" diff --git a/libs/jpeglib.h b/libs/jpeglib.h index 81ca1b4..e93ab53 100755 --- a/libs/jpeglib.h +++ b/libs/jpeglib.h @@ -1,1087 +1,1087 @@ -/*
 - * jpeglib.h
 - *
 - * Copyright (C) 1991-1995, 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 defines the application interface for the JPEG library.
 - * Most applications using the library need only include this file,
 - * and perhaps jerror.h if they want to know the exact error codes.
 - */
 -
 -#ifndef JPEGLIB_H
 -#define JPEGLIB_H
 -
 -#ifdef __cplusplus
 -extern "C"
 -{
 -#endif
 -
 -
 -
 -#ifdef __MACOS__
 -
 -// JDC: stuff to make mac version compile
 -#define	boolean	qboolean
 -#define	register
 -#define	INT32	int
 -
 -#endif
 -
 -// rad additions
 -// 11.29.99
 -
 -//#include "cmdlib.h"
 -#ifdef _WIN32
 -#include "windows.h"
 -#include "stdio.h"
 -#endif
 -
 -#ifndef INT32
 -#define	INT32	int
 -#endif
 -
 -extern void LoadJPGBuff(unsigned char *fbuffer, unsigned char **pic, int *width, int *height );
 -// rad end
 -
 -
 -/*
 - * First we include the configuration files that record how this
 - * installation of the JPEG library is set up.  jconfig.h can be
 - * generated automatically for many systems.  jmorecfg.h contains
 - * manual configuration options that most people need not worry about.
 - */
 -
 -#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */
 -#include "jpeg6/jconfig.h"		/* widely used configuration options */
 -#endif
 -#include "jpeg6/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 */
 -
 -
 -/* Various constants determining the sizes of things.
 - * All of these are specified by the JPEG standard, so don't change them
 - * if you want to be compatible.
 - */
 -
 -#define DCTSIZE		    8	/* The basic DCT block is 8x8 samples */
 -#define DCTSIZE2	    64	/* DCTSIZE squared; # of elements in a block */
 -#define NUM_QUANT_TBLS      4	/* Quantization tables are numbered 0..3 */
 -#define NUM_HUFF_TBLS       4	/* Huffman tables are numbered 0..3 */
 -#define NUM_ARITH_TBLS      16	/* Arith-coding tables are numbered 0..15 */
 -#define MAX_COMPS_IN_SCAN   4	/* JPEG limit on # of components in one scan */
 -#define MAX_SAMP_FACTOR     4	/* JPEG limit on sampling factors */
 -/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
 - * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
 - * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
 - * to handle it.  We even let you do this from the jconfig.h file.  However,
 - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
 - * sometimes emits noncompliant files doesn't mean you should too.
 - */
 -#define C_MAX_BLOCKS_IN_MCU   10 /* compressor's limit on blocks per MCU */
 -#ifndef D_MAX_BLOCKS_IN_MCU
 -#define D_MAX_BLOCKS_IN_MCU   10 /* decompressor's limit on blocks per MCU */
 -#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.
 - */
 -
 -typedef JSAMPLE FAR *JSAMPROW;	/* ptr to one image row of pixel samples. */
 -typedef JSAMPROW *JSAMPARRAY;	/* ptr to some rows (a 2-D sample array) */
 -typedef JSAMPARRAY *JSAMPIMAGE;	/* a 3-D sample array: top index is color */
 -
 -typedef JCOEF JBLOCK[DCTSIZE2];	/* one block of coefficients */
 -typedef JBLOCK FAR *JBLOCKROW;	/* pointer to one row of coefficient blocks */
 -typedef JBLOCKROW *JBLOCKARRAY;		/* a 2-D array of coefficient blocks */
 -typedef JBLOCKARRAY *JBLOCKIMAGE;	/* a 3-D array of coefficient blocks */
 -
 -typedef JCOEF FAR *JCOEFPTR;	/* useful in a couple of places */
 -
 -
 -/* Types for JPEG compression parameters and working tables. */
 -
 -
 -/* 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.
 -   */
 -  UINT16 quantval[DCTSIZE2];	/* quantization step for each coefficient */
 -  /* This field is used only during compression.  It's initialized FALSE when
 -   * the table is created, and set TRUE when it's been output to the file.
 -   * You could suppress output of a table by setting this to TRUE.
 -   * (See jpeg_suppress_tables for an example.)
 -   */
 -  boolean sent_table;		/* TRUE when table has been output */
 -} JQUANT_TBL;
 -
 -
 -/* Huffman coding tables. */
 -
 -typedef struct {
 -  /* These two fields directly represent the contents of a JPEG DHT marker */
 -  UINT8 bits[17];		/* bits[k] = # of symbols with codes of */
 -				/* length k bits; bits[0] is unused */
 -  UINT8 huffval[256];		/* The symbols, in order of incr code length */
 -  /* This field is used only during compression.  It's initialized FALSE when
 -   * the table is created, and set TRUE when it's been output to the file.
 -   * You could suppress output of a table by setting this to TRUE.
 -   * (See jpeg_suppress_tables for an example.)
 -   */
 -  boolean sent_table;		/* TRUE when table has been output */
 -} JHUFF_TBL;
 -
 -
 -/* Basic info about one component (color channel). */
 -
 -typedef struct {
 -  /* These values are fixed over the whole image. */
 -  /* For compression, they must be supplied by parameter setup; */
 -  /* for decompression, they are read from the SOF marker. */
 -  int component_id;		/* identifier for this component (0..255) */
 -  int component_index;		/* its index in SOF or cinfo->comp_info[] */
 -  int h_samp_factor;		/* horizontal sampling factor (1..4) */
 -  int v_samp_factor;		/* vertical sampling factor (1..4) */
 -  int quant_tbl_no;		/* quantization table selector (0..3) */
 -  /* These values may vary between scans. */
 -  /* For compression, they must be supplied by parameter setup; */
 -  /* for decompression, they are read from the SOS marker. */
 -  /* The decompressor output side may not use these variables. */
 -  int dc_tbl_no;		/* DC entropy table selector (0..3) */
 -  int ac_tbl_no;		/* AC entropy table selector (0..3) */
 -  
 -  /* Remaining fields should be treated as private by applications. */
 -  
 -  /* These values are computed during compression or decompression startup: */
 -  /* Component's size in DCT blocks.
 -   * Any dummy blocks added to complete an MCU are not counted; therefore
 -   * these values do not depend on whether a scan is interleaved or not.
 -   */
 -  JDIMENSION width_in_blocks;
 -  JDIMENSION height_in_blocks;
 -  /* Size of a DCT block in samples.  Always DCTSIZE for compression.
 -   * For decompression this is the size of the output from one DCT block,
 -   * reflecting any scaling we choose to apply during the IDCT step.
 -   * Values of 1,2,4,8 are likely to be supported.  Note that different
 -   * components may receive different IDCT scalings.
 -   */
 -  int DCT_scaled_size;
 -  /* The downsampled dimensions are the component's actual, unpadded number
 -   * of samples at the main buffer (preprocessing/compression interface), thus
 -   * downsampled_width = ceil(image_width * Hi/Hmax)
 -   * and similarly for height.  For decompression, IDCT scaling is included, so
 -   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
 -   */
 -  JDIMENSION downsampled_width;	 /* actual width in samples */
 -  JDIMENSION downsampled_height; /* actual height in samples */
 -  /* This flag is used only for decompression.  In cases where some of the
 -   * components will be ignored (eg grayscale output from YCbCr image),
 -   * we can skip most computations for the unused components.
 -   */
 -  boolean component_needed;	/* do we need the value of this component? */
 -
 -  /* These values are computed before starting a scan of the component. */
 -  /* The decompressor output side may not use these variables. */
 -  int MCU_width;		/* number of blocks per MCU, horizontally */
 -  int MCU_height;		/* number of blocks per MCU, vertically */
 -  int MCU_blocks;		/* MCU_width * MCU_height */
 -  int MCU_sample_width;		/* MCU width in samples, MCU_width*DCT_scaled_size */
 -  int last_col_width;		/* # of non-dummy blocks across in last MCU */
 -  int last_row_height;		/* # of non-dummy blocks down in last MCU */
 -
 -  /* 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.
 -   */
 -  JQUANT_TBL * quant_table;
 -
 -  /* Private per-component storage for DCT or IDCT subsystem. */
 -  void * dct_table;
 -} jpeg_component_info;
 -
 -
 -/* The script for encoding a multiple-scan file is an array of these: */
 -
 -typedef struct {
 -  int comps_in_scan;		/* number of components encoded in this scan */
 -  int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
 -  int Ss, Se;			/* progressive JPEG spectral selection parms */
 -  int Ah, Al;			/* progressive JPEG successive approx. parms */
 -} jpeg_scan_info;
 -
 -
 -/* Known color spaces. */
 -
 -typedef enum {
 -	JCS_UNKNOWN,		/* error/unspecified */
 -	JCS_GRAYSCALE,		/* monochrome */
 -	JCS_RGB,		/* red/green/blue */
 -	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
 -	JCS_CMYK,		/* C/M/Y/K */
 -	JCS_YCCK		/* Y/Cb/Cr/K */
 -} J_COLOR_SPACE;
 -
 -/* DCT/IDCT algorithm options. */
 -
 -typedef enum {
 -	JDCT_ISLOW,		/* slow but accurate integer algorithm */
 -	JDCT_IFAST,		/* faster, less accurate integer method */
 -	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */
 -} J_DCT_METHOD;
 -
 -#ifndef JDCT_DEFAULT		/* may be overridden in jconfig.h */
 -#define JDCT_DEFAULT  JDCT_ISLOW
 -#endif
 -#ifndef JDCT_FASTEST		/* may be overridden in jconfig.h */
 -#define JDCT_FASTEST  JDCT_IFAST
 -#endif
 -
 -/* Dithering options for decompression. */
 -
 -typedef enum {
 -	JDITHER_NONE,		/* no dithering */
 -	JDITHER_ORDERED,	/* simple ordered dither */
 -	JDITHER_FS		/* Floyd-Steinberg error diffusion dither */
 -} J_DITHER_MODE;
 -
 -
 -/* Common fields between JPEG compression and decompression master structs. */
 -
 -#define jpeg_common_fields \
 -  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 */
 -
 -/* 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
 - * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
 - */
 -struct jpeg_common_struct {
 -  jpeg_common_fields;		/* Fields common to both master struct types */
 -  /* Additional fields follow in an actual jpeg_compress_struct or
 -   * jpeg_decompress_struct.  All three structs must agree on these
 -   * initial fields!  (This would be a lot cleaner in C++.)
 -   */
 -};
 -
 -typedef struct jpeg_common_struct * j_common_ptr;
 -typedef struct jpeg_compress_struct * j_compress_ptr;
 -typedef struct jpeg_decompress_struct * j_decompress_ptr;
 -
 -
 -/* Master record for a compression instance */
 -
 -struct jpeg_compress_struct {
 -  jpeg_common_fields;		/* Fields shared with jpeg_decompress_struct */
 -
 -  /* Destination for compressed data */
 -  struct jpeg_destination_mgr * dest;
 -
 -  /* Description of source image --- these fields must be filled in by
 -   * outer application before starting compression.  in_color_space must
 -   * be correct before you can even call jpeg_set_defaults().
 -   */
 -
 -  JDIMENSION image_width;	/* input image width */
 -  JDIMENSION image_height;	/* input image height */
 -  int input_components;		/* # of color components in input image */
 -  J_COLOR_SPACE in_color_space;	/* colorspace of input image */
 -
 -  double input_gamma;		/* image gamma of input image */
 -
 -  /* Compression parameters --- these fields must be set before calling
 -   * jpeg_start_compress().  We recommend calling jpeg_set_defaults() to
 -   * initialize everything to reasonable defaults, then changing anything
 -   * the application specifically wants to change.  That way you won't get
 -   * burnt when new parameters are added.  Also note that there are several
 -   * helper routines to simplify changing parameters.
 -   */
 -
 -  int data_precision;		/* bits of precision in image data */
 -
 -  int num_components;		/* # of color components in JPEG image */
 -  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
 -
 -  jpeg_component_info * comp_info;
 -  /* comp_info[i] describes component that appears i'th in SOF */
 -  
 -  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
 -  /* ptrs to coefficient quantization tables, or NULL if not defined */
 -  
 -  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
 -  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
 -  /* ptrs to Huffman coding tables, or NULL if not defined */
 -  
 -  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
 -  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
 -  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
 -
 -  int num_scans;		/* # of entries in scan_info array */
 -  const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
 -  /* The default value of scan_info is NULL, which causes a single-scan
 -   * sequential JPEG file to be emitted.  To create a multi-scan file,
 -   * set num_scans and scan_info to point to an array of scan definitions.
 -   */
 -
 -  boolean raw_data_in;		/* TRUE=caller supplies downsampled data */
 -  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
 -  boolean optimize_coding;	/* TRUE=optimize entropy encoding parms */
 -  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 -  int smoothing_factor;		/* 1..100, or 0 for no input smoothing */
 -  J_DCT_METHOD dct_method;	/* DCT algorithm selector */
 -
 -  /* The restart interval can be specified in absolute MCUs by setting
 -   * restart_interval, or in MCU rows by setting restart_in_rows
 -   * (in which case the correct restart_interval will be figured
 -   * for each scan).
 -   */
 -  unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
 -  int restart_in_rows;		/* if > 0, MCU rows per restart interval */
 -
 -  /* Parameters controlling emission of special markers. */
 -
 -  boolean write_JFIF_header;	/* should a JFIF marker be written? */
 -  /* 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 */
 -  /* ratio is defined by X_density/Y_density even when density_unit=0. */
 -  UINT8 density_unit;		/* JFIF code for pixel size units */
 -  UINT16 X_density;		/* Horizontal pixel density */
 -  UINT16 Y_density;		/* Vertical pixel density */
 -  boolean write_Adobe_marker;	/* should an Adobe marker be written? */
 -  
 -  /* State variable: index of next scanline to be written to
 -   * jpeg_write_scanlines().  Application may use this to control its
 -   * processing loop, e.g., "while (next_scanline < image_height)".
 -   */
 -
 -  JDIMENSION next_scanline;	/* 0 .. image_height-1  */
 -
 -  /* Remaining fields are known throughout compressor, but generally
 -   * should not be touched by a surrounding application.
 -   */
 -
 -  /*
 -   * These fields are computed during compression startup
 -   */
 -  boolean progressive_mode;	/* TRUE if scan script uses progressive mode */
 -  int max_h_samp_factor;	/* largest h_samp_factor */
 -  int max_v_samp_factor;	/* largest v_samp_factor */
 -
 -  JDIMENSION total_iMCU_rows;	/* # of iMCU rows to be input to coef ctlr */
 -  /* The coefficient controller receives data in units of MCU rows as defined
 -   * for fully interleaved scans (whether the JPEG file is interleaved or not).
 -   * There are v_samp_factor * DCTSIZE sample rows of each component in an
 -   * "iMCU" (interleaved MCU) row.
 -   */
 -  
 -  /*
 -   * These fields are valid during any one scan.
 -   * They describe the components and MCUs actually appearing in the scan.
 -   */
 -  int comps_in_scan;		/* # of JPEG components in this scan */
 -  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
 -  /* *cur_comp_info[i] describes component that appears i'th in SOS */
 -  
 -  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
 -  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
 -  
 -  int blocks_in_MCU;		/* # of DCT blocks per MCU */
 -  int MCU_membership[C_MAX_BLOCKS_IN_MCU];
 -  /* MCU_membership[i] is index in cur_comp_info of component owning */
 -  /* i'th block in an MCU */
 -
 -  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
 -
 -  /*
 -   * Links to compression subobjects (methods and private variables of modules)
 -   */
 -  struct jpeg_comp_master * master;
 -  struct jpeg_c_main_controller * main;
 -  struct jpeg_c_prep_controller * prep;
 -  struct jpeg_c_coef_controller * coef;
 -  struct jpeg_marker_writer * marker;
 -  struct jpeg_color_converter * cconvert;
 -  struct jpeg_downsampler * downsample;
 -  struct jpeg_forward_dct * fdct;
 -  struct jpeg_entropy_encoder * entropy;
 -};
 -
 -
 -/* Master record for a decompression instance */
 -
 -struct jpeg_decompress_struct {
 -  jpeg_common_fields;		/* Fields shared with jpeg_compress_struct */
 -
 -  /* Source of compressed data */
 -  struct jpeg_source_mgr * src;
 -
 -  /* Basic description of image --- filled in by jpeg_read_header(). */
 -  /* Application may inspect these values to decide how to process image. */
 -
 -  JDIMENSION image_width;	/* nominal image width (from SOF marker) */
 -  JDIMENSION image_height;	/* nominal image height */
 -  int num_components;		/* # of color components in JPEG image */
 -  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
 -
 -  /* Decompression processing parameters --- these fields must be set before
 -   * calling jpeg_start_decompress().  Note that jpeg_read_header() initializes
 -   * them to default values.
 -   */
 -
 -  J_COLOR_SPACE out_color_space; /* colorspace for output */
 -
 -  unsigned int scale_num, scale_denom; /* fraction by which to scale image */
 -
 -  double output_gamma;		/* image gamma wanted in output */
 -
 -  boolean buffered_image;	/* TRUE=multiple output passes */
 -  boolean raw_data_out;		/* TRUE=downsampled data wanted */
 -
 -  J_DCT_METHOD dct_method;	/* IDCT algorithm selector */
 -  boolean do_fancy_upsampling;	/* TRUE=apply fancy upsampling */
 -  boolean do_block_smoothing;	/* TRUE=apply interblock smoothing */
 -
 -  boolean quantize_colors;	/* TRUE=colormapped output wanted */
 -  /* the following are ignored if not quantize_colors: */
 -  J_DITHER_MODE dither_mode;	/* type of color dithering to use */
 -  boolean two_pass_quantize;	/* TRUE=use two-pass color quantization */
 -  int desired_number_of_colors;	/* max # colors to use in created colormap */
 -  /* these are significant only in buffered-image mode: */
 -  boolean enable_1pass_quant;	/* enable future use of 1-pass quantizer */
 -  boolean enable_external_quant;/* enable future use of external colormap */
 -  boolean enable_2pass_quant;	/* enable future use of 2-pass quantizer */
 -
 -  /* Description of actual output image that will be returned to application.
 -   * These fields are computed by jpeg_start_decompress().
 -   * You can also use jpeg_calc_output_dimensions() to determine these values
 -   * in advance of calling jpeg_start_decompress().
 -   */
 -
 -  JDIMENSION output_width;	/* scaled image width */
 -  JDIMENSION output_height;	/* scaled image height */
 -  int out_color_components;	/* # of color components in out_color_space */
 -  int output_components;	/* # of color components returned */
 -  /* output_components is 1 (a colormap index) when quantizing colors;
 -   * otherwise it equals out_color_components.
 -   */
 -  int rec_outbuf_height;	/* min recommended height of scanline buffer */
 -  /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
 -   * high, space and time will be wasted due to unnecessary data copying.
 -   * Usually rec_outbuf_height will be 1 or 2, at most 4.
 -   */
 -
 -  /* When quantizing colors, the output colormap is described by these fields.
 -   * The application can supply a colormap by setting colormap non-NULL before
 -   * calling jpeg_start_decompress; otherwise a colormap is created during
 -   * jpeg_start_decompress or jpeg_start_output.
 -   * The map has out_color_components rows and actual_number_of_colors columns.
 -   */
 -  int actual_number_of_colors;	/* number of entries in use */
 -  JSAMPARRAY colormap;		/* The color map as a 2-D pixel array */
 -
 -  /* State variables: these variables indicate the progress of decompression.
 -   * The application may examine these but must not modify them.
 -   */
 -
 -  /* Row index of next scanline to be read from jpeg_read_scanlines().
 -   * Application may use this to control its processing loop, e.g.,
 -   * "while (output_scanline < output_height)".
 -   */
 -  JDIMENSION output_scanline;	/* 0 .. output_height-1  */
 -
 -  /* Current input scan number and number of iMCU rows completed in scan.
 -   * These indicate the progress of the decompressor input side.
 -   */
 -  int input_scan_number;	/* Number of SOS markers seen so far */
 -  JDIMENSION input_iMCU_row;	/* Number of iMCU rows completed */
 -
 -  /* The "output scan number" is the notional scan being displayed by the
 -   * output side.  The decompressor will not allow output scan/row number
 -   * to get ahead of input scan/row, but it can fall arbitrarily far behind.
 -   */
 -  int output_scan_number;	/* Nominal scan number being displayed */
 -  JDIMENSION output_iMCU_row;	/* Number of iMCU rows read */
 -
 -  /* Current progression status.  coef_bits[c][i] indicates the precision
 -   * with which component c's DCT coefficient i (in zigzag order) is known.
 -   * It is -1 when no data has yet been received, otherwise it is the point
 -   * transform (shift) value for the most recent scan of the coefficient
 -   * (thus, 0 at completion of the progression).
 -   * This pointer is NULL when reading a non-progressive file.
 -   */
 -  int (*coef_bits)[DCTSIZE2];	/* -1 or current Al value for each coef */
 -
 -  /* Internal JPEG parameters --- the application usually need not look at
 -   * these fields.  Note that the decompressor output side may not use
 -   * any parameters that can change between scans.
 -   */
 -
 -  /* Quantization and Huffman tables are carried forward across input
 -   * datastreams when processing abbreviated JPEG datastreams.
 -   */
 -
 -  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
 -  /* ptrs to coefficient quantization tables, or NULL if not defined */
 -
 -  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
 -  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
 -  /* ptrs to Huffman coding tables, or NULL if not defined */
 -
 -  /* These parameters are never carried across datastreams, since they
 -   * are given in SOF/SOS markers or defined to be reset by SOI.
 -   */
 -
 -  int data_precision;		/* bits of precision in image data */
 -
 -  jpeg_component_info * comp_info;
 -  /* comp_info[i] describes component that appears i'th in SOF */
 -
 -  boolean progressive_mode;	/* TRUE if SOFn specifies progressive mode */
 -  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */
 -
 -  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
 -  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
 -  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
 -
 -  unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
 -
 -  /* These fields record data obtained from optional markers recognized by
 -   * the JPEG library.
 -   */
 -  boolean saw_JFIF_marker;	/* TRUE iff a JFIF APP0 marker was found */
 -  /* Data copied from JFIF marker: */
 -  UINT8 density_unit;		/* JFIF code for pixel size units */
 -  UINT16 X_density;		/* Horizontal pixel density */
 -  UINT16 Y_density;		/* Vertical pixel density */
 -  boolean saw_Adobe_marker;	/* TRUE iff an Adobe APP14 marker was found */
 -  UINT8 Adobe_transform;	/* Color transform code from Adobe marker */
 -
 -  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 -
 -  /* Remaining fields are known throughout decompressor, but generally
 -   * should not be touched by a surrounding application.
 -   */
 -
 -  /*
 -   * These fields are computed during decompression startup
 -   */
 -  int max_h_samp_factor;	/* largest h_samp_factor */
 -  int max_v_samp_factor;	/* largest v_samp_factor */
 -
 -  int min_DCT_scaled_size;	/* smallest DCT_scaled_size of any component */
 -
 -  JDIMENSION total_iMCU_rows;	/* # of iMCU rows in image */
 -  /* The coefficient controller's input and output progress is measured in
 -   * units of "iMCU" (interleaved MCU) rows.  These are the same as MCU rows
 -   * in fully interleaved JPEG scans, but are used whether the scan is
 -   * interleaved or not.  We define an iMCU row as v_samp_factor DCT block
 -   * rows of each component.  Therefore, the IDCT output contains
 -   * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
 -   */
 -
 -  JSAMPLE * sample_range_limit; /* table for fast range-limiting */
 -
 -  /*
 -   * These fields are valid during any one scan.
 -   * They describe the components and MCUs actually appearing in the scan.
 -   * Note that the decompressor output side must not use these fields.
 -   */
 -  int comps_in_scan;		/* # of JPEG components in this scan */
 -  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
 -  /* *cur_comp_info[i] describes component that appears i'th in SOS */
 -
 -  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */
 -  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */
 -
 -  int blocks_in_MCU;		/* # of DCT blocks per MCU */
 -  int MCU_membership[D_MAX_BLOCKS_IN_MCU];
 -  /* MCU_membership[i] is index in cur_comp_info of component owning */
 -  /* i'th block in an MCU */
 -
 -  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */
 -
 -  /* This field is shared between entropy decoder and marker parser.
 -   * It is either zero or the code of a JPEG marker that has been
 -   * read from the data source, but has not yet been processed.
 -   */
 -  int unread_marker;
 -
 -  /*
 -   * Links to decompression subobjects (methods, private variables of modules)
 -   */
 -  struct jpeg_decomp_master * master;
 -  struct jpeg_d_main_controller * main;
 -  struct jpeg_d_coef_controller * coef;
 -  struct jpeg_d_post_controller * post;
 -  struct jpeg_input_controller * inputctl;
 -  struct jpeg_marker_reader * marker;
 -  struct jpeg_entropy_decoder * entropy;
 -  struct jpeg_inverse_dct * idct;
 -  struct jpeg_upsampler * upsample;
 -  struct jpeg_color_deconverter * cconvert;
 -  struct jpeg_color_quantizer * cquantize;
 -};
 -
 -
 -/* "Object" declarations for JPEG modules that may be supplied or called
 - * directly by the surrounding application.
 - * As with all objects in the JPEG library, these structs only define the
 - * publicly visible methods and state variables of a module.  Additional
 - * private fields may exist after the public ones.
 - */
 -
 -
 -/* Error handler object */
 -
 -struct jpeg_error_mgr {
 -  /* Error exit handler: does not return to caller */
 -  JMETHOD(void, error_exit, (j_common_ptr cinfo));
 -  /* Conditionally emit a trace or warning message */
 -  JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
 -  /* Routine that actually outputs a trace or error message */
 -  JMETHOD(void, output_message, (j_common_ptr cinfo));
 -  /* Format a message string for the most recent JPEG error or message */
 -  JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
 -#define JMSG_LENGTH_MAX  200	/* recommended size of format_message buffer */
 -  /* Reset error state variables at start of a new image */
 -  JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
 -  
 -  /* The message ID code and any parameters are saved here.
 -   * A message can have one string parameter or up to 8 int parameters.
 -   */
 -  int msg_code;
 -#define JMSG_STR_PARM_MAX  80
 -  union {
 -    int i[8];
 -    char s[JMSG_STR_PARM_MAX];
 -  } msg_parm;
 -  
 -  /* Standard state variables for error facility */
 -  
 -  int trace_level;		/* max msg_level that will be displayed */
 -  
 -  /* For recoverable corrupt-data errors, we emit a warning message,
 -   * but keep going unless emit_message chooses to abort.  emit_message
 -   * should count warnings in num_warnings.  The surrounding application
 -   * can check for bad data by seeing if num_warnings is nonzero at the
 -   * end of processing.
 -   */
 -  long num_warnings;		/* number of corrupt-data warnings */
 -
 -  /* These fields point to the table(s) of error message strings.
 -   * An application can change the table pointer to switch to a different
 -   * message list (typically, to change the language in which errors are
 -   * reported).  Some applications may wish to add additional error codes
 -   * that will be handled by the JPEG library error mechanism; the second
 -   * table pointer is used for this purpose.
 -   *
 -   * First table includes all errors generated by JPEG library itself.
 -   * Error code 0 is reserved for a "no such error string" message.
 -   */
 -  const char * const * jpeg_message_table; /* Library errors */
 -  int last_jpeg_message;    /* Table contains strings 0..last_jpeg_message */
 -  /* Second table can be added by application (see cjpeg/djpeg for example).
 -   * It contains strings numbered first_addon_message..last_addon_message.
 -   */
 -  const char * const * addon_message_table; /* Non-library errors */
 -  int first_addon_message;	/* code for first string in addon table */
 -  int last_addon_message;	/* code for last string in addon table */
 -};
 -
 -
 -/* Progress monitor object */
 -
 -struct jpeg_progress_mgr {
 -  JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
 -
 -  long pass_counter;		/* work units completed in this pass */
 -  long pass_limit;		/* total number of work units in this pass */
 -  int completed_passes;		/* passes completed so far */
 -  int total_passes;		/* total number of passes expected */
 -};
 -
 -
 -/* Data destination object for compression */
 -
 -struct jpeg_destination_mgr {
 -  JOCTET * next_output_byte;	/* => next byte to write in buffer */
 -  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */
 -
 -  JMETHOD(void, init_destination, (j_compress_ptr cinfo));
 -  JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
 -  JMETHOD(void, term_destination, (j_compress_ptr cinfo));
 -};
 -
 -
 -/* Data source object for decompression */
 -
 -struct jpeg_source_mgr {
 -  const JOCTET * next_input_byte; /* => next byte to read from buffer */
 -  size_t bytes_in_buffer;	/* # of bytes remaining in buffer */
 -
 -  JMETHOD(void, init_source, (j_decompress_ptr cinfo));
 -  JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
 -  JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
 -  JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
 -  JMETHOD(void, term_source, (j_decompress_ptr cinfo));
 -};
 -
 -
 -/* Memory manager object.
 - * Allocates "small" objects (a few K total), "large" objects (tens of K),
 - * and "really big" objects (virtual arrays with backing store if needed).
 - * The memory manager does not allow individual objects to be freed; rather,
 - * each created object is assigned to a pool, and whole pools can be freed
 - * at once.  This is faster and more convenient than remembering exactly what
 - * to free, especially where malloc()/free() are not too speedy.
 - * NB: alloc routines never return NULL.  They exit to error_exit if not
 - * successful.
 - */
 -
 -#define JPOOL_PERMANENT	0	/* lasts until master record is destroyed */
 -#define JPOOL_IMAGE	1	/* lasts until done with image/datastream */
 -#define JPOOL_NUMPOOLS	2
 -
 -typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
 -typedef struct jvirt_barray_control * jvirt_barray_ptr;
 -
 -
 -struct jpeg_memory_mgr {
 -  /* Method pointers */
 -  JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
 -				size_t sizeofobject));
 -  JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
 -				     size_t sizeofobject));
 -  JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
 -				     JDIMENSION samplesperrow,
 -				     JDIMENSION numrows));
 -  JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
 -				      JDIMENSION blocksperrow,
 -				      JDIMENSION numrows));
 -  JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
 -						  int pool_id,
 -						  boolean pre_zero,
 -						  JDIMENSION samplesperrow,
 -						  JDIMENSION numrows,
 -						  JDIMENSION maxaccess));
 -  JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
 -						  int pool_id,
 -						  boolean pre_zero,
 -						  JDIMENSION blocksperrow,
 -						  JDIMENSION numrows,
 -						  JDIMENSION maxaccess));
 -  JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
 -  JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
 -					   jvirt_sarray_ptr ptr,
 -					   JDIMENSION start_row,
 -					   JDIMENSION num_rows,
 -					   boolean writable));
 -  JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
 -					    jvirt_barray_ptr ptr,
 -					    JDIMENSION start_row,
 -					    JDIMENSION num_rows,
 -					    boolean writable));
 -  JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
 -  JMETHOD(void, self_destruct, (j_common_ptr cinfo));
 -
 -  /* Limit on memory allocation for this JPEG object.  (Note that this is
 -   * merely advisory, not a guaranteed maximum; it only affects the space
 -   * used for virtual-array buffers.)  May be changed by outer application
 -   * after creating the JPEG object.
 -   */
 -  long max_memory_to_use;
 -};
 -
 -
 -/* Routine signature for application-supplied marker processing methods.
 - * Need not pass marker code since it is stored in cinfo->unread_marker.
 - */
 -typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
 -
 -
 -/* Declarations for routines called by application.
 - * The JPP macro hides prototype parameters from compilers that can't cope.
 - * Note JPP requires double parentheses.
 - */
 -
 -#ifdef HAVE_PROTOTYPES
 -#define JPP(arglist)	arglist
 -#else
 -#define JPP(arglist)	()
 -#endif
 -
 -
 -/* Short forms of external names for systems with brain-damaged linkers.
 - * We shorten external names to be unique in the first six letters, which
 - * is good enough for all known systems.
 - * (If your compiler itself needs names to be unique in less than 15 
 - * characters, you are out of luck.  Get a better compiler.)
 - */
 -
 -#ifdef NEED_SHORT_EXTERNAL_NAMES
 -#define jpeg_std_error		jStdError
 -#define jpeg_create_compress	jCreaCompress
 -#define jpeg_create_decompress	jCreaDecompress
 -#define jpeg_destroy_compress	jDestCompress
 -#define jpeg_destroy_decompress	jDestDecompress
 -#define jpeg_stdio_dest		jStdDest
 -#define jpeg_stdio_src		jStdSrc
 -#define jpeg_set_defaults	jSetDefaults
 -#define jpeg_set_colorspace	jSetColorspace
 -#define jpeg_default_colorspace	jDefColorspace
 -#define jpeg_set_quality	jSetQuality
 -#define jpeg_set_linear_quality	jSetLQuality
 -#define jpeg_add_quant_table	jAddQuantTable
 -#define jpeg_quality_scaling	jQualityScaling
 -#define jpeg_simple_progression	jSimProgress
 -#define jpeg_suppress_tables	jSuppressTables
 -#define jpeg_alloc_quant_table	jAlcQTable
 -#define jpeg_alloc_huff_table	jAlcHTable
 -#define jpeg_start_compress	jStrtCompress
 -#define jpeg_write_scanlines	jWrtScanlines
 -#define jpeg_finish_compress	jFinCompress
 -#define jpeg_write_raw_data	jWrtRawData
 -#define jpeg_write_marker	jWrtMarker
 -#define jpeg_write_tables	jWrtTables
 -#define jpeg_read_header	jReadHeader
 -#define jpeg_start_decompress	jStrtDecompress
 -#define jpeg_read_scanlines	jReadScanlines
 -#define jpeg_finish_decompress	jFinDecompress
 -#define jpeg_read_raw_data	jReadRawData
 -#define jpeg_has_multiple_scans	jHasMultScn
 -#define jpeg_start_output	jStrtOutput
 -#define jpeg_finish_output	jFinOutput
 -#define jpeg_input_complete	jInComplete
 -#define jpeg_new_colormap	jNewCMap
 -#define jpeg_consume_input	jConsumeInput
 -#define jpeg_calc_output_dimensions	jCalcDimensions
 -#define jpeg_set_marker_processor	jSetMarker
 -#define jpeg_read_coefficients	jReadCoefs
 -#define jpeg_write_coefficients	jWrtCoefs
 -#define jpeg_copy_critical_parameters	jCopyCrit
 -#define jpeg_abort_compress	jAbrtCompress
 -#define jpeg_abort_decompress	jAbrtDecompress
 -#define jpeg_abort		jAbort
 -#define jpeg_destroy		jDestroy
 -#define jpeg_resync_to_restart	jResyncRestart
 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
 -
 -
 -/* 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));
 -
 -/* 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, unsigned char *infile));
 -
 -/* Default parameter setup for compression */
 -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));
 -
 -/* 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));
 -
 -/* 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));
 -
 -/* 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));
 -
 -/* Alternate compression function: just write an abbreviated table file */
 -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));
 -/* 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 */
 -#define JPEG_HEADER_TABLES_ONLY	2 /* Found valid table-specs-only datastream */
 -/* If you pass require_image = TRUE (normal case), you need not check for
 - * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
 - * JPEG_SUSPENDED is only possible if you use a data source module that can
 - * give a suspension return (the stdio source module doesn't).
 - */
 -
 -/* 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));
 -
 -/* 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));
 -
 -/* 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));
 -/* 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 */
 -#define JPEG_REACHED_EOI	2 /* Reached end of image */
 -#define JPEG_ROW_COMPLETED	3 /* Completed one iMCU row */
 -#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));
 -
 -/* 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));
 -
 -/* 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));
 -
 -/* If you choose to abort compression or decompression before completing
 - * jpeg_finish_(de)compress, then you need to clean up to release memory,
 - * temporary files, etc.  You can just call jpeg_destroy_(de)compress
 - * 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));
 -
 -/* 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));
 -
 -/* Default restart-marker-resync procedure for use by data source modules */
 -EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
 -					   int desired));
 -
 -
 -/* These marker codes are exported since applications and data source modules
 - * are likely to want to use them.
 - */
 -
 -#define JPEG_RST0	0xD0	/* RST0 marker code */
 -#define JPEG_EOI	0xD9	/* EOI marker code */
 -#define JPEG_APP0	0xE0	/* APP0 marker code */
 -#define JPEG_COM	0xFE	/* COM marker code */
 -
 -
 -/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
 - * for structure definitions that are never filled in, keep it quiet by
 - * supplying dummy definitions for the various substructures.
 - */
 -
 -#ifdef INCOMPLETE_TYPES_BROKEN
 -#ifndef JPEG_INTERNALS		/* will be defined in jpegint.h */
 -struct jvirt_sarray_control { long dummy; };
 -struct jvirt_barray_control { long dummy; };
 -struct jpeg_comp_master { long dummy; };
 -struct jpeg_c_main_controller { long dummy; };
 -struct jpeg_c_prep_controller { long dummy; };
 -struct jpeg_c_coef_controller { long dummy; };
 -struct jpeg_marker_writer { long dummy; };
 -struct jpeg_color_converter { long dummy; };
 -struct jpeg_downsampler { long dummy; };
 -struct jpeg_forward_dct { long dummy; };
 -struct jpeg_entropy_encoder { long dummy; };
 -struct jpeg_decomp_master { long dummy; };
 -struct jpeg_d_main_controller { long dummy; };
 -struct jpeg_d_coef_controller { long dummy; };
 -struct jpeg_d_post_controller { long dummy; };
 -struct jpeg_input_controller { long dummy; };
 -struct jpeg_marker_reader { long dummy; };
 -struct jpeg_entropy_decoder { long dummy; };
 -struct jpeg_inverse_dct { long dummy; };
 -struct jpeg_upsampler { long dummy; };
 -struct jpeg_color_deconverter { long dummy; };
 -struct jpeg_color_quantizer { long dummy; };
 -#endif /* JPEG_INTERNALS */
 -#endif /* INCOMPLETE_TYPES_BROKEN */
 -
 -
 -/*
 - * The JPEG library modules define JPEG_INTERNALS before including this file.
 - * The internal structure declarations are read only when that is true.
 - * Applications using the library should not include jpegint.h, but may wish
 - * to include jerror.h.
 - */
 -
 -#ifdef JPEG_INTERNALS
 -#include "jpegint.h"		/* fetch private declarations */
 -#include "jerror.h"		/* fetch error codes too */
 -#endif
 -
 -#ifdef __cplusplus
 -}
 -#endif
 -
 -#endif /* JPEGLIB_H */
 +/* + * jpeglib.h + * + * Copyright (C) 1991-1995, 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 defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +#ifdef __MACOS__ + +// JDC: stuff to make mac version compile +#define	boolean	qboolean +#define	register +#define	INT32	int + +#endif + +// rad additions +// 11.29.99 + +//#include "cmdlib.h" +#ifdef _WIN32 +#include "windows.h" +#include "stdio.h" +#endif + +#ifndef INT32 +#define	INT32	int +#endif + +extern void LoadJPGBuff(unsigned char *fbuffer, unsigned char **pic, int *width, int *height ); +// rad end + + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up.  jconfig.h can be + * generated automatically for many systems.  jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */ +#include "jpeg6/jconfig.h"		/* widely used configuration options */ +#endif +#include "jpeg6/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 */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE		    8	/* The basic DCT block is 8x8 samples */ +#define DCTSIZE2	    64	/* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS      4	/* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS       4	/* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS      16	/* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN   4	/* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR     4	/* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it.  We even let you do this from the jconfig.h file.  However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU   10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU   10 /* decompressor's limit on blocks per MCU */ +#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. + */ + +typedef JSAMPLE FAR *JSAMPROW;	/* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY;	/* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE;	/* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2];	/* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW;	/* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY;		/* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE;	/* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR;	/* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* 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. +   */ +  UINT16 quantval[DCTSIZE2];	/* quantization step for each coefficient */ +  /* This field is used only during compression.  It's initialized FALSE when +   * the table is created, and set TRUE when it's been output to the file. +   * You could suppress output of a table by setting this to TRUE. +   * (See jpeg_suppress_tables for an example.) +   */ +  boolean sent_table;		/* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { +  /* These two fields directly represent the contents of a JPEG DHT marker */ +  UINT8 bits[17];		/* bits[k] = # of symbols with codes of */ +				/* length k bits; bits[0] is unused */ +  UINT8 huffval[256];		/* The symbols, in order of incr code length */ +  /* This field is used only during compression.  It's initialized FALSE when +   * the table is created, and set TRUE when it's been output to the file. +   * You could suppress output of a table by setting this to TRUE. +   * (See jpeg_suppress_tables for an example.) +   */ +  boolean sent_table;		/* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { +  /* These values are fixed over the whole image. */ +  /* For compression, they must be supplied by parameter setup; */ +  /* for decompression, they are read from the SOF marker. */ +  int component_id;		/* identifier for this component (0..255) */ +  int component_index;		/* its index in SOF or cinfo->comp_info[] */ +  int h_samp_factor;		/* horizontal sampling factor (1..4) */ +  int v_samp_factor;		/* vertical sampling factor (1..4) */ +  int quant_tbl_no;		/* quantization table selector (0..3) */ +  /* These values may vary between scans. */ +  /* For compression, they must be supplied by parameter setup; */ +  /* for decompression, they are read from the SOS marker. */ +  /* The decompressor output side may not use these variables. */ +  int dc_tbl_no;		/* DC entropy table selector (0..3) */ +  int ac_tbl_no;		/* AC entropy table selector (0..3) */ +   +  /* Remaining fields should be treated as private by applications. */ +   +  /* These values are computed during compression or decompression startup: */ +  /* Component's size in DCT blocks. +   * Any dummy blocks added to complete an MCU are not counted; therefore +   * these values do not depend on whether a scan is interleaved or not. +   */ +  JDIMENSION width_in_blocks; +  JDIMENSION height_in_blocks; +  /* Size of a DCT block in samples.  Always DCTSIZE for compression. +   * For decompression this is the size of the output from one DCT block, +   * reflecting any scaling we choose to apply during the IDCT step. +   * Values of 1,2,4,8 are likely to be supported.  Note that different +   * components may receive different IDCT scalings. +   */ +  int DCT_scaled_size; +  /* The downsampled dimensions are the component's actual, unpadded number +   * of samples at the main buffer (preprocessing/compression interface), thus +   * downsampled_width = ceil(image_width * Hi/Hmax) +   * and similarly for height.  For decompression, IDCT scaling is included, so +   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) +   */ +  JDIMENSION downsampled_width;	 /* actual width in samples */ +  JDIMENSION downsampled_height; /* actual height in samples */ +  /* This flag is used only for decompression.  In cases where some of the +   * components will be ignored (eg grayscale output from YCbCr image), +   * we can skip most computations for the unused components. +   */ +  boolean component_needed;	/* do we need the value of this component? */ + +  /* These values are computed before starting a scan of the component. */ +  /* The decompressor output side may not use these variables. */ +  int MCU_width;		/* number of blocks per MCU, horizontally */ +  int MCU_height;		/* number of blocks per MCU, vertically */ +  int MCU_blocks;		/* MCU_width * MCU_height */ +  int MCU_sample_width;		/* MCU width in samples, MCU_width*DCT_scaled_size */ +  int last_col_width;		/* # of non-dummy blocks across in last MCU */ +  int last_row_height;		/* # of non-dummy blocks down in last MCU */ + +  /* 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. +   */ +  JQUANT_TBL * quant_table; + +  /* Private per-component storage for DCT or IDCT subsystem. */ +  void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { +  int comps_in_scan;		/* number of components encoded in this scan */ +  int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ +  int Ss, Se;			/* progressive JPEG spectral selection parms */ +  int Ah, Al;			/* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + + +/* Known color spaces. */ + +typedef enum { +	JCS_UNKNOWN,		/* error/unspecified */ +	JCS_GRAYSCALE,		/* monochrome */ +	JCS_RGB,		/* red/green/blue */ +	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */ +	JCS_CMYK,		/* C/M/Y/K */ +	JCS_YCCK		/* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { +	JDCT_ISLOW,		/* slow but accurate integer algorithm */ +	JDCT_IFAST,		/* faster, less accurate integer method */ +	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT		/* may be overridden in jconfig.h */ +#define JDCT_DEFAULT  JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST		/* may be overridden in jconfig.h */ +#define JDCT_FASTEST  JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { +	JDITHER_NONE,		/* no dithering */ +	JDITHER_ORDERED,	/* simple ordered dither */ +	JDITHER_FS		/* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ +  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 */ + +/* 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 + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { +  jpeg_common_fields;		/* Fields common to both master struct types */ +  /* Additional fields follow in an actual jpeg_compress_struct or +   * jpeg_decompress_struct.  All three structs must agree on these +   * initial fields!  (This would be a lot cleaner in C++.) +   */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { +  jpeg_common_fields;		/* Fields shared with jpeg_decompress_struct */ + +  /* Destination for compressed data */ +  struct jpeg_destination_mgr * dest; + +  /* Description of source image --- these fields must be filled in by +   * outer application before starting compression.  in_color_space must +   * be correct before you can even call jpeg_set_defaults(). +   */ + +  JDIMENSION image_width;	/* input image width */ +  JDIMENSION image_height;	/* input image height */ +  int input_components;		/* # of color components in input image */ +  J_COLOR_SPACE in_color_space;	/* colorspace of input image */ + +  double input_gamma;		/* image gamma of input image */ + +  /* Compression parameters --- these fields must be set before calling +   * jpeg_start_compress().  We recommend calling jpeg_set_defaults() to +   * initialize everything to reasonable defaults, then changing anything +   * the application specifically wants to change.  That way you won't get +   * burnt when new parameters are added.  Also note that there are several +   * helper routines to simplify changing parameters. +   */ + +  int data_precision;		/* bits of precision in image data */ + +  int num_components;		/* # of color components in JPEG image */ +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + +  jpeg_component_info * comp_info; +  /* comp_info[i] describes component that appears i'th in SOF */ +   +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; +  /* ptrs to coefficient quantization tables, or NULL if not defined */ +   +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; +  /* ptrs to Huffman coding tables, or NULL if not defined */ +   +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + +  int num_scans;		/* # of entries in scan_info array */ +  const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ +  /* The default value of scan_info is NULL, which causes a single-scan +   * sequential JPEG file to be emitted.  To create a multi-scan file, +   * set num_scans and scan_info to point to an array of scan definitions. +   */ + +  boolean raw_data_in;		/* TRUE=caller supplies downsampled data */ +  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */ +  boolean optimize_coding;	/* TRUE=optimize entropy encoding parms */ +  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */ +  int smoothing_factor;		/* 1..100, or 0 for no input smoothing */ +  J_DCT_METHOD dct_method;	/* DCT algorithm selector */ + +  /* The restart interval can be specified in absolute MCUs by setting +   * restart_interval, or in MCU rows by setting restart_in_rows +   * (in which case the correct restart_interval will be figured +   * for each scan). +   */ +  unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ +  int restart_in_rows;		/* if > 0, MCU rows per restart interval */ + +  /* Parameters controlling emission of special markers. */ + +  boolean write_JFIF_header;	/* should a JFIF marker be written? */ +  /* 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 */ +  /* ratio is defined by X_density/Y_density even when density_unit=0. */ +  UINT8 density_unit;		/* JFIF code for pixel size units */ +  UINT16 X_density;		/* Horizontal pixel density */ +  UINT16 Y_density;		/* Vertical pixel density */ +  boolean write_Adobe_marker;	/* should an Adobe marker be written? */ +   +  /* State variable: index of next scanline to be written to +   * jpeg_write_scanlines().  Application may use this to control its +   * processing loop, e.g., "while (next_scanline < image_height)". +   */ + +  JDIMENSION next_scanline;	/* 0 .. image_height-1  */ + +  /* Remaining fields are known throughout compressor, but generally +   * should not be touched by a surrounding application. +   */ + +  /* +   * These fields are computed during compression startup +   */ +  boolean progressive_mode;	/* TRUE if scan script uses progressive mode */ +  int max_h_samp_factor;	/* largest h_samp_factor */ +  int max_v_samp_factor;	/* largest v_samp_factor */ + +  JDIMENSION total_iMCU_rows;	/* # of iMCU rows to be input to coef ctlr */ +  /* The coefficient controller receives data in units of MCU rows as defined +   * for fully interleaved scans (whether the JPEG file is interleaved or not). +   * There are v_samp_factor * DCTSIZE sample rows of each component in an +   * "iMCU" (interleaved MCU) row. +   */ +   +  /* +   * These fields are valid during any one scan. +   * They describe the components and MCUs actually appearing in the scan. +   */ +  int comps_in_scan;		/* # of JPEG components in this scan */ +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; +  /* *cur_comp_info[i] describes component that appears i'th in SOS */ +   +  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */ +  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */ +   +  int blocks_in_MCU;		/* # of DCT blocks per MCU */ +  int MCU_membership[C_MAX_BLOCKS_IN_MCU]; +  /* MCU_membership[i] is index in cur_comp_info of component owning */ +  /* i'th block in an MCU */ + +  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */ + +  /* +   * Links to compression subobjects (methods and private variables of modules) +   */ +  struct jpeg_comp_master * master; +  struct jpeg_c_main_controller * main; +  struct jpeg_c_prep_controller * prep; +  struct jpeg_c_coef_controller * coef; +  struct jpeg_marker_writer * marker; +  struct jpeg_color_converter * cconvert; +  struct jpeg_downsampler * downsample; +  struct jpeg_forward_dct * fdct; +  struct jpeg_entropy_encoder * entropy; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { +  jpeg_common_fields;		/* Fields shared with jpeg_compress_struct */ + +  /* Source of compressed data */ +  struct jpeg_source_mgr * src; + +  /* Basic description of image --- filled in by jpeg_read_header(). */ +  /* Application may inspect these values to decide how to process image. */ + +  JDIMENSION image_width;	/* nominal image width (from SOF marker) */ +  JDIMENSION image_height;	/* nominal image height */ +  int num_components;		/* # of color components in JPEG image */ +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + +  /* Decompression processing parameters --- these fields must be set before +   * calling jpeg_start_decompress().  Note that jpeg_read_header() initializes +   * them to default values. +   */ + +  J_COLOR_SPACE out_color_space; /* colorspace for output */ + +  unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + +  double output_gamma;		/* image gamma wanted in output */ + +  boolean buffered_image;	/* TRUE=multiple output passes */ +  boolean raw_data_out;		/* TRUE=downsampled data wanted */ + +  J_DCT_METHOD dct_method;	/* IDCT algorithm selector */ +  boolean do_fancy_upsampling;	/* TRUE=apply fancy upsampling */ +  boolean do_block_smoothing;	/* TRUE=apply interblock smoothing */ + +  boolean quantize_colors;	/* TRUE=colormapped output wanted */ +  /* the following are ignored if not quantize_colors: */ +  J_DITHER_MODE dither_mode;	/* type of color dithering to use */ +  boolean two_pass_quantize;	/* TRUE=use two-pass color quantization */ +  int desired_number_of_colors;	/* max # colors to use in created colormap */ +  /* these are significant only in buffered-image mode: */ +  boolean enable_1pass_quant;	/* enable future use of 1-pass quantizer */ +  boolean enable_external_quant;/* enable future use of external colormap */ +  boolean enable_2pass_quant;	/* enable future use of 2-pass quantizer */ + +  /* Description of actual output image that will be returned to application. +   * These fields are computed by jpeg_start_decompress(). +   * You can also use jpeg_calc_output_dimensions() to determine these values +   * in advance of calling jpeg_start_decompress(). +   */ + +  JDIMENSION output_width;	/* scaled image width */ +  JDIMENSION output_height;	/* scaled image height */ +  int out_color_components;	/* # of color components in out_color_space */ +  int output_components;	/* # of color components returned */ +  /* output_components is 1 (a colormap index) when quantizing colors; +   * otherwise it equals out_color_components. +   */ +  int rec_outbuf_height;	/* min recommended height of scanline buffer */ +  /* If the buffer passed to jpeg_read_scanlines() is less than this many rows +   * high, space and time will be wasted due to unnecessary data copying. +   * Usually rec_outbuf_height will be 1 or 2, at most 4. +   */ + +  /* When quantizing colors, the output colormap is described by these fields. +   * The application can supply a colormap by setting colormap non-NULL before +   * calling jpeg_start_decompress; otherwise a colormap is created during +   * jpeg_start_decompress or jpeg_start_output. +   * The map has out_color_components rows and actual_number_of_colors columns. +   */ +  int actual_number_of_colors;	/* number of entries in use */ +  JSAMPARRAY colormap;		/* The color map as a 2-D pixel array */ + +  /* State variables: these variables indicate the progress of decompression. +   * The application may examine these but must not modify them. +   */ + +  /* Row index of next scanline to be read from jpeg_read_scanlines(). +   * Application may use this to control its processing loop, e.g., +   * "while (output_scanline < output_height)". +   */ +  JDIMENSION output_scanline;	/* 0 .. output_height-1  */ + +  /* Current input scan number and number of iMCU rows completed in scan. +   * These indicate the progress of the decompressor input side. +   */ +  int input_scan_number;	/* Number of SOS markers seen so far */ +  JDIMENSION input_iMCU_row;	/* Number of iMCU rows completed */ + +  /* The "output scan number" is the notional scan being displayed by the +   * output side.  The decompressor will not allow output scan/row number +   * to get ahead of input scan/row, but it can fall arbitrarily far behind. +   */ +  int output_scan_number;	/* Nominal scan number being displayed */ +  JDIMENSION output_iMCU_row;	/* Number of iMCU rows read */ + +  /* Current progression status.  coef_bits[c][i] indicates the precision +   * with which component c's DCT coefficient i (in zigzag order) is known. +   * It is -1 when no data has yet been received, otherwise it is the point +   * transform (shift) value for the most recent scan of the coefficient +   * (thus, 0 at completion of the progression). +   * This pointer is NULL when reading a non-progressive file. +   */ +  int (*coef_bits)[DCTSIZE2];	/* -1 or current Al value for each coef */ + +  /* Internal JPEG parameters --- the application usually need not look at +   * these fields.  Note that the decompressor output side may not use +   * any parameters that can change between scans. +   */ + +  /* Quantization and Huffman tables are carried forward across input +   * datastreams when processing abbreviated JPEG datastreams. +   */ + +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; +  /* ptrs to coefficient quantization tables, or NULL if not defined */ + +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; +  /* ptrs to Huffman coding tables, or NULL if not defined */ + +  /* These parameters are never carried across datastreams, since they +   * are given in SOF/SOS markers or defined to be reset by SOI. +   */ + +  int data_precision;		/* bits of precision in image data */ + +  jpeg_component_info * comp_info; +  /* comp_info[i] describes component that appears i'th in SOF */ + +  boolean progressive_mode;	/* TRUE if SOFn specifies progressive mode */ +  boolean arith_code;		/* TRUE=arithmetic coding, FALSE=Huffman */ + +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + +  unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + +  /* These fields record data obtained from optional markers recognized by +   * the JPEG library. +   */ +  boolean saw_JFIF_marker;	/* TRUE iff a JFIF APP0 marker was found */ +  /* Data copied from JFIF marker: */ +  UINT8 density_unit;		/* JFIF code for pixel size units */ +  UINT16 X_density;		/* Horizontal pixel density */ +  UINT16 Y_density;		/* Vertical pixel density */ +  boolean saw_Adobe_marker;	/* TRUE iff an Adobe APP14 marker was found */ +  UINT8 Adobe_transform;	/* Color transform code from Adobe marker */ + +  boolean CCIR601_sampling;	/* TRUE=first samples are cosited */ + +  /* Remaining fields are known throughout decompressor, but generally +   * should not be touched by a surrounding application. +   */ + +  /* +   * These fields are computed during decompression startup +   */ +  int max_h_samp_factor;	/* largest h_samp_factor */ +  int max_v_samp_factor;	/* largest v_samp_factor */ + +  int min_DCT_scaled_size;	/* smallest DCT_scaled_size of any component */ + +  JDIMENSION total_iMCU_rows;	/* # of iMCU rows in image */ +  /* The coefficient controller's input and output progress is measured in +   * units of "iMCU" (interleaved MCU) rows.  These are the same as MCU rows +   * in fully interleaved JPEG scans, but are used whether the scan is +   * interleaved or not.  We define an iMCU row as v_samp_factor DCT block +   * rows of each component.  Therefore, the IDCT output contains +   * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. +   */ + +  JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + +  /* +   * These fields are valid during any one scan. +   * They describe the components and MCUs actually appearing in the scan. +   * Note that the decompressor output side must not use these fields. +   */ +  int comps_in_scan;		/* # of JPEG components in this scan */ +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; +  /* *cur_comp_info[i] describes component that appears i'th in SOS */ + +  JDIMENSION MCUs_per_row;	/* # of MCUs across the image */ +  JDIMENSION MCU_rows_in_scan;	/* # of MCU rows in the image */ + +  int blocks_in_MCU;		/* # of DCT blocks per MCU */ +  int MCU_membership[D_MAX_BLOCKS_IN_MCU]; +  /* MCU_membership[i] is index in cur_comp_info of component owning */ +  /* i'th block in an MCU */ + +  int Ss, Se, Ah, Al;		/* progressive JPEG parameters for scan */ + +  /* This field is shared between entropy decoder and marker parser. +   * It is either zero or the code of a JPEG marker that has been +   * read from the data source, but has not yet been processed. +   */ +  int unread_marker; + +  /* +   * Links to decompression subobjects (methods, private variables of modules) +   */ +  struct jpeg_decomp_master * master; +  struct jpeg_d_main_controller * main; +  struct jpeg_d_coef_controller * coef; +  struct jpeg_d_post_controller * post; +  struct jpeg_input_controller * inputctl; +  struct jpeg_marker_reader * marker; +  struct jpeg_entropy_decoder * entropy; +  struct jpeg_inverse_dct * idct; +  struct jpeg_upsampler * upsample; +  struct jpeg_color_deconverter * cconvert; +  struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module.  Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { +  /* Error exit handler: does not return to caller */ +  JMETHOD(void, error_exit, (j_common_ptr cinfo)); +  /* Conditionally emit a trace or warning message */ +  JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); +  /* Routine that actually outputs a trace or error message */ +  JMETHOD(void, output_message, (j_common_ptr cinfo)); +  /* Format a message string for the most recent JPEG error or message */ +  JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX  200	/* recommended size of format_message buffer */ +  /* Reset error state variables at start of a new image */ +  JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); +   +  /* The message ID code and any parameters are saved here. +   * A message can have one string parameter or up to 8 int parameters. +   */ +  int msg_code; +#define JMSG_STR_PARM_MAX  80 +  union { +    int i[8]; +    char s[JMSG_STR_PARM_MAX]; +  } msg_parm; +   +  /* Standard state variables for error facility */ +   +  int trace_level;		/* max msg_level that will be displayed */ +   +  /* For recoverable corrupt-data errors, we emit a warning message, +   * but keep going unless emit_message chooses to abort.  emit_message +   * should count warnings in num_warnings.  The surrounding application +   * can check for bad data by seeing if num_warnings is nonzero at the +   * end of processing. +   */ +  long num_warnings;		/* number of corrupt-data warnings */ + +  /* These fields point to the table(s) of error message strings. +   * An application can change the table pointer to switch to a different +   * message list (typically, to change the language in which errors are +   * reported).  Some applications may wish to add additional error codes +   * that will be handled by the JPEG library error mechanism; the second +   * table pointer is used for this purpose. +   * +   * First table includes all errors generated by JPEG library itself. +   * Error code 0 is reserved for a "no such error string" message. +   */ +  const char * const * jpeg_message_table; /* Library errors */ +  int last_jpeg_message;    /* Table contains strings 0..last_jpeg_message */ +  /* Second table can be added by application (see cjpeg/djpeg for example). +   * It contains strings numbered first_addon_message..last_addon_message. +   */ +  const char * const * addon_message_table; /* Non-library errors */ +  int first_addon_message;	/* code for first string in addon table */ +  int last_addon_message;	/* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { +  JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + +  long pass_counter;		/* work units completed in this pass */ +  long pass_limit;		/* total number of work units in this pass */ +  int completed_passes;		/* passes completed so far */ +  int total_passes;		/* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { +  JOCTET * next_output_byte;	/* => next byte to write in buffer */ +  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */ + +  JMETHOD(void, init_destination, (j_compress_ptr cinfo)); +  JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); +  JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { +  const JOCTET * next_input_byte; /* => next byte to read from buffer */ +  size_t bytes_in_buffer;	/* # of bytes remaining in buffer */ + +  JMETHOD(void, init_source, (j_decompress_ptr cinfo)); +  JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); +  JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); +  JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); +  JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once.  This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL.  They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT	0	/* lasts until master record is destroyed */ +#define JPOOL_IMAGE	1	/* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS	2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { +  /* Method pointers */ +  JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, +				size_t sizeofobject)); +  JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, +				     size_t sizeofobject)); +  JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, +				     JDIMENSION samplesperrow, +				     JDIMENSION numrows)); +  JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, +				      JDIMENSION blocksperrow, +				      JDIMENSION numrows)); +  JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, +						  int pool_id, +						  boolean pre_zero, +						  JDIMENSION samplesperrow, +						  JDIMENSION numrows, +						  JDIMENSION maxaccess)); +  JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, +						  int pool_id, +						  boolean pre_zero, +						  JDIMENSION blocksperrow, +						  JDIMENSION numrows, +						  JDIMENSION maxaccess)); +  JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); +  JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, +					   jvirt_sarray_ptr ptr, +					   JDIMENSION start_row, +					   JDIMENSION num_rows, +					   boolean writable)); +  JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, +					    jvirt_barray_ptr ptr, +					    JDIMENSION start_row, +					    JDIMENSION num_rows, +					    boolean writable)); +  JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); +  JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + +  /* Limit on memory allocation for this JPEG object.  (Note that this is +   * merely advisory, not a guaranteed maximum; it only affects the space +   * used for virtual-array buffers.)  May be changed by outer application +   * after creating the JPEG object. +   */ +  long max_memory_to_use; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist)	arglist +#else +#define JPP(arglist)	() +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15  + * characters, you are out of luck.  Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error		jStdError +#define jpeg_create_compress	jCreaCompress +#define jpeg_create_decompress	jCreaDecompress +#define jpeg_destroy_compress	jDestCompress +#define jpeg_destroy_decompress	jDestDecompress +#define jpeg_stdio_dest		jStdDest +#define jpeg_stdio_src		jStdSrc +#define jpeg_set_defaults	jSetDefaults +#define jpeg_set_colorspace	jSetColorspace +#define jpeg_default_colorspace	jDefColorspace +#define jpeg_set_quality	jSetQuality +#define jpeg_set_linear_quality	jSetLQuality +#define jpeg_add_quant_table	jAddQuantTable +#define jpeg_quality_scaling	jQualityScaling +#define jpeg_simple_progression	jSimProgress +#define jpeg_suppress_tables	jSuppressTables +#define jpeg_alloc_quant_table	jAlcQTable +#define jpeg_alloc_huff_table	jAlcHTable +#define jpeg_start_compress	jStrtCompress +#define jpeg_write_scanlines	jWrtScanlines +#define jpeg_finish_compress	jFinCompress +#define jpeg_write_raw_data	jWrtRawData +#define jpeg_write_marker	jWrtMarker +#define jpeg_write_tables	jWrtTables +#define jpeg_read_header	jReadHeader +#define jpeg_start_decompress	jStrtDecompress +#define jpeg_read_scanlines	jReadScanlines +#define jpeg_finish_decompress	jFinDecompress +#define jpeg_read_raw_data	jReadRawData +#define jpeg_has_multiple_scans	jHasMultScn +#define jpeg_start_output	jStrtOutput +#define jpeg_finish_output	jFinOutput +#define jpeg_input_complete	jInComplete +#define jpeg_new_colormap	jNewCMap +#define jpeg_consume_input	jConsumeInput +#define jpeg_calc_output_dimensions	jCalcDimensions +#define jpeg_set_marker_processor	jSetMarker +#define jpeg_read_coefficients	jReadCoefs +#define jpeg_write_coefficients	jWrtCoefs +#define jpeg_copy_critical_parameters	jCopyCrit +#define jpeg_abort_compress	jAbrtCompress +#define jpeg_abort_decompress	jAbrtDecompress +#define jpeg_abort		jAbort +#define jpeg_destroy		jDestroy +#define jpeg_resync_to_restart	jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* 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)); + +/* 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, unsigned char *infile)); + +/* Default parameter setup for compression */ +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)); + +/* 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)); + +/* 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)); + +/* 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)); + +/* Alternate compression function: just write an abbreviated table file */ +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)); +/* 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 */ +#define JPEG_HEADER_TABLES_ONLY	2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* 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)); + +/* 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)); + +/* 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)); +/* 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 */ +#define JPEG_REACHED_EOI	2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED	3 /* Completed one iMCU row */ +#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)); + +/* 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)); + +/* 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)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc.  You can just call jpeg_destroy_(de)compress + * 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)); + +/* 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)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, +					   int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0	0xD0	/* RST0 marker code */ +#define JPEG_EOI	0xD9	/* EOI marker code */ +#define JPEG_APP0	0xE0	/* APP0 marker code */ +#define JPEG_COM	0xFE	/* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS		/* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h"		/* fetch private declarations */ +#include "jerror.h"		/* fetch error codes too */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* JPEGLIB_H */ diff --git a/libs/pak/pak.vcproj b/libs/pak/pak.vcproj index bf74cae..196a45a 100755 --- a/libs/pak/pak.vcproj +++ b/libs/pak/pak.vcproj @@ -1,173 +1,173 @@ -<?xml version="1.0" encoding="Windows-1252"?>
 -<VisualStudioProject
 -	ProjectType="Visual C++"
 -	Version="7.10"
 -	Name="pak"
 -	SccProjectName=""$/source/q3radiant", FEFAAAAA"
 -	SccLocalPath="..\..\q3radiant">
 -	<Platforms>
 -		<Platform
 -			Name="Win32"/>
 -	</Platforms>
 -	<Configurations>
 -		<Configuration
 -			Name="Debug|Win32"
 -			OutputDirectory=".\Debug"
 -			IntermediateDirectory=".\Debug"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="0"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
 -				BasicRuntimeChecks="3"
 -				RuntimeLibrary="1"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Debug/pak.pch"
 -				AssemblerListingLocation=".\Debug/"
 -				ObjectFile=".\Debug/"
 -				ProgramDataBaseFileName=".\Debug/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				DebugInformationFormat="4"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\pakd.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="_DEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -		<Configuration
 -			Name="Release|Win32"
 -			OutputDirectory=".\Release"
 -			IntermediateDirectory=".\Release"
 -			ConfigurationType="4"
 -			UseOfMFC="0"
 -			ATLMinimizesCRunTimeLibraryUsage="FALSE"
 -			CharacterSet="2">
 -			<Tool
 -				Name="VCCLCompilerTool"
 -				Optimization="0"
 -				AdditionalIncludeDirectories=".."
 -				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
 -				RuntimeLibrary="0"
 -				RuntimeTypeInfo="TRUE"
 -				UsePrecompiledHeader="2"
 -				PrecompiledHeaderFile=".\Release/pak.pch"
 -				AssemblerListingLocation=".\Release/"
 -				ObjectFile=".\Release/"
 -				ProgramDataBaseFileName=".\Release/"
 -				WarningLevel="3"
 -				SuppressStartupBanner="TRUE"
 -				CompileAs="0"/>
 -			<Tool
 -				Name="VCCustomBuildTool"/>
 -			<Tool
 -				Name="VCLibrarianTool"
 -				OutputFile="..\pak.lib"
 -				SuppressStartupBanner="TRUE"/>
 -			<Tool
 -				Name="VCMIDLTool"/>
 -			<Tool
 -				Name="VCPostBuildEventTool"/>
 -			<Tool
 -				Name="VCPreBuildEventTool"/>
 -			<Tool
 -				Name="VCPreLinkEventTool"/>
 -			<Tool
 -				Name="VCResourceCompilerTool"
 -				PreprocessorDefinitions="NDEBUG"
 -				Culture="1033"/>
 -			<Tool
 -				Name="VCWebServiceProxyGeneratorTool"/>
 -			<Tool
 -				Name="VCXMLDataGeneratorTool"/>
 -			<Tool
 -				Name="VCManagedWrapperGeneratorTool"/>
 -			<Tool
 -				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
 -		</Configuration>
 -	</Configurations>
 -	<References>
 -	</References>
 -	<Files>
 -		<Filter
 -			Name="Source Files"
 -			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
 -			<File
 -				RelativePath="pakstuff.cpp">
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -			</File>
 -			<File
 -				RelativePath="unzip.cpp">
 -				<FileConfiguration
 -					Name="Debug|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""
 -						BasicRuntimeChecks="3"/>
 -				</FileConfiguration>
 -				<FileConfiguration
 -					Name="Release|Win32">
 -					<Tool
 -						Name="VCCLCompilerTool"
 -						Optimization="0"
 -						AdditionalIncludeDirectories=""
 -						PreprocessorDefinitions=""/>
 -				</FileConfiguration>
 -			</File>
 -		</Filter>
 -		<Filter
 -			Name="Header Files"
 -			Filter="h;hpp;hxx;hm;inl">
 -			<File
 -				RelativePath="..\pakstuff.h">
 -			</File>
 -		</Filter>
 -	</Files>
 -	<Globals>
 -	</Globals>
 -</VisualStudioProject>
 +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject +	ProjectType="Visual C++" +	Version="7.10" +	Name="pak" +	SccProjectName=""$/source/q3radiant", FEFAAAAA" +	SccLocalPath="..\..\q3radiant"> +	<Platforms> +		<Platform +			Name="Win32"/> +	</Platforms> +	<Configurations> +		<Configuration +			Name="Debug|Win32" +			OutputDirectory=".\Debug" +			IntermediateDirectory=".\Debug" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;_DEBUG;_LIB" +				BasicRuntimeChecks="3" +				RuntimeLibrary="1" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Debug/pak.pch" +				AssemblerListingLocation=".\Debug/" +				ObjectFile=".\Debug/" +				ProgramDataBaseFileName=".\Debug/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				DebugInformationFormat="4" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\pakd.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="_DEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Release|Win32" +			OutputDirectory=".\Release" +			IntermediateDirectory=".\Release" +			ConfigurationType="4" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories=".." +				PreprocessorDefinitions="WIN32;NDEBUG;_LIB" +				RuntimeLibrary="0" +				RuntimeTypeInfo="TRUE" +				UsePrecompiledHeader="2" +				PrecompiledHeaderFile=".\Release/pak.pch" +				AssemblerListingLocation=".\Release/" +				ObjectFile=".\Release/" +				ProgramDataBaseFileName=".\Release/" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLibrarianTool" +				OutputFile="..\pak.lib" +				SuppressStartupBanner="TRUE"/> +			<Tool +				Name="VCMIDLTool"/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="NDEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +	</Configurations> +	<References> +	</References> +	<Files> +		<Filter +			Name="Source Files" +			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> +			<File +				RelativePath="pakstuff.cpp"> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="unzip.cpp"> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="" +						BasicRuntimeChecks="3"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions=""/> +				</FileConfiguration> +			</File> +		</Filter> +		<Filter +			Name="Header Files" +			Filter="h;hpp;hxx;hm;inl"> +			<File +				RelativePath="..\pakstuff.h"> +			</File> +		</Filter> +	</Files> +	<Globals> +	</Globals> +</VisualStudioProject> diff --git a/libs/pak/pakstuff.cpp b/libs/pak/pakstuff.cpp index a4e1dc7..011c27d 100755 --- a/libs/pak/pakstuff.cpp +++ b/libs/pak/pakstuff.cpp @@ -19,1191 +19,1191 @@ along with Foobar; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  ===========================================================================  */ -
 -#include <stdio.h>
 -#include <stdarg.h>
 -#include <stdlib.h>
 -#include <string.h>
 -#include <windows.h>
 -#include "io.h"
 -#include "pakstuff.h"
 -#include "unzip.h"
 -//#include "cmdlib.h"
 -#include "str.h"
 -
 -int m_nPAKIndex;
 -FILE* pakfile[16];
 -struct PACKDirectory	pakdir;
 -PACKDirPtr				pakdirptr = &pakdir;
 -UInt16					dirsize;
 -boolean					pakopen = false;
 -int						f_type;
 -DIRECTORY				*paktextures = NULL;
 -boolean					HavePakColormap;
 -UInt32					PakColormapOffset;
 -UInt32					PakColormapSize;
 -DIRECTORY				*dirhead = NULL;
 -boolean g_bPK3 = false;
 -char g_strBasePath[1024];
 -
 -struct PK3FileInfo
 -{
 -  unzFile m_zFile;
 -  char *m_pName;
 -  unz_s m_zInfo;
 -  long m_lSize;
 -  ~PK3FileInfo()
 -  {
 -    delete []m_pName;
 -  }
 -  bool operator ==(const PK3FileInfo& rhs) const { return strcmp(m_pName, rhs.m_pName) == 0; }
 -};
 -
 -#define __PATHSEPERATOR   '/'
 -
 -#define LOG_PAKFAIL
 -
 -#ifdef LOG_PAKFAIL
 -
 -class LogFile
 -{
 -public:
 -  FILE *m_pFile;
 -  LogFile(const char* pName)
 -  {
 -    m_pFile = fopen(pName, "w");
 -  }
 -  ~LogFile()
 -  {
 -    if (m_pFile)
 -    {
 -      fclose(m_pFile);
 -    }
 -  }
 -  void Log(const char *pFormat, ...)
 -  {
 -    va_list arg_ptr;
 -    va_start(arg_ptr, pFormat);
 -    fprintf(m_pFile, pFormat, arg_ptr);
 -    va_end(arg_ptr);
 -  }
 -};
 -
 -LogFile g_LogFile("c:\\paklog.txt");
 -#endif
 -
 -template <class T> class StrPtr : public Str
 -{
 -protected:
 -  T* m_pPtr;
 -  StrPtr()
 -  {
 -    m_pPtr = NULL;
 -  }
 -
 -  StrPtr(const char *pStr, T *p) : Str(pStr)
 -  {
 -    m_pPtr = p;
 -  }
 -
 -  T* Ptr()
 -  {
 -    return m_pPtr;
 -  }
 -
 -  T& Ref()
 -  {
 -    return *m_pPtr;
 -  }
 -    
 -
 -};
 -// PtrList
 -// a list of ptrs
 -// 
 -template <class T> class PtrList
 -{
 -protected:
 -  T *m_pPtr;
 -  PtrList *m_pNext;
 -
 -public:
 -
 -  PtrList()
 -  {
 -    m_pNext = NULL;
 -    m_pPtr = NULL;
 -  }
 -
 -  PtrList(T *ip)
 -  {
 -    m_pNext = NULL;
 -    m_pPtr = ip;
 -  }
 -
 -  ~PtrList()
 -  {
 -    delete m_pPtr;
 -  }
 -
 -  PtrList* Next()
 -  {
 -    return m_pNext;
 -  }
 -
 -  void Add(T *ip)
 -  {
 -    PtrList *pl = this;
 -    while (pl && pl->m_pNext)
 -    {
 -      pl = pl->Next();
 -    }
 -    pl->m_pNext = new PtrList(ip);
 -  }
 -
 -  void Remove()
 -  {
 -    PtrList *p = m_pNext;
 -    if (p)
 -    {
 -      while (p->m_pNext != this && p->m_pNext != NULL)
 -      {
 -        p = p->m_pNext;
 -      }
 -      if (p->m_pNext == this)
 -      {
 -        p->m_pNext = m_pNext;
 -      }
 -    }
 -  }
 -
 -  virtual PtrList* Find(T *ip)
 -  {
 -    PtrList *p = m_pNext;
 -    while (p)
 -    {
 -      if (*p->m_pPtr == *ip)
 -      {
 -        return p;
 -      }
 -      p = p->m_pNext;
 -    }
 -    return NULL;
 -  }
 -
 -  // remove vp from the list
 -  void Remove(T *ip)
 -  {
 -    PtrList *p = Find(ip);
 -    if (p)
 -    {
 -      p->Remove();
 -    }
 -  }
 -
 -  T* Ptr()
 -  {
 -    return m_pPtr;
 -  }
 -
 -  T& Ref()
 -  {
 -    return *m_pPtr;
 -  }
 -
 -  void RemoveAll()
 -  {
 -    PtrList *p = m_pNext;
 -    while (p)
 -    {
 -      PtrList *p2 = p;
 -      p = p->m_pNext;
 -      delete p2;
 -    }
 -  }
 -};
 -
 -
 -typedef PtrList<unzFile> ZFileList;
 -typedef PtrList<Str> StrList;
 -typedef PtrList<PK3FileInfo> PK3List;
 -
 -
 -StrList g_PK3TexturePaths;
 -PK3List g_PK3Files;
 -ZFileList g_zFiles;
 -#define WORK_LEN 1024
 -#define TEXTURE_PATH "textures"
 -#define PATH_SEPERATORS "/\\:\0"
 -
 -
 -char* __StrDup(char* pStr)
 -{ 
 -  if (pStr)
 -  {
 -    return strcpy(new char[strlen(pStr)+1], pStr); 
 -  }
 -  return NULL;
 -}
 -
 -char* __StrDup(const char* pStr)
 -{ 
 -  if (pStr)
 -  {
 -    return strcpy(new char[strlen(pStr)+1], pStr); 
 -  }
 -  return NULL;
 -}
 -
 -#define MEM_BLOCKSIZE 4096
 -void* __qblockmalloc(size_t nSize)
 -{
 -	void *b;
 -  // round up to threshold
 -  int nAllocSize = nSize % MEM_BLOCKSIZE;
 -  if ( nAllocSize > 0)
 -  {
 -    nSize += MEM_BLOCKSIZE - nAllocSize;
 -  }
 -	b = malloc(nSize + 1);
 -	memset (b, 0, nSize);
 -	return b;
 -}
 -
 -void* __qmalloc (size_t nSize)
 -{
 -	void *b;
 -	b = malloc(nSize + 1);
 -	memset (b, 0, nSize);
 -	return b;
 -}
 -
 -
 -/*
 -====================
 -Extract file parts
 -====================
 -*/
 -void __ExtractFilePath (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != __PATHSEPERATOR)
 -		src--;
 -
 -	memcpy (dest, path, src-path);
 -	dest[src-path] = 0;
 -}
 -
 -void __ExtractFileName (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != '/' 
 -		 && *(src-1) != '\\' )
 -		src--;
 -
 -	while (*src)
 -	{
 -		*dest++ = *src++;
 -	}
 -	*dest = 0;
 -}
 -
 -void __ExtractFileBase (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a \ or the start
 -//
 -	while (src != path && *(src-1) != '/' 
 -		 && *(src-1) != '\\' )
 -		src--;
 -
 -	while (*src && *src != '.')
 -	{
 -		*dest++ = *src++;
 -	}
 -	*dest = 0;
 -}
 -
 -void __ExtractFileExtension (const char *path, char *dest)
 -{
 -	const char *src;
 -
 -	src = path + strlen(path) - 1;
 -
 -//
 -// back up until a . or the start
 -//
 -	while (src != path && *(src-1) != '.')
 -		src--;
 -	if (src == path)
 -	{
 -		*dest = 0;	// no extension
 -		return;
 -	}
 -
 -	strcpy (dest,src);
 -}
 -
 -
 -void __ConvertDOSToUnixName( char *dst, const char *src )
 -{
 -	while ( *src )
 -	{
 -		if ( *src == '\\' )
 -			*dst = '/';
 -		else
 -			*dst = *src;
 -		dst++; src++;
 -	}
 -	*dst = 0;
 -}
 -
 -
 -
 -
 -
 -void AddSlash(Str& str)
 -{
 -  int nLen = str.GetLength();
 -  if (nLen > 0)
 -  {
 -    if (str[nLen-1] != '\\' && str[nLen-1] != '/')
 -      str += '\\';
 -  }
 -}
 -
 -void FindReplace(Str& strContents, const char* pTag, const char* pValue)
 -{
 -  if (strcmp(pTag, pValue) == 0)
 -    return;
 -  for (int nPos = strContents.Find(pTag); nPos >= 0; nPos = strContents.Find(pTag))
 -  {
 -    int nRightLen = strContents.GetLength() - strlen(pTag) - nPos;
 -    Str strLeft(strContents.Left(nPos));
 -    Str strRight(strContents.Right(nRightLen));
 -    strLeft += pValue;
 -    strLeft += strRight;
 -    strContents = strLeft;
 -  }
 -}
 -
 -
 -
 -
 -
 -void ProgError(char *errstr, ...)
 -{
 -  va_list args;
 -
 -  va_start(args, errstr);
 -  printf("\nProgram Error: *** ");
 -  vprintf(errstr, args);
 -  printf(" ***\n");
 -  va_end(args);
 -  exit(5);
 -}
 -
 -boolean ReadBytes(FILE *file, void *addr, UInt32 size)
 -{
 -  while (size > 0x8000)
 -    {
 -      if (fread(addr, 1, 0x8000, file) != 0x8000)
 -	return false;
 -      addr = (char *)addr + 0x8000;
 -      size -= 0x8000;
 -    }
 -  if (fread(addr, 1, size, file) != size)
 -    return false;
 -  return true;
 -}
 -int ReadMagic(FILE *file)
 -{
 -  UInt8 buf[4];
 -
 -  if (ReadBytes(file, buf, 4) == FALSE)
 -    return FTYPE_ERROR;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IWAD", 4))
 -    return FTYPE_IWAD;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "PWAD", 4))
 -    return FTYPE_PWAD;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "PACK", 4))
 -    return FTYPE_PACK;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "WAD2", 4))
 -    return FTYPE_WAD2;
 -  if (buf[0] == 0x17 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0)
 -    return FTYPE_BSP;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IDPO", 4))
 -    return FTYPE_MODEL;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IDSP", 4))
 -    return FTYPE_SPRITE;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "RIFF", 4))
 -    return FTYPE_WAV;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), ".snd", 4))
 -    return FTYPE_AU;
 -  if (buf[0] == 'P')
 -    {
 -      if (buf[1] == '1')
 -	return FTYPE_PBM_ASC;
 -      if (buf[1] == '2')
 -	return FTYPE_PGM_ASC;
 -      if (buf[1] == '3')
 -	return FTYPE_PPM_ASC;
 -      if (buf[1] == '4')
 -	return FTYPE_PBM_RAW;
 -      if (buf[1] == '5')
 -	return FTYPE_PGM_RAW;
 -      if (buf[1] == '6')
 -	return FTYPE_PPM_RAW;
 -    }
 -  if (buf[0] == 'B' && buf[1] == 'M')
 -    return FTYPE_BMP;
 -  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "GIF8", 4))
 -    return FTYPE_GIF;
 -  if (buf[0] == 0x0a && buf[1] == 0x05 && buf[2] == 0x01 && buf[3] == 0x08)
 -    return FTYPE_PCX;
 -  return FTYPE_UNKNOWN;
 -}
 -FILE *OpenFileReadMagic(const char *filename, int *ftype_r)
 -{
 -  FILE *f;
 -
 -  *ftype_r = FTYPE_ERROR;
 -  if ((f = fopen(filename, "rb")) == NULL)
 -    return NULL;
 -  *ftype_r = ReadMagic(f);
 -  if (*ftype_r == FTYPE_ERROR)
 -    {
 -      fclose(f);
 -      return NULL;
 -    }
 -  return f;
 -}
 -boolean WriteBytes(FILE *file, void *addr, UInt32 size)
 -{
 -  while (size > 0x8000)
 -    {
 -      if (fwrite(addr, 1, 0x8000, file) != 0x8000)
 -	return FALSE;
 -      addr = (char *)addr + 0x8000;
 -      size -= 0x8000;
 -    }
 -  if (fwrite(addr, 1, size, file) != size)
 -    return FALSE;
 -  return TRUE;
 -}
 -char *ConvertFilePath(char *filename)
 -{
 -  char *cp;
 -  
 -  if (filename == NULL)
 -    ProgError("BUG: cannot convert a NULL pathname");
 -  for (cp = filename; *cp; cp++)
 -    if (*cp == '/' || *cp == '\\')
 -      {
 -#ifdef QEU_DOS
 -	*cp = '\\';
 -#else
 -	*cp = '/';
 -#endif
 -      }
 -  return filename;
 -}
 -
 -/*
 - * Read the PACK directory into memory.  The optional offset to the
 - * start of the PACK file is given in "offset".  The number of files in
 - * the directory is returned in *dirsize_r.
 - */
 -PACKDirPtr ReadPACKDirectory(FILE *packfile, UInt32 offset, UInt16 *dirsize_r)
 -{
 -  PACKDirPtr dir;
 -  UInt32     pos, size;
 -  UInt16     max, i;
 -
 -  *dirsize_r = 0;
 -  if (packfile == NULL)
 -    return NULL;
 -  if ((fseek(packfile, offset, SEEK_SET) < 0)
 -      || (ReadMagic(packfile) != FTYPE_PACK)
 -      || (ReadInt32(packfile, &pos) == FALSE)
 -      || (ReadInt32(packfile, &size) == FALSE)
 -      || (size == 0L)
 -      || (size / sizeof(struct PACKDirectory) > 65535L)
 -      || (fseek(packfile, offset + pos, SEEK_SET) < 0))
 -    return NULL;
 -  dir = (PACKDirPtr)__qmalloc(size);
 -  max = (UInt16)(size / sizeof(struct PACKDirectory));
 -  for (i = 0; i < max; i++)
 -    {
 -      if (ReadBytes(packfile, &dir[i], sizeof(struct PACKDirectory)) == FALSE)
 -	{
 -	  free(dir);
 -	  return NULL;
 -	}
 -      ConvertFilePath(dir[i].name);
 -      dir[i].offset = SwapInt32(dir[i].offset);
 -      dir[i].size = SwapInt32(dir[i].size);
 -    }
 -  *dirsize_r = max;
 -  return dir;
 -}
 -
 -/*
 - * Print the contents of the PACK directory in "outf".
 - */
 -void DumpPACKDirectory(FILE *outf, PACKDirPtr dir, UInt16 dirsize)
 -{
 -	UInt16 i;
 -	UInt32 sum;
 -	char   buf[57];
 -
 -	if (outf == NULL || dir == NULL || dirsize == 0)
 -		return;
 -	fprintf(outf, "num    offset     size    file name\n");
 -	fprintf(outf, "       (hex)      (dec)\n");
 -	sum = 0L;
 -	for (i = 0; i < dirsize; i++)
 -	{
 -		if(!strnicmp(dir[i].name, "textures", 8))
 -		{
 -   	   strncpy(buf, dir[i].name, 56);
 -	      buf[56] = '\0';
 -      	fprintf(outf, "%3u  0x%08lx  %6ld   %s\n",
 -		      i, dir[i].offset, dir[i].size, buf);
 -	      sum += dir[i].size;
 -		}
 -    }
 -	fprintf(outf, "\nTotal size for %3u entries:  %7lu bytes.\n", dirsize, sum);
 -	fprintf(outf, "Size of the PACK directory:  %7lu bytes.\n",
 -		(UInt32)dirsize * (UInt32)sizeof(struct PACKDirectory));
 -	fprintf(outf, "Total (header + data + dir): %7lu bytes.\n",
 -		12L + sum + (UInt32)dirsize * (UInt32)sizeof(struct PACKDirectory));
 -}
 -
 -void ClearFileList(FILELIST **list)
 -{
 -	FILELIST	*temp;
 -
 -	while(*list)
 -	{
 -		temp = *list;
 -		*list = (*list)->next;
 -		free(temp);
 -	}
 -}
 -
 -void ClearDirList(DIRLIST **list)
 -{
 -	DIRLIST	*temp;
 -
 -	while(*list)
 -	{
 -		temp = *list;
 -		*list = (*list)->next;
 -		free(temp);
 -	}
 -}
 -
 -DIRECTORY *FindPakDir(DIRECTORY *dir, char *name)
 -{
 -	DIRECTORY	*currentPtr;
 -
 -	for(currentPtr = dir; currentPtr; currentPtr = currentPtr->next)
 -	{
 -		if(!stricmp(name, currentPtr->name))
 -		{
 -			return currentPtr;
 -		}
 -	}
 -	return NULL;
 -}
 -
 -
 -// LoadPK3FileList
 -// ---------------
 -//
 -// This gets passed a file mask which we want to remove as 
 -// we are only interested in the directory name and any given
 -// extension. Only handles explicit filenames or *.something
 -//
 -boolean LoadPK3FileList(FILELIST **filelist, const char *pattern)
 -{
 -  char cSearch[WORK_LEN];
 -	__ConvertDOSToUnixName( cSearch, pattern );
 -  char cPath[WORK_LEN];
 -  char cExt[WORK_LEN];
 -  char cFile[WORK_LEN];
 -  char cWork[WORK_LEN];
 -  __ExtractFilePath(pattern, cPath);
 -  __ExtractFileName(pattern, cFile);
 -  __ExtractFileExtension(pattern, cExt);
 -  const char *pCompare = (strnicmp(cFile, "*.", 2) == 0) ? cExt : cFile;
 -  strcpy(cWork, cPath);
 -  sprintf(cPath, "textures/%s", cWork);
 -
 -  PK3List *p = g_PK3Files.Next();
 -  while (p != NULL)
 -  {
 -    // qualify the path
 -    PK3FileInfo *pKey = p->Ptr();
 -    if (strstr(pKey->m_pName, cPath) && strstr(pKey->m_pName, pCompare))
 -    {
 -      __ExtractFileName(pKey->m_pName, cWork); 
 -      AddToFileListAlphabetized(filelist, cWork, 0, 0, false);
 -    }
 -    p = p->Next();
 -  }
 -  return (*filelist) != NULL;
 -}
 -
 -boolean GetPackFileList(FILELIST **filelist, char *pattern)
 -{
 -	char					*str1, *str2;
 -	int						i;
 -	DIRECTORY				*dummy = paktextures;
 -	FILELIST				*temp;
 -
 -	if (!pakopen)
 -		return false;
 -
 -  if (g_bPK3)
 -  {
 -    return LoadPK3FileList(filelist, pattern);
 -  }
 -
 -	str1 = pattern;
 -
 -	for(i = 0; pattern[i] != '\0'; i++)
 -	{
 -		if(pattern[i] == '\\')
 -			pattern[i] = '/';
 -	}
 -
 -	while(strchr(str1, '/'))
 -	{
 -		str2 = strchr(str1, '/');
 -		*str2++ = '\0';
 -		dummy = FindPakDir(dummy, str1);
 -		if(!dummy)
 -			return false;
 -		str1 = str2;
 -	}
 -	for(temp = dummy->files; temp; temp=temp->next)
 -	{
 -	  AddToFileListAlphabetized(filelist, temp->filename, temp->offset, 0, false);
 -	}
 -	return true;
 -}
 -
 -boolean GetPackTextureDirs(DIRLIST **dirlist)
 -{
 -	UInt16					i;
 -	char					buf[57];
 -
 -	if (!pakopen)
 -		return 1;
 -
 -  if (g_bPK3)
 -  {
 -    StrList *pl = g_PK3TexturePaths.Next();
 -    while (pl != NULL)
 -    {
 -      AddToDirListAlphabetized(dirlist, pl->Ref(), 0);
 -      pl = pl->Next();
 -    }
 -    return true;
 -  }
 -
 -	for (i = 0; i < dirsize; i++)
 -	{
 -		if(!strnicmp(pakdirptr[i].name, "textures", 8))
 -		{
 -			strncpy(buf, &(pakdirptr[i].name[9]), 46);
 -			if(strchr(buf, '\\'))
 -	      	*strchr(buf, '\\') = '\0';
 -			else if(strchr(buf, '/'))
 -	      	*strchr(buf, '/') = '\0';
 -			else
 -	      	buf[56] = '\0';
 -
 -			if(strchr(buf, '.'))
 -				continue;
 -
 -			AddToDirListAlphabetized(dirlist, buf, 0);
 -		}
 -	}
 -	return true;
 -}
 -
 -boolean AddToDirListAlphabetized(DIRLIST **list, char *dirname, int from)
 -{
 -	DIRLIST	*currentPtr, *previousPtr, *newPtr;
 -
 -	strlwr(dirname);
 -	for(currentPtr = *list; currentPtr; currentPtr = currentPtr->next)
 -	{
 -		if(!stricmp(dirname, currentPtr->dirname))
 -		{
 -			return false;
 -		}
 -	}
 -	previousPtr = NULL;
 -	currentPtr = *list;
 -
 -	if((newPtr = (DIRLIST *)__qmalloc(sizeof(DIRLIST))) == NULL)
 -		return false;
 -
 -	strcpy(newPtr->dirname, dirname);
 -	newPtr->from = from;
 -
 -	while(currentPtr != NULL && stricmp(dirname, currentPtr->dirname) > 0)
 -	{
 -		previousPtr = currentPtr;
 -		currentPtr = currentPtr->next;
 -	} //End while
 -	if(previousPtr == NULL)
 -	{
 -		newPtr->next = *list;
 -		*list = newPtr;
 -	} //End if
 -	else
 -	{
 -		previousPtr->next = newPtr;
 -		newPtr->next = currentPtr;
 -	} //End else
 -	return true;
 -}
 -
 -boolean AddToFileListAlphabetized(FILELIST **list, char *filename, UInt32 offset, UInt32 size, boolean dirs)
 -{
 -	FILELIST	*currentPtr, *previousPtr, *newPtr;
 -
 -	for(currentPtr = *list; currentPtr; currentPtr = currentPtr->next)
 -	{
 -		if(!stricmp(filename, currentPtr->filename))
 -		{
 -			return false;
 -		}
 -	}
 -	previousPtr = NULL;
 -	currentPtr = *list;
 -
 -	if((newPtr = (FILELIST *)__qmalloc(sizeof(FILELIST))) == NULL)
 -		return false;
 -
 -	strcpy(newPtr->filename, filename);
 -	newPtr->offset = offset;
 -	newPtr->size = size;
 -
 -	while(currentPtr != NULL && stricmp(filename, currentPtr->filename) > 0)
 -	{
 -		previousPtr = currentPtr;
 -		currentPtr = currentPtr->next;
 -	} //End while
 -	if(previousPtr == NULL)
 -	{
 -		newPtr->next = *list;
 -		*list = newPtr;
 -	} //End if
 -	else
 -	{
 -		previousPtr->next = newPtr;
 -		newPtr->next = currentPtr;
 -	} //End else
 -	return true;
 -}
 -
 -boolean PakLoadFile(const char *filename, void **bufferptr)
 -{
 -	FILELIST	*p = NULL;
 -	DIRECTORY	*dummy;
 -	void		*buffer;
 -	char		*str1, *str2;
 -
 -	if(!pakopen)
 -		return false;
 -
 -  Str str(filename);
 -  __ConvertDOSToUnixName(str, str);
 -
 -	dummy = paktextures;
 -	str1 = str;
 -
 -	while(strchr(str1, '/'))
 -	{
 -		str2 = strchr(str1, '/');
 -		*str2++ = '\0';
 -		dummy = FindPakDir(dummy, str1);
 -		if(!dummy)
 -			return false;
 -		str1 = str2;
 -	}
 -
 -  // FIXME: add error handling routines
 -	for(p = dummy->files; p; p = p->next)
 -	{
 -		if(!stricmp(str1, p->filename))
 -		{
 -			if (fseek(pakfile[m_nPAKIndex], p->offset, SEEK_SET) < 0)
 -			{
 -				//Sys_Printf("Unexpected EOF in pakfile\n");
 -				return false;
 -			}
 -			if((buffer = __qmalloc(p->size+5)) == NULL)
 -				//Error("Could not allocate memory");
 -	
 -			if(fread(buffer, 1, p->size, pakfile[m_nPAKIndex]) != p->size)
 -			{
 -				//Sys_Printf("Error reading %s from pak\n", str1);
 -				free(buffer);
 -				return false;
 -			}
 -			*bufferptr = buffer;
 -			return true;
 -		}
 -	}
 -	return false;
 -}
 -
 -int PakLoadAnyFile(const char *filename, void **bufferptr)
 -{
 -  char cWork[WORK_LEN];
 -  if (g_bPK3)
 -  {
 -    PK3FileInfo *pInfo;
 -    Str strKey;
 -    // need to lookup the file without the base/texture path on it
 -    Str strBase(g_strBasePath);
 -    AddSlash(strBase);
 -    __ConvertDOSToUnixName(cWork, strBase);
 -    Str strFile(filename);
 -    __ConvertDOSToUnixName(strFile, strFile);
 -    strFile.MakeLower();
 -    strlwr(cWork);
 -    FindReplace(strFile, cWork, "");
 -
 -    PK3FileInfo infoFind;
 -    infoFind.m_pName = __StrDup(strFile.GetBuffer());
 -    PK3List *pList = g_PK3Files.Find(&infoFind);
 -    if (pList)
 -    {
 -      pInfo = pList->Ptr();
 -      memcpy(pInfo->m_zFile, &pInfo->m_zInfo, sizeof(unz_s));
 -      if (unzOpenCurrentFile(pInfo->m_zFile) == UNZ_OK)
 -      {
 -        void *buffer = __qblockmalloc(pInfo->m_lSize+1);
 -        int n = unzReadCurrentFile(pInfo->m_zFile , buffer, pInfo->m_lSize);
 -        *bufferptr = buffer;
 -        unzCloseCurrentFile(pInfo->m_zFile);
 -        return n;
 -      }
 -    }
 -#ifdef LOG_PAKFAIL
 -    sprintf(cWork, "PAK failed on %s\n", filename);
 -    g_LogFile.Log(cWork);
 -#endif
 -    return -1;
 -  }
 -
 -	for (int i = 0; i < dirsize; i++)
 -	{
 -		if(!stricmp(filename, pakdirptr[i].name))
 -		{
 -			if (fseek(pakfile[m_nPAKIndex], pakdirptr[i].offset, SEEK_SET) >= 0)
 -      {
 -	      void *buffer = __qmalloc (pakdirptr[i].size+1);
 -	      ((char *)buffer)[pakdirptr[i].size] = 0;
 -			  if (fread(buffer, 1, pakdirptr[i].size, pakfile[m_nPAKIndex]) == pakdirptr[i].size)
 -        {
 -          *bufferptr = buffer;
 -          return pakdirptr[i].size;
 -        }
 -      }
 -		}
 -	}
 -#ifdef LOG_PAKFAIL
 -    sprintf(cWork, "PAK failed on %s\n", filename);
 -    g_LogFile.Log(cWork);
 -#endif
 -  return -1;
 -}
 -
 -
 -
 -DIRECTORY *AddPakDir(DIRECTORY **dir, char *name)
 -{
 -	DIRECTORY	*currentPtr, *previousPtr, *newPtr;
 -
 -	for(currentPtr = *dir; currentPtr; currentPtr = currentPtr->next)
 -	{
 -		if(!stricmp(name, currentPtr->name))
 -		{
 -			return currentPtr;
 -		}
 -	}
 -	previousPtr = NULL;
 -	currentPtr = *dir;
 -
 -	if((newPtr = (DIRECTORY *)__qmalloc(sizeof(DIRECTORY))) == NULL)
 -		return NULL;
 -
 -	strcpy(newPtr->name, name);
 -	newPtr->files = NULL;
 -
 -	while(currentPtr != NULL && stricmp(name, currentPtr->name) > 0)
 -	{
 -		previousPtr = currentPtr;
 -		currentPtr = currentPtr->next;
 -	}
 -	if(previousPtr == NULL)
 -	{
 -		newPtr->next = *dir;
 -		*dir = newPtr;
 -	}
 -	else
 -	{
 -		previousPtr->next = newPtr;
 -		newPtr->next = currentPtr;
 -	}
 -	return newPtr;
 -}
 -
 -
 -// OpenPK3
 -// -------
 -// Opens a PK3 ( or zip ) file and creates a list of filenames
 -// and zip info structures
 -// 
 -boolean OpenPK3(const char *filename)
 -{
 -  char cFilename[WORK_LEN];
 -  char cName[WORK_LEN];
 -  char cWork[WORK_LEN];
 -  unz_file_info zInfo;
 -  unzFile *zFile = new unzFile(unzOpen(filename));
 -  g_zFiles.Add(zFile);
 -  if (zFile != NULL)
 -  {
 -    int nStatus = unzGoToFirstFile(*zFile);
 -    while (nStatus == UNZ_OK)
 -    {
 -      cFilename[0] = '\0';
 -      unzGetCurrentFileInfo(*zFile, &zInfo, cFilename, WORK_LEN, NULL, 0, NULL, 0);
 -      strlwr(cFilename);
 -    	__ConvertDOSToUnixName( cWork, cFilename);
 -      if (strstr(cWork, ".") != NULL)
 -      {
 -        PK3FileInfo *pInfo = new PK3FileInfo();
 -        pInfo->m_pName = __StrDup(cWork);
 -        memcpy(&pInfo->m_zInfo, (unz_s*)*zFile, sizeof(unz_s));
 -        pInfo->m_lSize = zInfo.uncompressed_size;
 -        pInfo->m_zFile = *zFile;
 -        g_PK3Files.Add(pInfo);
 -      }
 -      char *p = strstr(cFilename, TEXTURE_PATH);
 -      if (p != NULL)
 -      {
 -        // FIXME: path differences per os ?
 -        // catch solo directory entry
 -        if (strlen(p) > strlen(TEXTURE_PATH) + 1)
 -        {
 -          // skip textures + path seperator
 -          p += strlen(TEXTURE_PATH) + 1;
 -          int nEnd = strcspn(p, PATH_SEPERATORS);
 -          strncpy(cName, p, nEnd);
 -          cName[nEnd] = '\0';
 -
 -          boolean bFound = false;
 -          StrList *pl = g_PK3TexturePaths.Next();
 -          while (pl != NULL)
 -          {
 -            if (strcmpi(pl->Ref(), cName) == 0)
 -            {
 -              // already have this, continue
 -              bFound = true;
 -              break;
 -            }
 -            pl = pl->Next();
 -          }
 -          if (!bFound)
 -          {
 -            g_PK3TexturePaths.Add(new Str(cName));
 -          }
 -        }
 -      }
 -      nStatus = unzGoToNextFile(*zFile);
 -    }
 -  }
 -  return (zFile != NULL);
 -}
 -
 -void closePK3(unzFile zf)
 -{
 -  unzClose(zf);
 -}
 -
 -void OpenPakFile(const char *filename)
 -{
 -	int			i;
 -	char		*str1, *str2;
 -	DIRECTORY	*dummy;
 -
 -	if(!pakopen)
 -		paktextures = NULL;
 -
 -	HavePakColormap = false;
 -
 -  Str strTest(filename);
 -  strTest.MakeLower();
 -  if (strTest.Find("pk3") >= 0 || strTest.Find("zip") >= 0)
 -  {
 -    pakopen = g_bPK3 = OpenPK3(filename);
 -    return;
 -  }
 -
 -
 -	if((pakfile[m_nPAKIndex] = OpenFileReadMagic(filename, &f_type)) == NULL)
 -	{
 -    //FIXME: error routine
 -		//Sys_Printf("ERROR: Could not open %s", filename);
 -		return;
 -	}
 -	if(f_type != FTYPE_PACK)
 -	{
 -		//Sys_Printf("ERROR: %s is not a valid pack file", filename);
 -		if(f_type != FTYPE_ERROR)
 -			fclose(pakfile[m_nPAKIndex]);
 -		return;
 -	}
 -	pakdirptr = ReadPACKDirectory(pakfile[m_nPAKIndex], 0, &dirsize);
 -	if (pakdirptr == NULL)
 -	{
 -		//Sys_Printf("ERROR: Could not read pack directory", filename);
 -		fclose(pakfile[m_nPAKIndex]);
 -		return;
 -	}
 -	if (dirsize == 0)
 -	{
 -		fclose(pakfile[m_nPAKIndex]);
 -		return;
 -	}
 -	for (i = 0; i < dirsize; i++)
 -	{
 -		if(!strnicmp("textures/", pakdirptr[i].name, 9))
 -		{
 -			dummy = paktextures;
 -			str1 = pakdirptr[i].name+9;
 -			while(strchr(str1, '/'))
 -			{
 -				str2 = strchr(str1, '/');
 -				*str2++ = '\0';
 -					dummy = AddPakDir(dummy==paktextures?&paktextures:&dummy, str1);
 -				str1 = str2;
 -			}
 -
 -			AddToFileListAlphabetized(&(dummy->files), str1, pakdirptr[i].offset, pakdirptr[i].size, true);
 -		}
 -		else if(!strnicmp("pics/colormap.pcx", pakdirptr[i].name, 17))
 -		{
 -			HavePakColormap = true;
 -			PakColormapOffset = pakdirptr[i].offset;
 -			PakColormapSize = pakdirptr[i].size;
 -		}
 -	}
 -	pakopen = true;
 -
 -}
 -
 -void ClearPaKDir(DIRECTORY **dir)
 -{
 -	DIRECTORY	*d1 = *dir, *d2;
 -
 -	while(d1)
 -	{
 -		ClearFileList(&(d1->files));
 -		d2 = d1;
 -		d1 = d1->next;
 -		free(d2);
 -	}
 -}
 -
 -void CleanUpPakDirs()
 -{
 -  ClearPaKDir(&paktextures);
 -  paktextures = NULL;
 -  dirhead = NULL;
 -  g_PK3TexturePaths.RemoveAll();
 -  g_PK3Files.RemoveAll();
 -}
 -
 -void ClosePakFile(void)
 -{
 -	if(pakopen)
 -  {
 -    if (g_bPK3)
 -    {
 -      ZFileList *p = g_zFiles.Next();
 -      while (p != NULL)
 -      {
 -        unzFile uz = p->Ref();
 -        closePK3(uz);
 -        p = p->Next();
 -      }
 -    }
 -    else
 -    {
 -      fclose(pakfile[m_nPAKIndex]);
 -    }
 -  }
 -	pakopen = false;
 -  CleanUpPakDirs();
 -}
 -
 -
 -void WINAPI InitPakFile(const char * pBasePath, const char *pName)
 -{
 -  m_nPAKIndex = 0;
 -  pakopen = false;
 -	paktextures = NULL;
 -  strcpy(g_strBasePath, pBasePath);
 -  if (pName == NULL)
 -  {
 -    char cWork[WORK_LEN];
 -	  Str strPath(pBasePath);
 -    AddSlash(strPath);
 -  	strPath += "*.pk3";
 -  	bool bGo = true;
 -	  struct _finddata_t fileinfo;
 -  	int handle = _findfirst (strPath, &fileinfo);
 -	  if (handle != -1)
 -  	{
 -	  	do
 -		  {
 -        sprintf(cWork, "%s\\%s", pBasePath, fileinfo.name);
 -        OpenPakFile(cWork);
 -		  } while (_findnext( handle, &fileinfo ) != -1);
 -	    _findclose (handle);
 -    }
 -	}
 -  else
 -  {
 -	  OpenPakFile(pName);
 -  }
 -}
 -
 + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <windows.h> +#include "io.h" +#include "pakstuff.h" +#include "unzip.h" +//#include "cmdlib.h" +#include "str.h" + +int m_nPAKIndex; +FILE* pakfile[16]; +struct PACKDirectory	pakdir; +PACKDirPtr				pakdirptr = &pakdir; +UInt16					dirsize; +boolean					pakopen = false; +int						f_type; +DIRECTORY				*paktextures = NULL; +boolean					HavePakColormap; +UInt32					PakColormapOffset; +UInt32					PakColormapSize; +DIRECTORY				*dirhead = NULL; +boolean g_bPK3 = false; +char g_strBasePath[1024]; + +struct PK3FileInfo +{ +  unzFile m_zFile; +  char *m_pName; +  unz_s m_zInfo; +  long m_lSize; +  ~PK3FileInfo() +  { +    delete []m_pName; +  } +  bool operator ==(const PK3FileInfo& rhs) const { return strcmp(m_pName, rhs.m_pName) == 0; } +}; + +#define __PATHSEPERATOR   '/' + +#define LOG_PAKFAIL + +#ifdef LOG_PAKFAIL + +class LogFile +{ +public: +  FILE *m_pFile; +  LogFile(const char* pName) +  { +    m_pFile = fopen(pName, "w"); +  } +  ~LogFile() +  { +    if (m_pFile) +    { +      fclose(m_pFile); +    } +  } +  void Log(const char *pFormat, ...) +  { +    va_list arg_ptr; +    va_start(arg_ptr, pFormat); +    fprintf(m_pFile, pFormat, arg_ptr); +    va_end(arg_ptr); +  } +}; + +LogFile g_LogFile("c:\\paklog.txt"); +#endif + +template <class T> class StrPtr : public Str +{ +protected: +  T* m_pPtr; +  StrPtr() +  { +    m_pPtr = NULL; +  } + +  StrPtr(const char *pStr, T *p) : Str(pStr) +  { +    m_pPtr = p; +  } + +  T* Ptr() +  { +    return m_pPtr; +  } + +  T& Ref() +  { +    return *m_pPtr; +  } +     + +}; +// PtrList +// a list of ptrs +//  +template <class T> class PtrList +{ +protected: +  T *m_pPtr; +  PtrList *m_pNext; + +public: + +  PtrList() +  { +    m_pNext = NULL; +    m_pPtr = NULL; +  } + +  PtrList(T *ip) +  { +    m_pNext = NULL; +    m_pPtr = ip; +  } + +  ~PtrList() +  { +    delete m_pPtr; +  } + +  PtrList* Next() +  { +    return m_pNext; +  } + +  void Add(T *ip) +  { +    PtrList *pl = this; +    while (pl && pl->m_pNext) +    { +      pl = pl->Next(); +    } +    pl->m_pNext = new PtrList(ip); +  } + +  void Remove() +  { +    PtrList *p = m_pNext; +    if (p) +    { +      while (p->m_pNext != this && p->m_pNext != NULL) +      { +        p = p->m_pNext; +      } +      if (p->m_pNext == this) +      { +        p->m_pNext = m_pNext; +      } +    } +  } + +  virtual PtrList* Find(T *ip) +  { +    PtrList *p = m_pNext; +    while (p) +    { +      if (*p->m_pPtr == *ip) +      { +        return p; +      } +      p = p->m_pNext; +    } +    return NULL; +  } + +  // remove vp from the list +  void Remove(T *ip) +  { +    PtrList *p = Find(ip); +    if (p) +    { +      p->Remove(); +    } +  } + +  T* Ptr() +  { +    return m_pPtr; +  } + +  T& Ref() +  { +    return *m_pPtr; +  } + +  void RemoveAll() +  { +    PtrList *p = m_pNext; +    while (p) +    { +      PtrList *p2 = p; +      p = p->m_pNext; +      delete p2; +    } +  } +}; + + +typedef PtrList<unzFile> ZFileList; +typedef PtrList<Str> StrList; +typedef PtrList<PK3FileInfo> PK3List; + + +StrList g_PK3TexturePaths; +PK3List g_PK3Files; +ZFileList g_zFiles; +#define WORK_LEN 1024 +#define TEXTURE_PATH "textures" +#define PATH_SEPERATORS "/\\:\0" + + +char* __StrDup(char* pStr) +{  +  if (pStr) +  { +    return strcpy(new char[strlen(pStr)+1], pStr);  +  } +  return NULL; +} + +char* __StrDup(const char* pStr) +{  +  if (pStr) +  { +    return strcpy(new char[strlen(pStr)+1], pStr);  +  } +  return NULL; +} + +#define MEM_BLOCKSIZE 4096 +void* __qblockmalloc(size_t nSize) +{ +	void *b; +  // round up to threshold +  int nAllocSize = nSize % MEM_BLOCKSIZE; +  if ( nAllocSize > 0) +  { +    nSize += MEM_BLOCKSIZE - nAllocSize; +  } +	b = malloc(nSize + 1); +	memset (b, 0, nSize); +	return b; +} + +void* __qmalloc (size_t nSize) +{ +	void *b; +	b = malloc(nSize + 1); +	memset (b, 0, nSize); +	return b; +} + + +/* +==================== +Extract file parts +==================== +*/ +void __ExtractFilePath (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != __PATHSEPERATOR) +		src--; + +	memcpy (dest, path, src-path); +	dest[src-path] = 0; +} + +void __ExtractFileName (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != '/'  +		 && *(src-1) != '\\' ) +		src--; + +	while (*src) +	{ +		*dest++ = *src++; +	} +	*dest = 0; +} + +void __ExtractFileBase (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// +	while (src != path && *(src-1) != '/'  +		 && *(src-1) != '\\' ) +		src--; + +	while (*src && *src != '.') +	{ +		*dest++ = *src++; +	} +	*dest = 0; +} + +void __ExtractFileExtension (const char *path, char *dest) +{ +	const char *src; + +	src = path + strlen(path) - 1; + +// +// back up until a . or the start +// +	while (src != path && *(src-1) != '.') +		src--; +	if (src == path) +	{ +		*dest = 0;	// no extension +		return; +	} + +	strcpy (dest,src); +} + + +void __ConvertDOSToUnixName( char *dst, const char *src ) +{ +	while ( *src ) +	{ +		if ( *src == '\\' ) +			*dst = '/'; +		else +			*dst = *src; +		dst++; src++; +	} +	*dst = 0; +} + + + + + +void AddSlash(Str& str) +{ +  int nLen = str.GetLength(); +  if (nLen > 0) +  { +    if (str[nLen-1] != '\\' && str[nLen-1] != '/') +      str += '\\'; +  } +} + +void FindReplace(Str& strContents, const char* pTag, const char* pValue) +{ +  if (strcmp(pTag, pValue) == 0) +    return; +  for (int nPos = strContents.Find(pTag); nPos >= 0; nPos = strContents.Find(pTag)) +  { +    int nRightLen = strContents.GetLength() - strlen(pTag) - nPos; +    Str strLeft(strContents.Left(nPos)); +    Str strRight(strContents.Right(nRightLen)); +    strLeft += pValue; +    strLeft += strRight; +    strContents = strLeft; +  } +} + + + + + +void ProgError(char *errstr, ...) +{ +  va_list args; + +  va_start(args, errstr); +  printf("\nProgram Error: *** "); +  vprintf(errstr, args); +  printf(" ***\n"); +  va_end(args); +  exit(5); +} + +boolean ReadBytes(FILE *file, void *addr, UInt32 size) +{ +  while (size > 0x8000) +    { +      if (fread(addr, 1, 0x8000, file) != 0x8000) +	return false; +      addr = (char *)addr + 0x8000; +      size -= 0x8000; +    } +  if (fread(addr, 1, size, file) != size) +    return false; +  return true; +} +int ReadMagic(FILE *file) +{ +  UInt8 buf[4]; + +  if (ReadBytes(file, buf, 4) == FALSE) +    return FTYPE_ERROR; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IWAD", 4)) +    return FTYPE_IWAD; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "PWAD", 4)) +    return FTYPE_PWAD; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "PACK", 4)) +    return FTYPE_PACK; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "WAD2", 4)) +    return FTYPE_WAD2; +  if (buf[0] == 0x17 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0) +    return FTYPE_BSP; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IDPO", 4)) +    return FTYPE_MODEL; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "IDSP", 4)) +    return FTYPE_SPRITE; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "RIFF", 4)) +    return FTYPE_WAV; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), ".snd", 4)) +    return FTYPE_AU; +  if (buf[0] == 'P') +    { +      if (buf[1] == '1') +	return FTYPE_PBM_ASC; +      if (buf[1] == '2') +	return FTYPE_PGM_ASC; +      if (buf[1] == '3') +	return FTYPE_PPM_ASC; +      if (buf[1] == '4') +	return FTYPE_PBM_RAW; +      if (buf[1] == '5') +	return FTYPE_PGM_RAW; +      if (buf[1] == '6') +	return FTYPE_PPM_RAW; +    } +  if (buf[0] == 'B' && buf[1] == 'M') +    return FTYPE_BMP; +  if (!strncmp(reinterpret_cast<const char*>(&buf[0]), "GIF8", 4)) +    return FTYPE_GIF; +  if (buf[0] == 0x0a && buf[1] == 0x05 && buf[2] == 0x01 && buf[3] == 0x08) +    return FTYPE_PCX; +  return FTYPE_UNKNOWN; +} +FILE *OpenFileReadMagic(const char *filename, int *ftype_r) +{ +  FILE *f; + +  *ftype_r = FTYPE_ERROR; +  if ((f = fopen(filename, "rb")) == NULL) +    return NULL; +  *ftype_r = ReadMagic(f); +  if (*ftype_r == FTYPE_ERROR) +    { +      fclose(f); +      return NULL; +    } +  return f; +} +boolean WriteBytes(FILE *file, void *addr, UInt32 size) +{ +  while (size > 0x8000) +    { +      if (fwrite(addr, 1, 0x8000, file) != 0x8000) +	return FALSE; +      addr = (char *)addr + 0x8000; +      size -= 0x8000; +    } +  if (fwrite(addr, 1, size, file) != size) +    return FALSE; +  return TRUE; +} +char *ConvertFilePath(char *filename) +{ +  char *cp; +   +  if (filename == NULL) +    ProgError("BUG: cannot convert a NULL pathname"); +  for (cp = filename; *cp; cp++) +    if (*cp == '/' || *cp == '\\') +      { +#ifdef QEU_DOS +	*cp = '\\'; +#else +	*cp = '/'; +#endif +      } +  return filename; +} + +/* + * Read the PACK directory into memory.  The optional offset to the + * start of the PACK file is given in "offset".  The number of files in + * the directory is returned in *dirsize_r. + */ +PACKDirPtr ReadPACKDirectory(FILE *packfile, UInt32 offset, UInt16 *dirsize_r) +{ +  PACKDirPtr dir; +  UInt32     pos, size; +  UInt16     max, i; + +  *dirsize_r = 0; +  if (packfile == NULL) +    return NULL; +  if ((fseek(packfile, offset, SEEK_SET) < 0) +      || (ReadMagic(packfile) != FTYPE_PACK) +      || (ReadInt32(packfile, &pos) == FALSE) +      || (ReadInt32(packfile, &size) == FALSE) +      || (size == 0L) +      || (size / sizeof(struct PACKDirectory) > 65535L) +      || (fseek(packfile, offset + pos, SEEK_SET) < 0)) +    return NULL; +  dir = (PACKDirPtr)__qmalloc(size); +  max = (UInt16)(size / sizeof(struct PACKDirectory)); +  for (i = 0; i < max; i++) +    { +      if (ReadBytes(packfile, &dir[i], sizeof(struct PACKDirectory)) == FALSE) +	{ +	  free(dir); +	  return NULL; +	} +      ConvertFilePath(dir[i].name); +      dir[i].offset = SwapInt32(dir[i].offset); +      dir[i].size = SwapInt32(dir[i].size); +    } +  *dirsize_r = max; +  return dir; +} + +/* + * Print the contents of the PACK directory in "outf". + */ +void DumpPACKDirectory(FILE *outf, PACKDirPtr dir, UInt16 dirsize) +{ +	UInt16 i; +	UInt32 sum; +	char   buf[57]; + +	if (outf == NULL || dir == NULL || dirsize == 0) +		return; +	fprintf(outf, "num    offset     size    file name\n"); +	fprintf(outf, "       (hex)      (dec)\n"); +	sum = 0L; +	for (i = 0; i < dirsize; i++) +	{ +		if(!strnicmp(dir[i].name, "textures", 8)) +		{ +   	   strncpy(buf, dir[i].name, 56); +	      buf[56] = '\0'; +      	fprintf(outf, "%3u  0x%08lx  %6ld   %s\n", +		      i, dir[i].offset, dir[i].size, buf); +	      sum += dir[i].size; +		} +    } +	fprintf(outf, "\nTotal size for %3u entries:  %7lu bytes.\n", dirsize, sum); +	fprintf(outf, "Size of the PACK directory:  %7lu bytes.\n", +		(UInt32)dirsize * (UInt32)sizeof(struct PACKDirectory)); +	fprintf(outf, "Total (header + data + dir): %7lu bytes.\n", +		12L + sum + (UInt32)dirsize * (UInt32)sizeof(struct PACKDirectory)); +} + +void ClearFileList(FILELIST **list) +{ +	FILELIST	*temp; + +	while(*list) +	{ +		temp = *list; +		*list = (*list)->next; +		free(temp); +	} +} + +void ClearDirList(DIRLIST **list) +{ +	DIRLIST	*temp; + +	while(*list) +	{ +		temp = *list; +		*list = (*list)->next; +		free(temp); +	} +} + +DIRECTORY *FindPakDir(DIRECTORY *dir, char *name) +{ +	DIRECTORY	*currentPtr; + +	for(currentPtr = dir; currentPtr; currentPtr = currentPtr->next) +	{ +		if(!stricmp(name, currentPtr->name)) +		{ +			return currentPtr; +		} +	} +	return NULL; +} + + +// LoadPK3FileList +// --------------- +// +// This gets passed a file mask which we want to remove as  +// we are only interested in the directory name and any given +// extension. Only handles explicit filenames or *.something +// +boolean LoadPK3FileList(FILELIST **filelist, const char *pattern) +{ +  char cSearch[WORK_LEN]; +	__ConvertDOSToUnixName( cSearch, pattern ); +  char cPath[WORK_LEN]; +  char cExt[WORK_LEN]; +  char cFile[WORK_LEN]; +  char cWork[WORK_LEN]; +  __ExtractFilePath(pattern, cPath); +  __ExtractFileName(pattern, cFile); +  __ExtractFileExtension(pattern, cExt); +  const char *pCompare = (strnicmp(cFile, "*.", 2) == 0) ? cExt : cFile; +  strcpy(cWork, cPath); +  sprintf(cPath, "textures/%s", cWork); + +  PK3List *p = g_PK3Files.Next(); +  while (p != NULL) +  { +    // qualify the path +    PK3FileInfo *pKey = p->Ptr(); +    if (strstr(pKey->m_pName, cPath) && strstr(pKey->m_pName, pCompare)) +    { +      __ExtractFileName(pKey->m_pName, cWork);  +      AddToFileListAlphabetized(filelist, cWork, 0, 0, false); +    } +    p = p->Next(); +  } +  return (*filelist) != NULL; +} + +boolean GetPackFileList(FILELIST **filelist, char *pattern) +{ +	char					*str1, *str2; +	int						i; +	DIRECTORY				*dummy = paktextures; +	FILELIST				*temp; + +	if (!pakopen) +		return false; + +  if (g_bPK3) +  { +    return LoadPK3FileList(filelist, pattern); +  } + +	str1 = pattern; + +	for(i = 0; pattern[i] != '\0'; i++) +	{ +		if(pattern[i] == '\\') +			pattern[i] = '/'; +	} + +	while(strchr(str1, '/')) +	{ +		str2 = strchr(str1, '/'); +		*str2++ = '\0'; +		dummy = FindPakDir(dummy, str1); +		if(!dummy) +			return false; +		str1 = str2; +	} +	for(temp = dummy->files; temp; temp=temp->next) +	{ +	  AddToFileListAlphabetized(filelist, temp->filename, temp->offset, 0, false); +	} +	return true; +} + +boolean GetPackTextureDirs(DIRLIST **dirlist) +{ +	UInt16					i; +	char					buf[57]; + +	if (!pakopen) +		return 1; + +  if (g_bPK3) +  { +    StrList *pl = g_PK3TexturePaths.Next(); +    while (pl != NULL) +    { +      AddToDirListAlphabetized(dirlist, pl->Ref(), 0); +      pl = pl->Next(); +    } +    return true; +  } + +	for (i = 0; i < dirsize; i++) +	{ +		if(!strnicmp(pakdirptr[i].name, "textures", 8)) +		{ +			strncpy(buf, &(pakdirptr[i].name[9]), 46); +			if(strchr(buf, '\\')) +	      	*strchr(buf, '\\') = '\0'; +			else if(strchr(buf, '/')) +	      	*strchr(buf, '/') = '\0'; +			else +	      	buf[56] = '\0'; + +			if(strchr(buf, '.')) +				continue; + +			AddToDirListAlphabetized(dirlist, buf, 0); +		} +	} +	return true; +} + +boolean AddToDirListAlphabetized(DIRLIST **list, char *dirname, int from) +{ +	DIRLIST	*currentPtr, *previousPtr, *newPtr; + +	strlwr(dirname); +	for(currentPtr = *list; currentPtr; currentPtr = currentPtr->next) +	{ +		if(!stricmp(dirname, currentPtr->dirname)) +		{ +			return false; +		} +	} +	previousPtr = NULL; +	currentPtr = *list; + +	if((newPtr = (DIRLIST *)__qmalloc(sizeof(DIRLIST))) == NULL) +		return false; + +	strcpy(newPtr->dirname, dirname); +	newPtr->from = from; + +	while(currentPtr != NULL && stricmp(dirname, currentPtr->dirname) > 0) +	{ +		previousPtr = currentPtr; +		currentPtr = currentPtr->next; +	} //End while +	if(previousPtr == NULL) +	{ +		newPtr->next = *list; +		*list = newPtr; +	} //End if +	else +	{ +		previousPtr->next = newPtr; +		newPtr->next = currentPtr; +	} //End else +	return true; +} + +boolean AddToFileListAlphabetized(FILELIST **list, char *filename, UInt32 offset, UInt32 size, boolean dirs) +{ +	FILELIST	*currentPtr, *previousPtr, *newPtr; + +	for(currentPtr = *list; currentPtr; currentPtr = currentPtr->next) +	{ +		if(!stricmp(filename, currentPtr->filename)) +		{ +			return false; +		} +	} +	previousPtr = NULL; +	currentPtr = *list; + +	if((newPtr = (FILELIST *)__qmalloc(sizeof(FILELIST))) == NULL) +		return false; + +	strcpy(newPtr->filename, filename); +	newPtr->offset = offset; +	newPtr->size = size; + +	while(currentPtr != NULL && stricmp(filename, currentPtr->filename) > 0) +	{ +		previousPtr = currentPtr; +		currentPtr = currentPtr->next; +	} //End while +	if(previousPtr == NULL) +	{ +		newPtr->next = *list; +		*list = newPtr; +	} //End if +	else +	{ +		previousPtr->next = newPtr; +		newPtr->next = currentPtr; +	} //End else +	return true; +} + +boolean PakLoadFile(const char *filename, void **bufferptr) +{ +	FILELIST	*p = NULL; +	DIRECTORY	*dummy; +	void		*buffer; +	char		*str1, *str2; + +	if(!pakopen) +		return false; + +  Str str(filename); +  __ConvertDOSToUnixName(str, str); + +	dummy = paktextures; +	str1 = str; + +	while(strchr(str1, '/')) +	{ +		str2 = strchr(str1, '/'); +		*str2++ = '\0'; +		dummy = FindPakDir(dummy, str1); +		if(!dummy) +			return false; +		str1 = str2; +	} + +  // FIXME: add error handling routines +	for(p = dummy->files; p; p = p->next) +	{ +		if(!stricmp(str1, p->filename)) +		{ +			if (fseek(pakfile[m_nPAKIndex], p->offset, SEEK_SET) < 0) +			{ +				//Sys_Printf("Unexpected EOF in pakfile\n"); +				return false; +			} +			if((buffer = __qmalloc(p->size+5)) == NULL) +				//Error("Could not allocate memory"); +	 +			if(fread(buffer, 1, p->size, pakfile[m_nPAKIndex]) != p->size) +			{ +				//Sys_Printf("Error reading %s from pak\n", str1); +				free(buffer); +				return false; +			} +			*bufferptr = buffer; +			return true; +		} +	} +	return false; +} + +int PakLoadAnyFile(const char *filename, void **bufferptr) +{ +  char cWork[WORK_LEN]; +  if (g_bPK3) +  { +    PK3FileInfo *pInfo; +    Str strKey; +    // need to lookup the file without the base/texture path on it +    Str strBase(g_strBasePath); +    AddSlash(strBase); +    __ConvertDOSToUnixName(cWork, strBase); +    Str strFile(filename); +    __ConvertDOSToUnixName(strFile, strFile); +    strFile.MakeLower(); +    strlwr(cWork); +    FindReplace(strFile, cWork, ""); + +    PK3FileInfo infoFind; +    infoFind.m_pName = __StrDup(strFile.GetBuffer()); +    PK3List *pList = g_PK3Files.Find(&infoFind); +    if (pList) +    { +      pInfo = pList->Ptr(); +      memcpy(pInfo->m_zFile, &pInfo->m_zInfo, sizeof(unz_s)); +      if (unzOpenCurrentFile(pInfo->m_zFile) == UNZ_OK) +      { +        void *buffer = __qblockmalloc(pInfo->m_lSize+1); +        int n = unzReadCurrentFile(pInfo->m_zFile , buffer, pInfo->m_lSize); +        *bufferptr = buffer; +        unzCloseCurrentFile(pInfo->m_zFile); +        return n; +      } +    } +#ifdef LOG_PAKFAIL +    sprintf(cWork, "PAK failed on %s\n", filename); +    g_LogFile.Log(cWork); +#endif +    return -1; +  } + +	for (int i = 0; i < dirsize; i++) +	{ +		if(!stricmp(filename, pakdirptr[i].name)) +		{ +			if (fseek(pakfile[m_nPAKIndex], pakdirptr[i].offset, SEEK_SET) >= 0) +      { +	      void *buffer = __qmalloc (pakdirptr[i].size+1); +	      ((char *)buffer)[pakdirptr[i].size] = 0; +			  if (fread(buffer, 1, pakdirptr[i].size, pakfile[m_nPAKIndex]) == pakdirptr[i].size) +        { +          *bufferptr = buffer; +          return pakdirptr[i].size; +        } +      } +		} +	} +#ifdef LOG_PAKFAIL +    sprintf(cWork, "PAK failed on %s\n", filename); +    g_LogFile.Log(cWork); +#endif +  return -1; +} + + + +DIRECTORY *AddPakDir(DIRECTORY **dir, char *name) +{ +	DIRECTORY	*currentPtr, *previousPtr, *newPtr; + +	for(currentPtr = *dir; currentPtr; currentPtr = currentPtr->next) +	{ +		if(!stricmp(name, currentPtr->name)) +		{ +			return currentPtr; +		} +	} +	previousPtr = NULL; +	currentPtr = *dir; + +	if((newPtr = (DIRECTORY *)__qmalloc(sizeof(DIRECTORY))) == NULL) +		return NULL; + +	strcpy(newPtr->name, name); +	newPtr->files = NULL; + +	while(currentPtr != NULL && stricmp(name, currentPtr->name) > 0) +	{ +		previousPtr = currentPtr; +		currentPtr = currentPtr->next; +	} +	if(previousPtr == NULL) +	{ +		newPtr->next = *dir; +		*dir = newPtr; +	} +	else +	{ +		previousPtr->next = newPtr; +		newPtr->next = currentPtr; +	} +	return newPtr; +} + + +// OpenPK3 +// ------- +// Opens a PK3 ( or zip ) file and creates a list of filenames +// and zip info structures +//  +boolean OpenPK3(const char *filename) +{ +  char cFilename[WORK_LEN]; +  char cName[WORK_LEN]; +  char cWork[WORK_LEN]; +  unz_file_info zInfo; +  unzFile *zFile = new unzFile(unzOpen(filename)); +  g_zFiles.Add(zFile); +  if (zFile != NULL) +  { +    int nStatus = unzGoToFirstFile(*zFile); +    while (nStatus == UNZ_OK) +    { +      cFilename[0] = '\0'; +      unzGetCurrentFileInfo(*zFile, &zInfo, cFilename, WORK_LEN, NULL, 0, NULL, 0); +      strlwr(cFilename); +    	__ConvertDOSToUnixName( cWork, cFilename); +      if (strstr(cWork, ".") != NULL) +      { +        PK3FileInfo *pInfo = new PK3FileInfo(); +        pInfo->m_pName = __StrDup(cWork); +        memcpy(&pInfo->m_zInfo, (unz_s*)*zFile, sizeof(unz_s)); +        pInfo->m_lSize = zInfo.uncompressed_size; +        pInfo->m_zFile = *zFile; +        g_PK3Files.Add(pInfo); +      } +      char *p = strstr(cFilename, TEXTURE_PATH); +      if (p != NULL) +      { +        // FIXME: path differences per os ? +        // catch solo directory entry +        if (strlen(p) > strlen(TEXTURE_PATH) + 1) +        { +          // skip textures + path seperator +          p += strlen(TEXTURE_PATH) + 1; +          int nEnd = strcspn(p, PATH_SEPERATORS); +          strncpy(cName, p, nEnd); +          cName[nEnd] = '\0'; + +          boolean bFound = false; +          StrList *pl = g_PK3TexturePaths.Next(); +          while (pl != NULL) +          { +            if (strcmpi(pl->Ref(), cName) == 0) +            { +              // already have this, continue +              bFound = true; +              break; +            } +            pl = pl->Next(); +          } +          if (!bFound) +          { +            g_PK3TexturePaths.Add(new Str(cName)); +          } +        } +      } +      nStatus = unzGoToNextFile(*zFile); +    } +  } +  return (zFile != NULL); +} + +void closePK3(unzFile zf) +{ +  unzClose(zf); +} + +void OpenPakFile(const char *filename) +{ +	int			i; +	char		*str1, *str2; +	DIRECTORY	*dummy; + +	if(!pakopen) +		paktextures = NULL; + +	HavePakColormap = false; + +  Str strTest(filename); +  strTest.MakeLower(); +  if (strTest.Find("pk3") >= 0 || strTest.Find("zip") >= 0) +  { +    pakopen = g_bPK3 = OpenPK3(filename); +    return; +  } + + +	if((pakfile[m_nPAKIndex] = OpenFileReadMagic(filename, &f_type)) == NULL) +	{ +    //FIXME: error routine +		//Sys_Printf("ERROR: Could not open %s", filename); +		return; +	} +	if(f_type != FTYPE_PACK) +	{ +		//Sys_Printf("ERROR: %s is not a valid pack file", filename); +		if(f_type != FTYPE_ERROR) +			fclose(pakfile[m_nPAKIndex]); +		return; +	} +	pakdirptr = ReadPACKDirectory(pakfile[m_nPAKIndex], 0, &dirsize); +	if (pakdirptr == NULL) +	{ +		//Sys_Printf("ERROR: Could not read pack directory", filename); +		fclose(pakfile[m_nPAKIndex]); +		return; +	} +	if (dirsize == 0) +	{ +		fclose(pakfile[m_nPAKIndex]); +		return; +	} +	for (i = 0; i < dirsize; i++) +	{ +		if(!strnicmp("textures/", pakdirptr[i].name, 9)) +		{ +			dummy = paktextures; +			str1 = pakdirptr[i].name+9; +			while(strchr(str1, '/')) +			{ +				str2 = strchr(str1, '/'); +				*str2++ = '\0'; +					dummy = AddPakDir(dummy==paktextures?&paktextures:&dummy, str1); +				str1 = str2; +			} + +			AddToFileListAlphabetized(&(dummy->files), str1, pakdirptr[i].offset, pakdirptr[i].size, true); +		} +		else if(!strnicmp("pics/colormap.pcx", pakdirptr[i].name, 17)) +		{ +			HavePakColormap = true; +			PakColormapOffset = pakdirptr[i].offset; +			PakColormapSize = pakdirptr[i].size; +		} +	} +	pakopen = true; + +} + +void ClearPaKDir(DIRECTORY **dir) +{ +	DIRECTORY	*d1 = *dir, *d2; + +	while(d1) +	{ +		ClearFileList(&(d1->files)); +		d2 = d1; +		d1 = d1->next; +		free(d2); +	} +} + +void CleanUpPakDirs() +{ +  ClearPaKDir(&paktextures); +  paktextures = NULL; +  dirhead = NULL; +  g_PK3TexturePaths.RemoveAll(); +  g_PK3Files.RemoveAll(); +} + +void ClosePakFile(void) +{ +	if(pakopen) +  { +    if (g_bPK3) +    { +      ZFileList *p = g_zFiles.Next(); +      while (p != NULL) +      { +        unzFile uz = p->Ref(); +        closePK3(uz); +        p = p->Next(); +      } +    } +    else +    { +      fclose(pakfile[m_nPAKIndex]); +    } +  } +	pakopen = false; +  CleanUpPakDirs(); +} + + +void WINAPI InitPakFile(const char * pBasePath, const char *pName) +{ +  m_nPAKIndex = 0; +  pakopen = false; +	paktextures = NULL; +  strcpy(g_strBasePath, pBasePath); +  if (pName == NULL) +  { +    char cWork[WORK_LEN]; +	  Str strPath(pBasePath); +    AddSlash(strPath); +  	strPath += "*.pk3"; +  	bool bGo = true; +	  struct _finddata_t fileinfo; +  	int handle = _findfirst (strPath, &fileinfo); +	  if (handle != -1) +  	{ +	  	do +		  { +        sprintf(cWork, "%s\\%s", pBasePath, fileinfo.name); +        OpenPakFile(cWork); +		  } while (_findnext( handle, &fileinfo ) != -1); +	    _findclose (handle); +    } +	} +  else +  { +	  OpenPakFile(pName); +  } +} + diff --git a/libs/pak/unzip.cpp b/libs/pak/unzip.cpp index 20087da..8dc82c4 100755 --- a/libs/pak/unzip.cpp +++ b/libs/pak/unzip.cpp @@ -1,4546 +1,4546 @@ -/*****************************************************************************
 - * name:		unzip.c
 - *
 - * desc:		IO on .zip files using portions of zlib 
 - *
 - * $Archive: /source/code/qcommon/unzip.c $
 - * $Author: ttimo $ 
 - * $Revision: 1.1.1.3 $
 - * $Modtime: 10/19/99 3:59p $
 - * $Date: 2000/01/11 16:37:27 $
 - *
 - *****************************************************************************/
 -
 -#include <stdio.h>
 -#include <string.h>
 -#include <windows.h>
 -#include "unzip.h"
 -//#include "cmdlib.h"
 -
 -/* unzip.h -- IO for uncompress .zip files using zlib 
 -   Version 0.15 beta, Mar 19th, 1998,
 -
 -   Copyright (C) 1998 Gilles Vollant
 -
 -   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
 -     WinZip, InfoZip tools and compatible.
 -   Encryption and multi volume ZipFile (span) are not supported.
 -   Old compressions used by old PKZip 1.x are not supported
 -
 -   THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
 -   CAN CHANGE IN FUTURE VERSION !!
 -   I WAIT FEEDBACK at mail info@winimage.com
 -   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
 -
 -   Condition of use and distribution are the same than zlib :
 -
 -  This software is provided 'as-is', without any express or implied
 -  warranty.  In no event will the authors be held liable for any damages
 -  arising from the use of this software.
 -
 -  Permission is granted to anyone to use this software for any purpose,
 -  including commercial applications, and to alter it and redistribute it
 -  freely, subject to the following restrictions:
 -
 -  1. The origin of this software must not be misrepresented; you must not
 -     claim that you wrote the original software. If you use this software
 -     in a product, an acknowledgment in the product documentation would be
 -     appreciated but is not required.
 -  2. Altered source versions must be plainly marked as such, and must not be
 -     misrepresented as being the original software.
 -  3. This notice may not be removed or altered from any source distribution.
 -
 -
 -*/
 -/* for more info about .ZIP format, see 
 -      ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
 -   PkWare has also a specification at :
 -      ftp://ftp.pkware.com/probdesc.zip */
 -
 -/* zlib.h -- interface of the 'zlib' general purpose compression library
 -  version 1.1.3, July 9th, 1998
 -
 -  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
 -
 -  This software is provided 'as-is', without any express or implied
 -  warranty.  In no event will the authors be held liable for any damages
 -  arising from the use of this software.
 -
 -  Permission is granted to anyone to use this software for any purpose,
 -  including commercial applications, and to alter it and redistribute it
 -  freely, subject to the following restrictions:
 -
 -  1. The origin of this software must not be misrepresented; you must not
 -     claim that you wrote the original software. If you use this software
 -     in a product, an acknowledgment in the product documentation would be
 -     appreciated but is not required.
 -  2. Altered source versions must be plainly marked as such, and must not be
 -     misrepresented as being the original software.
 -  3. This notice may not be removed or altered from any source distribution.
 -
 -  Jean-loup Gailly        Mark Adler
 -  jloup@gzip.org          madler@alumni.caltech.edu
 -
 -
 -  The data format used by the zlib library is described by RFCs (Request for
 -  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
 -  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
 -*/
 -
 -/* zconf.h -- configuration of the zlib compression library
 - * Copyright (C) 1995-1998 Jean-loup Gailly.
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */
 -
 -#ifndef _ZCONF_H
 -#define _ZCONF_H
 -
 -/* Maximum value for memLevel in deflateInit2 */
 -#ifndef MAX_MEM_LEVEL
 -#  ifdef MAXSEG_64K
 -#    define MAX_MEM_LEVEL 8
 -#  else
 -#    define MAX_MEM_LEVEL 9
 -#  endif
 -#endif
 -
 -/* Maximum value for windowBits in deflateInit2 and inflateInit2.
 - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
 - * created by gzip. (Files created by minigzip can still be extracted by
 - * gzip.)
 - */
 -#ifndef MAX_WBITS
 -#  define MAX_WBITS   15 /* 32K LZ77 window */
 -#endif
 -
 -/* The memory requirements for deflate are (in bytes):
 -            (1 << (windowBits+2)) +  (1 << (memLevel+9))
 - that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
 - plus a few kilobytes for small objects. For example, if you want to reduce
 - the default memory requirements from 256K to 128K, compile with
 -     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
 - Of course this will generally degrade compression (there's no free lunch).
 -
 -   The memory requirements for inflate are (in bytes) 1 << windowBits
 - that is, 32K for windowBits=15 (default value) plus a few kilobytes
 - for small objects.
 -*/
 -
 -                        /* Type declarations */
 -
 -#ifndef OF /* function prototypes */
 -#define OF(args)  args
 -#endif
 -
 -typedef unsigned char  Byte;  /* 8 bits */
 -typedef unsigned int   uInt;  /* 16 bits or more */
 -typedef unsigned long  uLong; /* 32 bits or more */
 -typedef Byte    *voidp;
 -
 -#ifndef SEEK_SET
 -#  define SEEK_SET        0       /* Seek from beginning of file.  */
 -#  define SEEK_CUR        1       /* Seek from current position.  */
 -#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
 -#endif
 -
 -#endif /* _ZCONF_H */
 -
 -#define ZLIB_VERSION "1.1.3"
 -
 -/* 
 -     The 'zlib' compression library provides in-memory compression and
 -  decompression functions, including integrity checks of the uncompressed
 -  data.  This version of the library supports only one compression method
 -  (deflation) but other algorithms will be added later and will have the same
 -  stream interface.
 -
 -     Compression can be done in a single step if the buffers are large
 -  enough (for example if an input file is mmap'ed), or can be done by
 -  repeated calls of the compression function.  In the latter case, the
 -  application must provide more input and/or consume the output
 -  (providing more output space) before each call.
 -
 -     The library also supports reading and writing files in gzip (.gz) format
 -  with an interface similar to that of stdio.
 -
 -     The library does not install any signal handler. The decoder checks
 -  the consistency of the compressed data, so the library should never
 -  crash even in case of corrupted input.
 -*/
 -
 -/*
 -   The application must update next_in and avail_in when avail_in has
 -   dropped to zero. It must update next_out and avail_out when avail_out
 -   has dropped to zero. The application must initialize zalloc, zfree and
 -   opaque before calling the init function. All other fields are set by the
 -   compression library and must not be updated by the application.
 -
 -   The opaque value provided by the application will be passed as the first
 -   parameter for calls of zalloc and zfree. This can be useful for custom
 -   memory management. The compression library attaches no meaning to the
 -   opaque value.
 -
 -   zalloc must return Z_NULL if there is not enough memory for the object.
 -   If zlib is used in a multi-threaded application, zalloc and zfree must be
 -   thread safe.
 -
 -   On 16-bit systems, the functions zalloc and zfree must be able to allocate
 -   exactly 65536 bytes, but will not be required to allocate more than this
 -   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
 -   pointers returned by zalloc for objects of exactly 65536 bytes *must*
 -   have their offset normalized to zero. The default allocation function
 -   provided by this library ensures this (see zutil.c). To reduce memory
 -   requirements and avoid any allocation of 64K objects, at the expense of
 -   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
 -
 -   The fields total_in and total_out can be used for statistics or
 -   progress reports. After compression, total_in holds the total size of
 -   the uncompressed data and may be saved for use in the decompressor
 -   (particularly if the decompressor wants to decompress everything in
 -   a single step).
 -*/
 -
 -                        /* constants */
 -
 -#define Z_NO_FLUSH      0
 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
 -#define Z_SYNC_FLUSH    2
 -#define Z_FULL_FLUSH    3
 -#define Z_FINISH        4
 -/* Allowed flush values; see deflate() below for details */
 -
 -#define Z_OK            0
 -#define Z_STREAM_END    1
 -#define Z_NEED_DICT     2
 -#define Z_ERRNO        (-1)
 -#define Z_STREAM_ERROR (-2)
 -#define Z_DATA_ERROR   (-3)
 -#define Z_MEM_ERROR    (-4)
 -#define Z_BUF_ERROR    (-5)
 -#define Z_VERSION_ERROR (-6)
 -/* Return codes for the compression/decompression functions. Negative
 - * values are errors, positive values are used for special but normal events.
 - */
 -
 -#define Z_NO_COMPRESSION         0
 -#define Z_BEST_SPEED             1
 -#define Z_BEST_COMPRESSION       9
 -#define Z_DEFAULT_COMPRESSION  (-1)
 -/* compression levels */
 -
 -#define Z_FILTERED            1
 -#define Z_HUFFMAN_ONLY        2
 -#define Z_DEFAULT_STRATEGY    0
 -/* compression strategy; see deflateInit2() below for details */
 -
 -#define Z_BINARY   0
 -#define Z_ASCII    1
 -#define Z_UNKNOWN  2
 -/* Possible values of the data_type field */
 -
 -#define Z_DEFLATED   8
 -/* The deflate compression method (the only one supported in this version) */
 -
 -#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
 -
 -#define zlib_version zlibVersion()
 -/* for compatibility with versions < 1.0.2 */
 -
 -                        /* basic functions */
 -
 -const char * zlibVersion OF((void));
 -/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
 -   If the first character differs, the library code actually used is
 -   not compatible with the zlib.h header file used by the application.
 -   This check is automatically made by deflateInit and inflateInit.
 - */
 -
 -/* 
 -int deflateInit OF((z_streamp strm, int level));
 -
 -     Initializes the internal stream state for compression. The fields
 -   zalloc, zfree and opaque must be initialized before by the caller.
 -   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
 -   use default allocation functions.
 -
 -     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
 -   1 gives best speed, 9 gives best compression, 0 gives no compression at
 -   all (the input data is simply copied a block at a time).
 -   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
 -   compression (currently equivalent to level 6).
 -
 -     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
 -   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
 -   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
 -   with the version assumed by the caller (ZLIB_VERSION).
 -   msg is set to null if there is no error message.  deflateInit does not
 -   perform any compression: this will be done by deflate().
 -*/
 -
 -
 -int deflate OF((z_streamp strm, int flush));
 -/*
 -    deflate compresses as much data as possible, and stops when the input
 -  buffer becomes empty or the output buffer becomes full. It may introduce some
 -  output latency (reading input without producing any output) except when
 -  forced to flush.
 -
 -    The detailed semantics are as follows. deflate performs one or both of the
 -  following actions:
 -
 -  - Compress more input starting at next_in and update next_in and avail_in
 -    accordingly. If not all input can be processed (because there is not
 -    enough room in the output buffer), next_in and avail_in are updated and
 -    processing will resume at this point for the next call of deflate().
 -
 -  - Provide more output starting at next_out and update next_out and avail_out
 -    accordingly. This action is forced if the parameter flush is non zero.
 -    Forcing flush frequently degrades the compression ratio, so this parameter
 -    should be set only when necessary (in interactive applications).
 -    Some output may be provided even if flush is not set.
 -
 -  Before the call of deflate(), the application should ensure that at least
 -  one of the actions is possible, by providing more input and/or consuming
 -  more output, and updating avail_in or avail_out accordingly; avail_out
 -  should never be zero before the call. The application can consume the
 -  compressed output when it wants, for example when the output buffer is full
 -  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
 -  and with zero avail_out, it must be called again after making room in the
 -  output buffer because there might be more output pending.
 -
 -    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
 -  flushed to the output buffer and the output is aligned on a byte boundary, so
 -  that the decompressor can get all input data available so far. (In particular
 -  avail_in is zero after the call if enough output space has been provided
 -  before the call.)  Flushing may degrade compression for some compression
 -  algorithms and so it should be used only when necessary.
 -
 -    If flush is set to Z_FULL_FLUSH, all output is flushed as with
 -  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
 -  restart from this point if previous compressed data has been damaged or if
 -  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
 -  the compression.
 -
 -    If deflate returns with avail_out == 0, this function must be called again
 -  with the same value of the flush parameter and more output space (updated
 -  avail_out), until the flush is complete (deflate returns with non-zero
 -  avail_out).
 -
 -    If the parameter flush is set to Z_FINISH, pending input is processed,
 -  pending output is flushed and deflate returns with Z_STREAM_END if there
 -  was enough output space; if deflate returns with Z_OK, this function must be
 -  called again with Z_FINISH and more output space (updated avail_out) but no
 -  more input data, until it returns with Z_STREAM_END or an error. After
 -  deflate has returned Z_STREAM_END, the only possible operations on the
 -  stream are deflateReset or deflateEnd.
 -  
 -    Z_FINISH can be used immediately after deflateInit if all the compression
 -  is to be done in a single step. In this case, avail_out must be at least
 -  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
 -  Z_STREAM_END, then it must be called again as described above.
 -
 -    deflate() sets strm->adler to the adler32 checksum of all input read
 -  so (that is, total_in bytes).
 -
 -    deflate() may update data_type if it can make a good guess about
 -  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
 -  binary. This field is only for information purposes and does not affect
 -  the compression algorithm in any manner.
 -
 -    deflate() returns Z_OK if some progress has been made (more input
 -  processed or more output produced), Z_STREAM_END if all input has been
 -  consumed and all output has been produced (only when flush is set to
 -  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
 -  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
 -  (for example avail_in or avail_out was zero).
 -*/
 -
 -
 -int deflateEnd OF((z_streamp strm));
 -/*
 -     All dynamically allocated data structures for this stream are freed.
 -   This function discards any unprocessed input and does not flush any
 -   pending output.
 -
 -     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
 -   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
 -   prematurely (some input or output was discarded). In the error case,
 -   msg may be set but then points to a static string (which must not be
 -   deallocated).
 -*/
 -
 -
 -/* 
 -int inflateInit OF((z_streamp strm));
 -
 -     Initializes the internal stream state for decompression. The fields
 -   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
 -   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
 -   value depends on the compression method), inflateInit determines the
 -   compression method from the zlib header and allocates all data structures
 -   accordingly; otherwise the allocation will be deferred to the first call of
 -   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
 -   use default allocation functions.
 -
 -     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
 -   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
 -   version assumed by the caller.  msg is set to null if there is no error
 -   message. inflateInit does not perform any decompression apart from reading
 -   the zlib header if present: this will be done by inflate().  (So next_in and
 -   avail_in may be modified, but next_out and avail_out are unchanged.)
 -*/
 -
 -
 -int inflate OF((z_streamp strm, int flush));
 -/*
 -    inflate decompresses as much data as possible, and stops when the input
 -  buffer becomes empty or the output buffer becomes full. It may some
 -  introduce some output latency (reading input without producing any output)
 -  except when forced to flush.
 -
 -  The detailed semantics are as follows. inflate performs one or both of the
 -  following actions:
 -
 -  - Decompress more input starting at next_in and update next_in and avail_in
 -    accordingly. If not all input can be processed (because there is not
 -    enough room in the output buffer), next_in is updated and processing
 -    will resume at this point for the next call of inflate().
 -
 -  - Provide more output starting at next_out and update next_out and avail_out
 -    accordingly.  inflate() provides as much output as possible, until there
 -    is no more input data or no more space in the output buffer (see below
 -    about the flush parameter).
 -
 -  Before the call of inflate(), the application should ensure that at least
 -  one of the actions is possible, by providing more input and/or consuming
 -  more output, and updating the next_* and avail_* values accordingly.
 -  The application can consume the uncompressed output when it wants, for
 -  example when the output buffer is full (avail_out == 0), or after each
 -  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
 -  must be called again after making room in the output buffer because there
 -  might be more output pending.
 -
 -    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
 -  output as possible to the output buffer. The flushing behavior of inflate is
 -  not specified for values of the flush parameter other than Z_SYNC_FLUSH
 -  and Z_FINISH, but the current implementation actually flushes as much output
 -  as possible anyway.
 -
 -    inflate() should normally be called until it returns Z_STREAM_END or an
 -  error. However if all decompression is to be performed in a single step
 -  (a single call of inflate), the parameter flush should be set to
 -  Z_FINISH. In this case all pending input is processed and all pending
 -  output is flushed; avail_out must be large enough to hold all the
 -  uncompressed data. (The size of the uncompressed data may have been saved
 -  by the compressor for this purpose.) The next operation on this stream must
 -  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
 -  is never required, but can be used to inform inflate that a faster routine
 -  may be used for the single inflate() call.
 -
 -     If a preset dictionary is needed at this point (see inflateSetDictionary
 -  below), inflate sets strm-adler to the adler32 checksum of the
 -  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
 -  it sets strm->adler to the adler32 checksum of all output produced
 -  so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
 -  an error code as described below. At the end of the stream, inflate()
 -  checks that its computed adler32 checksum is equal to that saved by the
 -  compressor and returns Z_STREAM_END only if the checksum is correct.
 -
 -    inflate() returns Z_OK if some progress has been made (more input processed
 -  or more output produced), Z_STREAM_END if the end of the compressed data has
 -  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
 -  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
 -  corrupted (input stream not conforming to the zlib format or incorrect
 -  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
 -  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
 -  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
 -  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
 -  case, the application may then call inflateSync to look for a good
 -  compression block.
 -*/
 -
 -
 -int inflateEnd OF((z_streamp strm));
 -/*
 -     All dynamically allocated data structures for this stream are freed.
 -   This function discards any unprocessed input and does not flush any
 -   pending output.
 -
 -     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
 -   was inconsistent. In the error case, msg may be set but then points to a
 -   static string (which must not be deallocated).
 -*/
 -
 -                        /* Advanced functions */
 -
 -/*
 -    The following functions are needed only in some special applications.
 -*/
 -
 -/*   
 -int deflateInit2 OF((z_streamp strm,
 -                                     int  level,
 -                                     int  method,
 -                                     int  windowBits,
 -                                     int  memLevel,
 -                                     int  strategy));
 -
 -     This is another version of deflateInit with more compression options. The
 -   fields next_in, zalloc, zfree and opaque must be initialized before by
 -   the caller.
 -
 -     The method parameter is the compression method. It must be Z_DEFLATED in
 -   this version of the library.
 -
 -     The windowBits parameter is the base two logarithm of the window size
 -   (the size of the history buffer).  It should be in the range 8..15 for this
 -   version of the library. Larger values of this parameter result in better
 -   compression at the expense of memory usage. The default value is 15 if
 -   deflateInit is used instead.
 -
 -     The memLevel parameter specifies how much memory should be allocated
 -   for the internal compression state. memLevel=1 uses minimum memory but
 -   is slow and reduces compression ratio; memLevel=9 uses maximum memory
 -   for optimal speed. The default value is 8. See zconf.h for total memory
 -   usage as a function of windowBits and memLevel.
 -
 -     The strategy parameter is used to tune the compression algorithm. Use the
 -   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
 -   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
 -   string match).  Filtered data consists mostly of small values with a
 -   somewhat random distribution. In this case, the compression algorithm is
 -   tuned to compress them better. The effect of Z_FILTERED is to force more
 -   Huffman coding and less string matching; it is somewhat intermediate
 -   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
 -   the compression ratio but not the correctness of the compressed output even
 -   if it is not set appropriately.
 -
 -      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 -   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
 -   method). msg is set to null if there is no error message.  deflateInit2 does
 -   not perform any compression: this will be done by deflate().
 -*/
 -                            
 -int deflateSetDictionary OF((z_streamp strm,
 -                                             const Byte *dictionary,
 -                                             uInt  dictLength));
 -/*
 -     Initializes the compression dictionary from the given byte sequence
 -   without producing any compressed output. This function must be called
 -   immediately after deflateInit, deflateInit2 or deflateReset, before any
 -   call of deflate. The compressor and decompressor must use exactly the same
 -   dictionary (see inflateSetDictionary).
 -
 -     The dictionary should consist of strings (byte sequences) that are likely
 -   to be encountered later in the data to be compressed, with the most commonly
 -   used strings preferably put towards the end of the dictionary. Using a
 -   dictionary is most useful when the data to be compressed is short and can be
 -   predicted with good accuracy; the data can then be compressed better than
 -   with the default empty dictionary.
 -
 -     Depending on the size of the compression data structures selected by
 -   deflateInit or deflateInit2, a part of the dictionary may in effect be
 -   discarded, for example if the dictionary is larger than the window size in
 -   deflate or deflate2. Thus the strings most likely to be useful should be
 -   put at the end of the dictionary, not at the front.
 -
 -     Upon return of this function, strm->adler is set to the Adler32 value
 -   of the dictionary; the decompressor may later use this value to determine
 -   which dictionary has been used by the compressor. (The Adler32 value
 -   applies to the whole dictionary even if only a subset of the dictionary is
 -   actually used by the compressor.)
 -
 -     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
 -   parameter is invalid (such as NULL dictionary) or the stream state is
 -   inconsistent (for example if deflate has already been called for this stream
 -   or if the compression method is bsort). deflateSetDictionary does not
 -   perform any compression: this will be done by deflate().
 -*/
 -
 -int deflateCopy OF((z_streamp dest,
 -                                    z_streamp source));
 -/*
 -     Sets the destination stream as a complete copy of the source stream.
 -
 -     This function can be useful when several compression strategies will be
 -   tried, for example when there are several ways of pre-processing the input
 -   data with a filter. The streams that will be discarded should then be freed
 -   by calling deflateEnd.  Note that deflateCopy duplicates the internal
 -   compression state which can be quite large, so this strategy is slow and
 -   can consume lots of memory.
 -
 -     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
 -   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
 -   (such as zalloc being NULL). msg is left unchanged in both source and
 -   destination.
 -*/
 -
 -int deflateReset OF((z_streamp strm));
 -/*
 -     This function is equivalent to deflateEnd followed by deflateInit,
 -   but does not free and reallocate all the internal compression state.
 -   The stream will keep the same compression level and any other attributes
 -   that may have been set by deflateInit2.
 -
 -      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
 -   stream state was inconsistent (such as zalloc or state being NULL).
 -*/
 -
 -int deflateParams OF((z_streamp strm,
 -				      int level,
 -				      int strategy));
 -/*
 -     Dynamically update the compression level and compression strategy.  The
 -   interpretation of level and strategy is as in deflateInit2.  This can be
 -   used to switch between compression and straight copy of the input data, or
 -   to switch to a different kind of input data requiring a different
 -   strategy. If the compression level is changed, the input available so far
 -   is compressed with the old level (and may be flushed); the new level will
 -   take effect only at the next call of deflate().
 -
 -     Before the call of deflateParams, the stream state must be set as for
 -   a call of deflate(), since the currently available input may have to
 -   be compressed and flushed. In particular, strm->avail_out must be non-zero.
 -
 -     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
 -   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
 -   if strm->avail_out was zero.
 -*/
 -
 -/*   
 -int inflateInit2 OF((z_streamp strm,
 -                                     int  windowBits));
 -
 -     This is another version of inflateInit with an extra parameter. The
 -   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
 -   before by the caller.
 -
 -     The windowBits parameter is the base two logarithm of the maximum window
 -   size (the size of the history buffer).  It should be in the range 8..15 for
 -   this version of the library. The default value is 15 if inflateInit is used
 -   instead. If a compressed stream with a larger window size is given as
 -   input, inflate() will return with the error code Z_DATA_ERROR instead of
 -   trying to allocate a larger window.
 -
 -      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 -   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
 -   memLevel). msg is set to null if there is no error message.  inflateInit2
 -   does not perform any decompression apart from reading the zlib header if
 -   present: this will be done by inflate(). (So next_in and avail_in may be
 -   modified, but next_out and avail_out are unchanged.)
 -*/
 -
 -int inflateSetDictionary OF((z_streamp strm,
 -                                             const Byte *dictionary,
 -                                             uInt  dictLength));
 -/*
 -     Initializes the decompression dictionary from the given uncompressed byte
 -   sequence. This function must be called immediately after a call of inflate
 -   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
 -   can be determined from the Adler32 value returned by this call of
 -   inflate. The compressor and decompressor must use exactly the same
 -   dictionary (see deflateSetDictionary).
 -
 -     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
 -   parameter is invalid (such as NULL dictionary) or the stream state is
 -   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
 -   expected one (incorrect Adler32 value). inflateSetDictionary does not
 -   perform any decompression: this will be done by subsequent calls of
 -   inflate().
 -*/
 -
 -int inflateSync OF((z_streamp strm));
 -/* 
 -    Skips invalid compressed data until a full flush point (see above the
 -  description of deflate with Z_FULL_FLUSH) can be found, or until all
 -  available input is skipped. No output is provided.
 -
 -    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
 -  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
 -  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
 -  case, the application may save the current current value of total_in which
 -  indicates where valid compressed data was found. In the error case, the
 -  application may repeatedly call inflateSync, providing more input each time,
 -  until success or end of the input data.
 -*/
 -
 -int inflateReset OF((z_streamp strm));
 -/*
 -     This function is equivalent to inflateEnd followed by inflateInit,
 -   but does not free and reallocate all the internal decompression state.
 -   The stream will keep attributes that may have been set by inflateInit2.
 -
 -      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
 -   stream state was inconsistent (such as zalloc or state being NULL).
 -*/
 -
 -
 -                        /* utility functions */
 -
 -/*
 -     The following utility functions are implemented on top of the
 -   basic stream-oriented functions. To simplify the interface, some
 -   default options are assumed (compression level and memory usage,
 -   standard memory allocation functions). The source code of these
 -   utility functions can easily be modified if you need special options.
 -*/
 -
 -int compress OF((Byte *dest,   uLong *destLen,
 -                                 const Byte *source, uLong sourceLen));
 -/*
 -     Compresses the source buffer into the destination buffer.  sourceLen is
 -   the byte length of the source buffer. Upon entry, destLen is the total
 -   size of the destination buffer, which must be at least 0.1% larger than
 -   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
 -   compressed buffer.
 -     This function can be used to compress a whole file at once if the
 -   input file is mmap'ed.
 -     compress returns Z_OK if success, Z_MEM_ERROR if there was not
 -   enough memory, Z_BUF_ERROR if there was not enough room in the output
 -   buffer.
 -*/
 -
 -int compress2 OF((Byte *dest,   uLong *destLen,
 -                                  const Byte *source, uLong sourceLen,
 -                                  int level));
 -/*
 -     Compresses the source buffer into the destination buffer. The level
 -   parameter has the same meaning as in deflateInit.  sourceLen is the byte
 -   length of the source buffer. Upon entry, destLen is the total size of the
 -   destination buffer, which must be at least 0.1% larger than sourceLen plus
 -   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
 -
 -     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 -   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
 -   Z_STREAM_ERROR if the level parameter is invalid.
 -*/
 -
 -int uncompress OF((Byte *dest,   uLong *destLen,
 -                                   const Byte *source, uLong sourceLen));
 -/*
 -     Decompresses the source buffer into the destination buffer.  sourceLen is
 -   the byte length of the source buffer. Upon entry, destLen is the total
 -   size of the destination buffer, which must be large enough to hold the
 -   entire uncompressed data. (The size of the uncompressed data must have
 -   been saved previously by the compressor and transmitted to the decompressor
 -   by some mechanism outside the scope of this compression library.)
 -   Upon exit, destLen is the actual size of the compressed buffer.
 -     This function can be used to decompress a whole file at once if the
 -   input file is mmap'ed.
 -
 -     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
 -   enough memory, Z_BUF_ERROR if there was not enough room in the output
 -   buffer, or Z_DATA_ERROR if the input data was corrupted.
 -*/
 -
 -
 -typedef voidp gzFile;
 -
 -gzFile gzopen  OF((const char *path, const char *mode));
 -/*
 -     Opens a gzip (.gz) file for reading or writing. The mode parameter
 -   is as in fopen ("rb" or "wb") but can also include a compression level
 -   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
 -   Huffman only compression as in "wb1h". (See the description
 -   of deflateInit2 for more information about the strategy parameter.)
 -
 -     gzopen can be used to read a file which is not in gzip format; in this
 -   case gzread will directly read from the file without decompression.
 -
 -     gzopen returns NULL if the file could not be opened or if there was
 -   insufficient memory to allocate the (de)compression state; errno
 -   can be checked to distinguish the two cases (if errno is zero, the
 -   zlib error is Z_MEM_ERROR).  */
 -
 -gzFile gzdopen  OF((int fd, const char *mode));
 -/*
 -     gzdopen() associates a gzFile with the file descriptor fd.  File
 -   descriptors are obtained from calls like open, dup, creat, pipe or
 -   fileno (in the file has been previously opened with fopen).
 -   The mode parameter is as in gzopen.
 -     The next call of gzclose on the returned gzFile will also close the
 -   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
 -   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
 -     gzdopen returns NULL if there was insufficient memory to allocate
 -   the (de)compression state.
 -*/
 -
 -int gzsetparams OF((gzFile file, int level, int strategy));
 -/*
 -     Dynamically update the compression level or strategy. See the description
 -   of deflateInit2 for the meaning of these parameters.
 -     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
 -   opened for writing.
 -*/
 -
 -int    gzread  OF((gzFile file, voidp buf, unsigned len));
 -/*
 -     Reads the given number of uncompressed bytes from the compressed file.
 -   If the input file was not in gzip format, gzread copies the given number
 -   of bytes into the buffer.
 -     gzread returns the number of uncompressed bytes actually read (0 for
 -   end of file, -1 for error). */
 -
 -int    gzwrite OF((gzFile file, 
 -				   const voidp buf, unsigned len));
 -/*
 -     Writes the given number of uncompressed bytes into the compressed file.
 -   gzwrite returns the number of uncompressed bytes actually written
 -   (0 in case of error).
 -*/
 -
 -int    gzprintf OF((gzFile file, const char *format, ...));
 -/*
 -     Converts, formats, and writes the args to the compressed file under
 -   control of the format string, as in fprintf. gzprintf returns the number of
 -   uncompressed bytes actually written (0 in case of error).
 -*/
 -
 -int gzputs OF((gzFile file, const char *s));
 -/*
 -      Writes the given null-terminated string to the compressed file, excluding
 -   the terminating null character.
 -      gzputs returns the number of characters written, or -1 in case of error.
 -*/
 -
 -char * gzgets OF((gzFile file, char *buf, int len));
 -/*
 -      Reads bytes from the compressed file until len-1 characters are read, or
 -   a newline character is read and transferred to buf, or an end-of-file
 -   condition is encountered.  The string is then terminated with a null
 -   character.
 -      gzgets returns buf, or Z_NULL in case of error.
 -*/
 -
 -int    gzputc OF((gzFile file, int c));
 -/*
 -      Writes c, converted to an unsigned char, into the compressed file.
 -   gzputc returns the value that was written, or -1 in case of error.
 -*/
 -
 -int    gzgetc OF((gzFile file));
 -/*
 -      Reads one byte from the compressed file. gzgetc returns this byte
 -   or -1 in case of end of file or error.
 -*/
 -
 -int    gzflush OF((gzFile file, int flush));
 -/*
 -     Flushes all pending output into the compressed file. The parameter
 -   flush is as in the deflate() function. The return value is the zlib
 -   error number (see function gzerror below). gzflush returns Z_OK if
 -   the flush parameter is Z_FINISH and all output could be flushed.
 -     gzflush should be called only when strictly necessary because it can
 -   degrade compression.
 -*/
 -
 -long gzseek OF((gzFile file,
 -				      long offset, int whence));
 -/* 
 -      Sets the starting position for the next gzread or gzwrite on the
 -   given compressed file. The offset represents a number of bytes in the
 -   uncompressed data stream. The whence parameter is defined as in lseek(2);
 -   the value SEEK_END is not supported.
 -     If the file is opened for reading, this function is emulated but can be
 -   extremely slow. If the file is opened for writing, only forward seeks are
 -   supported; gzseek then compresses a sequence of zeroes up to the new
 -   starting position.
 -
 -      gzseek returns the resulting offset location as measured in bytes from
 -   the beginning of the uncompressed stream, or -1 in case of error, in
 -   particular if the file is opened for writing and the new starting position
 -   would be before the current position.
 -*/
 -
 -int    gzrewind OF((gzFile file));
 -/*
 -     Rewinds the given file. This function is supported only for reading.
 -
 -   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
 -*/
 -
 -long    gztell OF((gzFile file));
 -/*
 -     Returns the starting position for the next gzread or gzwrite on the
 -   given compressed file. This position represents a number of bytes in the
 -   uncompressed data stream.
 -
 -   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
 -*/
 -
 -int gzeof OF((gzFile file));
 -/*
 -     Returns 1 when EOF has previously been detected reading the given
 -   input stream, otherwise zero.
 -*/
 -
 -int    gzclose OF((gzFile file));
 -/*
 -     Flushes all pending output if necessary, closes the compressed file
 -   and deallocates all the (de)compression state. The return value is the zlib
 -   error number (see function gzerror below).
 -*/
 -
 -const char * gzerror OF((gzFile file, int *errnum));
 -/*
 -     Returns the error message for the last error which occurred on the
 -   given compressed file. errnum is set to zlib error number. If an
 -   error occurred in the file system and not in the compression library,
 -   errnum is set to Z_ERRNO and the application may consult errno
 -   to get the exact error code.
 -*/
 -
 -                        /* checksum functions */
 -
 -/*
 -     These functions are not related to compression but are exported
 -   anyway because they might be useful in applications using the
 -   compression library.
 -*/
 -
 -uLong adler32 OF((uLong adler, const Byte *buf, uInt len));
 -
 -/*
 -     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
 -   return the updated checksum. If buf is NULL, this function returns
 -   the required initial value for the checksum.
 -   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
 -   much faster. Usage example:
 -
 -     uLong adler = adler32(0L, Z_NULL, 0);
 -
 -     while (read_buffer(buffer, length) != EOF) {
 -       adler = adler32(adler, buffer, length);
 -     }
 -     if (adler != original_adler) error();
 -*/
 -
 -uLong crc32   OF((uLong crc, const Byte *buf, uInt len));
 -/*
 -     Update a running crc with the bytes buf[0..len-1] and return the updated
 -   crc. If buf is NULL, this function returns the required initial value
 -   for the crc. Pre- and post-conditioning (one's complement) is performed
 -   within this function so it shouldn't be done by the application.
 -   Usage example:
 -
 -     uLong crc = crc32(0L, Z_NULL, 0);
 -
 -     while (read_buffer(buffer, length) != EOF) {
 -       crc = crc32(crc, buffer, length);
 -     }
 -     if (crc != original_crc) error();
 -*/
 -
 -// private stuff to not include cmdlib.h
 -/*
 -============================================================================
 -
 -					BYTE ORDER FUNCTIONS
 -
 -============================================================================
 -*/
 -
 -#ifdef _SGI_SOURCE
 -#define	__BIG_ENDIAN__
 -#endif
 -
 -#ifdef __BIG_ENDIAN__
 -
 -short   __LittleShort (short l)
 -{
 -	byte    b1,b2;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -
 -	return (b1<<8) + b2;
 -}
 -
 -short   __BigShort (short l)
 -{
 -	return l;
 -}
 -
 -
 -int    __LittleLong (int l)
 -{
 -	byte    b1,b2,b3,b4;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -	b3 = (l>>16)&255;
 -	b4 = (l>>24)&255;
 -
 -	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
 -}
 -
 -int    __BigLong (int l)
 -{
 -	return l;
 -}
 -
 -
 -float	__LittleFloat (float l)
 -{
 -	union {byte b[4]; float f;} in, out;
 -	
 -	in.f = l;
 -	out.b[0] = in.b[3];
 -	out.b[1] = in.b[2];
 -	out.b[2] = in.b[1];
 -	out.b[3] = in.b[0];
 -	
 -	return out.f;
 -}
 -
 -float	__BigFloat (float l)
 -{
 -	return l;
 -}
 -
 -
 -#else
 -
 -
 -short   __BigShort (short l)
 -{
 -	byte    b1,b2;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -
 -	return (b1<<8) + b2;
 -}
 -
 -short   __LittleShort (short l)
 -{
 -	return l;
 -}
 -
 -
 -int    __BigLong (int l)
 -{
 -	byte    b1,b2,b3,b4;
 -
 -	b1 = l&255;
 -	b2 = (l>>8)&255;
 -	b3 = (l>>16)&255;
 -	b4 = (l>>24)&255;
 -
 -	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
 -}
 -
 -int    __LittleLong (int l)
 -{
 -	return l;
 -}
 -
 -float	__BigFloat (float l)
 -{
 -	union {byte b[4]; float f;} in, out;
 -	
 -	in.f = l;
 -	out.b[0] = in.b[3];
 -	out.b[1] = in.b[2];
 -	out.b[2] = in.b[1];
 -	out.b[3] = in.b[0];
 -	
 -	return out.f;
 -}
 -
 -float	__LittleFloat (float l)
 -{
 -	return l;
 -}
 -
 -
 -
 -#endif
 -
 -
 -
 -
 -                        /* various hacks, don't look :) */
 -
 -/* deflateInit and inflateInit are macros to allow checking the zlib version
 - * and the compiler's view of z_stream:
 - */
 -int deflateInit_ OF((z_streamp strm, int level,
 -                                     const char *version, int stream_size));
 -int inflateInit_ OF((z_streamp strm,
 -                                     const char *version, int stream_size));
 -int deflateInit2_ OF((z_streamp strm, int  level, int  method,
 -                                      int windowBits, int memLevel,
 -                                      int strategy, const char *version,
 -                                      int stream_size));
 -int inflateInit2_ OF((z_streamp strm, int  windowBits,
 -                                      const char *version, int stream_size));
 -#define deflateInit(strm, level) \
 -        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
 -#define inflateInit(strm) \
 -        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
 -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
 -        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
 -                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
 -#define inflateInit2(strm, windowBits) \
 -        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
 -
 -
 -const char   * zError           OF((int err));
 -int            inflateSyncPoint OF((z_streamp z));
 -const uLong * get_crc_table    OF((void));
 -
 -typedef unsigned char  uch;
 -typedef unsigned short ush;
 -typedef unsigned long  ulg;
 -
 -extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
 -/* (size given to avoid silly warnings with Visual C++) */
 -
 -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
 -
 -#define ERR_RETURN(strm,err) \
 -  return (strm->msg = (char*)ERR_MSG(err), (err))
 -/* To be used only when the state is known to be valid */
 -
 -        /* common constants */
 -
 -#ifndef DEF_WBITS
 -#  define DEF_WBITS MAX_WBITS
 -#endif
 -/* default windowBits for decompression. MAX_WBITS is for compression only */
 -
 -#if MAX_MEM_LEVEL >= 8
 -#  define DEF_MEM_LEVEL 8
 -#else
 -#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
 -#endif
 -/* default memLevel */
 -
 -#define STORED_BLOCK 0
 -#define STATIC_TREES 1
 -#define DYN_TREES    2
 -/* The three kinds of block type */
 -
 -#define MIN_MATCH  3
 -#define MAX_MATCH  258
 -/* The minimum and maximum match lengths */
 -
 -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
 -
 -        /* target dependencies */
 -
 -        /* Common defaults */
 -
 -#ifndef OS_CODE
 -#  define OS_CODE  0x03  /* assume Unix */
 -#endif
 -
 -#ifndef F_OPEN
 -#  define F_OPEN(name, mode) fopen((name), (mode))
 -#endif
 -
 -         /* functions */
 -
 -#ifdef HAVE_STRERROR
 -   extern char *strerror OF((int));
 -#  define zstrerror(errnum) strerror(errnum)
 -#else
 -#  define zstrerror(errnum) ""
 -#endif
 -
 -#define zmemcpy memcpy
 -#define zmemcmp memcmp
 -#define zmemzero(dest, len) memset(dest, 0, len)
 -
 -/* Diagnostic functions */
 -#ifdef _ZIP_DEBUG_
 -   int z_verbose = 0;
 -#  define Assert(cond,msg) assert(cond);
 -   //{if(!(cond)) Sys_Error(msg);}
 -#  define Trace(x) {if (z_verbose>=0) Sys_Error x ;}
 -#  define Tracev(x) {if (z_verbose>0) Sys_Error x ;}
 -#  define Tracevv(x) {if (z_verbose>1) Sys_Error x ;}
 -#  define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;}
 -#  define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;}
 -#else
 -#  define Assert(cond,msg)
 -#  define Trace(x)
 -#  define Tracev(x)
 -#  define Tracevv(x)
 -#  define Tracec(c,x)
 -#  define Tracecv(c,x)
 -#endif
 -
 -
 -typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len));
 -voidp zcalloc OF((voidp opaque, unsigned items, unsigned size));
 -void   zcfree  OF((voidp opaque, voidp ptr));
 -
 -#define ZALLOC(strm, items, size) \
 -           (*((strm)->zalloc))((strm)->opaque, (items), (size))
 -#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidp)(addr))
 -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
 -
 -
 -#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
 -                      !defined(CASESENSITIVITYDEFAULT_NO)
 -#define CASESENSITIVITYDEFAULT_NO
 -#endif
 -
 -
 -#ifndef UNZ_BUFSIZE
 -#define UNZ_BUFSIZE (65536)
 -#endif
 -
 -#ifndef UNZ_MAXFILENAMEINZIP
 -#define UNZ_MAXFILENAMEINZIP (256)
 -#endif
 -
 -#ifndef ALLOC
 -# define ALLOC(size) (malloc(size))
 -#endif
 -#ifndef TRYFREE
 -# define TRYFREE(p) {if (p) free(p);}
 -#endif
 -
 -#define SIZECENTRALDIRITEM (0x2e)
 -#define SIZEZIPLOCALHEADER (0x1e)
 -
 -
 -
 -/* ===========================================================================
 -     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
 -   for end of file.
 -   IN assertion: the stream s has been sucessfully opened for reading.
 -*/
 -
 -/*
 -static int unzlocal_getByte(FILE *fin,int *pi)
 -{
 -    unsigned char c;
 -	int err = fread(&c, 1, 1, fin);
 -    if (err==1)
 -    {
 -        *pi = (int)c;
 -        return UNZ_OK;
 -    }
 -    else
 -    {
 -        if (ferror(fin)) 
 -            return UNZ_ERRNO;
 -        else
 -            return UNZ_EOF;
 -    }
 -}
 -*/
 -
 -/* ===========================================================================
 -   Reads a long in LSB order from the given gz_stream. Sets 
 -*/
 -static int unzlocal_getShort (FILE* fin, uLong *pX)
 -{
 -	short	v;
 -
 -	fread( &v, sizeof(v), 1, fin );
 -
 -	*pX = __LittleShort( v);
 -	return UNZ_OK;
 -
 -/*
 -    uLong x ;
 -    int i;
 -    int err;
 -
 -    err = unzlocal_getByte(fin,&i);
 -    x = (uLong)i;
 -    
 -    if (err==UNZ_OK)
 -        err = unzlocal_getByte(fin,&i);
 -    x += ((uLong)i)<<8;
 -   
 -    if (err==UNZ_OK)
 -        *pX = x;
 -    else
 -        *pX = 0;
 -    return err;
 -*/
 -}
 -
 -static int unzlocal_getLong (FILE *fin, uLong *pX)
 -{
 -	int		v;
 -
 -	fread( &v, sizeof(v), 1, fin );
 -
 -	*pX = __LittleLong( v);
 -	return UNZ_OK;
 -
 -/*
 -    uLong x ;
 -    int i;
 -    int err;
 -
 -    err = unzlocal_getByte(fin,&i);
 -    x = (uLong)i;
 -    
 -    if (err==UNZ_OK)
 -        err = unzlocal_getByte(fin,&i);
 -    x += ((uLong)i)<<8;
 -
 -    if (err==UNZ_OK)
 -        err = unzlocal_getByte(fin,&i);
 -    x += ((uLong)i)<<16;
 -
 -    if (err==UNZ_OK)
 -        err = unzlocal_getByte(fin,&i);
 -    x += ((uLong)i)<<24;
 -   
 -    if (err==UNZ_OK)
 -        *pX = x;
 -    else
 -        *pX = 0;
 -    return err;
 -*/
 -}
 -
 -
 -/* My own strcmpi / strcasecmp */
 -static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2)
 -{
 -	for (;;)
 -	{
 -		char c1=*(fileName1++);
 -		char c2=*(fileName2++);
 -		if ((c1>='a') && (c1<='z'))
 -			c1 -= 0x20;
 -		if ((c2>='a') && (c2<='z'))
 -			c2 -= 0x20;
 -		if (c1=='\0')
 -			return ((c2=='\0') ? 0 : -1);
 -		if (c2=='\0')
 -			return 1;
 -		if (c1<c2)
 -			return -1;
 -		if (c1>c2)
 -			return 1;
 -	}
 -}
 -
 -
 -#ifdef  CASESENSITIVITYDEFAULT_NO
 -#define CASESENSITIVITYDEFAULTVALUE 2
 -#else
 -#define CASESENSITIVITYDEFAULTVALUE 1
 -#endif
 -
 -#ifndef STRCMPCASENOSENTIVEFUNCTION
 -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
 -#endif
 -
 -/* 
 -   Compare two filename (fileName1,fileName2).
 -   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
 -   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
 -                                                                or strcasecmp)
 -   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
 -        (like 1 on Unix, 2 on Windows)
 -
 -*/
 -extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity)
 -{
 -	if (iCaseSensitivity==0)
 -		iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
 -
 -	if (iCaseSensitivity==1)
 -		return strcmp(fileName1,fileName2);
 -
 -	return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
 -} 
 -
 -#define BUFREADCOMMENT (0x400)
 -
 -/*
 -  Locate the Central directory of a zipfile (at the end, just before
 -    the global comment)
 -*/
 -static uLong unzlocal_SearchCentralDir(FILE *fin)
 -{
 -	unsigned char* buf;
 -	uLong uSizeFile;
 -	uLong uBackRead;
 -	uLong uMaxBack=0xffff; /* maximum size of global comment */
 -	uLong uPosFound=0;
 -	
 -	if (fseek(fin,0,SEEK_END) != 0)
 -		return 0;
 -
 -
 -	uSizeFile = ftell( fin );
 -	
 -	if (uMaxBack>uSizeFile)
 -		uMaxBack = uSizeFile;
 -
 -	buf = (unsigned char*)malloc(BUFREADCOMMENT+4);
 -	if (buf==NULL)
 -		return 0;
 -
 -	uBackRead = 4;
 -	while (uBackRead<uMaxBack)
 -	{
 -		uLong uReadSize,uReadPos ;
 -		int i;
 -		if (uBackRead+BUFREADCOMMENT>uMaxBack) 
 -			uBackRead = uMaxBack;
 -		else
 -			uBackRead+=BUFREADCOMMENT;
 -		uReadPos = uSizeFile-uBackRead ;
 -		
 -		uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 
 -                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
 -		if (fseek(fin,uReadPos,SEEK_SET)!=0)
 -			break;
 -
 -		if (fread(buf,(uInt)uReadSize,1,fin)!=1)
 -			break;
 -
 -                for (i=(int)uReadSize-3; (i--)>0;)
 -			if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 
 -				((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
 -			{
 -				uPosFound = uReadPos+i;
 -				break;
 -			}
 -
 -		if (uPosFound!=0)
 -			break;
 -	}
 -	free(buf);
 -	return uPosFound;
 -}
 -
 -extern unzFile unzReOpen (const char* path, unzFile file)
 -{
 -	unz_s *s;
 -	FILE * fin;
 -
 -    fin=fopen(path,"rb");
 -	if (fin==NULL)
 -		return NULL;
 -
 -	s=(unz_s*)malloc(sizeof(unz_s));
 -	memcpy(s, (unz_s*)file, sizeof(unz_s));
 -
 -	s->file = fin;
 -	return (unzFile)s;	
 -}
 -
 -/*
 -  Open a Zip file. path contain the full pathname (by example,
 -     on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
 -	 "zlib/zlib109.zip".
 -	 If the zipfile cannot be opened (file don't exist or in not valid), the
 -	   return value is NULL.
 -     Else, the return value is a unzFile Handle, usable with other function
 -	   of this unzip package.
 -*/
 -extern unzFile unzOpen (const char* path)
 -{
 -	unz_s us;
 -	unz_s *s;
 -	uLong central_pos,uL;
 -	FILE * fin ;
 -
 -	uLong number_disk;          /* number of the current dist, used for 
 -								   spaning ZIP, unsupported, always 0*/
 -	uLong number_disk_with_CD;  /* number the the disk with central dir, used
 -								   for spaning ZIP, unsupported, always 0*/
 -	uLong number_entry_CD;      /* total number of entries in
 -	                               the central dir 
 -	                               (same than number_entry on nospan) */
 -
 -	int err=UNZ_OK;
 -
 -    fin=fopen(path,"rb");
 -	if (fin==NULL)
 -		return NULL;
 -
 -	central_pos = unzlocal_SearchCentralDir(fin);
 -	if (central_pos==0)
 -		err=UNZ_ERRNO;
 -
 -	if (fseek(fin,central_pos,SEEK_SET)!=0)
 -		err=UNZ_ERRNO;
 -
 -	/* the signature, already checked */
 -	if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* number of this disk */
 -	if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* number of the disk with the start of the central directory */
 -	if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* total number of entries in the central dir on this disk */
 -	if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* total number of entries in the central dir */
 -	if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if ((number_entry_CD!=us.gi.number_entry) ||
 -		(number_disk_with_CD!=0) ||
 -		(number_disk!=0))
 -		err=UNZ_BADZIPFILE;
 -
 -	/* size of the central directory */
 -	if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* offset of start of central directory with respect to the 
 -	      starting disk number */
 -	if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	/* zipfile comment length */
 -	if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if ((central_pos<us.offset_central_dir+us.size_central_dir) && 
 -		(err==UNZ_OK))
 -		err=UNZ_BADZIPFILE;
 -
 -	if (err!=UNZ_OK)
 -	{
 -		fclose(fin);
 -		return NULL;
 -	}
 -
 -	us.file=fin;
 -	us.byte_before_the_zipfile = central_pos -
 -		                    (us.offset_central_dir+us.size_central_dir);
 -	us.central_pos = central_pos;
 -    us.pfile_in_zip_read = NULL;
 -	
 -
 -	s=(unz_s*)malloc(sizeof(unz_s));
 -	*s=us;
 -//	unzGoToFirstFile((unzFile)s);	
 -	return (unzFile)s;	
 -}
 -
 -
 -/*
 -  Close a ZipFile opened with unzipOpen.
 -  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
 -    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
 -  return UNZ_OK if there is no problem. */
 -extern int unzClose (unzFile file)
 -{
 -	unz_s* s;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -
 -    if (s->pfile_in_zip_read!=NULL)
 -        unzCloseCurrentFile(file);
 -
 -	fclose(s->file);
 -	free(s);
 -	return UNZ_OK;
 -}
 -
 -
 -/*
 -  Write info about the ZipFile in the *pglobal_info structure.
 -  No preparation of the structure is needed
 -  return UNZ_OK if there is no problem. */
 -extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info)
 -{
 -	unz_s* s;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -	*pglobal_info=s->gi;
 -	return UNZ_OK;
 -}
 -
 -
 -/*
 -   Translate date/time from Dos format to tm_unz (readable more easilty)
 -*/
 -static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm)
 -{
 -    uLong uDate;
 -    uDate = (uLong)(ulDosDate>>16);
 -    ptm->tm_mday = (uInt)(uDate&0x1f) ;
 -    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
 -    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
 -
 -    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
 -    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
 -    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
 -}
 -
 -/*
 -  Get Info about the current file in the zipfile, with internal only info
 -*/
 -static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
 -                                                  unz_file_info *pfile_info,
 -                                                  unz_file_info_internal 
 -                                                  *pfile_info_internal,
 -                                                  char *szFileName,
 -												  uLong fileNameBufferSize,
 -                                                  void *extraField,
 -												  uLong extraFieldBufferSize,
 -                                                  char *szComment,
 -												  uLong commentBufferSize)
 -{
 -	unz_s* s;
 -	unz_file_info file_info;
 -	unz_file_info_internal file_info_internal;
 -	int err=UNZ_OK;
 -	uLong uMagic;
 -	long lSeek=0;
 -
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -	if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
 -		err=UNZ_ERRNO;
 -
 -
 -	/* we check the magic */
 -	if (err==UNZ_OK)
 -		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
 -			err=UNZ_ERRNO;
 -		else if (uMagic!=0x02014b50)
 -			err=UNZ_BADZIPFILE;
 -
 -	if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
 -
 -	if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	lSeek+=file_info.size_filename;
 -	if ((err==UNZ_OK) && (szFileName!=NULL))
 -	{
 -		uLong uSizeRead ;
 -		if (file_info.size_filename<fileNameBufferSize)
 -		{
 -			*(szFileName+file_info.size_filename)='\0';
 -			uSizeRead = file_info.size_filename;
 -		}
 -		else
 -			uSizeRead = fileNameBufferSize;
 -
 -		if ((file_info.size_filename>0) && (fileNameBufferSize>0))
 -			if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
 -				err=UNZ_ERRNO;
 -		lSeek -= uSizeRead;
 -	}
 -
 -	
 -	if ((err==UNZ_OK) && (extraField!=NULL))
 -	{
 -		uLong uSizeRead ;
 -		if (file_info.size_file_extra<extraFieldBufferSize)
 -			uSizeRead = file_info.size_file_extra;
 -		else
 -			uSizeRead = extraFieldBufferSize;
 -
 -		if (lSeek!=0)
 -			if (fseek(s->file,lSeek,SEEK_CUR)==0)
 -				lSeek=0;
 -			else
 -				err=UNZ_ERRNO;
 -		if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
 -			if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
 -				err=UNZ_ERRNO;
 -		lSeek += file_info.size_file_extra - uSizeRead;
 -	}
 -	else
 -		lSeek+=file_info.size_file_extra; 
 -
 -	
 -	if ((err==UNZ_OK) && (szComment!=NULL))
 -	{
 -		uLong uSizeRead ;
 -		if (file_info.size_file_comment<commentBufferSize)
 -		{
 -			*(szComment+file_info.size_file_comment)='\0';
 -			uSizeRead = file_info.size_file_comment;
 -		}
 -		else
 -			uSizeRead = commentBufferSize;
 -
 -		if (lSeek!=0)
 -			if (fseek(s->file,lSeek,SEEK_CUR)==0)
 -				lSeek=0;
 -			else
 -				err=UNZ_ERRNO;
 -		if ((file_info.size_file_comment>0) && (commentBufferSize>0))
 -			if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
 -				err=UNZ_ERRNO;
 -		lSeek+=file_info.size_file_comment - uSizeRead;
 -	}
 -	else
 -		lSeek+=file_info.size_file_comment;
 -
 -	if ((err==UNZ_OK) && (pfile_info!=NULL))
 -		*pfile_info=file_info;
 -
 -	if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
 -		*pfile_info_internal=file_info_internal;
 -
 -	return err;
 -}
 -
 -
 -
 -/*
 -  Write info about the ZipFile in the *pglobal_info structure.
 -  No preparation of the structure is needed
 -  return UNZ_OK if there is no problem.
 -*/
 -extern int unzGetCurrentFileInfo (	unzFile file, unz_file_info *pfile_info,
 -									char *szFileName, uLong fileNameBufferSize,
 -									void *extraField, uLong extraFieldBufferSize,
 -									char *szComment, uLong commentBufferSize)
 -{
 -	return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
 -												szFileName,fileNameBufferSize,
 -												extraField,extraFieldBufferSize,
 -												szComment,commentBufferSize);
 -}
 -
 -/*
 -  Set the current file of the zipfile to the first file.
 -  return UNZ_OK if there is no problem
 -*/
 -extern int unzGoToFirstFile (unzFile file)
 -{
 -	int err=UNZ_OK;
 -	unz_s* s;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -	s->pos_in_central_dir=s->offset_central_dir;
 -	s->num_file=0;
 -	err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
 -											 &s->cur_file_info_internal,
 -											 NULL,0,NULL,0,NULL,0);
 -	s->current_file_ok = (err == UNZ_OK);
 -	return err;
 -}
 -
 -
 -/*
 -  Set the current file of the zipfile to the next file.
 -  return UNZ_OK if there is no problem
 -  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
 -*/
 -extern int unzGoToNextFile (unzFile file)
 -{
 -	unz_s* s;	
 -	int err;
 -
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -	if (!s->current_file_ok)
 -		return UNZ_END_OF_LIST_OF_FILE;
 -	if (s->num_file+1==s->gi.number_entry)
 -		return UNZ_END_OF_LIST_OF_FILE;
 -
 -	s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
 -			s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
 -	s->num_file++;
 -	err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
 -											   &s->cur_file_info_internal,
 -											   NULL,0,NULL,0,NULL,0);
 -	s->current_file_ok = (err == UNZ_OK);
 -	return err;
 -}
 -
 -
 -/*
 -  Try locate the file szFileName in the zipfile.
 -  For the iCaseSensitivity signification, see unzipStringFileNameCompare
 -
 -  return value :
 -  UNZ_OK if the file is found. It becomes the current file.
 -  UNZ_END_OF_LIST_OF_FILE if the file is not found
 -*/
 -extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
 -{
 -	unz_s* s;	
 -	int err;
 -
 -	
 -	uLong num_fileSaved;
 -	uLong pos_in_central_dirSaved;
 -
 -
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -
 -    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
 -        return UNZ_PARAMERROR;
 -
 -	s=(unz_s*)file;
 -	if (!s->current_file_ok)
 -		return UNZ_END_OF_LIST_OF_FILE;
 -
 -	num_fileSaved = s->num_file;
 -	pos_in_central_dirSaved = s->pos_in_central_dir;
 -
 -	err = unzGoToFirstFile(file);
 -
 -	while (err == UNZ_OK)
 -	{
 -		char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
 -		unzGetCurrentFileInfo(file,NULL,
 -								szCurrentFileName,sizeof(szCurrentFileName)-1,
 -								NULL,0,NULL,0);
 -		if (unzStringFileNameCompare(szCurrentFileName,
 -										szFileName,iCaseSensitivity)==0)
 -			return UNZ_OK;
 -		err = unzGoToNextFile(file);
 -	}
 -
 -	s->num_file = num_fileSaved ;
 -	s->pos_in_central_dir = pos_in_central_dirSaved ;
 -	return err;
 -}
 -
 -
 -/*
 -  Read the static header of the current zipfile
 -  Check the coherency of the static header and info in the end of central
 -        directory about this file
 -  store in *piSizeVar the size of extra info in static header
 -        (filename and size of extra field data)
 -*/
 -static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
 -													uLong *poffset_local_extrafield,
 -													uInt *psize_local_extrafield)
 -{
 -	uLong uMagic,uData,uFlags;
 -	uLong size_filename;
 -	uLong size_extra_field;
 -	int err=UNZ_OK;
 -
 -	*piSizeVar = 0;
 -	*poffset_local_extrafield = 0;
 -	*psize_local_extrafield = 0;
 -
 -	if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
 -								s->byte_before_the_zipfile,SEEK_SET)!=0)
 -		return UNZ_ERRNO;
 -
 -
 -	if (err==UNZ_OK)
 -		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
 -			err=UNZ_ERRNO;
 -		else if (uMagic!=0x04034b50)
 -			err=UNZ_BADZIPFILE;
 -
 -	if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -/*
 -	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
 -		err=UNZ_BADZIPFILE;
 -*/
 -	if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
 -		err=UNZ_BADZIPFILE;
 -
 -    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
 -                         (s->cur_file_info.compression_method!=Z_DEFLATED))
 -        err=UNZ_BADZIPFILE;
 -
 -	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
 -		err=UNZ_ERRNO;
 -
 -	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
 -		err=UNZ_ERRNO;
 -	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
 -		                      ((uFlags & 8)==0))
 -		err=UNZ_BADZIPFILE;
 -
 -	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
 -		err=UNZ_ERRNO;
 -	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
 -							  ((uFlags & 8)==0))
 -		err=UNZ_BADZIPFILE;
 -
 -	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
 -		err=UNZ_ERRNO;
 -	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 
 -							  ((uFlags & 8)==0))
 -		err=UNZ_BADZIPFILE;
 -
 -
 -	if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -	else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
 -		err=UNZ_BADZIPFILE;
 -
 -	*piSizeVar += (uInt)size_filename;
 -
 -	if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
 -		err=UNZ_ERRNO;
 -	*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
 -									SIZEZIPLOCALHEADER + size_filename;
 -	*psize_local_extrafield = (uInt)size_extra_field;
 -
 -	*piSizeVar += (uInt)size_extra_field;
 -
 -	return err;
 -}
 -												
 -/*
 -  Open for reading data the current file in the zipfile.
 -  If there is no error and the file is opened, the return value is UNZ_OK.
 -*/
 -extern int unzOpenCurrentFile (unzFile file)
 -{
 -	int err=UNZ_OK;
 -	int Store;
 -	uInt iSizeVar;
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	uLong offset_local_extrafield;  /* offset of the static extra field */
 -	uInt  size_local_extrafield;    /* size of the static extra field */
 -
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -	if (!s->current_file_ok)
 -		return UNZ_PARAMERROR;
 -
 -    if (s->pfile_in_zip_read != NULL)
 -        unzCloseCurrentFile(file);
 -
 -	if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
 -				&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
 -		return UNZ_BADZIPFILE;
 -
 -	pfile_in_zip_read_info = (file_in_zip_read_info_s*)
 -									    malloc(sizeof(file_in_zip_read_info_s));
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_INTERNALERROR;
 -
 -	pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE);
 -	pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
 -	pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
 -	pfile_in_zip_read_info->pos_local_extrafield=0;
 -
 -	if (pfile_in_zip_read_info->read_buffer==NULL)
 -	{
 -		free(pfile_in_zip_read_info);
 -		return UNZ_INTERNALERROR;
 -	}
 -
 -	pfile_in_zip_read_info->stream_initialised=0;
 -	
 -	if ((s->cur_file_info.compression_method!=0) &&
 -        (s->cur_file_info.compression_method!=Z_DEFLATED))
 -		err=UNZ_BADZIPFILE;
 -	Store = s->cur_file_info.compression_method==0;
 -
 -	pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
 -	pfile_in_zip_read_info->crc32=0;
 -	pfile_in_zip_read_info->compression_method =
 -            s->cur_file_info.compression_method;
 -	pfile_in_zip_read_info->file=s->file;
 -	pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
 -
 -    pfile_in_zip_read_info->stream.total_out = 0;
 -
 -	if (!Store)
 -	{
 -	  pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
 -	  pfile_in_zip_read_info->stream.zfree = (free_func)0;
 -	  pfile_in_zip_read_info->stream.opaque = (voidp)0; 
 -      
 -	  err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
 -	  if (err == Z_OK)
 -	    pfile_in_zip_read_info->stream_initialised=1;
 -        /* windowBits is passed < 0 to tell that there is no zlib header.
 -         * Note that in this case inflate *requires* an extra "dummy" byte
 -         * after the compressed stream in order to complete decompression and
 -         * return Z_STREAM_END. 
 -         * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
 -         * size of both compressed and uncompressed data
 -         */
 -	}
 -	pfile_in_zip_read_info->rest_read_compressed = 
 -            s->cur_file_info.compressed_size ;
 -	pfile_in_zip_read_info->rest_read_uncompressed = 
 -            s->cur_file_info.uncompressed_size ;
 -
 -	
 -	pfile_in_zip_read_info->pos_in_zipfile = 
 -            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 
 -			  iSizeVar;
 -	
 -	pfile_in_zip_read_info->stream.avail_in = (uInt)0;
 -
 -
 -	s->pfile_in_zip_read = pfile_in_zip_read_info;
 -    return UNZ_OK;
 -}
 -
 -
 -/*
 -  Read bytes from the current file.
 -  buf contain buffer where data must be copied
 -  len the size of buf.
 -
 -  return the number of byte copied if somes bytes are copied
 -  return 0 if the end of file was reached
 -  return <0 with error code if there is an error
 -    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
 -*/
 -extern int unzReadCurrentFile  (unzFile file, void *buf, unsigned len)
 -{
 -	int err=UNZ_OK;
 -	uInt iRead = 0;
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -    pfile_in_zip_read_info=s->pfile_in_zip_read;
 -
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_PARAMERROR;
 -
 -
 -	if ((pfile_in_zip_read_info->read_buffer == NULL))
 -		return UNZ_END_OF_LIST_OF_FILE;
 -	if (len==0)
 -		return 0;
 -
 -	pfile_in_zip_read_info->stream.next_out = (Byte*)buf;
 -
 -	pfile_in_zip_read_info->stream.avail_out = (uInt)len;
 -	
 -	if (len>pfile_in_zip_read_info->rest_read_uncompressed)
 -		pfile_in_zip_read_info->stream.avail_out = 
 -		  (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
 -
 -	while (pfile_in_zip_read_info->stream.avail_out>0)
 -	{
 -		if ((pfile_in_zip_read_info->stream.avail_in==0) &&
 -            (pfile_in_zip_read_info->rest_read_compressed>0))
 -		{
 -			uInt uReadThis = UNZ_BUFSIZE;
 -			if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
 -				uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
 -			if (uReadThis == 0)
 -				return UNZ_EOF;
 -			if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed)
 -				if (fseek(pfile_in_zip_read_info->file,
 -						  pfile_in_zip_read_info->pos_in_zipfile + 
 -							 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
 -					return UNZ_ERRNO;
 -			if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
 -                         pfile_in_zip_read_info->file)!=1)
 -				return UNZ_ERRNO;
 -			pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
 -
 -			pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
 -			
 -			pfile_in_zip_read_info->stream.next_in = 
 -                (Byte*)pfile_in_zip_read_info->read_buffer;
 -			pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
 -		}
 -
 -		if (pfile_in_zip_read_info->compression_method==0)
 -		{
 -			uInt uDoCopy,i ;
 -			if (pfile_in_zip_read_info->stream.avail_out < 
 -                            pfile_in_zip_read_info->stream.avail_in)
 -				uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
 -			else
 -				uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
 -				
 -			for (i=0;i<uDoCopy;i++)
 -				*(pfile_in_zip_read_info->stream.next_out+i) =
 -                        *(pfile_in_zip_read_info->stream.next_in+i);
 -					
 -			pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
 -								pfile_in_zip_read_info->stream.next_out,
 -								uDoCopy);
 -			pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
 -			pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
 -			pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
 -			pfile_in_zip_read_info->stream.next_out += uDoCopy;
 -			pfile_in_zip_read_info->stream.next_in += uDoCopy;
 -            pfile_in_zip_read_info->stream.total_out += uDoCopy;
 -			iRead += uDoCopy;
 -		}
 -		else
 -		{
 -			uLong uTotalOutBefore,uTotalOutAfter;
 -			const Byte *bufBefore;
 -			uLong uOutThis;
 -			int flush=Z_SYNC_FLUSH;
 -
 -			uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
 -			bufBefore = pfile_in_zip_read_info->stream.next_out;
 -
 -			/*
 -			if ((pfile_in_zip_read_info->rest_read_uncompressed ==
 -			         pfile_in_zip_read_info->stream.avail_out) &&
 -				(pfile_in_zip_read_info->rest_read_compressed == 0))
 -				flush = Z_FINISH;
 -			*/
 -			err=inflate(&pfile_in_zip_read_info->stream,flush);
 -
 -			uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
 -			uOutThis = uTotalOutAfter-uTotalOutBefore;
 -			
 -			pfile_in_zip_read_info->crc32 = 
 -                crc32(pfile_in_zip_read_info->crc32,bufBefore,
 -                        (uInt)(uOutThis));
 -
 -			pfile_in_zip_read_info->rest_read_uncompressed -=
 -                uOutThis;
 -
 -			iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
 -            
 -			if (err==Z_STREAM_END)
 -				return (iRead==0) ? UNZ_EOF : iRead;
 -			if (err!=Z_OK) 
 -				break;
 -		}
 -	}
 -
 -	if (err==Z_OK)
 -		return iRead;
 -	return err;
 -}
 -
 -
 -/*
 -  Give the current position in uncompressed data
 -*/
 -extern long unztell (unzFile file)
 -{
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -    pfile_in_zip_read_info=s->pfile_in_zip_read;
 -
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_PARAMERROR;
 -
 -	return (long)pfile_in_zip_read_info->stream.total_out;
 -}
 -
 -
 -/*
 -  return 1 if the end of file was reached, 0 elsewhere 
 -*/
 -extern int unzeof (unzFile file)
 -{
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -    pfile_in_zip_read_info=s->pfile_in_zip_read;
 -
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_PARAMERROR;
 -	
 -	if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
 -		return 1;
 -	else
 -		return 0;
 -}
 -
 -
 -
 -/*
 -  Read extra field from the current file (opened by unzOpenCurrentFile)
 -  This is the static-header version of the extra field (sometimes, there is
 -    more info in the static-header version than in the central-header)
 -
 -  if buf==NULL, it return the size of the static extra field that can be read
 -
 -  if buf!=NULL, len is the size of the buffer, the extra header is copied in
 -	buf.
 -  the return value is the number of bytes copied in buf, or (if <0) 
 -	the error code
 -*/
 -extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len)
 -{
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	uInt read_now;
 -	uLong size_to_read;
 -
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -    pfile_in_zip_read_info=s->pfile_in_zip_read;
 -
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_PARAMERROR;
 -
 -	size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 
 -				pfile_in_zip_read_info->pos_local_extrafield);
 -
 -	if (buf==NULL)
 -		return (int)size_to_read;
 -	
 -	if (len>size_to_read)
 -		read_now = (uInt)size_to_read;
 -	else
 -		read_now = (uInt)len ;
 -
 -	if (read_now==0)
 -		return 0;
 -	
 -	if (fseek(pfile_in_zip_read_info->file,
 -              pfile_in_zip_read_info->offset_local_extrafield + 
 -			  pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
 -		return UNZ_ERRNO;
 -
 -	if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
 -		return UNZ_ERRNO;
 -
 -	return (int)read_now;
 -}
 -
 -/*
 -  Close the file in zip opened with unzipOpenCurrentFile
 -  Return UNZ_CRCERROR if all the file was read but the CRC is not good
 -*/
 -extern int unzCloseCurrentFile (unzFile file)
 -{
 -	int err=UNZ_OK;
 -
 -	unz_s* s;
 -	file_in_zip_read_info_s* pfile_in_zip_read_info;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -    pfile_in_zip_read_info=s->pfile_in_zip_read;
 -
 -	if (pfile_in_zip_read_info==NULL)
 -		return UNZ_PARAMERROR;
 -
 -
 -	if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
 -	{
 -		if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
 -			err=UNZ_CRCERROR;
 -	}
 -
 -
 -	free(pfile_in_zip_read_info->read_buffer);
 -	pfile_in_zip_read_info->read_buffer = NULL;
 -	if (pfile_in_zip_read_info->stream_initialised)
 -		inflateEnd(&pfile_in_zip_read_info->stream);
 -
 -	pfile_in_zip_read_info->stream_initialised = 0;
 -	free(pfile_in_zip_read_info);
 -
 -    s->pfile_in_zip_read=NULL;
 -
 -	return err;
 -}
 -
 -
 -/*
 -  Get the global comment string of the ZipFile, in the szComment buffer.
 -  uSizeBuf is the size of the szComment buffer.
 -  return the number of byte copied or an error code <0
 -*/
 -extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf)
 -{
 -	unz_s* s;
 -	uLong uReadThis ;
 -	if (file==NULL)
 -		return UNZ_PARAMERROR;
 -	s=(unz_s*)file;
 -
 -	uReadThis = uSizeBuf;
 -	if (uReadThis>s->gi.size_comment)
 -		uReadThis = s->gi.size_comment;
 -
 -	if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
 -		return UNZ_ERRNO;
 -
 -	if (uReadThis>0)
 -    {
 -      *szComment='\0';
 -	  if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
 -		return UNZ_ERRNO;
 -    }
 -
 -	if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
 -		*(szComment+s->gi.size_comment)='\0';
 -	return (int)uReadThis;
 -}
 -
 -/* crc32.c -- compute the CRC-32 of a data stream
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */
 -
 -#ifdef DYNAMIC_CRC_TABLE
 -
 -static int crc_table_empty = 1;
 -static uLong crc_table[256];
 -static void make_crc_table OF((void));
 -
 -/*
 -  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
 -  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
 -
 -  Polynomials over GF(2) are represented in binary, one bit per coefficient,
 -  with the lowest powers in the most significant bit.  Then adding polynomials
 -  is just exclusive-or, and multiplying a polynomial by x is a right shift by
 -  one.  If we call the above polynomial p, and represent a byte as the
 -  polynomial q, also with the lowest power in the most significant bit (so the
 -  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
 -  where a mod b means the remainder after dividing a by b.
 -
 -  This calculation is done using the shift-register method of multiplying and
 -  taking the remainder.  The register is initialized to zero, and for each
 -  incoming bit, x^32 is added mod p to the register if the bit is a one (where
 -  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
 -  x (which is shifting right by one and adding x^32 mod p if the bit shifted
 -  out is a one).  We start with the highest power (least significant bit) of
 -  q and repeat for all eight bits of q.
 -
 -  The table is simply the CRC of all possible eight bit values.  This is all
 -  the information needed to generate CRC's on data a byte at a time for all
 -  combinations of CRC register values and incoming bytes.
 -*/
 -static void make_crc_table()
 -{
 -  uLong c;
 -  int n, k;
 -  uLong poly;            /* polynomial exclusive-or pattern */
 -  /* terms of polynomial defining this crc (except x^32): */
 -  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
 -
 -  /* make exclusive-or pattern from polynomial (0xedb88320L) */
 -  poly = 0L;
 -  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
 -    poly |= 1L << (31 - p[n]);
 - 
 -  for (n = 0; n < 256; n++)
 -  {
 -    c = (uLong)n;
 -    for (k = 0; k < 8; k++)
 -      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
 -    crc_table[n] = c;
 -  }
 -  crc_table_empty = 0;
 -}
 -#else
 -/* ========================================================================
 - * Table of CRC-32's of all single-byte values (made by make_crc_table)
 - */
 -static const uLong crc_table[256] = {
 -  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
 -  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
 -  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
 -  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
 -  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
 -  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
 -  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
 -  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
 -  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
 -  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
 -  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
 -  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
 -  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
 -  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
 -  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
 -  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
 -  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
 -  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
 -  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
 -  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
 -  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
 -  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
 -  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
 -  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
 -  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
 -  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
 -  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
 -  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
 -  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
 -  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
 -  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
 -  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
 -  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
 -  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
 -  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
 -  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
 -  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
 -  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
 -  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
 -  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
 -  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
 -  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
 -  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
 -  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
 -  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
 -  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
 -  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
 -  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
 -  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
 -  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
 -  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
 -  0x2d02ef8dL
 -};
 -#endif
 -
 -/* =========================================================================
 - * This function can be used by asm versions of crc32()
 - */
 -const uLong * get_crc_table()
 -{
 -#ifdef DYNAMIC_CRC_TABLE
 -  if (crc_table_empty) make_crc_table();
 -#endif
 -  return (const uLong *)crc_table;
 -}
 -
 -/* ========================================================================= */
 -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
 -#define DO2(buf)  DO1(buf); DO1(buf);
 -#define DO4(buf)  DO2(buf); DO2(buf);
 -#define DO8(buf)  DO4(buf); DO4(buf);
 -
 -/* ========================================================================= */
 -uLong crc32(uLong crc, const Byte *buf, uInt len)
 -{
 -    if (buf == Z_NULL) return 0L;
 -#ifdef DYNAMIC_CRC_TABLE
 -    if (crc_table_empty)
 -      make_crc_table();
 -#endif
 -    crc = crc ^ 0xffffffffL;
 -    while (len >= 8)
 -    {
 -      DO8(buf);
 -      len -= 8;
 -    }
 -    if (len) do {
 -      DO1(buf);
 -    } while (--len);
 -    return crc ^ 0xffffffffL;
 -}
 -
 -/* infblock.h -- header to use infblock.c
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -struct inflate_blocks_state;
 -typedef struct inflate_blocks_state inflate_blocks_statef;
 -
 -extern inflate_blocks_statef * inflate_blocks_new OF((
 -    z_streamp z,
 -    check_func c,               /* check function */
 -    uInt w));                   /* window size */
 -
 -extern int inflate_blocks OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    int));                      /* initial return code */
 -
 -extern void inflate_blocks_reset OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    uLong *));                  /* check value on output */
 -
 -extern int inflate_blocks_free OF((
 -    inflate_blocks_statef *,
 -    z_streamp));
 -
 -extern void inflate_set_dictionary OF((
 -    inflate_blocks_statef *s,
 -    const Byte *d,  /* dictionary */
 -    uInt  n));       /* dictionary length */
 -
 -extern int inflate_blocks_sync_point OF((
 -    inflate_blocks_statef *s));
 -
 -/* simplify the use of the inflate_huft type with some defines */
 -#define exop word.what.Exop
 -#define bits word.what.Bits
 -
 -/* Table for deflate from PKZIP's appnote.txt. */
 -static const uInt border[] = { /* Order of the bit length code lengths */
 -        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
 -
 -/* inftrees.h -- header to use inftrees.c
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -/* Huffman code lookup table entry--this entry is four bytes for machines
 -   that have 16-bit pointers (e.g. PC's in the small or medium model). */
 -
 -typedef struct inflate_huft_s inflate_huft;
 -
 -struct inflate_huft_s {
 -  union {
 -    struct {
 -      Byte Exop;        /* number of extra bits or operation */
 -      Byte Bits;        /* number of bits in this code or subcode */
 -    } what;
 -    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
 -  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
 -  uInt base;            /* literal, length base, distance base,
 -                           or table offset */
 -};
 -
 -/* Maximum size of dynamic tree.  The maximum found in a long but non-
 -   exhaustive search was 1004 huft structures (850 for length/literals
 -   and 154 for distances, the latter actually the result of an
 -   exhaustive search).  The actual maximum is not known, but the
 -   value below is more than safe. */
 -#define MANY 1440
 -
 -extern int inflate_trees_bits OF((
 -    uInt *,                    /* 19 code lengths */
 -    uInt *,                    /* bits tree desired/actual depth */
 -    inflate_huft * *,       /* bits tree result */
 -    inflate_huft *,             /* space for trees */
 -    z_streamp));                /* for messages */
 -
 -extern int inflate_trees_dynamic OF((
 -    uInt,                       /* number of literal/length codes */
 -    uInt,                       /* number of distance codes */
 -    uInt *,                    /* that many (total) code lengths */
 -    uInt *,                    /* literal desired/actual bit depth */
 -    uInt *,                    /* distance desired/actual bit depth */
 -    inflate_huft * *,       /* literal/length tree result */
 -    inflate_huft * *,       /* distance tree result */
 -    inflate_huft *,             /* space for trees */
 -    z_streamp));                /* for messages */
 -
 -extern int inflate_trees_fixed OF((
 -    uInt *,                    /* literal desired/actual bit depth */
 -    uInt *,                    /* distance desired/actual bit depth */
 -    inflate_huft * *,       /* literal/length tree result */
 -    inflate_huft * *,       /* distance tree result */
 -    z_streamp));                /* for memory allocation */
 -
 -
 -/* infcodes.h -- header to use infcodes.c
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -struct inflate_codes_state;
 -typedef struct inflate_codes_state inflate_codes_statef;
 -
 -extern inflate_codes_statef *inflate_codes_new OF((
 -    uInt, uInt,
 -    inflate_huft *, inflate_huft *,
 -    z_streamp ));
 -
 -extern int inflate_codes OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    int));
 -
 -extern void inflate_codes_free OF((
 -    inflate_codes_statef *,
 -    z_streamp ));
 -
 -/* infutil.h -- types and macros common to blocks and codes
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -#ifndef _INFUTIL_H
 -#define _INFUTIL_H
 -
 -typedef enum {
 -      TYPE,     /* get type bits (3, including end bit) */
 -      LENS,     /* get lengths for stored */
 -      STORED,   /* processing stored block */
 -      TABLE,    /* get table lengths */
 -      BTREE,    /* get bit lengths tree for a dynamic block */
 -      DTREE,    /* get length, distance trees for a dynamic block */
 -      CODES,    /* processing fixed or dynamic block */
 -      DRY,      /* output remaining window bytes */
 -      DONE,     /* finished last block, done */
 -      BAD}      /* got a data error--stuck here */
 -inflate_block_mode;
 -
 -/* inflate blocks semi-private state */
 -struct inflate_blocks_state {
 -
 -  /* mode */
 -  inflate_block_mode  mode;     /* current inflate_block mode */
 -
 -  /* mode dependent information */
 -  union {
 -    uInt left;          /* if STORED, bytes left to copy */
 -    struct {
 -      uInt table;               /* table lengths (14 bits) */
 -      uInt index;               /* index into blens (or border) */
 -      uInt *blens;             /* bit lengths of codes */
 -      uInt bb;                  /* bit length tree depth */
 -      inflate_huft *tb;         /* bit length decoding tree */
 -    } trees;            /* if DTREE, decoding info for trees */
 -    struct {
 -      inflate_codes_statef 
 -         *codes;
 -    } decode;           /* if CODES, current state */
 -  } sub;                /* submode */
 -  uInt last;            /* true if this block is the last block */
 -
 -  /* mode independent information */
 -  uInt bitk;            /* bits in bit buffer */
 -  uLong bitb;           /* bit buffer */
 -  inflate_huft *hufts;  /* single malloc for tree space */
 -  Byte *window;        /* sliding window */
 -  Byte *end;           /* one byte after sliding window */
 -  Byte *read;          /* window read pointer */
 -  Byte *write;         /* window write pointer */
 -  check_func checkfn;   /* check function */
 -  uLong check;          /* check on output */
 -
 -};
 -
 -
 -/* defines for inflate input/output */
 -/*   update pointers and return */
 -#define UPDBITS {s->bitb=b;s->bitk=k;}
 -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
 -#define UPDOUT {s->write=q;}
 -#define UPDATE {UPDBITS UPDIN UPDOUT}
 -#define LEAVE {UPDATE return inflate_flush(s,z,r);}
 -/*   get bytes and bits */
 -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
 -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
 -#define NEXTBYTE (n--,*p++)
 -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
 -#define DUMPBITS(j) {b>>=(j);k-=(j);}
 -/*   output bytes */
 -#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
 -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
 -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
 -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
 -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
 -#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
 -/*   load static pointers */
 -#define LOAD {LOADIN LOADOUT}
 -
 -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
 -extern uInt inflate_mask[17];
 -
 -/* copy as much as possible from the sliding window to the output area */
 -extern int inflate_flush OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    int));
 -
 -#endif
 -
 -								
 -/*
 -   Notes beyond the 1.93a appnote.txt:
 -
 -   1. Distance pointers never point before the beginning of the output
 -      stream.
 -   2. Distance pointers can point back across blocks, up to 32k away.
 -   3. There is an implied maximum of 7 bits for the bit length table and
 -      15 bits for the actual data.
 -   4. If only one code exists, then it is encoded using one bit.  (Zero
 -      would be more efficient, but perhaps a little confusing.)  If two
 -      codes exist, they are coded using one bit each (0 and 1).
 -   5. There is no way of sending zero distance codes--a dummy must be
 -      sent if there are none.  (History: a pre 2.0 version of PKZIP would
 -      store blocks with no distance codes, but this was discovered to be
 -      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
 -      zero distance codes, which is sent as one code of zero bits in
 -      length.
 -   6. There are up to 286 literal/length codes.  Code 256 represents the
 -      end-of-block.  Note however that the static length tree defines
 -      288 codes just to fill out the Huffman codes.  Codes 286 and 287
 -      cannot be used though, since there is no length base or extra bits
 -      defined for them.  Similarily, there are up to 30 distance codes.
 -      However, static trees define 32 codes (all 5 bits) to fill out the
 -      Huffman codes, but the last two had better not show up in the data.
 -   7. Unzip can check dynamic Huffman blocks for complete code sets.
 -      The exception is that a single code would not be complete (see #4).
 -   8. The five bits following the block type is really the number of
 -      literal codes sent minus 257.
 -   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
 -      (1+6+6).  Therefore, to output three times the length, you output
 -      three codes (1+1+1), whereas to output four times the same length,
 -      you only need two codes (1+3).  Hmm.
 -  10. In the tree reconstruction algorithm, Code = Code + Increment
 -      only if BitLength(i) is not zero.  (Pretty obvious.)
 -  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
 -  12. Note: length code 284 can represent 227-258, but length code 285
 -      really is 258.  The last length deserves its own, short code
 -      since it gets used a lot in very redundant files.  The length
 -      258 is special since 258 - 3 (the min match length) is 255.
 -  13. The literal/length and distance code bit lengths are read as a
 -      single stream of lengths.  It is possible (and advantageous) for
 -      a repeat code (16, 17, or 18) to go across the boundary between
 -      the two sets of lengths.
 - */
 -
 -
 -void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c)
 -{
 -  if (c != Z_NULL)
 -    *c = s->check;
 -  if (s->mode == BTREE || s->mode == DTREE)
 -    ZFREE(z, s->sub.trees.blens);
 -  if (s->mode == CODES)
 -    inflate_codes_free(s->sub.decode.codes, z);
 -  s->mode = TYPE;
 -  s->bitk = 0;
 -  s->bitb = 0;
 -  s->read = s->write = s->window;
 -  if (s->checkfn != Z_NULL)
 -    z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0);
 -  Tracev(("inflate:   blocks reset\n"));
 -}
 -
 -
 -inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w)
 -{
 -  inflate_blocks_statef *s;
 -
 -  if ((s = (inflate_blocks_statef *)ZALLOC
 -       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
 -    return s;
 -  if ((s->hufts =
 -       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
 -  {
 -    ZFREE(z, s);
 -    return Z_NULL;
 -  }
 -  if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL)
 -  {
 -    ZFREE(z, s->hufts);
 -    ZFREE(z, s);
 -    return Z_NULL;
 -  }
 -  s->end = s->window + w;
 -  s->checkfn = c;
 -  s->mode = TYPE;
 -  Tracev(("inflate:   blocks allocated\n"));
 -  inflate_blocks_reset(s, z, Z_NULL);
 -  return s;
 -}
 -
 -
 -int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r)
 -{
 -  uInt t;               /* temporary storage */
 -  uLong b;              /* bit buffer */
 -  uInt k;               /* bits in bit buffer */
 -  Byte *p;             /* input data pointer */
 -  uInt n;               /* bytes available there */
 -  Byte *q;             /* output window write pointer */
 -  uInt m;               /* bytes to end of window or read pointer */
 -
 -  /* copy input/output information to locals (UPDATE macro restores) */
 -  LOAD
 -
 -  /* process input based on current state */
 -  while (1) switch (s->mode)
 -  {
 -    case TYPE:
 -      NEEDBITS(3)
 -      t = (uInt)b & 7;
 -      s->last = t & 1;
 -      switch (t >> 1)
 -      {
 -        case 0:                         /* stored */
 -          Tracev(("inflate:     stored block%s\n",
 -                 s->last ? " (last)" : ""));
 -          DUMPBITS(3)
 -          t = k & 7;                    /* go to byte boundary */
 -          DUMPBITS(t)
 -          s->mode = LENS;               /* get length of stored block */
 -          break;
 -        case 1:                         /* fixed */
 -          Tracev(("inflate:     fixed codes block%s\n",
 -                 s->last ? " (last)" : ""));
 -          {
 -            uInt bl, bd;
 -            inflate_huft *tl, *td;
 -
 -            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
 -            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
 -            if (s->sub.decode.codes == Z_NULL)
 -            {
 -              r = Z_MEM_ERROR;
 -              LEAVE
 -            }
 -          }
 -          DUMPBITS(3)
 -          s->mode = CODES;
 -          break;
 -        case 2:                         /* dynamic */
 -          Tracev(("inflate:     dynamic codes block%s\n",
 -                 s->last ? " (last)" : ""));
 -          DUMPBITS(3)
 -          s->mode = TABLE;
 -          break;
 -        case 3:                         /* illegal */
 -          DUMPBITS(3)
 -          s->mode = BAD;
 -          z->msg = (char*)"invalid block type";
 -          r = Z_DATA_ERROR;
 -          LEAVE
 -      }
 -      break;
 -    case LENS:
 -      NEEDBITS(32)
 -      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
 -      {
 -        s->mode = BAD;
 -        z->msg = (char*)"invalid stored block lengths";
 -        r = Z_DATA_ERROR;
 -        LEAVE
 -      }
 -      s->sub.left = (uInt)b & 0xffff;
 -      b = k = 0;                      /* dump bits */
 -      Tracev(("inflate:       stored length %u\n", s->sub.left));
 -      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
 -      break;
 -    case STORED:
 -      if (n == 0)
 -        LEAVE
 -      NEEDOUT
 -      t = s->sub.left;
 -      if (t > n) t = n;
 -      if (t > m) t = m;
 -      zmemcpy(q, p, t);
 -      p += t;  n -= t;
 -      q += t;  m -= t;
 -      if ((s->sub.left -= t) != 0)
 -        break;
 -      Tracev(("inflate:       stored end, %lu total out\n",
 -              z->total_out + (q >= s->read ? q - s->read :
 -              (s->end - s->read) + (q - s->window))));
 -      s->mode = s->last ? DRY : TYPE;
 -      break;
 -    case TABLE:
 -      NEEDBITS(14)
 -      s->sub.trees.table = t = (uInt)b & 0x3fff;
 -#ifndef PKZIP_BUG_WORKAROUND
 -      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
 -      {
 -        s->mode = BAD;
 -        z->msg = (char*)"too many length or distance symbols";
 -        r = Z_DATA_ERROR;
 -        LEAVE
 -      }
 -#endif
 -      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
 -      if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
 -      {
 -        r = Z_MEM_ERROR;
 -        LEAVE
 -      }
 -      DUMPBITS(14)
 -      s->sub.trees.index = 0;
 -      Tracev(("inflate:       table sizes ok\n"));
 -      s->mode = BTREE;
 -    case BTREE:
 -      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
 -      {
 -        NEEDBITS(3)
 -        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
 -        DUMPBITS(3)
 -      }
 -      while (s->sub.trees.index < 19)
 -        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
 -      s->sub.trees.bb = 7;
 -      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
 -                             &s->sub.trees.tb, s->hufts, z);
 -      if (t != Z_OK)
 -      {
 -        ZFREE(z, s->sub.trees.blens);
 -        r = t;
 -        if (r == Z_DATA_ERROR)
 -          s->mode = BAD;
 -        LEAVE
 -      }
 -      s->sub.trees.index = 0;
 -      Tracev(("inflate:       bits tree ok\n"));
 -      s->mode = DTREE;
 -    case DTREE:
 -      while (t = s->sub.trees.table,
 -             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
 -      {
 -        inflate_huft *h;
 -        uInt i, j, c;
 -
 -        t = s->sub.trees.bb;
 -        NEEDBITS(t)
 -        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
 -        t = h->bits;
 -        c = h->base;
 -        if (c < 16)
 -        {
 -          DUMPBITS(t)
 -          s->sub.trees.blens[s->sub.trees.index++] = c;
 -        }
 -        else /* c == 16..18 */
 -        {
 -          i = c == 18 ? 7 : c - 14;
 -          j = c == 18 ? 11 : 3;
 -          NEEDBITS(t + i)
 -          DUMPBITS(t)
 -          j += (uInt)b & inflate_mask[i];
 -          DUMPBITS(i)
 -          i = s->sub.trees.index;
 -          t = s->sub.trees.table;
 -          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
 -              (c == 16 && i < 1))
 -          {
 -            ZFREE(z, s->sub.trees.blens);
 -            s->mode = BAD;
 -            z->msg = (char*)"invalid bit length repeat";
 -            r = Z_DATA_ERROR;
 -            LEAVE
 -          }
 -          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
 -          do {
 -            s->sub.trees.blens[i++] = c;
 -          } while (--j);
 -          s->sub.trees.index = i;
 -        }
 -      }
 -      s->sub.trees.tb = Z_NULL;
 -      {
 -        uInt bl, bd;
 -        inflate_huft *tl, *td;
 -        inflate_codes_statef *c;
 -
 -        bl = 9;         /* must be <= 9 for lookahead assumptions */
 -        bd = 6;         /* must be <= 9 for lookahead assumptions */
 -        t = s->sub.trees.table;
 -        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
 -                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
 -                                  s->hufts, z);
 -        ZFREE(z, s->sub.trees.blens);
 -        if (t != Z_OK)
 -        {
 -          if (t == (uInt)Z_DATA_ERROR)
 -            s->mode = BAD;
 -          r = t;
 -          LEAVE
 -        }
 -        Tracev(("inflate:       trees ok\n"));
 -        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
 -        {
 -          r = Z_MEM_ERROR;
 -          LEAVE
 -        }
 -        s->sub.decode.codes = c;
 -      }
 -      s->mode = CODES;
 -    case CODES:
 -      UPDATE
 -      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
 -        return inflate_flush(s, z, r);
 -      r = Z_OK;
 -      inflate_codes_free(s->sub.decode.codes, z);
 -      LOAD
 -      Tracev(("inflate:       codes end, %lu total out\n",
 -              z->total_out + (q >= s->read ? q - s->read :
 -              (s->end - s->read) + (q - s->window))));
 -      if (!s->last)
 -      {
 -        s->mode = TYPE;
 -        break;
 -      }
 -      s->mode = DRY;
 -    case DRY:
 -      FLUSH
 -      if (s->read != s->write)
 -        LEAVE
 -      s->mode = DONE;
 -    case DONE:
 -      r = Z_STREAM_END;
 -      LEAVE
 -    case BAD:
 -      r = Z_DATA_ERROR;
 -      LEAVE
 -    default:
 -      r = Z_STREAM_ERROR;
 -      LEAVE
 -  }
 -}
 -
 -
 -int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z)
 -{
 -  inflate_blocks_reset(s, z, Z_NULL);
 -  ZFREE(z, s->window);
 -  ZFREE(z, s->hufts);
 -  ZFREE(z, s);
 -  Tracev(("inflate:   blocks freed\n"));
 -  return Z_OK;
 -}
 -
 -
 -void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n)
 -{
 -  zmemcpy(s->window, d, n);
 -  s->read = s->write = s->window + n;
 -}
 -
 -
 -/* Returns true if inflate is currently at the end of a block generated
 - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
 - * IN assertion: s != Z_NULL
 - */
 -int inflate_blocks_sync_point(inflate_blocks_statef *s)
 -{
 -  return s->mode == LENS;
 -}
 -
 -
 -/* And'ing with mask[n] masks the lower n bits */
 -uInt inflate_mask[17] = {
 -    0x0000,
 -    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
 -    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
 -};
 -
 -
 -/* copy as much as possible from the sliding window to the output area */
 -int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r)
 -{
 -  uInt n;
 -  Byte *p;
 -  Byte *q;
 -
 -  /* static copies of source and destination pointers */
 -  p = z->next_out;
 -  q = s->read;
 -
 -  /* compute number of bytes to copy as as end of window */
 -  n = (uInt)((q <= s->write ? s->write : s->end) - q);
 -  if (n > z->avail_out) n = z->avail_out;
 -  if (n && r == Z_BUF_ERROR) r = Z_OK;
 -
 -  /* update counters */
 -  z->avail_out -= n;
 -  z->total_out += n;
 -
 -  /* update check information */
 -  if (s->checkfn != Z_NULL)
 -    z->adler = s->check = (*s->checkfn)(s->check, q, n);
 -
 -  /* copy as as end of window */
 -  zmemcpy(p, q, n);
 -  p += n;
 -  q += n;
 -
 -  /* see if more to copy at beginning of window */
 -  if (q == s->end)
 -  {
 -    /* wrap pointers */
 -    q = s->window;
 -    if (s->write == s->end)
 -      s->write = s->window;
 -
 -    /* compute bytes to copy */
 -    n = (uInt)(s->write - q);
 -    if (n > z->avail_out) n = z->avail_out;
 -    if (n && r == Z_BUF_ERROR) r = Z_OK;
 -
 -    /* update counters */
 -    z->avail_out -= n;
 -    z->total_out += n;
 -
 -    /* update check information */
 -    if (s->checkfn != Z_NULL)
 -      z->adler = s->check = (*s->checkfn)(s->check, q, n);
 -
 -    /* copy */
 -    zmemcpy(p, q, n);
 -    p += n;
 -    q += n;
 -  }
 -
 -  /* update pointers */
 -  z->next_out = p;
 -  s->read = q;
 -
 -  /* done */
 -  return r;
 -}
 -
 -/* inftrees.c -- generate Huffman trees for efficient decoding
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -const char inflate_copyright[] =
 -   " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
 -/*
 -  If you use the zlib library in a product, an acknowledgment is welcome
 -  in the documentation of your product. If for some reason you cannot
 -  include such an acknowledgment, I would appreciate that you keep this
 -  copyright string in the executable of your product.
 - */
 -
 -/* simplify the use of the inflate_huft type with some defines */
 -#define exop word.what.Exop
 -#define bits word.what.Bits
 -
 -
 -static int huft_build OF((
 -    uInt *,				/* code lengths in bits */
 -    uInt,               /* number of codes */
 -    uInt,               /* number of "simple" codes */
 -    const uInt *,		/* list of base values for non-simple codes */
 -    const uInt *,		/* list of extra bits for non-simple codes */
 -    inflate_huft **,	/* result: starting table */
 -    uInt *,				/* maximum lookup bits (returns actual) */
 -    inflate_huft *,     /* space for trees */
 -    uInt *,             /* hufts used in space */
 -    uInt * ));			/* space for values */
 -
 -/* Tables for deflate from PKZIP's appnote.txt. */
 -static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
 -        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
 -        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
 -        /* see note #13 above about 258 */
 -static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
 -        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
 -        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
 -static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
 -        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
 -        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
 -        8193, 12289, 16385, 24577};
 -static const uInt cpdext[30] = { /* Extra bits for distance codes */
 -        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
 -        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
 -        12, 12, 13, 13};
 -
 -/*
 -   Huffman code decoding is performed using a multi-level table lookup.
 -   The fastest way to decode is to simply build a lookup table whose
 -   size is determined by the longest code.  However, the time it takes
 -   to build this table can also be a factor if the data being decoded
 -   is not very long.  The most common codes are necessarily the
 -   shortest codes, so those codes dominate the decoding time, and hence
 -   the speed.  The idea is you can have a shorter table that decodes the
 -   shorter, more probable codes, and then point to subsidiary tables for
 -   the longer codes.  The time it costs to decode the longer codes is
 -   then traded against the time it takes to make longer tables.
 -
 -   This results of this trade are in the variables lbits and dbits
 -   below.  lbits is the number of bits the first level table for literal/
 -   length codes can decode in one step, and dbits is the same thing for
 -   the distance codes.  Subsequent tables are also less than or equal to
 -   those sizes.  These values may be adjusted either when all of the
 -   codes are shorter than that, in which case the longest code length in
 -   bits is used, or when the shortest code is *longer* than the requested
 -   table size, in which case the length of the shortest code in bits is
 -   used.
 -
 -   There are two different values for the two tables, since they code a
 -   different number of possibilities each.  The literal/length table
 -   codes 286 possible values, or in a flat code, a little over eight
 -   bits.  The distance table codes 30 possible values, or a little less
 -   than five bits, flat.  The optimum values for speed end up being
 -   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
 -   The optimum values may differ though from machine to machine, and
 -   possibly even between compilers.  Your mileage may vary.
 - */
 -
 -
 -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
 -#define BMAX 15         /* maximum bit length of any code */
 -
 -static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v)
 -//uInt *b;               /* code lengths in bits (all assumed <= BMAX) */
 -//uInt n;                 /* number of codes (assumed <= 288) */
 -//uInt s;                 /* number of simple-valued codes (0..s-1) */
 -//const uInt *d;         /* list of base values for non-simple codes */
 -//const uInt *e;         /* list of extra bits for non-simple codes */
 -//inflate_huft ** t;		/* result: starting table */
 -//uInt *m;               /* maximum lookup bits, returns actual */
 -//inflate_huft *hp;       /* space for trees */
 -//uInt *hn;               /* hufts used in space */
 -//uInt *v;               /* working area: values in order of bit length */
 -/* Given a list of code lengths and a maximum table size, make a set of
 -   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
 -   if the given code set is incomplete (the tables are still built in this
 -   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
 -   lengths), or Z_MEM_ERROR if not enough memory. */
 -{
 -
 -  uInt a;                       /* counter for codes of length k */
 -  uInt c[BMAX+1];               /* bit length count table */
 -  uInt f;                       /* i repeats in table every f entries */
 -  int g;                        /* maximum code length */
 -  int h;                        /* table level */
 -  register uInt i;              /* counter, current code */
 -  register uInt j;              /* counter */
 -  register int k;               /* number of bits in current code */
 -  int l;                        /* bits per table (returned in m) */
 -  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
 -  register uInt *p;            /* pointer into c[], b[], or v[] */
 -  inflate_huft *q;              /* points to current table */
 -  struct inflate_huft_s r;      /* table entry for structure assignment */
 -  inflate_huft *u[BMAX];        /* table stack */
 -  register int w;               /* bits before this table == (l * h) */
 -  uInt x[BMAX+1];               /* bit offsets, then code stack */
 -  uInt *xp;                    /* pointer into x */
 -  int y;                        /* number of dummy codes added */
 -  uInt z;                       /* number of entries in current table */
 -
 -
 -  /* Generate counts for each bit length */
 -  p = c;
 -#define C0 *p++ = 0;
 -#define C2 C0 C0 C0 C0
 -#define C4 C2 C2 C2 C2
 -  C4                            /* clear c[]--assume BMAX+1 is 16 */
 -  p = b;  i = n;
 -  do {
 -    c[*p++]++;                  /* assume all entries <= BMAX */
 -  } while (--i);
 -  if (c[0] == n)                /* null input--all zero length codes */
 -  {
 -    *t = (inflate_huft *)Z_NULL;
 -    *m = 0;
 -    return Z_OK;
 -  }
 -
 -
 -  /* Find minimum and maximum length, bound *m by those */
 -  l = *m;
 -  for (j = 1; j <= BMAX; j++)
 -    if (c[j])
 -      break;
 -  k = j;                        /* minimum code length */
 -  if ((uInt)l < j)
 -    l = j;
 -  for (i = BMAX; i; i--)
 -    if (c[i])
 -      break;
 -  g = i;                        /* maximum code length */
 -  if ((uInt)l > i)
 -    l = i;
 -  *m = l;
 -
 -
 -  /* Adjust last length count to fill out codes, if needed */
 -  for (y = 1 << j; j < i; j++, y <<= 1)
 -    if ((y -= c[j]) < 0)
 -      return Z_DATA_ERROR;
 -  if ((y -= c[i]) < 0)
 -    return Z_DATA_ERROR;
 -  c[i] += y;
 -
 -
 -  /* Generate starting offsets into the value table for each length */
 -  x[1] = j = 0;
 -  p = c + 1;  xp = x + 2;
 -  while (--i) {                 /* note that i == g from above */
 -    *xp++ = (j += *p++);
 -  }
 -
 -
 -  /* Make a table of values in order of bit lengths */
 -  p = b;  i = 0;
 -  do {
 -    if ((j = *p++) != 0)
 -      v[x[j]++] = i;
 -  } while (++i < n);
 -  n = x[g];                     /* set n to length of v */
 -
 -
 -  /* Generate the Huffman codes and for each, make the table entries */
 -  x[0] = i = 0;                 /* first Huffman code is zero */
 -  p = v;                        /* grab values in bit order */
 -  h = -1;                       /* no tables yet--level -1 */
 -  w = -l;                       /* bits decoded == (l * h) */
 -  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
 -  q = (inflate_huft *)Z_NULL;   /* ditto */
 -  z = 0;                        /* ditto */
 -
 -  /* go through the bit lengths (k already is bits in shortest code) */
 -  for (; k <= g; k++)
 -  {
 -    a = c[k];
 -    while (a--)
 -    {
 -      /* here i is the Huffman code of length k bits for value *p */
 -      /* make tables up to required level */
 -      while (k > w + l)
 -      {
 -        h++;
 -        w += l;                 /* previous table always l bits */
 -
 -        /* compute minimum size table less than or equal to l bits */
 -        z = g - w;
 -        z = z > (uInt)l ? l : z;        /* table size upper limit */
 -        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
 -        {                       /* too few codes for k-w bit table */
 -          f -= a + 1;           /* deduct codes from patterns left */
 -          xp = c + k;
 -          if (j < z)
 -            while (++j < z)     /* try smaller tables up to z bits */
 -            {
 -              if ((f <<= 1) <= *++xp)
 -                break;          /* enough codes to use up j bits */
 -              f -= *xp;         /* else deduct codes from patterns */
 -            }
 -        }
 -        z = 1 << j;             /* table entries for j-bit table */
 -
 -        /* allocate new table */
 -        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
 -          return Z_MEM_ERROR;   /* not enough memory */
 -        u[h] = q = hp + *hn;
 -        *hn += z;
 -
 -        /* connect to last table, if there is one */
 -        if (h)
 -        {
 -          x[h] = i;             /* save pattern for backing up */
 -          r.bits = (Byte)l;     /* bits to dump before this table */
 -          r.exop = (Byte)j;     /* bits in this table */
 -          j = i >> (w - l);
 -          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
 -          u[h-1][j] = r;        /* connect to last table */
 -        }
 -        else
 -          *t = q;               /* first table is returned result */
 -      }
 -
 -      /* set up table entry in r */
 -      r.bits = (Byte)(k - w);
 -      if (p >= v + n)
 -        r.exop = 128 + 64;      /* out of values--invalid code */
 -      else if (*p < s)
 -      {
 -        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
 -        r.base = *p++;          /* simple code is just the value */
 -      }
 -      else
 -      {
 -        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
 -        r.base = d[*p++ - s];
 -      }
 -
 -      /* fill code-like entries with r */
 -      f = 1 << (k - w);
 -      for (j = i >> w; j < z; j += f)
 -        q[j] = r;
 -
 -      /* backwards increment the k-bit code i */
 -      for (j = 1 << (k - 1); i & j; j >>= 1)
 -        i ^= j;
 -      i ^= j;
 -
 -      /* backup over finished tables */
 -      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
 -      while ((i & mask) != x[h])
 -      {
 -        h--;                    /* don't need to update q */
 -        w -= l;
 -        mask = (1 << w) - 1;
 -      }
 -    }
 -  }
 -
 -
 -  /* Return Z_BUF_ERROR if we were given an incomplete table */
 -  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
 -}
 -
 -
 -int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z)
 -//uInt *c;               /* 19 code lengths */
 -//uInt *bb;              /* bits tree desired/actual depth */
 -//inflate_huft * *tb; /* bits tree result */
 -//inflate_huft *hp;       /* space for trees */
 -//z_streamp z;            /* for messages */
 -{
 -  int r;
 -  uInt hn = 0;          /* hufts used in space */
 -  uInt *v;             /* work area for huft_build */
 -
 -  if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
 -    return Z_MEM_ERROR;
 -  r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL,
 -                 tb, bb, hp, &hn, v);
 -  if (r == Z_DATA_ERROR)
 -    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
 -  else if (r == Z_BUF_ERROR || *bb == 0)
 -  {
 -    z->msg = (char*)"incomplete dynamic bit lengths tree";
 -    r = Z_DATA_ERROR;
 -  }
 -  ZFREE(z, v);
 -  return r;
 -}
 -
 -
 -int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z)
 -//uInt nl;                /* number of literal/length codes */
 -//uInt nd;                /* number of distance codes */
 -//uInt *c;               /* that many (total) code lengths */
 -//uInt *bl;              /* literal desired/actual bit depth */
 -//uInt *bd;              /* distance desired/actual bit depth */
 -//inflate_huft * *tl; /* literal/length tree result */
 -//inflate_huft * *td; /* distance tree result */
 -//inflate_huft *hp;       /* space for trees */
 -//z_streamp z;            /* for messages */
 -{
 -  int r;
 -  uInt hn = 0;          /* hufts used in space */
 -  uInt *v;             /* work area for huft_build */
 -
 -  /* allocate work area */
 -  if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
 -    return Z_MEM_ERROR;
 -
 -  /* build literal/length tree */
 -  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
 -  if (r != Z_OK || *bl == 0)
 -  {
 -    if (r == Z_DATA_ERROR)
 -      z->msg = (char*)"oversubscribed literal/length tree";
 -    else if (r != Z_MEM_ERROR)
 -    {
 -      z->msg = (char*)"incomplete literal/length tree";
 -      r = Z_DATA_ERROR;
 -    }
 -    ZFREE(z, v);
 -    return r;
 -  }
 -
 -  /* build distance tree */
 -  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
 -  if (r != Z_OK || (*bd == 0 && nl > 257))
 -  {
 -    if (r == Z_DATA_ERROR)
 -      z->msg = (char*)"oversubscribed distance tree";
 -    else if (r == Z_BUF_ERROR) {
 -#ifdef PKZIP_BUG_WORKAROUND
 -      r = Z_OK;
 -    }
 -#else
 -      z->msg = (char*)"incomplete distance tree";
 -      r = Z_DATA_ERROR;
 -    }
 -    else if (r != Z_MEM_ERROR)
 -    {
 -      z->msg = (char*)"empty distance tree with lengths";
 -      r = Z_DATA_ERROR;
 -    }
 -    ZFREE(z, v);
 -    return r;
 -#endif
 -  }
 -
 -  /* done */
 -  ZFREE(z, v);
 -  return Z_OK;
 -}
 -
 -/* inffixed.h -- table for decoding fixed codes
 - * Generated automatically by the maketree.c program
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -static uInt fixed_bl = 9;
 -static uInt fixed_bd = 5;
 -static inflate_huft fixed_tl[] = {
 -    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
 -    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
 -    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
 -    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
 -    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
 -    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
 -    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
 -    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
 -    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
 -    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
 -    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
 -    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
 -    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
 -    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
 -    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
 -    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
 -    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
 -    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
 -    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
 -    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
 -    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
 -    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
 -    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
 -    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
 -    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
 -    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
 -    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
 -    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
 -    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
 -    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
 -    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
 -    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
 -    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
 -    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
 -    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
 -    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
 -    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
 -    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
 -    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
 -    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
 -    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
 -    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
 -    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
 -    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
 -    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
 -    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
 -    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
 -    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
 -    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
 -    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
 -    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
 -    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
 -    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
 -    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
 -    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
 -    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
 -    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
 -    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
 -    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
 -    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
 -    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
 -    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
 -    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
 -    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
 -    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
 -    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
 -    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
 -    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
 -    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
 -    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
 -    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
 -    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
 -    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
 -    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
 -    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
 -    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
 -    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
 -    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
 -    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
 -    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
 -    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
 -    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
 -    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
 -    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
 -    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
 -    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
 -    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
 -    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
 -    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
 -    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
 -    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
 -    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
 -    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
 -    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
 -    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
 -    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
 -    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
 -    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
 -    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
 -    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
 -    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
 -    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
 -    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
 -    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
 -    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
 -    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
 -    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
 -    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
 -    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
 -    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
 -    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
 -    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
 -    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
 -    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
 -    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
 -    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
 -    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
 -    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
 -    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
 -    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
 -    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
 -    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
 -    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
 -    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
 -    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
 -    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
 -    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
 -    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
 -  };
 -static inflate_huft fixed_td[] = {
 -    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
 -    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
 -    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
 -    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
 -    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
 -    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
 -    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
 -    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
 -  };
 -
 -int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z)
 -//uInt *bl;               /* literal desired/actual bit depth */
 -//uInt *bd;               /* distance desired/actual bit depth */
 -//inflate_huft * *tl;  /* literal/length tree result */
 -//inflate_huft * *td;  /* distance tree result */
 -//z_streamp z;             /* for memory allocation */
 -{
 -  *bl = fixed_bl;
 -  *bd = fixed_bd;
 -  *tl = fixed_tl;
 -  *td = fixed_td;
 -  return Z_OK;
 -}
 -
 -/* simplify the use of the inflate_huft type with some defines */
 -#define exop word.what.Exop
 -#define bits word.what.Bits
 -
 -/* macros for bit input with no checking and for returning unused bytes */
 -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
 -#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
 -
 -/* Called with number of bytes left to write in window at least 258
 -   (the maximum string length) and number of input bytes available
 -   at least ten.  The ten bytes are six bytes for the longest length/
 -   distance pair plus four bytes for overloading the bit buffer. */
 -
 -int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z)
 -{
 -  inflate_huft *t;      /* temporary pointer */
 -  uInt e;               /* extra bits or operation */
 -  uLong b;              /* bit buffer */
 -  uInt k;               /* bits in bit buffer */
 -  Byte *p;             /* input data pointer */
 -  uInt n;               /* bytes available there */
 -  Byte *q;             /* output window write pointer */
 -  uInt m;               /* bytes to end of window or read pointer */
 -  uInt ml;              /* mask for literal/length tree */
 -  uInt md;              /* mask for distance tree */
 -  uInt c;               /* bytes to copy */
 -  uInt d;               /* distance back to copy from */
 -  Byte *r;             /* copy source pointer */
 -
 -  /* load input, output, bit values */
 -  LOAD
 -
 -  /* initialize masks */
 -  ml = inflate_mask[bl];
 -  md = inflate_mask[bd];
 -
 -  /* do until not enough input or output space for fast loop */
 -  do {                          /* assume called with m >= 258 && n >= 10 */
 -    /* get literal/length code */
 -    GRABBITS(20)                /* max bits for literal/length code */
 -    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
 -    {
 -      DUMPBITS(t->bits)
 -      Tracevv((t->base >= 0x20 && t->base < 0x7f ?
 -                "inflate:         * literal '%c'\n" :
 -                "inflate:         * literal 0x%02x\n", t->base));
 -      *q++ = (Byte)t->base;
 -      m--;
 -      continue;
 -    }
 -    do {
 -      DUMPBITS(t->bits)
 -      if (e & 16)
 -      {
 -        /* get extra bits for length */
 -        e &= 15;
 -        c = t->base + ((uInt)b & inflate_mask[e]);
 -        DUMPBITS(e)
 -        Tracevv(("inflate:         * length %u\n", c));
 -
 -        /* decode distance base of block to copy */
 -        GRABBITS(15);           /* max bits for distance code */
 -        e = (t = td + ((uInt)b & md))->exop;
 -        do {
 -          DUMPBITS(t->bits)
 -          if (e & 16)
 -          {
 -            /* get extra bits to add to distance base */
 -            e &= 15;
 -            GRABBITS(e)         /* get extra bits (up to 13) */
 -            d = t->base + ((uInt)b & inflate_mask[e]);
 -            DUMPBITS(e)
 -            Tracevv(("inflate:         * distance %u\n", d));
 -
 -            /* do the copy */
 -            m -= c;
 -            if ((uInt)(q - s->window) >= d)     /* offset before dest */
 -            {                                   /*  just copy */
 -              r = q - d;
 -              *q++ = *r++;  c--;        /* minimum count is three, */
 -              *q++ = *r++;  c--;        /*  so unroll loop a little */
 -            }
 -            else                        /* else offset after destination */
 -            {
 -              e = d - (uInt)(q - s->window); /* bytes from offset to end */
 -              r = s->end - e;           /* pointer to offset */
 -              if (c > e)                /* if source crosses, */
 -              {
 -                c -= e;                 /* copy to end of window */
 -                do {
 -                  *q++ = *r++;
 -                } while (--e);
 -                r = s->window;          /* copy rest from start of window */
 -              }
 -            }
 -            do {                        /* copy all or what's left */
 -              *q++ = *r++;
 -            } while (--c);
 -            break;
 -          }
 -          else if ((e & 64) == 0)
 -          {
 -            t += t->base;
 -            e = (t += ((uInt)b & inflate_mask[e]))->exop;
 -          }
 -          else
 -          {
 -            z->msg = (char*)"invalid distance code";
 -            UNGRAB
 -            UPDATE
 -            return Z_DATA_ERROR;
 -          }
 -        } while (1);
 -        break;
 -      }
 -      if ((e & 64) == 0)
 -      {
 -        t += t->base;
 -        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
 -        {
 -          DUMPBITS(t->bits)
 -          Tracevv((t->base >= 0x20 && t->base < 0x7f ?
 -                    "inflate:         * literal '%c'\n" :
 -                    "inflate:         * literal 0x%02x\n", t->base));
 -          *q++ = (Byte)t->base;
 -          m--;
 -          break;
 -        }
 -      }
 -      else if (e & 32)
 -      {
 -        Tracevv(("inflate:         * end of block\n"));
 -        UNGRAB
 -        UPDATE
 -        return Z_STREAM_END;
 -      }
 -      else
 -      {
 -        z->msg = (char*)"invalid literal/length code";
 -        UNGRAB
 -        UPDATE
 -        return Z_DATA_ERROR;
 -      }
 -    } while (1);
 -  } while (m >= 258 && n >= 10);
 -
 -  /* not enough input or output--restore pointers and return */
 -  UNGRAB
 -  UPDATE
 -  return Z_OK;
 -}
 -
 -/* infcodes.c -- process literals and length/distance pairs
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* simplify the use of the inflate_huft type with some defines */
 -#define exop word.what.Exop
 -#define bits word.what.Bits
 -
 -typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
 -      START,    /* x: set up for LEN */
 -      LEN,      /* i: get length/literal/eob next */
 -      LENEXT,   /* i: getting length extra (have base) */
 -      DIST,     /* i: get distance next */
 -      DISTEXT,  /* i: getting distance extra */
 -      COPY,     /* o: copying bytes in window, waiting for space */
 -      LIT,      /* o: got literal, waiting for output space */
 -      WASH,     /* o: got eob, possibly still output waiting */
 -      END,      /* x: got eob and all data flushed */
 -      BADCODE}  /* x: got error */
 -inflate_codes_mode;
 -
 -/* inflate codes private state */
 -struct inflate_codes_state {
 -
 -  /* mode */
 -  inflate_codes_mode mode;      /* current inflate_codes mode */
 -
 -  /* mode dependent information */
 -  uInt len;
 -  union {
 -    struct {
 -      inflate_huft *tree;       /* pointer into tree */
 -      uInt need;                /* bits needed */
 -    } code;             /* if LEN or DIST, where in tree */
 -    uInt lit;           /* if LIT, literal */
 -    struct {
 -      uInt get;                 /* bits to get for extra */
 -      uInt dist;                /* distance back to copy from */
 -    } copy;             /* if EXT or COPY, where and how much */
 -  } sub;                /* submode */
 -
 -  /* mode independent information */
 -  Byte lbits;           /* ltree bits decoded per branch */
 -  Byte dbits;           /* dtree bits decoder per branch */
 -  inflate_huft *ltree;          /* literal/length/eob tree */
 -  inflate_huft *dtree;          /* distance tree */
 -
 -};
 -
 -
 -inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z)
 -{
 -  inflate_codes_statef *c;
 -
 -  if ((c = (inflate_codes_statef *)
 -       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
 -  {
 -    c->mode = START;
 -    c->lbits = (Byte)bl;
 -    c->dbits = (Byte)bd;
 -    c->ltree = tl;
 -    c->dtree = td;
 -    Tracev(("inflate:       codes new\n"));
 -  }
 -  return c;
 -}
 -
 -
 -int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r)
 -{
 -  uInt j;               /* temporary storage */
 -  inflate_huft *t;      /* temporary pointer */
 -  uInt e;               /* extra bits or operation */
 -  uLong b;              /* bit buffer */
 -  uInt k;               /* bits in bit buffer */
 -  Byte *p;             /* input data pointer */
 -  uInt n;               /* bytes available there */
 -  Byte *q;             /* output window write pointer */
 -  uInt m;               /* bytes to end of window or read pointer */
 -  Byte *f;             /* pointer to copy strings from */
 -  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
 -
 -  /* copy input/output information to locals (UPDATE macro restores) */
 -  LOAD
 -
 -  /* process input and output based on current state */
 -  while (1) switch (c->mode)
 -  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
 -    case START:         /* x: set up for LEN */
 -#ifndef SLOW
 -      if (m >= 258 && n >= 10)
 -      {
 -        UPDATE
 -        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
 -        LOAD
 -        if (r != Z_OK)
 -        {
 -          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
 -          break;
 -        }
 -      }
 -#endif /* !SLOW */
 -      c->sub.code.need = c->lbits;
 -      c->sub.code.tree = c->ltree;
 -      c->mode = LEN;
 -    case LEN:           /* i: get length/literal/eob next */
 -      j = c->sub.code.need;
 -      NEEDBITS(j)
 -      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
 -      DUMPBITS(t->bits)
 -      e = (uInt)(t->exop);
 -      if (e == 0)               /* literal */
 -      {
 -        c->sub.lit = t->base;
 -        Tracevv((t->base >= 0x20 && t->base < 0x7f ?
 -                 "inflate:         literal '%c'\n" :
 -                 "inflate:         literal 0x%02x\n", t->base));
 -        c->mode = LIT;
 -        break;
 -      }
 -      if (e & 16)               /* length */
 -      {
 -        c->sub.copy.get = e & 15;
 -        c->len = t->base;
 -        c->mode = LENEXT;
 -        break;
 -      }
 -      if ((e & 64) == 0)        /* next table */
 -      {
 -        c->sub.code.need = e;
 -        c->sub.code.tree = t + t->base;
 -        break;
 -      }
 -      if (e & 32)               /* end of block */
 -      {
 -        Tracevv(("inflate:         end of block\n"));
 -        c->mode = WASH;
 -        break;
 -      }
 -      c->mode = BADCODE;        /* invalid code */
 -      z->msg = (char*)"invalid literal/length code";
 -      r = Z_DATA_ERROR;
 -      LEAVE
 -    case LENEXT:        /* i: getting length extra (have base) */
 -      j = c->sub.copy.get;
 -      NEEDBITS(j)
 -      c->len += (uInt)b & inflate_mask[j];
 -      DUMPBITS(j)
 -      c->sub.code.need = c->dbits;
 -      c->sub.code.tree = c->dtree;
 -      Tracevv(("inflate:         length %u\n", c->len));
 -      c->mode = DIST;
 -    case DIST:          /* i: get distance next */
 -      j = c->sub.code.need;
 -      NEEDBITS(j)
 -      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
 -      DUMPBITS(t->bits)
 -      e = (uInt)(t->exop);
 -      if (e & 16)               /* distance */
 -      {
 -        c->sub.copy.get = e & 15;
 -        c->sub.copy.dist = t->base;
 -        c->mode = DISTEXT;
 -        break;
 -      }
 -      if ((e & 64) == 0)        /* next table */
 -      {
 -        c->sub.code.need = e;
 -        c->sub.code.tree = t + t->base;
 -        break;
 -      }
 -      c->mode = BADCODE;        /* invalid code */
 -      z->msg = (char*)"invalid distance code";
 -      r = Z_DATA_ERROR;
 -      LEAVE
 -    case DISTEXT:       /* i: getting distance extra */
 -      j = c->sub.copy.get;
 -      NEEDBITS(j)
 -      c->sub.copy.dist += (uInt)b & inflate_mask[j];
 -      DUMPBITS(j)
 -      Tracevv(("inflate:         distance %u\n", c->sub.copy.dist));
 -      c->mode = COPY;
 -    case COPY:          /* o: copying bytes in window, waiting for space */
 -#ifndef __TURBOC__ /* Turbo C bug for following expression */
 -      f = (uInt)(q - s->window) < c->sub.copy.dist ?
 -          s->end - (c->sub.copy.dist - (q - s->window)) :
 -          q - c->sub.copy.dist;
 -#else
 -      f = q - c->sub.copy.dist;
 -      if ((uInt)(q - s->window) < c->sub.copy.dist)
 -        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
 -#endif
 -      while (c->len)
 -      {
 -        NEEDOUT
 -        OUTBYTE(*f++)
 -        if (f == s->end)
 -          f = s->window;
 -        c->len--;
 -      }
 -      c->mode = START;
 -      break;
 -    case LIT:           /* o: got literal, waiting for output space */
 -      NEEDOUT
 -      OUTBYTE(c->sub.lit)
 -      c->mode = START;
 -      break;
 -    case WASH:          /* o: got eob, possibly more output */
 -      if (k > 7)        /* return unused byte, if any */
 -      {
 -        Assert(k < 16, "inflate_codes grabbed too many bytes")
 -        k -= 8;
 -        n++;
 -        p--;            /* can always return one */
 -      }
 -      FLUSH
 -      if (s->read != s->write)
 -        LEAVE
 -      c->mode = END;
 -    case END:
 -      r = Z_STREAM_END;
 -      LEAVE
 -    case BADCODE:       /* x: got error */
 -      r = Z_DATA_ERROR;
 -      LEAVE
 -    default:
 -      r = Z_STREAM_ERROR;
 -      LEAVE
 -  }
 -#ifdef NEED_DUMMY_RETURN
 -  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
 -#endif
 -}
 -
 -
 -void inflate_codes_free(inflate_codes_statef *c, z_streamp z)
 -{
 -  ZFREE(z, c);
 -  Tracev(("inflate:       codes free\n"));
 -}
 -
 -/* adler32.c -- compute the Adler-32 checksum of a data stream
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -#define BASE 65521L /* largest prime smaller than 65536 */
 -#define NMAX 5552
 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
 -
 -#undef DO1
 -#undef DO2
 -#undef DO4
 -#undef DO8
 -
 -#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
 -#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
 -#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
 -#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
 -#define DO16(buf)   DO8(buf,0); DO8(buf,8);
 -
 -/* ========================================================================= */
 -uLong adler32(uLong adler, const Byte *buf, uInt len)
 -{
 -    unsigned long s1 = adler & 0xffff;
 -    unsigned long s2 = (adler >> 16) & 0xffff;
 -    int k;
 -
 -    if (buf == Z_NULL) return 1L;
 -
 -    while (len > 0) {
 -        k = len < NMAX ? len : NMAX;
 -        len -= k;
 -        while (k >= 16) {
 -            DO16(buf);
 -	    buf += 16;
 -            k -= 16;
 -        }
 -        if (k != 0) do {
 -            s1 += *buf++;
 -	    s2 += s1;
 -        } while (--k);
 -        s1 %= BASE;
 -        s2 %= BASE;
 -    }
 -    return (s2 << 16) | s1;
 -}
 -
 -/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */
 -
 -/* infblock.h -- header to use infblock.c
 - * Copyright (C) 1995-1998 Mark Adler
 - * For conditions of distribution and use, see copyright notice in zlib.h 
 - */
 -
 -/* WARNING: this file should *not* be used by applications. It is
 -   part of the implementation of the compression library and is
 -   subject to change. Applications should only use zlib.h.
 - */
 -
 -extern inflate_blocks_statef * inflate_blocks_new OF((
 -    z_streamp z,
 -    check_func c,               /* check function */
 -    uInt w));                   /* window size */
 -
 -extern int inflate_blocks OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    int));                      /* initial return code */
 -
 -extern void inflate_blocks_reset OF((
 -    inflate_blocks_statef *,
 -    z_streamp ,
 -    uLong *));                  /* check value on output */
 -
 -extern int inflate_blocks_free OF((
 -    inflate_blocks_statef *,
 -    z_streamp));
 -
 -extern void inflate_set_dictionary OF((
 -    inflate_blocks_statef *s,
 -    const Byte *d,  /* dictionary */
 -    uInt  n));       /* dictionary length */
 -
 -extern int inflate_blocks_sync_point OF((
 -    inflate_blocks_statef *s));
 -
 -typedef enum {
 -      imMETHOD,   /* waiting for method byte */
 -      imFLAG,     /* waiting for flag byte */
 -      imDICT4,    /* four dictionary check bytes to go */
 -      imDICT3,    /* three dictionary check bytes to go */
 -      imDICT2,    /* two dictionary check bytes to go */
 -      imDICT1,    /* one dictionary check byte to go */
 -      imDICT0,    /* waiting for inflateSetDictionary */
 -      imBLOCKS,   /* decompressing blocks */
 -      imCHECK4,   /* four check bytes to go */
 -      imCHECK3,   /* three check bytes to go */
 -      imCHECK2,   /* two check bytes to go */
 -      imCHECK1,   /* one check byte to go */
 -      imDONE,     /* finished check, done */
 -      imBAD}      /* got an error--stay here */
 -inflate_mode;
 -
 -/* inflate private state */
 -struct internal_state {
 -
 -  /* mode */
 -  inflate_mode  mode;   /* current inflate mode */
 -
 -  /* mode dependent information */
 -  union {
 -    uInt method;        /* if FLAGS, method byte */
 -    struct {
 -      uLong was;                /* computed check value */
 -      uLong need;               /* stream check value */
 -    } check;            /* if CHECK, check values to compare */
 -    uInt marker;        /* if BAD, inflateSync's marker bytes count */
 -  } sub;        /* submode */
 -
 -  /* mode independent information */
 -  int  nowrap;          /* flag for no wrapper */
 -  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
 -  inflate_blocks_statef 
 -    *blocks;            /* current inflate_blocks state */
 -
 -};
 -
 -
 -int inflateReset(z_streamp z)
 -{
 -  if (z == Z_NULL || z->state == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  z->total_in = z->total_out = 0;
 -  z->msg = Z_NULL;
 -  z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD;
 -  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
 -  Tracev(("inflate: reset\n"));
 -  return Z_OK;
 -}
 -
 -
 -int inflateEnd(z_streamp z)
 -{
 -  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  if (z->state->blocks != Z_NULL)
 -    inflate_blocks_free(z->state->blocks, z);
 -  ZFREE(z, z->state);
 -  z->state = Z_NULL;
 -  Tracev(("inflate: end\n"));
 -  return Z_OK;
 -}
 -
 -
 -
 -int inflateInit2_(z_streamp z, int w, const char *version, int stream_size)
 -{
 -  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
 -      stream_size != sizeof(z_stream))
 -      return Z_VERSION_ERROR;
 -
 -  /* initialize state */
 -  if (z == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  z->msg = Z_NULL;
 -  if (z->zalloc == Z_NULL)
 -  {
 -    z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc;
 -    z->opaque = (voidp)0;
 -  }
 -  if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree;
 -  if ((z->state = (struct internal_state *)
 -       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
 -    return Z_MEM_ERROR;
 -  z->state->blocks = Z_NULL;
 -
 -  /* handle undocumented nowrap option (no zlib header or check) */
 -  z->state->nowrap = 0;
 -  if (w < 0)
 -  {
 -    w = - w;
 -    z->state->nowrap = 1;
 -  }
 -
 -  /* set window size */
 -  if (w < 8 || w > 15)
 -  {
 -    inflateEnd(z);
 -    return Z_STREAM_ERROR;
 -  }
 -  z->state->wbits = (uInt)w;
 -
 -  /* create inflate_blocks state */
 -  if ((z->state->blocks =
 -      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
 -      == Z_NULL)
 -  {
 -    inflateEnd(z);
 -    return Z_MEM_ERROR;
 -  }
 -  Tracev(("inflate: allocated\n"));
 -
 -  /* reset state */
 -  inflateReset(z);
 -  return Z_OK;
 -}
 -
 -
 -int inflateInit_(z_streamp z, const char *version, int stream_size)
 -{
 -  return inflateInit2_(z, DEF_WBITS, version, stream_size);
 -}
 -
 -
 -#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;}
 -#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
 -
 -int inflate(z_streamp z, int f)
 -{
 -  int r;
 -  uInt b;
 -
 -  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
 -  r = Z_BUF_ERROR;
 -  while (1) switch (z->state->mode)
 -  {
 -    case imMETHOD:
 -      iNEEDBYTE
 -      if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED)
 -      {
 -        z->state->mode = imBAD;
 -        z->msg = (char*)"unknown compression method";
 -        z->state->sub.marker = 5;       /* can't try inflateSync */
 -        break;
 -      }
 -      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
 -      {
 -        z->state->mode = imBAD;
 -        z->msg = (char*)"invalid window size";
 -        z->state->sub.marker = 5;       /* can't try inflateSync */
 -        break;
 -      }
 -      z->state->mode = imFLAG;
 -    case imFLAG:
 -      iNEEDBYTE
 -      b = iNEXTBYTE;
 -      if (((z->state->sub.method << 8) + b) % 31)
 -      {
 -        z->state->mode = imBAD;
 -        z->msg = (char*)"incorrect header check";
 -        z->state->sub.marker = 5;       /* can't try inflateSync */
 -        break;
 -      }
 -      Tracev(("inflate: zlib header ok\n"));
 -      if (!(b & PRESET_DICT))
 -      {
 -        z->state->mode = imBLOCKS;
 -        break;
 -      }
 -      z->state->mode = imDICT4;
 -    case imDICT4:
 -      iNEEDBYTE
 -      z->state->sub.check.need = (uLong)iNEXTBYTE << 24;
 -      z->state->mode = imDICT3;
 -    case imDICT3:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE << 16;
 -      z->state->mode = imDICT2;
 -    case imDICT2:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE << 8;
 -      z->state->mode = imDICT1;
 -    case imDICT1:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE;
 -      z->adler = z->state->sub.check.need;
 -      z->state->mode = imDICT0;
 -      return Z_NEED_DICT;
 -    case imDICT0:
 -      z->state->mode = imBAD;
 -      z->msg = (char*)"need dictionary";
 -      z->state->sub.marker = 0;       /* can try inflateSync */
 -      return Z_STREAM_ERROR;
 -    case imBLOCKS:
 -      r = inflate_blocks(z->state->blocks, z, r);
 -      if (r == Z_DATA_ERROR)
 -      {
 -        z->state->mode = imBAD;
 -        z->state->sub.marker = 0;       /* can try inflateSync */
 -        break;
 -      }
 -      if (r == Z_OK)
 -        r = f;
 -      if (r != Z_STREAM_END)
 -        return r;
 -      r = f;
 -      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
 -      if (z->state->nowrap)
 -      {
 -        z->state->mode = imDONE;
 -        break;
 -      }
 -      z->state->mode = imCHECK4;
 -    case imCHECK4:
 -      iNEEDBYTE
 -      z->state->sub.check.need = (uLong)iNEXTBYTE << 24;
 -      z->state->mode = imCHECK3;
 -    case imCHECK3:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE << 16;
 -      z->state->mode = imCHECK2;
 -    case imCHECK2:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE << 8;
 -      z->state->mode = imCHECK1;
 -    case imCHECK1:
 -      iNEEDBYTE
 -      z->state->sub.check.need += (uLong)iNEXTBYTE;
 -
 -      if (z->state->sub.check.was != z->state->sub.check.need)
 -      {
 -        z->state->mode = imBAD;
 -        z->msg = (char*)"incorrect data check";
 -        z->state->sub.marker = 5;       /* can't try inflateSync */
 -        break;
 -      }
 -      Tracev(("inflate: zlib check ok\n"));
 -      z->state->mode = imDONE;
 -    case imDONE:
 -      return Z_STREAM_END;
 -    case imBAD:
 -      return Z_DATA_ERROR;
 -    default:
 -      return Z_STREAM_ERROR;
 -  }
 -#ifdef NEED_DUMMY_RETURN
 -  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
 -#endif
 -}
 -
 -
 -int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength)
 -{
 -  uInt length = dictLength;
 -
 -  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0)
 -    return Z_STREAM_ERROR;
 -
 -  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
 -  z->adler = 1L;
 -
 -  if (length >= ((uInt)1<<z->state->wbits))
 -  {
 -    length = (1<<z->state->wbits)-1;
 -    dictionary += dictLength - length;
 -  }
 -  inflate_set_dictionary(z->state->blocks, dictionary, length);
 -  z->state->mode = imBLOCKS;
 -  return Z_OK;
 -}
 -
 -
 -int inflateSync(z_streamp z)
 -{
 -  uInt n;       /* number of bytes to look at */
 -  Byte *p;     /* pointer to bytes */
 -  uInt m;       /* number of marker bytes found in a row */
 -  uLong r, w;   /* temporaries to save total_in and total_out */
 -
 -  /* set up */
 -  if (z == Z_NULL || z->state == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  if (z->state->mode != imBAD)
 -  {
 -    z->state->mode = imBAD;
 -    z->state->sub.marker = 0;
 -  }
 -  if ((n = z->avail_in) == 0)
 -    return Z_BUF_ERROR;
 -  p = z->next_in;
 -  m = z->state->sub.marker;
 -
 -  /* search */
 -  while (n && m < 4)
 -  {
 -    static const Byte mark[4] = {0, 0, 0xff, 0xff};
 -    if (*p == mark[m])
 -      m++;
 -    else if (*p)
 -      m = 0;
 -    else
 -      m = 4 - m;
 -    p++, n--;
 -  }
 -
 -  /* restore */
 -  z->total_in += p - z->next_in;
 -  z->next_in = p;
 -  z->avail_in = n;
 -  z->state->sub.marker = m;
 -
 -  /* return no joy or set up to restart on a new block */
 -  if (m != 4)
 -    return Z_DATA_ERROR;
 -  r = z->total_in;  w = z->total_out;
 -  inflateReset(z);
 -  z->total_in = r;  z->total_out = w;
 -  z->state->mode = imBLOCKS;
 -  return Z_OK;
 -}
 -
 -
 -/* Returns true if inflate is currently at the end of a block generated
 - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
 - * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
 - * but removes the length bytes of the resulting empty stored block. When
 - * decompressing, PPP checks that at the end of input packet, inflate is
 - * waiting for these length bytes.
 - */
 -int inflateSyncPoint(z_streamp z)
 -{
 -  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
 -    return Z_STREAM_ERROR;
 -  return inflate_blocks_sync_point(z->state->blocks);
 -}
 -
 -voidp zcalloc (voidp opaque, unsigned items, unsigned size)
 -{
 -    if (opaque) items += size - size; /* make compiler happy */
 -    return (voidp)malloc(items*size);
 -}
 -
 -void  zcfree (voidp opaque, voidp ptr)
 -{
 -    free(ptr);
 -    if (opaque) return; /* make compiler happy */
 -}
 -
 +/***************************************************************************** + * name:		unzip.c + * + * desc:		IO on .zip files using portions of zlib  + * + * $Archive: /source/code/qcommon/unzip.c $ + * $Author: ttimo $  + * $Revision: 1.1.1.3 $ + * $Modtime: 10/19/99 3:59p $ + * $Date: 2000/01/11 16:37:27 $ + * + *****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <windows.h> +#include "unzip.h" +//#include "cmdlib.h" + +/* unzip.h -- IO for uncompress .zip files using zlib  +   Version 0.15 beta, Mar 19th, 1998, + +   Copyright (C) 1998 Gilles Vollant + +   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g +     WinZip, InfoZip tools and compatible. +   Encryption and multi volume ZipFile (span) are not supported. +   Old compressions used by old PKZip 1.x are not supported + +   THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE +   CAN CHANGE IN FUTURE VERSION !! +   I WAIT FEEDBACK at mail info@winimage.com +   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + +   Condition of use and distribution are the same than zlib : + +  This software is provided 'as-is', without any express or implied +  warranty.  In no event will the authors be held liable for any damages +  arising from the use of this software. + +  Permission is granted to anyone to use this software for any purpose, +  including commercial applications, and to alter it and redistribute it +  freely, subject to the following restrictions: + +  1. The origin of this software must not be misrepresented; you must not +     claim that you wrote the original software. If you use this software +     in a product, an acknowledgment in the product documentation would be +     appreciated but is not required. +  2. Altered source versions must be plainly marked as such, and must not be +     misrepresented as being the original software. +  3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see  +      ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip +   PkWare has also a specification at : +      ftp://ftp.pkware.com/probdesc.zip */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library +  version 1.1.3, July 9th, 1998 + +  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + +  This software is provided 'as-is', without any express or implied +  warranty.  In no event will the authors be held liable for any damages +  arising from the use of this software. + +  Permission is granted to anyone to use this software for any purpose, +  including commercial applications, and to alter it and redistribute it +  freely, subject to the following restrictions: + +  1. The origin of this software must not be misrepresented; you must not +     claim that you wrote the original software. If you use this software +     in a product, an acknowledgment in the product documentation would be +     appreciated but is not required. +  2. Altered source versions must be plainly marked as such, and must not be +     misrepresented as being the original software. +  3. This notice may not be removed or altered from any source distribution. + +  Jean-loup Gailly        Mark Adler +  jloup@gzip.org          madler@alumni.caltech.edu + + +  The data format used by the zlib library is described by RFCs (Request for +  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt +  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-1998 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +#  ifdef MAXSEG_64K +#    define MAX_MEM_LEVEL 8 +#  else +#    define MAX_MEM_LEVEL 9 +#  endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +#  define MAX_WBITS   15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): +            (1 << (windowBits+2)) +  (1 << (memLevel+9)) + that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with +     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + +   The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + +                        /* Type declarations */ + +#ifndef OF /* function prototypes */ +#define OF(args)  args +#endif + +typedef unsigned char  Byte;  /* 8 bits */ +typedef unsigned int   uInt;  /* 16 bits or more */ +typedef unsigned long  uLong; /* 32 bits or more */ +typedef Byte    *voidp; + +#ifndef SEEK_SET +#  define SEEK_SET        0       /* Seek from beginning of file.  */ +#  define SEEK_CUR        1       /* Seek from current position.  */ +#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */ +#endif + +#endif /* _ZCONF_H */ + +#define ZLIB_VERSION "1.1.3" + +/*  +     The 'zlib' compression library provides in-memory compression and +  decompression functions, including integrity checks of the uncompressed +  data.  This version of the library supports only one compression method +  (deflation) but other algorithms will be added later and will have the same +  stream interface. + +     Compression can be done in a single step if the buffers are large +  enough (for example if an input file is mmap'ed), or can be done by +  repeated calls of the compression function.  In the latter case, the +  application must provide more input and/or consume the output +  (providing more output space) before each call. + +     The library also supports reading and writing files in gzip (.gz) format +  with an interface similar to that of stdio. + +     The library does not install any signal handler. The decoder checks +  the consistency of the compressed data, so the library should never +  crash even in case of corrupted input. +*/ + +/* +   The application must update next_in and avail_in when avail_in has +   dropped to zero. It must update next_out and avail_out when avail_out +   has dropped to zero. The application must initialize zalloc, zfree and +   opaque before calling the init function. All other fields are set by the +   compression library and must not be updated by the application. + +   The opaque value provided by the application will be passed as the first +   parameter for calls of zalloc and zfree. This can be useful for custom +   memory management. The compression library attaches no meaning to the +   opaque value. + +   zalloc must return Z_NULL if there is not enough memory for the object. +   If zlib is used in a multi-threaded application, zalloc and zfree must be +   thread safe. + +   On 16-bit systems, the functions zalloc and zfree must be able to allocate +   exactly 65536 bytes, but will not be required to allocate more than this +   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, +   pointers returned by zalloc for objects of exactly 65536 bytes *must* +   have their offset normalized to zero. The default allocation function +   provided by this library ensures this (see zutil.c). To reduce memory +   requirements and avoid any allocation of 64K objects, at the expense of +   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + +   The fields total_in and total_out can be used for statistics or +   progress reports. After compression, total_in holds the total size of +   the uncompressed data and may be saved for use in the decompressor +   (particularly if the decompressor wants to decompress everything in +   a single step). +*/ + +                        /* constants */ + +#define Z_NO_FLUSH      0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH    2 +#define Z_FULL_FLUSH    3 +#define Z_FINISH        4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK            0 +#define Z_STREAM_END    1 +#define Z_NEED_DICT     2 +#define Z_ERRNO        (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR   (-3) +#define Z_MEM_ERROR    (-4) +#define Z_BUF_ERROR    (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION         0 +#define Z_BEST_SPEED             1 +#define Z_BEST_COMPRESSION       9 +#define Z_DEFAULT_COMPRESSION  (-1) +/* compression levels */ + +#define Z_FILTERED            1 +#define Z_HUFFMAN_ONLY        2 +#define Z_DEFAULT_STRATEGY    0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY   0 +#define Z_ASCII    1 +#define Z_UNKNOWN  2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED   8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + +                        /* basic functions */ + +const char * zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. +   If the first character differs, the library code actually used is +   not compatible with the zlib.h header file used by the application. +   This check is automatically made by deflateInit and inflateInit. + */ + +/*  +int deflateInit OF((z_streamp strm, int level)); + +     Initializes the internal stream state for compression. The fields +   zalloc, zfree and opaque must be initialized before by the caller. +   If zalloc and zfree are set to Z_NULL, deflateInit updates them to +   use default allocation functions. + +     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: +   1 gives best speed, 9 gives best compression, 0 gives no compression at +   all (the input data is simply copied a block at a time). +   Z_DEFAULT_COMPRESSION requests a default compromise between speed and +   compression (currently equivalent to level 6). + +     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_STREAM_ERROR if level is not a valid compression level, +   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible +   with the version assumed by the caller (ZLIB_VERSION). +   msg is set to null if there is no error message.  deflateInit does not +   perform any compression: this will be done by deflate(). +*/ + + +int deflate OF((z_streamp strm, int flush)); +/* +    deflate compresses as much data as possible, and stops when the input +  buffer becomes empty or the output buffer becomes full. It may introduce some +  output latency (reading input without producing any output) except when +  forced to flush. + +    The detailed semantics are as follows. deflate performs one or both of the +  following actions: + +  - Compress more input starting at next_in and update next_in and avail_in +    accordingly. If not all input can be processed (because there is not +    enough room in the output buffer), next_in and avail_in are updated and +    processing will resume at this point for the next call of deflate(). + +  - Provide more output starting at next_out and update next_out and avail_out +    accordingly. This action is forced if the parameter flush is non zero. +    Forcing flush frequently degrades the compression ratio, so this parameter +    should be set only when necessary (in interactive applications). +    Some output may be provided even if flush is not set. + +  Before the call of deflate(), the application should ensure that at least +  one of the actions is possible, by providing more input and/or consuming +  more output, and updating avail_in or avail_out accordingly; avail_out +  should never be zero before the call. The application can consume the +  compressed output when it wants, for example when the output buffer is full +  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK +  and with zero avail_out, it must be called again after making room in the +  output buffer because there might be more output pending. + +    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is +  flushed to the output buffer and the output is aligned on a byte boundary, so +  that the decompressor can get all input data available so far. (In particular +  avail_in is zero after the call if enough output space has been provided +  before the call.)  Flushing may degrade compression for some compression +  algorithms and so it should be used only when necessary. + +    If flush is set to Z_FULL_FLUSH, all output is flushed as with +  Z_SYNC_FLUSH, and the compression state is reset so that decompression can +  restart from this point if previous compressed data has been damaged or if +  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade +  the compression. + +    If deflate returns with avail_out == 0, this function must be called again +  with the same value of the flush parameter and more output space (updated +  avail_out), until the flush is complete (deflate returns with non-zero +  avail_out). + +    If the parameter flush is set to Z_FINISH, pending input is processed, +  pending output is flushed and deflate returns with Z_STREAM_END if there +  was enough output space; if deflate returns with Z_OK, this function must be +  called again with Z_FINISH and more output space (updated avail_out) but no +  more input data, until it returns with Z_STREAM_END or an error. After +  deflate has returned Z_STREAM_END, the only possible operations on the +  stream are deflateReset or deflateEnd. +   +    Z_FINISH can be used immediately after deflateInit if all the compression +  is to be done in a single step. In this case, avail_out must be at least +  0.1% larger than avail_in plus 12 bytes.  If deflate does not return +  Z_STREAM_END, then it must be called again as described above. + +    deflate() sets strm->adler to the adler32 checksum of all input read +  so (that is, total_in bytes). + +    deflate() may update data_type if it can make a good guess about +  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered +  binary. This field is only for information purposes and does not affect +  the compression algorithm in any manner. + +    deflate() returns Z_OK if some progress has been made (more input +  processed or more output produced), Z_STREAM_END if all input has been +  consumed and all output has been produced (only when flush is set to +  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example +  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible +  (for example avail_in or avail_out was zero). +*/ + + +int deflateEnd OF((z_streamp strm)); +/* +     All dynamically allocated data structures for this stream are freed. +   This function discards any unprocessed input and does not flush any +   pending output. + +     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the +   stream state was inconsistent, Z_DATA_ERROR if the stream was freed +   prematurely (some input or output was discarded). In the error case, +   msg may be set but then points to a static string (which must not be +   deallocated). +*/ + + +/*  +int inflateInit OF((z_streamp strm)); + +     Initializes the internal stream state for decompression. The fields +   next_in, avail_in, zalloc, zfree and opaque must be initialized before by +   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact +   value depends on the compression method), inflateInit determines the +   compression method from the zlib header and allocates all data structures +   accordingly; otherwise the allocation will be deferred to the first call of +   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to +   use default allocation functions. + +     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the +   version assumed by the caller.  msg is set to null if there is no error +   message. inflateInit does not perform any decompression apart from reading +   the zlib header if present: this will be done by inflate().  (So next_in and +   avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +int inflate OF((z_streamp strm, int flush)); +/* +    inflate decompresses as much data as possible, and stops when the input +  buffer becomes empty or the output buffer becomes full. It may some +  introduce some output latency (reading input without producing any output) +  except when forced to flush. + +  The detailed semantics are as follows. inflate performs one or both of the +  following actions: + +  - Decompress more input starting at next_in and update next_in and avail_in +    accordingly. If not all input can be processed (because there is not +    enough room in the output buffer), next_in is updated and processing +    will resume at this point for the next call of inflate(). + +  - Provide more output starting at next_out and update next_out and avail_out +    accordingly.  inflate() provides as much output as possible, until there +    is no more input data or no more space in the output buffer (see below +    about the flush parameter). + +  Before the call of inflate(), the application should ensure that at least +  one of the actions is possible, by providing more input and/or consuming +  more output, and updating the next_* and avail_* values accordingly. +  The application can consume the uncompressed output when it wants, for +  example when the output buffer is full (avail_out == 0), or after each +  call of inflate(). If inflate returns Z_OK and with zero avail_out, it +  must be called again after making room in the output buffer because there +  might be more output pending. + +    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much +  output as possible to the output buffer. The flushing behavior of inflate is +  not specified for values of the flush parameter other than Z_SYNC_FLUSH +  and Z_FINISH, but the current implementation actually flushes as much output +  as possible anyway. + +    inflate() should normally be called until it returns Z_STREAM_END or an +  error. However if all decompression is to be performed in a single step +  (a single call of inflate), the parameter flush should be set to +  Z_FINISH. In this case all pending input is processed and all pending +  output is flushed; avail_out must be large enough to hold all the +  uncompressed data. (The size of the uncompressed data may have been saved +  by the compressor for this purpose.) The next operation on this stream must +  be inflateEnd to deallocate the decompression state. The use of Z_FINISH +  is never required, but can be used to inform inflate that a faster routine +  may be used for the single inflate() call. + +     If a preset dictionary is needed at this point (see inflateSetDictionary +  below), inflate sets strm-adler to the adler32 checksum of the +  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise  +  it sets strm->adler to the adler32 checksum of all output produced +  so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or +  an error code as described below. At the end of the stream, inflate() +  checks that its computed adler32 checksum is equal to that saved by the +  compressor and returns Z_STREAM_END only if the checksum is correct. + +    inflate() returns Z_OK if some progress has been made (more input processed +  or more output produced), Z_STREAM_END if the end of the compressed data has +  been reached and all uncompressed output has been produced, Z_NEED_DICT if a +  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was +  corrupted (input stream not conforming to the zlib format or incorrect +  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent +  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not +  enough memory, Z_BUF_ERROR if no progress is possible or if there was not +  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR +  case, the application may then call inflateSync to look for a good +  compression block. +*/ + + +int inflateEnd OF((z_streamp strm)); +/* +     All dynamically allocated data structures for this stream are freed. +   This function discards any unprocessed input and does not flush any +   pending output. + +     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state +   was inconsistent. In the error case, msg may be set but then points to a +   static string (which must not be deallocated). +*/ + +                        /* Advanced functions */ + +/* +    The following functions are needed only in some special applications. +*/ + +/*    +int deflateInit2 OF((z_streamp strm, +                                     int  level, +                                     int  method, +                                     int  windowBits, +                                     int  memLevel, +                                     int  strategy)); + +     This is another version of deflateInit with more compression options. The +   fields next_in, zalloc, zfree and opaque must be initialized before by +   the caller. + +     The method parameter is the compression method. It must be Z_DEFLATED in +   this version of the library. + +     The windowBits parameter is the base two logarithm of the window size +   (the size of the history buffer).  It should be in the range 8..15 for this +   version of the library. Larger values of this parameter result in better +   compression at the expense of memory usage. The default value is 15 if +   deflateInit is used instead. + +     The memLevel parameter specifies how much memory should be allocated +   for the internal compression state. memLevel=1 uses minimum memory but +   is slow and reduces compression ratio; memLevel=9 uses maximum memory +   for optimal speed. The default value is 8. See zconf.h for total memory +   usage as a function of windowBits and memLevel. + +     The strategy parameter is used to tune the compression algorithm. Use the +   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a +   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no +   string match).  Filtered data consists mostly of small values with a +   somewhat random distribution. In this case, the compression algorithm is +   tuned to compress them better. The effect of Z_FILTERED is to force more +   Huffman coding and less string matching; it is somewhat intermediate +   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects +   the compression ratio but not the correctness of the compressed output even +   if it is not set appropriately. + +      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid +   method). msg is set to null if there is no error message.  deflateInit2 does +   not perform any compression: this will be done by deflate(). +*/ +                             +int deflateSetDictionary OF((z_streamp strm, +                                             const Byte *dictionary, +                                             uInt  dictLength)); +/* +     Initializes the compression dictionary from the given byte sequence +   without producing any compressed output. This function must be called +   immediately after deflateInit, deflateInit2 or deflateReset, before any +   call of deflate. The compressor and decompressor must use exactly the same +   dictionary (see inflateSetDictionary). + +     The dictionary should consist of strings (byte sequences) that are likely +   to be encountered later in the data to be compressed, with the most commonly +   used strings preferably put towards the end of the dictionary. Using a +   dictionary is most useful when the data to be compressed is short and can be +   predicted with good accuracy; the data can then be compressed better than +   with the default empty dictionary. + +     Depending on the size of the compression data structures selected by +   deflateInit or deflateInit2, a part of the dictionary may in effect be +   discarded, for example if the dictionary is larger than the window size in +   deflate or deflate2. Thus the strings most likely to be useful should be +   put at the end of the dictionary, not at the front. + +     Upon return of this function, strm->adler is set to the Adler32 value +   of the dictionary; the decompressor may later use this value to determine +   which dictionary has been used by the compressor. (The Adler32 value +   applies to the whole dictionary even if only a subset of the dictionary is +   actually used by the compressor.) + +     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a +   parameter is invalid (such as NULL dictionary) or the stream state is +   inconsistent (for example if deflate has already been called for this stream +   or if the compression method is bsort). deflateSetDictionary does not +   perform any compression: this will be done by deflate(). +*/ + +int deflateCopy OF((z_streamp dest, +                                    z_streamp source)); +/* +     Sets the destination stream as a complete copy of the source stream. + +     This function can be useful when several compression strategies will be +   tried, for example when there are several ways of pre-processing the input +   data with a filter. The streams that will be discarded should then be freed +   by calling deflateEnd.  Note that deflateCopy duplicates the internal +   compression state which can be quite large, so this strategy is slow and +   can consume lots of memory. + +     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent +   (such as zalloc being NULL). msg is left unchanged in both source and +   destination. +*/ + +int deflateReset OF((z_streamp strm)); +/* +     This function is equivalent to deflateEnd followed by deflateInit, +   but does not free and reallocate all the internal compression state. +   The stream will keep the same compression level and any other attributes +   that may have been set by deflateInit2. + +      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent (such as zalloc or state being NULL). +*/ + +int deflateParams OF((z_streamp strm, +				      int level, +				      int strategy)); +/* +     Dynamically update the compression level and compression strategy.  The +   interpretation of level and strategy is as in deflateInit2.  This can be +   used to switch between compression and straight copy of the input data, or +   to switch to a different kind of input data requiring a different +   strategy. If the compression level is changed, the input available so far +   is compressed with the old level (and may be flushed); the new level will +   take effect only at the next call of deflate(). + +     Before the call of deflateParams, the stream state must be set as for +   a call of deflate(), since the currently available input may have to +   be compressed and flushed. In particular, strm->avail_out must be non-zero. + +     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source +   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR +   if strm->avail_out was zero. +*/ + +/*    +int inflateInit2 OF((z_streamp strm, +                                     int  windowBits)); + +     This is another version of inflateInit with an extra parameter. The +   fields next_in, avail_in, zalloc, zfree and opaque must be initialized +   before by the caller. + +     The windowBits parameter is the base two logarithm of the maximum window +   size (the size of the history buffer).  It should be in the range 8..15 for +   this version of the library. The default value is 15 if inflateInit is used +   instead. If a compressed stream with a larger window size is given as +   input, inflate() will return with the error code Z_DATA_ERROR instead of +   trying to allocate a larger window. + +      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative +   memLevel). msg is set to null if there is no error message.  inflateInit2 +   does not perform any decompression apart from reading the zlib header if +   present: this will be done by inflate(). (So next_in and avail_in may be +   modified, but next_out and avail_out are unchanged.) +*/ + +int inflateSetDictionary OF((z_streamp strm, +                                             const Byte *dictionary, +                                             uInt  dictLength)); +/* +     Initializes the decompression dictionary from the given uncompressed byte +   sequence. This function must be called immediately after a call of inflate +   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor +   can be determined from the Adler32 value returned by this call of +   inflate. The compressor and decompressor must use exactly the same +   dictionary (see deflateSetDictionary). + +     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a +   parameter is invalid (such as NULL dictionary) or the stream state is +   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the +   expected one (incorrect Adler32 value). inflateSetDictionary does not +   perform any decompression: this will be done by subsequent calls of +   inflate(). +*/ + +int inflateSync OF((z_streamp strm)); +/*  +    Skips invalid compressed data until a full flush point (see above the +  description of deflate with Z_FULL_FLUSH) can be found, or until all +  available input is skipped. No output is provided. + +    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR +  if no more input was provided, Z_DATA_ERROR if no flush point has been found, +  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success +  case, the application may save the current current value of total_in which +  indicates where valid compressed data was found. In the error case, the +  application may repeatedly call inflateSync, providing more input each time, +  until success or end of the input data. +*/ + +int inflateReset OF((z_streamp strm)); +/* +     This function is equivalent to inflateEnd followed by inflateInit, +   but does not free and reallocate all the internal decompression state. +   The stream will keep attributes that may have been set by inflateInit2. + +      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent (such as zalloc or state being NULL). +*/ + + +                        /* utility functions */ + +/* +     The following utility functions are implemented on top of the +   basic stream-oriented functions. To simplify the interface, some +   default options are assumed (compression level and memory usage, +   standard memory allocation functions). The source code of these +   utility functions can easily be modified if you need special options. +*/ + +int compress OF((Byte *dest,   uLong *destLen, +                                 const Byte *source, uLong sourceLen)); +/* +     Compresses the source buffer into the destination buffer.  sourceLen is +   the byte length of the source buffer. Upon entry, destLen is the total +   size of the destination buffer, which must be at least 0.1% larger than +   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the +   compressed buffer. +     This function can be used to compress a whole file at once if the +   input file is mmap'ed. +     compress returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_BUF_ERROR if there was not enough room in the output +   buffer. +*/ + +int compress2 OF((Byte *dest,   uLong *destLen, +                                  const Byte *source, uLong sourceLen, +                                  int level)); +/* +     Compresses the source buffer into the destination buffer. The level +   parameter has the same meaning as in deflateInit.  sourceLen is the byte +   length of the source buffer. Upon entry, destLen is the total size of the +   destination buffer, which must be at least 0.1% larger than sourceLen plus +   12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + +     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_BUF_ERROR if there was not enough room in the output buffer, +   Z_STREAM_ERROR if the level parameter is invalid. +*/ + +int uncompress OF((Byte *dest,   uLong *destLen, +                                   const Byte *source, uLong sourceLen)); +/* +     Decompresses the source buffer into the destination buffer.  sourceLen is +   the byte length of the source buffer. Upon entry, destLen is the total +   size of the destination buffer, which must be large enough to hold the +   entire uncompressed data. (The size of the uncompressed data must have +   been saved previously by the compressor and transmitted to the decompressor +   by some mechanism outside the scope of this compression library.) +   Upon exit, destLen is the actual size of the compressed buffer. +     This function can be used to decompress a whole file at once if the +   input file is mmap'ed. + +     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_BUF_ERROR if there was not enough room in the output +   buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +gzFile gzopen  OF((const char *path, const char *mode)); +/* +     Opens a gzip (.gz) file for reading or writing. The mode parameter +   is as in fopen ("rb" or "wb") but can also include a compression level +   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for +   Huffman only compression as in "wb1h". (See the description +   of deflateInit2 for more information about the strategy parameter.) + +     gzopen can be used to read a file which is not in gzip format; in this +   case gzread will directly read from the file without decompression. + +     gzopen returns NULL if the file could not be opened or if there was +   insufficient memory to allocate the (de)compression state; errno +   can be checked to distinguish the two cases (if errno is zero, the +   zlib error is Z_MEM_ERROR).  */ + +gzFile gzdopen  OF((int fd, const char *mode)); +/* +     gzdopen() associates a gzFile with the file descriptor fd.  File +   descriptors are obtained from calls like open, dup, creat, pipe or +   fileno (in the file has been previously opened with fopen). +   The mode parameter is as in gzopen. +     The next call of gzclose on the returned gzFile will also close the +   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file +   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +     gzdopen returns NULL if there was insufficient memory to allocate +   the (de)compression state. +*/ + +int gzsetparams OF((gzFile file, int level, int strategy)); +/* +     Dynamically update the compression level or strategy. See the description +   of deflateInit2 for the meaning of these parameters. +     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not +   opened for writing. +*/ + +int    gzread  OF((gzFile file, voidp buf, unsigned len)); +/* +     Reads the given number of uncompressed bytes from the compressed file. +   If the input file was not in gzip format, gzread copies the given number +   of bytes into the buffer. +     gzread returns the number of uncompressed bytes actually read (0 for +   end of file, -1 for error). */ + +int    gzwrite OF((gzFile file,  +				   const voidp buf, unsigned len)); +/* +     Writes the given number of uncompressed bytes into the compressed file. +   gzwrite returns the number of uncompressed bytes actually written +   (0 in case of error). +*/ + +int    gzprintf OF((gzFile file, const char *format, ...)); +/* +     Converts, formats, and writes the args to the compressed file under +   control of the format string, as in fprintf. gzprintf returns the number of +   uncompressed bytes actually written (0 in case of error). +*/ + +int gzputs OF((gzFile file, const char *s)); +/* +      Writes the given null-terminated string to the compressed file, excluding +   the terminating null character. +      gzputs returns the number of characters written, or -1 in case of error. +*/ + +char * gzgets OF((gzFile file, char *buf, int len)); +/* +      Reads bytes from the compressed file until len-1 characters are read, or +   a newline character is read and transferred to buf, or an end-of-file +   condition is encountered.  The string is then terminated with a null +   character. +      gzgets returns buf, or Z_NULL in case of error. +*/ + +int    gzputc OF((gzFile file, int c)); +/* +      Writes c, converted to an unsigned char, into the compressed file. +   gzputc returns the value that was written, or -1 in case of error. +*/ + +int    gzgetc OF((gzFile file)); +/* +      Reads one byte from the compressed file. gzgetc returns this byte +   or -1 in case of end of file or error. +*/ + +int    gzflush OF((gzFile file, int flush)); +/* +     Flushes all pending output into the compressed file. The parameter +   flush is as in the deflate() function. The return value is the zlib +   error number (see function gzerror below). gzflush returns Z_OK if +   the flush parameter is Z_FINISH and all output could be flushed. +     gzflush should be called only when strictly necessary because it can +   degrade compression. +*/ + +long gzseek OF((gzFile file, +				      long offset, int whence)); +/*  +      Sets the starting position for the next gzread or gzwrite on the +   given compressed file. The offset represents a number of bytes in the +   uncompressed data stream. The whence parameter is defined as in lseek(2); +   the value SEEK_END is not supported. +     If the file is opened for reading, this function is emulated but can be +   extremely slow. If the file is opened for writing, only forward seeks are +   supported; gzseek then compresses a sequence of zeroes up to the new +   starting position. + +      gzseek returns the resulting offset location as measured in bytes from +   the beginning of the uncompressed stream, or -1 in case of error, in +   particular if the file is opened for writing and the new starting position +   would be before the current position. +*/ + +int    gzrewind OF((gzFile file)); +/* +     Rewinds the given file. This function is supported only for reading. + +   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +long    gztell OF((gzFile file)); +/* +     Returns the starting position for the next gzread or gzwrite on the +   given compressed file. This position represents a number of bytes in the +   uncompressed data stream. + +   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +int gzeof OF((gzFile file)); +/* +     Returns 1 when EOF has previously been detected reading the given +   input stream, otherwise zero. +*/ + +int    gzclose OF((gzFile file)); +/* +     Flushes all pending output if necessary, closes the compressed file +   and deallocates all the (de)compression state. The return value is the zlib +   error number (see function gzerror below). +*/ + +const char * gzerror OF((gzFile file, int *errnum)); +/* +     Returns the error message for the last error which occurred on the +   given compressed file. errnum is set to zlib error number. If an +   error occurred in the file system and not in the compression library, +   errnum is set to Z_ERRNO and the application may consult errno +   to get the exact error code. +*/ + +                        /* checksum functions */ + +/* +     These functions are not related to compression but are exported +   anyway because they might be useful in applications using the +   compression library. +*/ + +uLong adler32 OF((uLong adler, const Byte *buf, uInt len)); + +/* +     Update a running Adler-32 checksum with the bytes buf[0..len-1] and +   return the updated checksum. If buf is NULL, this function returns +   the required initial value for the checksum. +   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed +   much faster. Usage example: + +     uLong adler = adler32(0L, Z_NULL, 0); + +     while (read_buffer(buffer, length) != EOF) { +       adler = adler32(adler, buffer, length); +     } +     if (adler != original_adler) error(); +*/ + +uLong crc32   OF((uLong crc, const Byte *buf, uInt len)); +/* +     Update a running crc with the bytes buf[0..len-1] and return the updated +   crc. If buf is NULL, this function returns the required initial value +   for the crc. Pre- and post-conditioning (one's complement) is performed +   within this function so it shouldn't be done by the application. +   Usage example: + +     uLong crc = crc32(0L, Z_NULL, 0); + +     while (read_buffer(buffer, length) != EOF) { +       crc = crc32(crc, buffer, length); +     } +     if (crc != original_crc) error(); +*/ + +// private stuff to not include cmdlib.h +/* +============================================================================ + +					BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +#ifdef _SGI_SOURCE +#define	__BIG_ENDIAN__ +#endif + +#ifdef __BIG_ENDIAN__ + +short   __LittleShort (short l) +{ +	byte    b1,b2; + +	b1 = l&255; +	b2 = (l>>8)&255; + +	return (b1<<8) + b2; +} + +short   __BigShort (short l) +{ +	return l; +} + + +int    __LittleLong (int l) +{ +	byte    b1,b2,b3,b4; + +	b1 = l&255; +	b2 = (l>>8)&255; +	b3 = (l>>16)&255; +	b4 = (l>>24)&255; + +	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int    __BigLong (int l) +{ +	return l; +} + + +float	__LittleFloat (float l) +{ +	union {byte b[4]; float f;} in, out; +	 +	in.f = l; +	out.b[0] = in.b[3]; +	out.b[1] = in.b[2]; +	out.b[2] = in.b[1]; +	out.b[3] = in.b[0]; +	 +	return out.f; +} + +float	__BigFloat (float l) +{ +	return l; +} + + +#else + + +short   __BigShort (short l) +{ +	byte    b1,b2; + +	b1 = l&255; +	b2 = (l>>8)&255; + +	return (b1<<8) + b2; +} + +short   __LittleShort (short l) +{ +	return l; +} + + +int    __BigLong (int l) +{ +	byte    b1,b2,b3,b4; + +	b1 = l&255; +	b2 = (l>>8)&255; +	b3 = (l>>16)&255; +	b4 = (l>>24)&255; + +	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int    __LittleLong (int l) +{ +	return l; +} + +float	__BigFloat (float l) +{ +	union {byte b[4]; float f;} in, out; +	 +	in.f = l; +	out.b[0] = in.b[3]; +	out.b[1] = in.b[2]; +	out.b[2] = in.b[1]; +	out.b[3] = in.b[0]; +	 +	return out.f; +} + +float	__LittleFloat (float l) +{ +	return l; +} + + + +#endif + + + + +                        /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +int deflateInit_ OF((z_streamp strm, int level, +                                     const char *version, int stream_size)); +int inflateInit_ OF((z_streamp strm, +                                     const char *version, int stream_size)); +int deflateInit2_ OF((z_streamp strm, int  level, int  method, +                                      int windowBits, int memLevel, +                                      int strategy, const char *version, +                                      int stream_size)); +int inflateInit2_ OF((z_streamp strm, int  windowBits, +                                      const char *version, int stream_size)); +#define deflateInit(strm, level) \ +        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ +        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ +        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ +                      (strategy),           ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ +        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +const char   * zError           OF((int err)); +int            inflateSyncPoint OF((z_streamp z)); +const uLong * get_crc_table    OF((void)); + +typedef unsigned char  uch; +typedef unsigned short ush; +typedef unsigned long  ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ +  return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + +        /* common constants */ + +#ifndef DEF_WBITS +#  define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +#  define DEF_MEM_LEVEL 8 +#else +#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES    2 +/* The three kinds of block type */ + +#define MIN_MATCH  3 +#define MAX_MATCH  258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + +        /* target dependencies */ + +        /* Common defaults */ + +#ifndef OS_CODE +#  define OS_CODE  0x03  /* assume Unix */ +#endif + +#ifndef F_OPEN +#  define F_OPEN(name, mode) fopen((name), (mode)) +#endif + +         /* functions */ + +#ifdef HAVE_STRERROR +   extern char *strerror OF((int)); +#  define zstrerror(errnum) strerror(errnum) +#else +#  define zstrerror(errnum) "" +#endif + +#define zmemcpy memcpy +#define zmemcmp memcmp +#define zmemzero(dest, len) memset(dest, 0, len) + +/* Diagnostic functions */ +#ifdef _ZIP_DEBUG_ +   int z_verbose = 0; +#  define Assert(cond,msg) assert(cond); +   //{if(!(cond)) Sys_Error(msg);} +#  define Trace(x) {if (z_verbose>=0) Sys_Error x ;} +#  define Tracev(x) {if (z_verbose>0) Sys_Error x ;} +#  define Tracevv(x) {if (z_verbose>1) Sys_Error x ;} +#  define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;} +#  define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;} +#else +#  define Assert(cond,msg) +#  define Trace(x) +#  define Tracev(x) +#  define Tracevv(x) +#  define Tracec(c,x) +#  define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len)); +voidp zcalloc OF((voidp opaque, unsigned items, unsigned size)); +void   zcfree  OF((voidp opaque, voidp ptr)); + +#define ZALLOC(strm, items, size) \ +           (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ +                      !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (65536) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + +/* =========================================================================== +     Read a byte from a gz_stream; update next_in and avail_in. Return EOF +   for end of file. +   IN assertion: the stream s has been sucessfully opened for reading. +*/ + +/* +static int unzlocal_getByte(FILE *fin,int *pi) +{ +    unsigned char c; +	int err = fread(&c, 1, 1, fin); +    if (err==1) +    { +        *pi = (int)c; +        return UNZ_OK; +    } +    else +    { +        if (ferror(fin))  +            return UNZ_ERRNO; +        else +            return UNZ_EOF; +    } +} +*/ + +/* =========================================================================== +   Reads a long in LSB order from the given gz_stream. Sets  +*/ +static int unzlocal_getShort (FILE* fin, uLong *pX) +{ +	short	v; + +	fread( &v, sizeof(v), 1, fin ); + +	*pX = __LittleShort( v); +	return UNZ_OK; + +/* +    uLong x ; +    int i; +    int err; + +    err = unzlocal_getByte(fin,&i); +    x = (uLong)i; +     +    if (err==UNZ_OK) +        err = unzlocal_getByte(fin,&i); +    x += ((uLong)i)<<8; +    +    if (err==UNZ_OK) +        *pX = x; +    else +        *pX = 0; +    return err; +*/ +} + +static int unzlocal_getLong (FILE *fin, uLong *pX) +{ +	int		v; + +	fread( &v, sizeof(v), 1, fin ); + +	*pX = __LittleLong( v); +	return UNZ_OK; + +/* +    uLong x ; +    int i; +    int err; + +    err = unzlocal_getByte(fin,&i); +    x = (uLong)i; +     +    if (err==UNZ_OK) +        err = unzlocal_getByte(fin,&i); +    x += ((uLong)i)<<8; + +    if (err==UNZ_OK) +        err = unzlocal_getByte(fin,&i); +    x += ((uLong)i)<<16; + +    if (err==UNZ_OK) +        err = unzlocal_getByte(fin,&i); +    x += ((uLong)i)<<24; +    +    if (err==UNZ_OK) +        *pX = x; +    else +        *pX = 0; +    return err; +*/ +} + + +/* My own strcmpi / strcasecmp */ +static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2) +{ +	for (;;) +	{ +		char c1=*(fileName1++); +		char c2=*(fileName2++); +		if ((c1>='a') && (c1<='z')) +			c1 -= 0x20; +		if ((c2>='a') && (c2<='z')) +			c2 -= 0x20; +		if (c1=='\0') +			return ((c2=='\0') ? 0 : -1); +		if (c2=='\0') +			return 1; +		if (c1<c2) +			return -1; +		if (c1>c2) +			return 1; +	} +} + + +#ifdef  CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/*  +   Compare two filename (fileName1,fileName2). +   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) +   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi +                                                                or strcasecmp) +   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system +        (like 1 on Unix, 2 on Windows) + +*/ +extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity) +{ +	if (iCaseSensitivity==0) +		iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + +	if (iCaseSensitivity==1) +		return strcmp(fileName1,fileName2); + +	return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +}  + +#define BUFREADCOMMENT (0x400) + +/* +  Locate the Central directory of a zipfile (at the end, just before +    the global comment) +*/ +static uLong unzlocal_SearchCentralDir(FILE *fin) +{ +	unsigned char* buf; +	uLong uSizeFile; +	uLong uBackRead; +	uLong uMaxBack=0xffff; /* maximum size of global comment */ +	uLong uPosFound=0; +	 +	if (fseek(fin,0,SEEK_END) != 0) +		return 0; + + +	uSizeFile = ftell( fin ); +	 +	if (uMaxBack>uSizeFile) +		uMaxBack = uSizeFile; + +	buf = (unsigned char*)malloc(BUFREADCOMMENT+4); +	if (buf==NULL) +		return 0; + +	uBackRead = 4; +	while (uBackRead<uMaxBack) +	{ +		uLong uReadSize,uReadPos ; +		int i; +		if (uBackRead+BUFREADCOMMENT>uMaxBack)  +			uBackRead = uMaxBack; +		else +			uBackRead+=BUFREADCOMMENT; +		uReadPos = uSizeFile-uBackRead ; +		 +		uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?  +                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); +		if (fseek(fin,uReadPos,SEEK_SET)!=0) +			break; + +		if (fread(buf,(uInt)uReadSize,1,fin)!=1) +			break; + +                for (i=(int)uReadSize-3; (i--)>0;) +			if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&  +				((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) +			{ +				uPosFound = uReadPos+i; +				break; +			} + +		if (uPosFound!=0) +			break; +	} +	free(buf); +	return uPosFound; +} + +extern unzFile unzReOpen (const char* path, unzFile file) +{ +	unz_s *s; +	FILE * fin; + +    fin=fopen(path,"rb"); +	if (fin==NULL) +		return NULL; + +	s=(unz_s*)malloc(sizeof(unz_s)); +	memcpy(s, (unz_s*)file, sizeof(unz_s)); + +	s->file = fin; +	return (unzFile)s;	 +} + +/* +  Open a Zip file. path contain the full pathname (by example, +     on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer +	 "zlib/zlib109.zip". +	 If the zipfile cannot be opened (file don't exist or in not valid), the +	   return value is NULL. +     Else, the return value is a unzFile Handle, usable with other function +	   of this unzip package. +*/ +extern unzFile unzOpen (const char* path) +{ +	unz_s us; +	unz_s *s; +	uLong central_pos,uL; +	FILE * fin ; + +	uLong number_disk;          /* number of the current dist, used for  +								   spaning ZIP, unsupported, always 0*/ +	uLong number_disk_with_CD;  /* number the the disk with central dir, used +								   for spaning ZIP, unsupported, always 0*/ +	uLong number_entry_CD;      /* total number of entries in +	                               the central dir  +	                               (same than number_entry on nospan) */ + +	int err=UNZ_OK; + +    fin=fopen(path,"rb"); +	if (fin==NULL) +		return NULL; + +	central_pos = unzlocal_SearchCentralDir(fin); +	if (central_pos==0) +		err=UNZ_ERRNO; + +	if (fseek(fin,central_pos,SEEK_SET)!=0) +		err=UNZ_ERRNO; + +	/* the signature, already checked */ +	if (unzlocal_getLong(fin,&uL)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* number of this disk */ +	if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* number of the disk with the start of the central directory */ +	if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* total number of entries in the central dir on this disk */ +	if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* total number of entries in the central dir */ +	if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) +		err=UNZ_ERRNO; + +	if ((number_entry_CD!=us.gi.number_entry) || +		(number_disk_with_CD!=0) || +		(number_disk!=0)) +		err=UNZ_BADZIPFILE; + +	/* size of the central directory */ +	if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* offset of start of central directory with respect to the  +	      starting disk number */ +	if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) +		err=UNZ_ERRNO; + +	/* zipfile comment length */ +	if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) +		err=UNZ_ERRNO; + +	if ((central_pos<us.offset_central_dir+us.size_central_dir) &&  +		(err==UNZ_OK)) +		err=UNZ_BADZIPFILE; + +	if (err!=UNZ_OK) +	{ +		fclose(fin); +		return NULL; +	} + +	us.file=fin; +	us.byte_before_the_zipfile = central_pos - +		                    (us.offset_central_dir+us.size_central_dir); +	us.central_pos = central_pos; +    us.pfile_in_zip_read = NULL; +	 + +	s=(unz_s*)malloc(sizeof(unz_s)); +	*s=us; +//	unzGoToFirstFile((unzFile)s);	 +	return (unzFile)s;	 +} + + +/* +  Close a ZipFile opened with unzipOpen. +  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), +    these files MUST be closed with unzipCloseCurrentFile before call unzipClose. +  return UNZ_OK if there is no problem. */ +extern int unzClose (unzFile file) +{ +	unz_s* s; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; + +    if (s->pfile_in_zip_read!=NULL) +        unzCloseCurrentFile(file); + +	fclose(s->file); +	free(s); +	return UNZ_OK; +} + + +/* +  Write info about the ZipFile in the *pglobal_info structure. +  No preparation of the structure is needed +  return UNZ_OK if there is no problem. */ +extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) +{ +	unz_s* s; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +	*pglobal_info=s->gi; +	return UNZ_OK; +} + + +/* +   Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) +{ +    uLong uDate; +    uDate = (uLong)(ulDosDate>>16); +    ptm->tm_mday = (uInt)(uDate&0x1f) ; +    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ; +    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + +    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); +    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ; +    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* +  Get Info about the current file in the zipfile, with internal only info +*/ +static int unzlocal_GetCurrentFileInfoInternal (unzFile file, +                                                  unz_file_info *pfile_info, +                                                  unz_file_info_internal  +                                                  *pfile_info_internal, +                                                  char *szFileName, +												  uLong fileNameBufferSize, +                                                  void *extraField, +												  uLong extraFieldBufferSize, +                                                  char *szComment, +												  uLong commentBufferSize) +{ +	unz_s* s; +	unz_file_info file_info; +	unz_file_info_internal file_info_internal; +	int err=UNZ_OK; +	uLong uMagic; +	long lSeek=0; + +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +	if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) +		err=UNZ_ERRNO; + + +	/* we check the magic */ +	if (err==UNZ_OK) +		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) +			err=UNZ_ERRNO; +		else if (uMagic!=0x02014b50) +			err=UNZ_BADZIPFILE; + +	if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) +		err=UNZ_ERRNO; + +    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + +	if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) +		err=UNZ_ERRNO; + +	lSeek+=file_info.size_filename; +	if ((err==UNZ_OK) && (szFileName!=NULL)) +	{ +		uLong uSizeRead ; +		if (file_info.size_filename<fileNameBufferSize) +		{ +			*(szFileName+file_info.size_filename)='\0'; +			uSizeRead = file_info.size_filename; +		} +		else +			uSizeRead = fileNameBufferSize; + +		if ((file_info.size_filename>0) && (fileNameBufferSize>0)) +			if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) +				err=UNZ_ERRNO; +		lSeek -= uSizeRead; +	} + +	 +	if ((err==UNZ_OK) && (extraField!=NULL)) +	{ +		uLong uSizeRead ; +		if (file_info.size_file_extra<extraFieldBufferSize) +			uSizeRead = file_info.size_file_extra; +		else +			uSizeRead = extraFieldBufferSize; + +		if (lSeek!=0) +			if (fseek(s->file,lSeek,SEEK_CUR)==0) +				lSeek=0; +			else +				err=UNZ_ERRNO; +		if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) +			if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) +				err=UNZ_ERRNO; +		lSeek += file_info.size_file_extra - uSizeRead; +	} +	else +		lSeek+=file_info.size_file_extra;  + +	 +	if ((err==UNZ_OK) && (szComment!=NULL)) +	{ +		uLong uSizeRead ; +		if (file_info.size_file_comment<commentBufferSize) +		{ +			*(szComment+file_info.size_file_comment)='\0'; +			uSizeRead = file_info.size_file_comment; +		} +		else +			uSizeRead = commentBufferSize; + +		if (lSeek!=0) +			if (fseek(s->file,lSeek,SEEK_CUR)==0) +				lSeek=0; +			else +				err=UNZ_ERRNO; +		if ((file_info.size_file_comment>0) && (commentBufferSize>0)) +			if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) +				err=UNZ_ERRNO; +		lSeek+=file_info.size_file_comment - uSizeRead; +	} +	else +		lSeek+=file_info.size_file_comment; + +	if ((err==UNZ_OK) && (pfile_info!=NULL)) +		*pfile_info=file_info; + +	if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) +		*pfile_info_internal=file_info_internal; + +	return err; +} + + + +/* +  Write info about the ZipFile in the *pglobal_info structure. +  No preparation of the structure is needed +  return UNZ_OK if there is no problem. +*/ +extern int unzGetCurrentFileInfo (	unzFile file, unz_file_info *pfile_info, +									char *szFileName, uLong fileNameBufferSize, +									void *extraField, uLong extraFieldBufferSize, +									char *szComment, uLong commentBufferSize) +{ +	return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, +												szFileName,fileNameBufferSize, +												extraField,extraFieldBufferSize, +												szComment,commentBufferSize); +} + +/* +  Set the current file of the zipfile to the first file. +  return UNZ_OK if there is no problem +*/ +extern int unzGoToFirstFile (unzFile file) +{ +	int err=UNZ_OK; +	unz_s* s; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +	s->pos_in_central_dir=s->offset_central_dir; +	s->num_file=0; +	err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, +											 &s->cur_file_info_internal, +											 NULL,0,NULL,0,NULL,0); +	s->current_file_ok = (err == UNZ_OK); +	return err; +} + + +/* +  Set the current file of the zipfile to the next file. +  return UNZ_OK if there is no problem +  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int unzGoToNextFile (unzFile file) +{ +	unz_s* s;	 +	int err; + +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +	if (!s->current_file_ok) +		return UNZ_END_OF_LIST_OF_FILE; +	if (s->num_file+1==s->gi.number_entry) +		return UNZ_END_OF_LIST_OF_FILE; + +	s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + +			s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; +	s->num_file++; +	err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, +											   &s->cur_file_info_internal, +											   NULL,0,NULL,0,NULL,0); +	s->current_file_ok = (err == UNZ_OK); +	return err; +} + + +/* +  Try locate the file szFileName in the zipfile. +  For the iCaseSensitivity signification, see unzipStringFileNameCompare + +  return value : +  UNZ_OK if the file is found. It becomes the current file. +  UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ +	unz_s* s;	 +	int err; + +	 +	uLong num_fileSaved; +	uLong pos_in_central_dirSaved; + + +	if (file==NULL) +		return UNZ_PARAMERROR; + +    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) +        return UNZ_PARAMERROR; + +	s=(unz_s*)file; +	if (!s->current_file_ok) +		return UNZ_END_OF_LIST_OF_FILE; + +	num_fileSaved = s->num_file; +	pos_in_central_dirSaved = s->pos_in_central_dir; + +	err = unzGoToFirstFile(file); + +	while (err == UNZ_OK) +	{ +		char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; +		unzGetCurrentFileInfo(file,NULL, +								szCurrentFileName,sizeof(szCurrentFileName)-1, +								NULL,0,NULL,0); +		if (unzStringFileNameCompare(szCurrentFileName, +										szFileName,iCaseSensitivity)==0) +			return UNZ_OK; +		err = unzGoToNextFile(file); +	} + +	s->num_file = num_fileSaved ; +	s->pos_in_central_dir = pos_in_central_dirSaved ; +	return err; +} + + +/* +  Read the static header of the current zipfile +  Check the coherency of the static header and info in the end of central +        directory about this file +  store in *piSizeVar the size of extra info in static header +        (filename and size of extra field data) +*/ +static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, +													uLong *poffset_local_extrafield, +													uInt *psize_local_extrafield) +{ +	uLong uMagic,uData,uFlags; +	uLong size_filename; +	uLong size_extra_field; +	int err=UNZ_OK; + +	*piSizeVar = 0; +	*poffset_local_extrafield = 0; +	*psize_local_extrafield = 0; + +	if (fseek(s->file,s->cur_file_info_internal.offset_curfile + +								s->byte_before_the_zipfile,SEEK_SET)!=0) +		return UNZ_ERRNO; + + +	if (err==UNZ_OK) +		if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) +			err=UNZ_ERRNO; +		else if (uMagic!=0x04034b50) +			err=UNZ_BADZIPFILE; + +	if (unzlocal_getShort(s->file,&uData) != UNZ_OK) +		err=UNZ_ERRNO; +/* +	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) +		err=UNZ_BADZIPFILE; +*/ +	if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) +		err=UNZ_ERRNO; + +	if (unzlocal_getShort(s->file,&uData) != UNZ_OK) +		err=UNZ_ERRNO; +	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) +		err=UNZ_BADZIPFILE; + +    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +                         (s->cur_file_info.compression_method!=Z_DEFLATED)) +        err=UNZ_BADZIPFILE; + +	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ +		err=UNZ_ERRNO; + +	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ +		err=UNZ_ERRNO; +	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && +		                      ((uFlags & 8)==0)) +		err=UNZ_BADZIPFILE; + +	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ +		err=UNZ_ERRNO; +	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && +							  ((uFlags & 8)==0)) +		err=UNZ_BADZIPFILE; + +	if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ +		err=UNZ_ERRNO; +	else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&  +							  ((uFlags & 8)==0)) +		err=UNZ_BADZIPFILE; + + +	if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) +		err=UNZ_ERRNO; +	else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) +		err=UNZ_BADZIPFILE; + +	*piSizeVar += (uInt)size_filename; + +	if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) +		err=UNZ_ERRNO; +	*poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + +									SIZEZIPLOCALHEADER + size_filename; +	*psize_local_extrafield = (uInt)size_extra_field; + +	*piSizeVar += (uInt)size_extra_field; + +	return err; +} +												 +/* +  Open for reading data the current file in the zipfile. +  If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int unzOpenCurrentFile (unzFile file) +{ +	int err=UNZ_OK; +	int Store; +	uInt iSizeVar; +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	uLong offset_local_extrafield;  /* offset of the static extra field */ +	uInt  size_local_extrafield;    /* size of the static extra field */ + +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +	if (!s->current_file_ok) +		return UNZ_PARAMERROR; + +    if (s->pfile_in_zip_read != NULL) +        unzCloseCurrentFile(file); + +	if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, +				&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) +		return UNZ_BADZIPFILE; + +	pfile_in_zip_read_info = (file_in_zip_read_info_s*) +									    malloc(sizeof(file_in_zip_read_info_s)); +	if (pfile_in_zip_read_info==NULL) +		return UNZ_INTERNALERROR; + +	pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE); +	pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; +	pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; +	pfile_in_zip_read_info->pos_local_extrafield=0; + +	if (pfile_in_zip_read_info->read_buffer==NULL) +	{ +		free(pfile_in_zip_read_info); +		return UNZ_INTERNALERROR; +	} + +	pfile_in_zip_read_info->stream_initialised=0; +	 +	if ((s->cur_file_info.compression_method!=0) && +        (s->cur_file_info.compression_method!=Z_DEFLATED)) +		err=UNZ_BADZIPFILE; +	Store = s->cur_file_info.compression_method==0; + +	pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; +	pfile_in_zip_read_info->crc32=0; +	pfile_in_zip_read_info->compression_method = +            s->cur_file_info.compression_method; +	pfile_in_zip_read_info->file=s->file; +	pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + +    pfile_in_zip_read_info->stream.total_out = 0; + +	if (!Store) +	{ +	  pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; +	  pfile_in_zip_read_info->stream.zfree = (free_func)0; +	  pfile_in_zip_read_info->stream.opaque = (voidp)0;  +       +	  err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); +	  if (err == Z_OK) +	    pfile_in_zip_read_info->stream_initialised=1; +        /* windowBits is passed < 0 to tell that there is no zlib header. +         * Note that in this case inflate *requires* an extra "dummy" byte +         * after the compressed stream in order to complete decompression and +         * return Z_STREAM_END.  +         * In unzip, i don't wait absolutely Z_STREAM_END because I known the  +         * size of both compressed and uncompressed data +         */ +	} +	pfile_in_zip_read_info->rest_read_compressed =  +            s->cur_file_info.compressed_size ; +	pfile_in_zip_read_info->rest_read_uncompressed =  +            s->cur_file_info.uncompressed_size ; + +	 +	pfile_in_zip_read_info->pos_in_zipfile =  +            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +  +			  iSizeVar; +	 +	pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + +	s->pfile_in_zip_read = pfile_in_zip_read_info; +    return UNZ_OK; +} + + +/* +  Read bytes from the current file. +  buf contain buffer where data must be copied +  len the size of buf. + +  return the number of byte copied if somes bytes are copied +  return 0 if the end of file was reached +  return <0 with error code if there is an error +    (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int unzReadCurrentFile  (unzFile file, void *buf, unsigned len) +{ +	int err=UNZ_OK; +	uInt iRead = 0; +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +    pfile_in_zip_read_info=s->pfile_in_zip_read; + +	if (pfile_in_zip_read_info==NULL) +		return UNZ_PARAMERROR; + + +	if ((pfile_in_zip_read_info->read_buffer == NULL)) +		return UNZ_END_OF_LIST_OF_FILE; +	if (len==0) +		return 0; + +	pfile_in_zip_read_info->stream.next_out = (Byte*)buf; + +	pfile_in_zip_read_info->stream.avail_out = (uInt)len; +	 +	if (len>pfile_in_zip_read_info->rest_read_uncompressed) +		pfile_in_zip_read_info->stream.avail_out =  +		  (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + +	while (pfile_in_zip_read_info->stream.avail_out>0) +	{ +		if ((pfile_in_zip_read_info->stream.avail_in==0) && +            (pfile_in_zip_read_info->rest_read_compressed>0)) +		{ +			uInt uReadThis = UNZ_BUFSIZE; +			if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) +				uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; +			if (uReadThis == 0) +				return UNZ_EOF; +			if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed) +				if (fseek(pfile_in_zip_read_info->file, +						  pfile_in_zip_read_info->pos_in_zipfile +  +							 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) +					return UNZ_ERRNO; +			if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, +                         pfile_in_zip_read_info->file)!=1) +				return UNZ_ERRNO; +			pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + +			pfile_in_zip_read_info->rest_read_compressed-=uReadThis; +			 +			pfile_in_zip_read_info->stream.next_in =  +                (Byte*)pfile_in_zip_read_info->read_buffer; +			pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; +		} + +		if (pfile_in_zip_read_info->compression_method==0) +		{ +			uInt uDoCopy,i ; +			if (pfile_in_zip_read_info->stream.avail_out <  +                            pfile_in_zip_read_info->stream.avail_in) +				uDoCopy = pfile_in_zip_read_info->stream.avail_out ; +			else +				uDoCopy = pfile_in_zip_read_info->stream.avail_in ; +				 +			for (i=0;i<uDoCopy;i++) +				*(pfile_in_zip_read_info->stream.next_out+i) = +                        *(pfile_in_zip_read_info->stream.next_in+i); +					 +			pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, +								pfile_in_zip_read_info->stream.next_out, +								uDoCopy); +			pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; +			pfile_in_zip_read_info->stream.avail_in -= uDoCopy; +			pfile_in_zip_read_info->stream.avail_out -= uDoCopy; +			pfile_in_zip_read_info->stream.next_out += uDoCopy; +			pfile_in_zip_read_info->stream.next_in += uDoCopy; +            pfile_in_zip_read_info->stream.total_out += uDoCopy; +			iRead += uDoCopy; +		} +		else +		{ +			uLong uTotalOutBefore,uTotalOutAfter; +			const Byte *bufBefore; +			uLong uOutThis; +			int flush=Z_SYNC_FLUSH; + +			uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; +			bufBefore = pfile_in_zip_read_info->stream.next_out; + +			/* +			if ((pfile_in_zip_read_info->rest_read_uncompressed == +			         pfile_in_zip_read_info->stream.avail_out) && +				(pfile_in_zip_read_info->rest_read_compressed == 0)) +				flush = Z_FINISH; +			*/ +			err=inflate(&pfile_in_zip_read_info->stream,flush); + +			uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; +			uOutThis = uTotalOutAfter-uTotalOutBefore; +			 +			pfile_in_zip_read_info->crc32 =  +                crc32(pfile_in_zip_read_info->crc32,bufBefore, +                        (uInt)(uOutThis)); + +			pfile_in_zip_read_info->rest_read_uncompressed -= +                uOutThis; + +			iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); +             +			if (err==Z_STREAM_END) +				return (iRead==0) ? UNZ_EOF : iRead; +			if (err!=Z_OK)  +				break; +		} +	} + +	if (err==Z_OK) +		return iRead; +	return err; +} + + +/* +  Give the current position in uncompressed data +*/ +extern long unztell (unzFile file) +{ +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +    pfile_in_zip_read_info=s->pfile_in_zip_read; + +	if (pfile_in_zip_read_info==NULL) +		return UNZ_PARAMERROR; + +	return (long)pfile_in_zip_read_info->stream.total_out; +} + + +/* +  return 1 if the end of file was reached, 0 elsewhere  +*/ +extern int unzeof (unzFile file) +{ +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +    pfile_in_zip_read_info=s->pfile_in_zip_read; + +	if (pfile_in_zip_read_info==NULL) +		return UNZ_PARAMERROR; +	 +	if (pfile_in_zip_read_info->rest_read_uncompressed == 0) +		return 1; +	else +		return 0; +} + + + +/* +  Read extra field from the current file (opened by unzOpenCurrentFile) +  This is the static-header version of the extra field (sometimes, there is +    more info in the static-header version than in the central-header) + +  if buf==NULL, it return the size of the static extra field that can be read + +  if buf!=NULL, len is the size of the buffer, the extra header is copied in +	buf. +  the return value is the number of bytes copied in buf, or (if <0)  +	the error code +*/ +extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len) +{ +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	uInt read_now; +	uLong size_to_read; + +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +    pfile_in_zip_read_info=s->pfile_in_zip_read; + +	if (pfile_in_zip_read_info==NULL) +		return UNZ_PARAMERROR; + +	size_to_read = (pfile_in_zip_read_info->size_local_extrafield -  +				pfile_in_zip_read_info->pos_local_extrafield); + +	if (buf==NULL) +		return (int)size_to_read; +	 +	if (len>size_to_read) +		read_now = (uInt)size_to_read; +	else +		read_now = (uInt)len ; + +	if (read_now==0) +		return 0; +	 +	if (fseek(pfile_in_zip_read_info->file, +              pfile_in_zip_read_info->offset_local_extrafield +  +			  pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) +		return UNZ_ERRNO; + +	if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) +		return UNZ_ERRNO; + +	return (int)read_now; +} + +/* +  Close the file in zip opened with unzipOpenCurrentFile +  Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int unzCloseCurrentFile (unzFile file) +{ +	int err=UNZ_OK; + +	unz_s* s; +	file_in_zip_read_info_s* pfile_in_zip_read_info; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; +    pfile_in_zip_read_info=s->pfile_in_zip_read; + +	if (pfile_in_zip_read_info==NULL) +		return UNZ_PARAMERROR; + + +	if (pfile_in_zip_read_info->rest_read_uncompressed == 0) +	{ +		if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) +			err=UNZ_CRCERROR; +	} + + +	free(pfile_in_zip_read_info->read_buffer); +	pfile_in_zip_read_info->read_buffer = NULL; +	if (pfile_in_zip_read_info->stream_initialised) +		inflateEnd(&pfile_in_zip_read_info->stream); + +	pfile_in_zip_read_info->stream_initialised = 0; +	free(pfile_in_zip_read_info); + +    s->pfile_in_zip_read=NULL; + +	return err; +} + + +/* +  Get the global comment string of the ZipFile, in the szComment buffer. +  uSizeBuf is the size of the szComment buffer. +  return the number of byte copied or an error code <0 +*/ +extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) +{ +	unz_s* s; +	uLong uReadThis ; +	if (file==NULL) +		return UNZ_PARAMERROR; +	s=(unz_s*)file; + +	uReadThis = uSizeBuf; +	if (uReadThis>s->gi.size_comment) +		uReadThis = s->gi.size_comment; + +	if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) +		return UNZ_ERRNO; + +	if (uReadThis>0) +    { +      *szComment='\0'; +	  if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) +		return UNZ_ERRNO; +    } + +	if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) +		*(szComment+s->gi.size_comment)='\0'; +	return (int)uReadThis; +} + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */ + +#ifdef DYNAMIC_CRC_TABLE + +static int crc_table_empty = 1; +static uLong crc_table[256]; +static void make_crc_table OF((void)); + +/* +  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: +  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + +  Polynomials over GF(2) are represented in binary, one bit per coefficient, +  with the lowest powers in the most significant bit.  Then adding polynomials +  is just exclusive-or, and multiplying a polynomial by x is a right shift by +  one.  If we call the above polynomial p, and represent a byte as the +  polynomial q, also with the lowest power in the most significant bit (so the +  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, +  where a mod b means the remainder after dividing a by b. + +  This calculation is done using the shift-register method of multiplying and +  taking the remainder.  The register is initialized to zero, and for each +  incoming bit, x^32 is added mod p to the register if the bit is a one (where +  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by +  x (which is shifting right by one and adding x^32 mod p if the bit shifted +  out is a one).  We start with the highest power (least significant bit) of +  q and repeat for all eight bits of q. + +  The table is simply the CRC of all possible eight bit values.  This is all +  the information needed to generate CRC's on data a byte at a time for all +  combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table() +{ +  uLong c; +  int n, k; +  uLong poly;            /* polynomial exclusive-or pattern */ +  /* terms of polynomial defining this crc (except x^32): */ +  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + +  /* make exclusive-or pattern from polynomial (0xedb88320L) */ +  poly = 0L; +  for (n = 0; n < sizeof(p)/sizeof(Byte); n++) +    poly |= 1L << (31 - p[n]); +  +  for (n = 0; n < 256; n++) +  { +    c = (uLong)n; +    for (k = 0; k < 8; k++) +      c = c & 1 ? poly ^ (c >> 1) : c >> 1; +    crc_table[n] = c; +  } +  crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +static const uLong crc_table[256] = { +  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, +  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, +  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, +  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, +  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, +  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, +  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, +  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, +  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, +  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, +  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, +  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, +  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, +  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, +  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, +  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, +  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, +  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, +  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, +  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, +  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, +  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, +  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, +  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, +  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, +  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, +  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, +  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, +  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, +  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, +  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, +  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, +  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, +  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, +  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, +  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, +  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, +  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, +  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, +  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, +  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, +  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, +  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, +  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, +  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, +  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, +  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, +  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, +  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, +  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, +  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, +  0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLong * get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE +  if (crc_table_empty) make_crc_table(); +#endif +  return (const uLong *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf)  DO1(buf); DO1(buf); +#define DO4(buf)  DO2(buf); DO2(buf); +#define DO8(buf)  DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(uLong crc, const Byte *buf, uInt len) +{ +    if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE +    if (crc_table_empty) +      make_crc_table(); +#endif +    crc = crc ^ 0xffffffffL; +    while (len >= 8) +    { +      DO8(buf); +      len -= 8; +    } +    if (len) do { +      DO1(buf); +    } while (--len); +    return crc ^ 0xffffffffL; +} + +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( +    z_streamp z, +    check_func c,               /* check function */ +    uInt w));                   /* window size */ + +extern int inflate_blocks OF(( +    inflate_blocks_statef *, +    z_streamp , +    int));                      /* initial return code */ + +extern void inflate_blocks_reset OF(( +    inflate_blocks_statef *, +    z_streamp , +    uLong *));                  /* check value on output */ + +extern int inflate_blocks_free OF(( +    inflate_blocks_statef *, +    z_streamp)); + +extern void inflate_set_dictionary OF(( +    inflate_blocks_statef *s, +    const Byte *d,  /* dictionary */ +    uInt  n));       /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( +    inflate_blocks_statef *s)); + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +static const uInt border[] = { /* Order of the bit length code lengths */ +        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines +   that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s inflate_huft; + +struct inflate_huft_s { +  union { +    struct { +      Byte Exop;        /* number of extra bits or operation */ +      Byte Bits;        /* number of bits in this code or subcode */ +    } what; +    uInt pad;           /* pad structure to a power of 2 (4 bytes for */ +  } word;               /*  16-bit, 8 bytes for 32-bit int's) */ +  uInt base;            /* literal, length base, distance base, +                           or table offset */ +}; + +/* Maximum size of dynamic tree.  The maximum found in a long but non- +   exhaustive search was 1004 huft structures (850 for length/literals +   and 154 for distances, the latter actually the result of an +   exhaustive search).  The actual maximum is not known, but the +   value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( +    uInt *,                    /* 19 code lengths */ +    uInt *,                    /* bits tree desired/actual depth */ +    inflate_huft * *,       /* bits tree result */ +    inflate_huft *,             /* space for trees */ +    z_streamp));                /* for messages */ + +extern int inflate_trees_dynamic OF(( +    uInt,                       /* number of literal/length codes */ +    uInt,                       /* number of distance codes */ +    uInt *,                    /* that many (total) code lengths */ +    uInt *,                    /* literal desired/actual bit depth */ +    uInt *,                    /* distance desired/actual bit depth */ +    inflate_huft * *,       /* literal/length tree result */ +    inflate_huft * *,       /* distance tree result */ +    inflate_huft *,             /* space for trees */ +    z_streamp));                /* for messages */ + +extern int inflate_trees_fixed OF(( +    uInt *,                    /* literal desired/actual bit depth */ +    uInt *,                    /* distance desired/actual bit depth */ +    inflate_huft * *,       /* literal/length tree result */ +    inflate_huft * *,       /* distance tree result */ +    z_streamp));                /* for memory allocation */ + + +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( +    uInt, uInt, +    inflate_huft *, inflate_huft *, +    z_streamp )); + +extern int inflate_codes OF(( +    inflate_blocks_statef *, +    z_streamp , +    int)); + +extern void inflate_codes_free OF(( +    inflate_codes_statef *, +    z_streamp )); + +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { +      TYPE,     /* get type bits (3, including end bit) */ +      LENS,     /* get lengths for stored */ +      STORED,   /* processing stored block */ +      TABLE,    /* get table lengths */ +      BTREE,    /* get bit lengths tree for a dynamic block */ +      DTREE,    /* get length, distance trees for a dynamic block */ +      CODES,    /* processing fixed or dynamic block */ +      DRY,      /* output remaining window bytes */ +      DONE,     /* finished last block, done */ +      BAD}      /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + +  /* mode */ +  inflate_block_mode  mode;     /* current inflate_block mode */ + +  /* mode dependent information */ +  union { +    uInt left;          /* if STORED, bytes left to copy */ +    struct { +      uInt table;               /* table lengths (14 bits) */ +      uInt index;               /* index into blens (or border) */ +      uInt *blens;             /* bit lengths of codes */ +      uInt bb;                  /* bit length tree depth */ +      inflate_huft *tb;         /* bit length decoding tree */ +    } trees;            /* if DTREE, decoding info for trees */ +    struct { +      inflate_codes_statef  +         *codes; +    } decode;           /* if CODES, current state */ +  } sub;                /* submode */ +  uInt last;            /* true if this block is the last block */ + +  /* mode independent information */ +  uInt bitk;            /* bits in bit buffer */ +  uLong bitb;           /* bit buffer */ +  inflate_huft *hufts;  /* single malloc for tree space */ +  Byte *window;        /* sliding window */ +  Byte *end;           /* one byte after sliding window */ +  Byte *read;          /* window read pointer */ +  Byte *write;         /* window write pointer */ +  check_func checkfn;   /* check function */ +  uLong check;          /* check on output */ + +}; + + +/* defines for inflate input/output */ +/*   update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/*   get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define DUMPBITS(j) {b>>=(j);k-=(j);} +/*   output bytes */ +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/*   load static pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( +    inflate_blocks_statef *, +    z_streamp , +    int)); + +#endif + +								 +/* +   Notes beyond the 1.93a appnote.txt: + +   1. Distance pointers never point before the beginning of the output +      stream. +   2. Distance pointers can point back across blocks, up to 32k away. +   3. There is an implied maximum of 7 bits for the bit length table and +      15 bits for the actual data. +   4. If only one code exists, then it is encoded using one bit.  (Zero +      would be more efficient, but perhaps a little confusing.)  If two +      codes exist, they are coded using one bit each (0 and 1). +   5. There is no way of sending zero distance codes--a dummy must be +      sent if there are none.  (History: a pre 2.0 version of PKZIP would +      store blocks with no distance codes, but this was discovered to be +      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow +      zero distance codes, which is sent as one code of zero bits in +      length. +   6. There are up to 286 literal/length codes.  Code 256 represents the +      end-of-block.  Note however that the static length tree defines +      288 codes just to fill out the Huffman codes.  Codes 286 and 287 +      cannot be used though, since there is no length base or extra bits +      defined for them.  Similarily, there are up to 30 distance codes. +      However, static trees define 32 codes (all 5 bits) to fill out the +      Huffman codes, but the last two had better not show up in the data. +   7. Unzip can check dynamic Huffman blocks for complete code sets. +      The exception is that a single code would not be complete (see #4). +   8. The five bits following the block type is really the number of +      literal codes sent minus 257. +   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits +      (1+6+6).  Therefore, to output three times the length, you output +      three codes (1+1+1), whereas to output four times the same length, +      you only need two codes (1+3).  Hmm. +  10. In the tree reconstruction algorithm, Code = Code + Increment +      only if BitLength(i) is not zero.  (Pretty obvious.) +  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19) +  12. Note: length code 284 can represent 227-258, but length code 285 +      really is 258.  The last length deserves its own, short code +      since it gets used a lot in very redundant files.  The length +      258 is special since 258 - 3 (the min match length) is 255. +  13. The literal/length and distance code bit lengths are read as a +      single stream of lengths.  It is possible (and advantageous) for +      a repeat code (16, 17, or 18) to go across the boundary between +      the two sets of lengths. + */ + + +void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) +{ +  if (c != Z_NULL) +    *c = s->check; +  if (s->mode == BTREE || s->mode == DTREE) +    ZFREE(z, s->sub.trees.blens); +  if (s->mode == CODES) +    inflate_codes_free(s->sub.decode.codes, z); +  s->mode = TYPE; +  s->bitk = 0; +  s->bitb = 0; +  s->read = s->write = s->window; +  if (s->checkfn != Z_NULL) +    z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); +  Tracev(("inflate:   blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) +{ +  inflate_blocks_statef *s; + +  if ((s = (inflate_blocks_statef *)ZALLOC +       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) +    return s; +  if ((s->hufts = +       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) +  { +    ZFREE(z, s); +    return Z_NULL; +  } +  if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) +  { +    ZFREE(z, s->hufts); +    ZFREE(z, s); +    return Z_NULL; +  } +  s->end = s->window + w; +  s->checkfn = c; +  s->mode = TYPE; +  Tracev(("inflate:   blocks allocated\n")); +  inflate_blocks_reset(s, z, Z_NULL); +  return s; +} + + +int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) +{ +  uInt t;               /* temporary storage */ +  uLong b;              /* bit buffer */ +  uInt k;               /* bits in bit buffer */ +  Byte *p;             /* input data pointer */ +  uInt n;               /* bytes available there */ +  Byte *q;             /* output window write pointer */ +  uInt m;               /* bytes to end of window or read pointer */ + +  /* copy input/output information to locals (UPDATE macro restores) */ +  LOAD + +  /* process input based on current state */ +  while (1) switch (s->mode) +  { +    case TYPE: +      NEEDBITS(3) +      t = (uInt)b & 7; +      s->last = t & 1; +      switch (t >> 1) +      { +        case 0:                         /* stored */ +          Tracev(("inflate:     stored block%s\n", +                 s->last ? " (last)" : "")); +          DUMPBITS(3) +          t = k & 7;                    /* go to byte boundary */ +          DUMPBITS(t) +          s->mode = LENS;               /* get length of stored block */ +          break; +        case 1:                         /* fixed */ +          Tracev(("inflate:     fixed codes block%s\n", +                 s->last ? " (last)" : "")); +          { +            uInt bl, bd; +            inflate_huft *tl, *td; + +            inflate_trees_fixed(&bl, &bd, &tl, &td, z); +            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); +            if (s->sub.decode.codes == Z_NULL) +            { +              r = Z_MEM_ERROR; +              LEAVE +            } +          } +          DUMPBITS(3) +          s->mode = CODES; +          break; +        case 2:                         /* dynamic */ +          Tracev(("inflate:     dynamic codes block%s\n", +                 s->last ? " (last)" : "")); +          DUMPBITS(3) +          s->mode = TABLE; +          break; +        case 3:                         /* illegal */ +          DUMPBITS(3) +          s->mode = BAD; +          z->msg = (char*)"invalid block type"; +          r = Z_DATA_ERROR; +          LEAVE +      } +      break; +    case LENS: +      NEEDBITS(32) +      if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) +      { +        s->mode = BAD; +        z->msg = (char*)"invalid stored block lengths"; +        r = Z_DATA_ERROR; +        LEAVE +      } +      s->sub.left = (uInt)b & 0xffff; +      b = k = 0;                      /* dump bits */ +      Tracev(("inflate:       stored length %u\n", s->sub.left)); +      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); +      break; +    case STORED: +      if (n == 0) +        LEAVE +      NEEDOUT +      t = s->sub.left; +      if (t > n) t = n; +      if (t > m) t = m; +      zmemcpy(q, p, t); +      p += t;  n -= t; +      q += t;  m -= t; +      if ((s->sub.left -= t) != 0) +        break; +      Tracev(("inflate:       stored end, %lu total out\n", +              z->total_out + (q >= s->read ? q - s->read : +              (s->end - s->read) + (q - s->window)))); +      s->mode = s->last ? DRY : TYPE; +      break; +    case TABLE: +      NEEDBITS(14) +      s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND +      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) +      { +        s->mode = BAD; +        z->msg = (char*)"too many length or distance symbols"; +        r = Z_DATA_ERROR; +        LEAVE +      } +#endif +      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); +      if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) +      { +        r = Z_MEM_ERROR; +        LEAVE +      } +      DUMPBITS(14) +      s->sub.trees.index = 0; +      Tracev(("inflate:       table sizes ok\n")); +      s->mode = BTREE; +    case BTREE: +      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) +      { +        NEEDBITS(3) +        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; +        DUMPBITS(3) +      } +      while (s->sub.trees.index < 19) +        s->sub.trees.blens[border[s->sub.trees.index++]] = 0; +      s->sub.trees.bb = 7; +      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, +                             &s->sub.trees.tb, s->hufts, z); +      if (t != Z_OK) +      { +        ZFREE(z, s->sub.trees.blens); +        r = t; +        if (r == Z_DATA_ERROR) +          s->mode = BAD; +        LEAVE +      } +      s->sub.trees.index = 0; +      Tracev(("inflate:       bits tree ok\n")); +      s->mode = DTREE; +    case DTREE: +      while (t = s->sub.trees.table, +             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) +      { +        inflate_huft *h; +        uInt i, j, c; + +        t = s->sub.trees.bb; +        NEEDBITS(t) +        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); +        t = h->bits; +        c = h->base; +        if (c < 16) +        { +          DUMPBITS(t) +          s->sub.trees.blens[s->sub.trees.index++] = c; +        } +        else /* c == 16..18 */ +        { +          i = c == 18 ? 7 : c - 14; +          j = c == 18 ? 11 : 3; +          NEEDBITS(t + i) +          DUMPBITS(t) +          j += (uInt)b & inflate_mask[i]; +          DUMPBITS(i) +          i = s->sub.trees.index; +          t = s->sub.trees.table; +          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || +              (c == 16 && i < 1)) +          { +            ZFREE(z, s->sub.trees.blens); +            s->mode = BAD; +            z->msg = (char*)"invalid bit length repeat"; +            r = Z_DATA_ERROR; +            LEAVE +          } +          c = c == 16 ? s->sub.trees.blens[i - 1] : 0; +          do { +            s->sub.trees.blens[i++] = c; +          } while (--j); +          s->sub.trees.index = i; +        } +      } +      s->sub.trees.tb = Z_NULL; +      { +        uInt bl, bd; +        inflate_huft *tl, *td; +        inflate_codes_statef *c; + +        bl = 9;         /* must be <= 9 for lookahead assumptions */ +        bd = 6;         /* must be <= 9 for lookahead assumptions */ +        t = s->sub.trees.table; +        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), +                                  s->sub.trees.blens, &bl, &bd, &tl, &td, +                                  s->hufts, z); +        ZFREE(z, s->sub.trees.blens); +        if (t != Z_OK) +        { +          if (t == (uInt)Z_DATA_ERROR) +            s->mode = BAD; +          r = t; +          LEAVE +        } +        Tracev(("inflate:       trees ok\n")); +        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) +        { +          r = Z_MEM_ERROR; +          LEAVE +        } +        s->sub.decode.codes = c; +      } +      s->mode = CODES; +    case CODES: +      UPDATE +      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) +        return inflate_flush(s, z, r); +      r = Z_OK; +      inflate_codes_free(s->sub.decode.codes, z); +      LOAD +      Tracev(("inflate:       codes end, %lu total out\n", +              z->total_out + (q >= s->read ? q - s->read : +              (s->end - s->read) + (q - s->window)))); +      if (!s->last) +      { +        s->mode = TYPE; +        break; +      } +      s->mode = DRY; +    case DRY: +      FLUSH +      if (s->read != s->write) +        LEAVE +      s->mode = DONE; +    case DONE: +      r = Z_STREAM_END; +      LEAVE +    case BAD: +      r = Z_DATA_ERROR; +      LEAVE +    default: +      r = Z_STREAM_ERROR; +      LEAVE +  } +} + + +int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) +{ +  inflate_blocks_reset(s, z, Z_NULL); +  ZFREE(z, s->window); +  ZFREE(z, s->hufts); +  ZFREE(z, s); +  Tracev(("inflate:   blocks freed\n")); +  return Z_OK; +} + + +void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n) +{ +  zmemcpy(s->window, d, n); +  s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH.  + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(inflate_blocks_statef *s) +{ +  return s->mode == LENS; +} + + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { +    0x0000, +    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, +    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r) +{ +  uInt n; +  Byte *p; +  Byte *q; + +  /* static copies of source and destination pointers */ +  p = z->next_out; +  q = s->read; + +  /* compute number of bytes to copy as as end of window */ +  n = (uInt)((q <= s->write ? s->write : s->end) - q); +  if (n > z->avail_out) n = z->avail_out; +  if (n && r == Z_BUF_ERROR) r = Z_OK; + +  /* update counters */ +  z->avail_out -= n; +  z->total_out += n; + +  /* update check information */ +  if (s->checkfn != Z_NULL) +    z->adler = s->check = (*s->checkfn)(s->check, q, n); + +  /* copy as as end of window */ +  zmemcpy(p, q, n); +  p += n; +  q += n; + +  /* see if more to copy at beginning of window */ +  if (q == s->end) +  { +    /* wrap pointers */ +    q = s->window; +    if (s->write == s->end) +      s->write = s->window; + +    /* compute bytes to copy */ +    n = (uInt)(s->write - q); +    if (n > z->avail_out) n = z->avail_out; +    if (n && r == Z_BUF_ERROR) r = Z_OK; + +    /* update counters */ +    z->avail_out -= n; +    z->total_out += n; + +    /* update check information */ +    if (s->checkfn != Z_NULL) +      z->adler = s->check = (*s->checkfn)(s->check, q, n); + +    /* copy */ +    zmemcpy(p, q, n); +    p += n; +    q += n; +  } + +  /* update pointers */ +  z->next_out = p; +  s->read = q; + +  /* done */ +  return r; +} + +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +const char inflate_copyright[] = +   " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; +/* +  If you use the zlib library in a product, an acknowledgment is welcome +  in the documentation of your product. If for some reason you cannot +  include such an acknowledgment, I would appreciate that you keep this +  copyright string in the executable of your product. + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +static int huft_build OF(( +    uInt *,				/* code lengths in bits */ +    uInt,               /* number of codes */ +    uInt,               /* number of "simple" codes */ +    const uInt *,		/* list of base values for non-simple codes */ +    const uInt *,		/* list of extra bits for non-simple codes */ +    inflate_huft **,	/* result: starting table */ +    uInt *,				/* maximum lookup bits (returns actual) */ +    inflate_huft *,     /* space for trees */ +    uInt *,             /* hufts used in space */ +    uInt * ));			/* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ +        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, +        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; +        /* see note #13 above about 258 */ +static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ +        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, +        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ +        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, +        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, +        8193, 12289, 16385, 24577}; +static const uInt cpdext[30] = { /* Extra bits for distance codes */ +        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, +        7, 7, 8, 8, 9, 9, 10, 10, 11, 11, +        12, 12, 13, 13}; + +/* +   Huffman code decoding is performed using a multi-level table lookup. +   The fastest way to decode is to simply build a lookup table whose +   size is determined by the longest code.  However, the time it takes +   to build this table can also be a factor if the data being decoded +   is not very long.  The most common codes are necessarily the +   shortest codes, so those codes dominate the decoding time, and hence +   the speed.  The idea is you can have a shorter table that decodes the +   shorter, more probable codes, and then point to subsidiary tables for +   the longer codes.  The time it costs to decode the longer codes is +   then traded against the time it takes to make longer tables. + +   This results of this trade are in the variables lbits and dbits +   below.  lbits is the number of bits the first level table for literal/ +   length codes can decode in one step, and dbits is the same thing for +   the distance codes.  Subsequent tables are also less than or equal to +   those sizes.  These values may be adjusted either when all of the +   codes are shorter than that, in which case the longest code length in +   bits is used, or when the shortest code is *longer* than the requested +   table size, in which case the length of the shortest code in bits is +   used. + +   There are two different values for the two tables, since they code a +   different number of possibilities each.  The literal/length table +   codes 286 possible values, or in a flat code, a little over eight +   bits.  The distance table codes 30 possible values, or a little less +   than five bits, flat.  The optimum values for speed end up being +   about one bit more than those, so lbits is 8+1 and dbits is 5+1. +   The optimum values may differ though from machine to machine, and +   possibly even between compilers.  Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15         /* maximum bit length of any code */ + +static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v) +//uInt *b;               /* code lengths in bits (all assumed <= BMAX) */ +//uInt n;                 /* number of codes (assumed <= 288) */ +//uInt s;                 /* number of simple-valued codes (0..s-1) */ +//const uInt *d;         /* list of base values for non-simple codes */ +//const uInt *e;         /* list of extra bits for non-simple codes */ +//inflate_huft ** t;		/* result: starting table */ +//uInt *m;               /* maximum lookup bits, returns actual */ +//inflate_huft *hp;       /* space for trees */ +//uInt *hn;               /* hufts used in space */ +//uInt *v;               /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of +   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR +   if the given code set is incomplete (the tables are still built in this +   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of +   lengths), or Z_MEM_ERROR if not enough memory. */ +{ + +  uInt a;                       /* counter for codes of length k */ +  uInt c[BMAX+1];               /* bit length count table */ +  uInt f;                       /* i repeats in table every f entries */ +  int g;                        /* maximum code length */ +  int h;                        /* table level */ +  register uInt i;              /* counter, current code */ +  register uInt j;              /* counter */ +  register int k;               /* number of bits in current code */ +  int l;                        /* bits per table (returned in m) */ +  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */ +  register uInt *p;            /* pointer into c[], b[], or v[] */ +  inflate_huft *q;              /* points to current table */ +  struct inflate_huft_s r;      /* table entry for structure assignment */ +  inflate_huft *u[BMAX];        /* table stack */ +  register int w;               /* bits before this table == (l * h) */ +  uInt x[BMAX+1];               /* bit offsets, then code stack */ +  uInt *xp;                    /* pointer into x */ +  int y;                        /* number of dummy codes added */ +  uInt z;                       /* number of entries in current table */ + + +  /* Generate counts for each bit length */ +  p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 +  C4                            /* clear c[]--assume BMAX+1 is 16 */ +  p = b;  i = n; +  do { +    c[*p++]++;                  /* assume all entries <= BMAX */ +  } while (--i); +  if (c[0] == n)                /* null input--all zero length codes */ +  { +    *t = (inflate_huft *)Z_NULL; +    *m = 0; +    return Z_OK; +  } + + +  /* Find minimum and maximum length, bound *m by those */ +  l = *m; +  for (j = 1; j <= BMAX; j++) +    if (c[j]) +      break; +  k = j;                        /* minimum code length */ +  if ((uInt)l < j) +    l = j; +  for (i = BMAX; i; i--) +    if (c[i]) +      break; +  g = i;                        /* maximum code length */ +  if ((uInt)l > i) +    l = i; +  *m = l; + + +  /* Adjust last length count to fill out codes, if needed */ +  for (y = 1 << j; j < i; j++, y <<= 1) +    if ((y -= c[j]) < 0) +      return Z_DATA_ERROR; +  if ((y -= c[i]) < 0) +    return Z_DATA_ERROR; +  c[i] += y; + + +  /* Generate starting offsets into the value table for each length */ +  x[1] = j = 0; +  p = c + 1;  xp = x + 2; +  while (--i) {                 /* note that i == g from above */ +    *xp++ = (j += *p++); +  } + + +  /* Make a table of values in order of bit lengths */ +  p = b;  i = 0; +  do { +    if ((j = *p++) != 0) +      v[x[j]++] = i; +  } while (++i < n); +  n = x[g];                     /* set n to length of v */ + + +  /* Generate the Huffman codes and for each, make the table entries */ +  x[0] = i = 0;                 /* first Huffman code is zero */ +  p = v;                        /* grab values in bit order */ +  h = -1;                       /* no tables yet--level -1 */ +  w = -l;                       /* bits decoded == (l * h) */ +  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */ +  q = (inflate_huft *)Z_NULL;   /* ditto */ +  z = 0;                        /* ditto */ + +  /* go through the bit lengths (k already is bits in shortest code) */ +  for (; k <= g; k++) +  { +    a = c[k]; +    while (a--) +    { +      /* here i is the Huffman code of length k bits for value *p */ +      /* make tables up to required level */ +      while (k > w + l) +      { +        h++; +        w += l;                 /* previous table always l bits */ + +        /* compute minimum size table less than or equal to l bits */ +        z = g - w; +        z = z > (uInt)l ? l : z;        /* table size upper limit */ +        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */ +        {                       /* too few codes for k-w bit table */ +          f -= a + 1;           /* deduct codes from patterns left */ +          xp = c + k; +          if (j < z) +            while (++j < z)     /* try smaller tables up to z bits */ +            { +              if ((f <<= 1) <= *++xp) +                break;          /* enough codes to use up j bits */ +              f -= *xp;         /* else deduct codes from patterns */ +            } +        } +        z = 1 << j;             /* table entries for j-bit table */ + +        /* allocate new table */ +        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */ +          return Z_MEM_ERROR;   /* not enough memory */ +        u[h] = q = hp + *hn; +        *hn += z; + +        /* connect to last table, if there is one */ +        if (h) +        { +          x[h] = i;             /* save pattern for backing up */ +          r.bits = (Byte)l;     /* bits to dump before this table */ +          r.exop = (Byte)j;     /* bits in this table */ +          j = i >> (w - l); +          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */ +          u[h-1][j] = r;        /* connect to last table */ +        } +        else +          *t = q;               /* first table is returned result */ +      } + +      /* set up table entry in r */ +      r.bits = (Byte)(k - w); +      if (p >= v + n) +        r.exop = 128 + 64;      /* out of values--invalid code */ +      else if (*p < s) +      { +        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */ +        r.base = *p++;          /* simple code is just the value */ +      } +      else +      { +        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ +        r.base = d[*p++ - s]; +      } + +      /* fill code-like entries with r */ +      f = 1 << (k - w); +      for (j = i >> w; j < z; j += f) +        q[j] = r; + +      /* backwards increment the k-bit code i */ +      for (j = 1 << (k - 1); i & j; j >>= 1) +        i ^= j; +      i ^= j; + +      /* backup over finished tables */ +      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */ +      while ((i & mask) != x[h]) +      { +        h--;                    /* don't need to update q */ +        w -= l; +        mask = (1 << w) - 1; +      } +    } +  } + + +  /* Return Z_BUF_ERROR if we were given an incomplete table */ +  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z) +//uInt *c;               /* 19 code lengths */ +//uInt *bb;              /* bits tree desired/actual depth */ +//inflate_huft * *tb; /* bits tree result */ +//inflate_huft *hp;       /* space for trees */ +//z_streamp z;            /* for messages */ +{ +  int r; +  uInt hn = 0;          /* hufts used in space */ +  uInt *v;             /* work area for huft_build */ + +  if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) +    return Z_MEM_ERROR; +  r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, +                 tb, bb, hp, &hn, v); +  if (r == Z_DATA_ERROR) +    z->msg = (char*)"oversubscribed dynamic bit lengths tree"; +  else if (r == Z_BUF_ERROR || *bb == 0) +  { +    z->msg = (char*)"incomplete dynamic bit lengths tree"; +    r = Z_DATA_ERROR; +  } +  ZFREE(z, v); +  return r; +} + + +int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z) +//uInt nl;                /* number of literal/length codes */ +//uInt nd;                /* number of distance codes */ +//uInt *c;               /* that many (total) code lengths */ +//uInt *bl;              /* literal desired/actual bit depth */ +//uInt *bd;              /* distance desired/actual bit depth */ +//inflate_huft * *tl; /* literal/length tree result */ +//inflate_huft * *td; /* distance tree result */ +//inflate_huft *hp;       /* space for trees */ +//z_streamp z;            /* for messages */ +{ +  int r; +  uInt hn = 0;          /* hufts used in space */ +  uInt *v;             /* work area for huft_build */ + +  /* allocate work area */ +  if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) +    return Z_MEM_ERROR; + +  /* build literal/length tree */ +  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); +  if (r != Z_OK || *bl == 0) +  { +    if (r == Z_DATA_ERROR) +      z->msg = (char*)"oversubscribed literal/length tree"; +    else if (r != Z_MEM_ERROR) +    { +      z->msg = (char*)"incomplete literal/length tree"; +      r = Z_DATA_ERROR; +    } +    ZFREE(z, v); +    return r; +  } + +  /* build distance tree */ +  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); +  if (r != Z_OK || (*bd == 0 && nl > 257)) +  { +    if (r == Z_DATA_ERROR) +      z->msg = (char*)"oversubscribed distance tree"; +    else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND +      r = Z_OK; +    } +#else +      z->msg = (char*)"incomplete distance tree"; +      r = Z_DATA_ERROR; +    } +    else if (r != Z_MEM_ERROR) +    { +      z->msg = (char*)"empty distance tree with lengths"; +      r = Z_DATA_ERROR; +    } +    ZFREE(z, v); +    return r; +#endif +  } + +  /* done */ +  ZFREE(z, v); +  return Z_OK; +} + +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +static uInt fixed_bl = 9; +static uInt fixed_bd = 5; +static inflate_huft fixed_tl[] = { +    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, +    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, +    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, +    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, +    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, +    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, +    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, +    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, +    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, +    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, +    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, +    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, +    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, +    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, +    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, +    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, +    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, +    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, +    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, +    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, +    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, +    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, +    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, +    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, +    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, +    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, +    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, +    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, +    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, +    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, +    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, +    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, +    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, +    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, +    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, +    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, +    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, +    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, +    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, +    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, +    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, +    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, +    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, +    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, +    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, +    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, +    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, +    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, +    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, +    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, +    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, +    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, +    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, +    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, +    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, +    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, +    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, +    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, +    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, +    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, +    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, +    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, +    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, +    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, +    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, +    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, +    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, +    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, +    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, +    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, +    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, +    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, +    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, +    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, +    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, +    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, +    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, +    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, +    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, +    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, +    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, +    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, +    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, +    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, +    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, +    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, +    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, +    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, +    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, +    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, +    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, +    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, +    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, +    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, +    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, +    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, +    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, +    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, +    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, +    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, +    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, +    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, +    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, +    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, +    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, +    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, +    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, +    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, +    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, +    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, +    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, +    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, +    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, +    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, +    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, +    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, +    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, +    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, +    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, +    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, +    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, +    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, +    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, +    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, +    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, +    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, +    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, +    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} +  }; +static inflate_huft fixed_td[] = { +    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, +    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, +    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, +    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, +    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, +    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, +    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, +    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} +  }; + +int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z) +//uInt *bl;               /* literal desired/actual bit depth */ +//uInt *bd;               /* distance desired/actual bit depth */ +//inflate_huft * *tl;  /* literal/length tree result */ +//inflate_huft * *td;  /* distance tree result */ +//z_streamp z;             /* for memory allocation */ +{ +  *bl = fixed_bl; +  *bd = fixed_bd; +  *tl = fixed_tl; +  *td = fixed_td; +  return Z_OK; +} + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 +   (the maximum string length) and number of input bytes available +   at least ten.  The ten bytes are six bytes for the longest length/ +   distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z) +{ +  inflate_huft *t;      /* temporary pointer */ +  uInt e;               /* extra bits or operation */ +  uLong b;              /* bit buffer */ +  uInt k;               /* bits in bit buffer */ +  Byte *p;             /* input data pointer */ +  uInt n;               /* bytes available there */ +  Byte *q;             /* output window write pointer */ +  uInt m;               /* bytes to end of window or read pointer */ +  uInt ml;              /* mask for literal/length tree */ +  uInt md;              /* mask for distance tree */ +  uInt c;               /* bytes to copy */ +  uInt d;               /* distance back to copy from */ +  Byte *r;             /* copy source pointer */ + +  /* load input, output, bit values */ +  LOAD + +  /* initialize masks */ +  ml = inflate_mask[bl]; +  md = inflate_mask[bd]; + +  /* do until not enough input or output space for fast loop */ +  do {                          /* assume called with m >= 258 && n >= 10 */ +    /* get literal/length code */ +    GRABBITS(20)                /* max bits for literal/length code */ +    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) +    { +      DUMPBITS(t->bits) +      Tracevv((t->base >= 0x20 && t->base < 0x7f ? +                "inflate:         * literal '%c'\n" : +                "inflate:         * literal 0x%02x\n", t->base)); +      *q++ = (Byte)t->base; +      m--; +      continue; +    } +    do { +      DUMPBITS(t->bits) +      if (e & 16) +      { +        /* get extra bits for length */ +        e &= 15; +        c = t->base + ((uInt)b & inflate_mask[e]); +        DUMPBITS(e) +        Tracevv(("inflate:         * length %u\n", c)); + +        /* decode distance base of block to copy */ +        GRABBITS(15);           /* max bits for distance code */ +        e = (t = td + ((uInt)b & md))->exop; +        do { +          DUMPBITS(t->bits) +          if (e & 16) +          { +            /* get extra bits to add to distance base */ +            e &= 15; +            GRABBITS(e)         /* get extra bits (up to 13) */ +            d = t->base + ((uInt)b & inflate_mask[e]); +            DUMPBITS(e) +            Tracevv(("inflate:         * distance %u\n", d)); + +            /* do the copy */ +            m -= c; +            if ((uInt)(q - s->window) >= d)     /* offset before dest */ +            {                                   /*  just copy */ +              r = q - d; +              *q++ = *r++;  c--;        /* minimum count is three, */ +              *q++ = *r++;  c--;        /*  so unroll loop a little */ +            } +            else                        /* else offset after destination */ +            { +              e = d - (uInt)(q - s->window); /* bytes from offset to end */ +              r = s->end - e;           /* pointer to offset */ +              if (c > e)                /* if source crosses, */ +              { +                c -= e;                 /* copy to end of window */ +                do { +                  *q++ = *r++; +                } while (--e); +                r = s->window;          /* copy rest from start of window */ +              } +            } +            do {                        /* copy all or what's left */ +              *q++ = *r++; +            } while (--c); +            break; +          } +          else if ((e & 64) == 0) +          { +            t += t->base; +            e = (t += ((uInt)b & inflate_mask[e]))->exop; +          } +          else +          { +            z->msg = (char*)"invalid distance code"; +            UNGRAB +            UPDATE +            return Z_DATA_ERROR; +          } +        } while (1); +        break; +      } +      if ((e & 64) == 0) +      { +        t += t->base; +        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) +        { +          DUMPBITS(t->bits) +          Tracevv((t->base >= 0x20 && t->base < 0x7f ? +                    "inflate:         * literal '%c'\n" : +                    "inflate:         * literal 0x%02x\n", t->base)); +          *q++ = (Byte)t->base; +          m--; +          break; +        } +      } +      else if (e & 32) +      { +        Tracevv(("inflate:         * end of block\n")); +        UNGRAB +        UPDATE +        return Z_STREAM_END; +      } +      else +      { +        z->msg = (char*)"invalid literal/length code"; +        UNGRAB +        UPDATE +        return Z_DATA_ERROR; +      } +    } while (1); +  } while (m >= 258 && n >= 10); + +  /* not enough input or output--restore pointers and return */ +  UNGRAB +  UPDATE +  return Z_OK; +} + +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ +      START,    /* x: set up for LEN */ +      LEN,      /* i: get length/literal/eob next */ +      LENEXT,   /* i: getting length extra (have base) */ +      DIST,     /* i: get distance next */ +      DISTEXT,  /* i: getting distance extra */ +      COPY,     /* o: copying bytes in window, waiting for space */ +      LIT,      /* o: got literal, waiting for output space */ +      WASH,     /* o: got eob, possibly still output waiting */ +      END,      /* x: got eob and all data flushed */ +      BADCODE}  /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + +  /* mode */ +  inflate_codes_mode mode;      /* current inflate_codes mode */ + +  /* mode dependent information */ +  uInt len; +  union { +    struct { +      inflate_huft *tree;       /* pointer into tree */ +      uInt need;                /* bits needed */ +    } code;             /* if LEN or DIST, where in tree */ +    uInt lit;           /* if LIT, literal */ +    struct { +      uInt get;                 /* bits to get for extra */ +      uInt dist;                /* distance back to copy from */ +    } copy;             /* if EXT or COPY, where and how much */ +  } sub;                /* submode */ + +  /* mode independent information */ +  Byte lbits;           /* ltree bits decoded per branch */ +  Byte dbits;           /* dtree bits decoder per branch */ +  inflate_huft *ltree;          /* literal/length/eob tree */ +  inflate_huft *dtree;          /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z) +{ +  inflate_codes_statef *c; + +  if ((c = (inflate_codes_statef *) +       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) +  { +    c->mode = START; +    c->lbits = (Byte)bl; +    c->dbits = (Byte)bd; +    c->ltree = tl; +    c->dtree = td; +    Tracev(("inflate:       codes new\n")); +  } +  return c; +} + + +int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) +{ +  uInt j;               /* temporary storage */ +  inflate_huft *t;      /* temporary pointer */ +  uInt e;               /* extra bits or operation */ +  uLong b;              /* bit buffer */ +  uInt k;               /* bits in bit buffer */ +  Byte *p;             /* input data pointer */ +  uInt n;               /* bytes available there */ +  Byte *q;             /* output window write pointer */ +  uInt m;               /* bytes to end of window or read pointer */ +  Byte *f;             /* pointer to copy strings from */ +  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */ + +  /* copy input/output information to locals (UPDATE macro restores) */ +  LOAD + +  /* process input and output based on current state */ +  while (1) switch (c->mode) +  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ +    case START:         /* x: set up for LEN */ +#ifndef SLOW +      if (m >= 258 && n >= 10) +      { +        UPDATE +        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); +        LOAD +        if (r != Z_OK) +        { +          c->mode = r == Z_STREAM_END ? WASH : BADCODE; +          break; +        } +      } +#endif /* !SLOW */ +      c->sub.code.need = c->lbits; +      c->sub.code.tree = c->ltree; +      c->mode = LEN; +    case LEN:           /* i: get length/literal/eob next */ +      j = c->sub.code.need; +      NEEDBITS(j) +      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); +      DUMPBITS(t->bits) +      e = (uInt)(t->exop); +      if (e == 0)               /* literal */ +      { +        c->sub.lit = t->base; +        Tracevv((t->base >= 0x20 && t->base < 0x7f ? +                 "inflate:         literal '%c'\n" : +                 "inflate:         literal 0x%02x\n", t->base)); +        c->mode = LIT; +        break; +      } +      if (e & 16)               /* length */ +      { +        c->sub.copy.get = e & 15; +        c->len = t->base; +        c->mode = LENEXT; +        break; +      } +      if ((e & 64) == 0)        /* next table */ +      { +        c->sub.code.need = e; +        c->sub.code.tree = t + t->base; +        break; +      } +      if (e & 32)               /* end of block */ +      { +        Tracevv(("inflate:         end of block\n")); +        c->mode = WASH; +        break; +      } +      c->mode = BADCODE;        /* invalid code */ +      z->msg = (char*)"invalid literal/length code"; +      r = Z_DATA_ERROR; +      LEAVE +    case LENEXT:        /* i: getting length extra (have base) */ +      j = c->sub.copy.get; +      NEEDBITS(j) +      c->len += (uInt)b & inflate_mask[j]; +      DUMPBITS(j) +      c->sub.code.need = c->dbits; +      c->sub.code.tree = c->dtree; +      Tracevv(("inflate:         length %u\n", c->len)); +      c->mode = DIST; +    case DIST:          /* i: get distance next */ +      j = c->sub.code.need; +      NEEDBITS(j) +      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); +      DUMPBITS(t->bits) +      e = (uInt)(t->exop); +      if (e & 16)               /* distance */ +      { +        c->sub.copy.get = e & 15; +        c->sub.copy.dist = t->base; +        c->mode = DISTEXT; +        break; +      } +      if ((e & 64) == 0)        /* next table */ +      { +        c->sub.code.need = e; +        c->sub.code.tree = t + t->base; +        break; +      } +      c->mode = BADCODE;        /* invalid code */ +      z->msg = (char*)"invalid distance code"; +      r = Z_DATA_ERROR; +      LEAVE +    case DISTEXT:       /* i: getting distance extra */ +      j = c->sub.copy.get; +      NEEDBITS(j) +      c->sub.copy.dist += (uInt)b & inflate_mask[j]; +      DUMPBITS(j) +      Tracevv(("inflate:         distance %u\n", c->sub.copy.dist)); +      c->mode = COPY; +    case COPY:          /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ +      f = (uInt)(q - s->window) < c->sub.copy.dist ? +          s->end - (c->sub.copy.dist - (q - s->window)) : +          q - c->sub.copy.dist; +#else +      f = q - c->sub.copy.dist; +      if ((uInt)(q - s->window) < c->sub.copy.dist) +        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif +      while (c->len) +      { +        NEEDOUT +        OUTBYTE(*f++) +        if (f == s->end) +          f = s->window; +        c->len--; +      } +      c->mode = START; +      break; +    case LIT:           /* o: got literal, waiting for output space */ +      NEEDOUT +      OUTBYTE(c->sub.lit) +      c->mode = START; +      break; +    case WASH:          /* o: got eob, possibly more output */ +      if (k > 7)        /* return unused byte, if any */ +      { +        Assert(k < 16, "inflate_codes grabbed too many bytes") +        k -= 8; +        n++; +        p--;            /* can always return one */ +      } +      FLUSH +      if (s->read != s->write) +        LEAVE +      c->mode = END; +    case END: +      r = Z_STREAM_END; +      LEAVE +    case BADCODE:       /* x: got error */ +      r = Z_DATA_ERROR; +      LEAVE +    default: +      r = Z_STREAM_ERROR; +      LEAVE +  } +#ifdef NEED_DUMMY_RETURN +  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(inflate_codes_statef *c, z_streamp z) +{ +  ZFREE(z, c); +  Tracev(("inflate:       codes free\n")); +} + +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#undef DO1 +#undef DO2 +#undef DO4 +#undef DO8 + +#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4); +#define DO16(buf)   DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong adler32(uLong adler, const Byte *buf, uInt len) +{ +    unsigned long s1 = adler & 0xffff; +    unsigned long s2 = (adler >> 16) & 0xffff; +    int k; + +    if (buf == Z_NULL) return 1L; + +    while (len > 0) { +        k = len < NMAX ? len : NMAX; +        len -= k; +        while (k >= 16) { +            DO16(buf); +	    buf += 16; +            k -= 16; +        } +        if (k != 0) do { +            s1 += *buf++; +	    s2 += s1; +        } while (--k); +        s1 %= BASE; +        s2 %= BASE; +    } +    return (s2 << 16) | s1; +} + +/* @(#) $Id: unzip.cpp,v 1.1.1.3 2000/01/11 16:37:27 ttimo Exp $ */ + +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h  + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +extern inflate_blocks_statef * inflate_blocks_new OF(( +    z_streamp z, +    check_func c,               /* check function */ +    uInt w));                   /* window size */ + +extern int inflate_blocks OF(( +    inflate_blocks_statef *, +    z_streamp , +    int));                      /* initial return code */ + +extern void inflate_blocks_reset OF(( +    inflate_blocks_statef *, +    z_streamp , +    uLong *));                  /* check value on output */ + +extern int inflate_blocks_free OF(( +    inflate_blocks_statef *, +    z_streamp)); + +extern void inflate_set_dictionary OF(( +    inflate_blocks_statef *s, +    const Byte *d,  /* dictionary */ +    uInt  n));       /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( +    inflate_blocks_statef *s)); + +typedef enum { +      imMETHOD,   /* waiting for method byte */ +      imFLAG,     /* waiting for flag byte */ +      imDICT4,    /* four dictionary check bytes to go */ +      imDICT3,    /* three dictionary check bytes to go */ +      imDICT2,    /* two dictionary check bytes to go */ +      imDICT1,    /* one dictionary check byte to go */ +      imDICT0,    /* waiting for inflateSetDictionary */ +      imBLOCKS,   /* decompressing blocks */ +      imCHECK4,   /* four check bytes to go */ +      imCHECK3,   /* three check bytes to go */ +      imCHECK2,   /* two check bytes to go */ +      imCHECK1,   /* one check byte to go */ +      imDONE,     /* finished check, done */ +      imBAD}      /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + +  /* mode */ +  inflate_mode  mode;   /* current inflate mode */ + +  /* mode dependent information */ +  union { +    uInt method;        /* if FLAGS, method byte */ +    struct { +      uLong was;                /* computed check value */ +      uLong need;               /* stream check value */ +    } check;            /* if CHECK, check values to compare */ +    uInt marker;        /* if BAD, inflateSync's marker bytes count */ +  } sub;        /* submode */ + +  /* mode independent information */ +  int  nowrap;          /* flag for no wrapper */ +  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */ +  inflate_blocks_statef  +    *blocks;            /* current inflate_blocks state */ + +}; + + +int inflateReset(z_streamp z) +{ +  if (z == Z_NULL || z->state == Z_NULL) +    return Z_STREAM_ERROR; +  z->total_in = z->total_out = 0; +  z->msg = Z_NULL; +  z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; +  inflate_blocks_reset(z->state->blocks, z, Z_NULL); +  Tracev(("inflate: reset\n")); +  return Z_OK; +} + + +int inflateEnd(z_streamp z) +{ +  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) +    return Z_STREAM_ERROR; +  if (z->state->blocks != Z_NULL) +    inflate_blocks_free(z->state->blocks, z); +  ZFREE(z, z->state); +  z->state = Z_NULL; +  Tracev(("inflate: end\n")); +  return Z_OK; +} + + + +int inflateInit2_(z_streamp z, int w, const char *version, int stream_size) +{ +  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || +      stream_size != sizeof(z_stream)) +      return Z_VERSION_ERROR; + +  /* initialize state */ +  if (z == Z_NULL) +    return Z_STREAM_ERROR; +  z->msg = Z_NULL; +  if (z->zalloc == Z_NULL) +  { +    z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc; +    z->opaque = (voidp)0; +  } +  if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree; +  if ((z->state = (struct internal_state *) +       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) +    return Z_MEM_ERROR; +  z->state->blocks = Z_NULL; + +  /* handle undocumented nowrap option (no zlib header or check) */ +  z->state->nowrap = 0; +  if (w < 0) +  { +    w = - w; +    z->state->nowrap = 1; +  } + +  /* set window size */ +  if (w < 8 || w > 15) +  { +    inflateEnd(z); +    return Z_STREAM_ERROR; +  } +  z->state->wbits = (uInt)w; + +  /* create inflate_blocks state */ +  if ((z->state->blocks = +      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) +      == Z_NULL) +  { +    inflateEnd(z); +    return Z_MEM_ERROR; +  } +  Tracev(("inflate: allocated\n")); + +  /* reset state */ +  inflateReset(z); +  return Z_OK; +} + + +int inflateInit_(z_streamp z, const char *version, int stream_size) +{ +  return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z_streamp z, int f) +{ +  int r; +  uInt b; + +  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) +    return Z_STREAM_ERROR; +  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; +  r = Z_BUF_ERROR; +  while (1) switch (z->state->mode) +  { +    case imMETHOD: +      iNEEDBYTE +      if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED) +      { +        z->state->mode = imBAD; +        z->msg = (char*)"unknown compression method"; +        z->state->sub.marker = 5;       /* can't try inflateSync */ +        break; +      } +      if ((z->state->sub.method >> 4) + 8 > z->state->wbits) +      { +        z->state->mode = imBAD; +        z->msg = (char*)"invalid window size"; +        z->state->sub.marker = 5;       /* can't try inflateSync */ +        break; +      } +      z->state->mode = imFLAG; +    case imFLAG: +      iNEEDBYTE +      b = iNEXTBYTE; +      if (((z->state->sub.method << 8) + b) % 31) +      { +        z->state->mode = imBAD; +        z->msg = (char*)"incorrect header check"; +        z->state->sub.marker = 5;       /* can't try inflateSync */ +        break; +      } +      Tracev(("inflate: zlib header ok\n")); +      if (!(b & PRESET_DICT)) +      { +        z->state->mode = imBLOCKS; +        break; +      } +      z->state->mode = imDICT4; +    case imDICT4: +      iNEEDBYTE +      z->state->sub.check.need = (uLong)iNEXTBYTE << 24; +      z->state->mode = imDICT3; +    case imDICT3: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE << 16; +      z->state->mode = imDICT2; +    case imDICT2: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE << 8; +      z->state->mode = imDICT1; +    case imDICT1: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE; +      z->adler = z->state->sub.check.need; +      z->state->mode = imDICT0; +      return Z_NEED_DICT; +    case imDICT0: +      z->state->mode = imBAD; +      z->msg = (char*)"need dictionary"; +      z->state->sub.marker = 0;       /* can try inflateSync */ +      return Z_STREAM_ERROR; +    case imBLOCKS: +      r = inflate_blocks(z->state->blocks, z, r); +      if (r == Z_DATA_ERROR) +      { +        z->state->mode = imBAD; +        z->state->sub.marker = 0;       /* can try inflateSync */ +        break; +      } +      if (r == Z_OK) +        r = f; +      if (r != Z_STREAM_END) +        return r; +      r = f; +      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); +      if (z->state->nowrap) +      { +        z->state->mode = imDONE; +        break; +      } +      z->state->mode = imCHECK4; +    case imCHECK4: +      iNEEDBYTE +      z->state->sub.check.need = (uLong)iNEXTBYTE << 24; +      z->state->mode = imCHECK3; +    case imCHECK3: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE << 16; +      z->state->mode = imCHECK2; +    case imCHECK2: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE << 8; +      z->state->mode = imCHECK1; +    case imCHECK1: +      iNEEDBYTE +      z->state->sub.check.need += (uLong)iNEXTBYTE; + +      if (z->state->sub.check.was != z->state->sub.check.need) +      { +        z->state->mode = imBAD; +        z->msg = (char*)"incorrect data check"; +        z->state->sub.marker = 5;       /* can't try inflateSync */ +        break; +      } +      Tracev(("inflate: zlib check ok\n")); +      z->state->mode = imDONE; +    case imDONE: +      return Z_STREAM_END; +    case imBAD: +      return Z_DATA_ERROR; +    default: +      return Z_STREAM_ERROR; +  } +#ifdef NEED_DUMMY_RETURN +  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */ +#endif +} + + +int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength) +{ +  uInt length = dictLength; + +  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0) +    return Z_STREAM_ERROR; + +  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; +  z->adler = 1L; + +  if (length >= ((uInt)1<<z->state->wbits)) +  { +    length = (1<<z->state->wbits)-1; +    dictionary += dictLength - length; +  } +  inflate_set_dictionary(z->state->blocks, dictionary, length); +  z->state->mode = imBLOCKS; +  return Z_OK; +} + + +int inflateSync(z_streamp z) +{ +  uInt n;       /* number of bytes to look at */ +  Byte *p;     /* pointer to bytes */ +  uInt m;       /* number of marker bytes found in a row */ +  uLong r, w;   /* temporaries to save total_in and total_out */ + +  /* set up */ +  if (z == Z_NULL || z->state == Z_NULL) +    return Z_STREAM_ERROR; +  if (z->state->mode != imBAD) +  { +    z->state->mode = imBAD; +    z->state->sub.marker = 0; +  } +  if ((n = z->avail_in) == 0) +    return Z_BUF_ERROR; +  p = z->next_in; +  m = z->state->sub.marker; + +  /* search */ +  while (n && m < 4) +  { +    static const Byte mark[4] = {0, 0, 0xff, 0xff}; +    if (*p == mark[m]) +      m++; +    else if (*p) +      m = 0; +    else +      m = 4 - m; +    p++, n--; +  } + +  /* restore */ +  z->total_in += p - z->next_in; +  z->next_in = p; +  z->avail_in = n; +  z->state->sub.marker = m; + +  /* return no joy or set up to restart on a new block */ +  if (m != 4) +    return Z_DATA_ERROR; +  r = z->total_in;  w = z->total_out; +  inflateReset(z); +  z->total_in = r;  z->total_out = w; +  z->state->mode = imBLOCKS; +  return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int inflateSyncPoint(z_streamp z) +{ +  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) +    return Z_STREAM_ERROR; +  return inflate_blocks_sync_point(z->state->blocks); +} + +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ +    if (opaque) items += size - size; /* make compiler happy */ +    return (voidp)malloc(items*size); +} + +void  zcfree (voidp opaque, voidp ptr) +{ +    free(ptr); +    if (opaque) return; /* make compiler happy */ +} + diff --git a/libs/pak/unzip.h b/libs/pak/unzip.h index d5c165d..79a487e 100755 --- a/libs/pak/unzip.h +++ b/libs/pak/unzip.h @@ -1,300 +1,300 @@ -
 -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
 -/* like the STRICT of WIN32, we define a pointer that cannot be converted
 -    from (void*) without cast */
 -typedef struct TagunzFile__ { int unused; } unzFile__; 
 -typedef unzFile__ *unzFile;
 -#else
 -typedef void* unzFile;
 -#endif
 -
 -
 -/* tm_unz contain date/time info */
 -typedef struct tm_unz_s 
 -{
 -	unsigned int tm_sec;            /* seconds after the minute - [0,59] */
 -	unsigned int tm_min;            /* minutes after the hour - [0,59] */
 -	unsigned int tm_hour;           /* hours since midnight - [0,23] */
 -	unsigned int tm_mday;           /* day of the month - [1,31] */
 -	unsigned int tm_mon;            /* months since January - [0,11] */
 -	unsigned int tm_year;           /* years - [1980..2044] */
 -} tm_unz;
 -
 -/* unz_global_info structure contain global data about the ZIPfile
 -   These data comes from the end of central dir */
 -typedef struct unz_global_info_s
 -{
 -	unsigned long number_entry;         /* total number of entries in the central dir on this disk */
 -	unsigned long size_comment;         /* size of the global comment of the zipfile */
 -} unz_global_info;
 -
 -
 -/* unz_file_info contain information about a file in the zipfile */
 -typedef struct unz_file_info_s
 -{
 -    unsigned long version;              /* version made by                 2 unsigned chars */
 -    unsigned long version_needed;       /* version needed to extract       2 unsigned chars */
 -    unsigned long flag;                 /* general purpose bit flag        2 unsigned chars */
 -    unsigned long compression_method;   /* compression method              2 unsigned chars */
 -    unsigned long dosDate;              /* last mod file date in Dos fmt   4 unsigned chars */
 -    unsigned long crc;                  /* crc-32                          4 unsigned chars */
 -    unsigned long compressed_size;      /* compressed size                 4 unsigned chars */ 
 -    unsigned long uncompressed_size;    /* uncompressed size               4 unsigned chars */ 
 -    unsigned long size_filename;        /* filename length                 2 unsigned chars */
 -    unsigned long size_file_extra;      /* extra field length              2 unsigned chars */
 -    unsigned long size_file_comment;    /* file comment length             2 unsigned chars */
 -
 -    unsigned long disk_num_start;       /* disk number start               2 unsigned chars */
 -    unsigned long internal_fa;          /* internal file attributes        2 unsigned chars */
 -    unsigned long external_fa;          /* external file attributes        4 unsigned chars */
 -
 -    tm_unz tmu_date;
 -} unz_file_info;
 -
 -/* unz_file_info_interntal contain internal info about a file in zipfile*/
 -typedef struct unz_file_info_internal_s
 -{
 -    unsigned long offset_curfile;/* relative offset of static header 4 unsigned chars */
 -} unz_file_info_internal;
 -
 -typedef void* (*alloc_func) (void* opaque, unsigned int items, unsigned int size);
 -typedef void   (*free_func) (void* opaque, void* address);
 -
 -struct internal_state;
 -
 -typedef struct z_stream_s {
 -    unsigned char    *next_in;  /* next input unsigned char */
 -    unsigned int     avail_in;  /* number of unsigned chars available at next_in */
 -    unsigned long    total_in;  /* total nb of input unsigned chars read so */
 -
 -    unsigned char    *next_out; /* next output unsigned char should be put there */
 -    unsigned int     avail_out; /* remaining free space at next_out */
 -    unsigned long    total_out; /* total nb of unsigned chars output so */
 -
 -    char     *msg;      /* last error message, NULL if no error */
 -    struct internal_state *state; /* not visible by applications */
 -
 -    alloc_func zalloc;  /* used to allocate the internal state */
 -    free_func  zfree;   /* used to free the internal state */
 -    unsigned char*     opaque;  /* private data object passed to zalloc and zfree */
 -
 -    int     data_type;  /* best guess about the data type: ascii or binary */
 -    unsigned long   adler;      /* adler32 value of the uncompressed data */
 -    unsigned long   reserved;   /* reserved for future use */
 -} z_stream;
 -
 -typedef z_stream *z_streamp;
 -
 -
 -/* file_in_zip_read_info_s contain internal information about a file in zipfile,
 -    when reading and decompress it */
 -typedef struct
 -{
 -	char  *read_buffer;         /* internal buffer for compressed data */
 -	z_stream stream;            /* zLib stream structure for inflate */
 -
 -	unsigned long pos_in_zipfile;       /* position in unsigned char on the zipfile, for fseek*/
 -	unsigned long stream_initialised;   /* flag set if stream structure is initialised*/
 -
 -	unsigned long offset_local_extrafield;/* offset of the static extra field */
 -	unsigned int  size_local_extrafield;/* size of the static extra field */
 -	unsigned long pos_local_extrafield;   /* position in the static extra field in read*/
 -
 -	unsigned long crc32;                /* crc32 of all data uncompressed */
 -	unsigned long crc32_wait;           /* crc32 we must obtain after decompress all */
 -	unsigned long rest_read_compressed; /* number of unsigned char to be decompressed */
 -	unsigned long rest_read_uncompressed;/*number of unsigned char to be obtained after decomp*/
 -	FILE* file;                 /* io structore of the zipfile */
 -	unsigned long compression_method;   /* compression method (0==store) */
 -	unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/
 -} file_in_zip_read_info_s;
 -
 -
 -/* unz_s contain internal information about the zipfile
 -*/
 -typedef struct
 -{
 -	FILE* file;                 /* io structore of the zipfile */
 -	unz_global_info gi;       /* public global information */
 -	unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/
 -	unsigned long num_file;             /* number of the current file in the zipfile*/
 -	unsigned long pos_in_central_dir;   /* pos of the current file in the central dir*/
 -	unsigned long current_file_ok;      /* flag about the usability of the current file*/
 -	unsigned long central_pos;          /* position of the beginning of the central dir*/
 -
 -	unsigned long size_central_dir;     /* size of the central directory  */
 -	unsigned long offset_central_dir;   /* offset of start of central directory with
 -								   respect to the starting disk number */
 -
 -	unz_file_info cur_file_info; /* public info about the current file in zip*/
 -	unz_file_info_internal cur_file_info_internal; /* private info about it*/
 -    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
 -	                                    file if we are decompressing it */
 -} unz_s;
 -
 -#define UNZ_OK                                  (0)
 -#define UNZ_END_OF_LIST_OF_FILE (-100)
 -#define UNZ_ERRNO               (Z_ERRNO)
 -#define UNZ_EOF                 (0)
 -#define UNZ_PARAMERROR                  (-102)
 -#define UNZ_BADZIPFILE                  (-103)
 -#define UNZ_INTERNALERROR               (-104)
 -#define UNZ_CRCERROR                    (-105)
 -
 -#define UNZ_CASESENSITIVE		1
 -#define UNZ_NOTCASESENSITIVE	2
 -#define UNZ_OSDEFAULTCASE		0
 -
 -extern int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity);
 -
 -/*
 -   Compare two filename (fileName1,fileName2).
 -   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
 -   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
 -								or strcasecmp)
 -   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
 -	(like 1 on Unix, 2 on Windows)
 -*/
 -
 -extern unzFile unzOpen (const char *path);
 -extern unzFile unzReOpen (const char* path, unzFile file);
 -
 -/*
 -  Open a Zip file. path contain the full pathname (by example,
 -     on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
 -	 "zlib/zlib111.zip".
 -	 If the zipfile cannot be opened (file don't exist or in not valid), the
 -	   return value is NULL.
 -     Else, the return value is a unzFile Handle, usable with other function
 -	   of this unzip package.
 -*/
 -
 -extern int unzClose (unzFile file);
 -
 -/*
 -  Close a ZipFile opened with unzipOpen.
 -  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
 -    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
 -  return UNZ_OK if there is no problem. */
 -
 -extern int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info);
 -
 -/*
 -  Write info about the ZipFile in the *pglobal_info structure.
 -  No preparation of the structure is needed
 -  return UNZ_OK if there is no problem. */
 -
 -
 -extern int unzGetGlobalComment (unzFile file, char *szComment, unsigned long uSizeBuf);
 -
 -/*
 -  Get the global comment string of the ZipFile, in the szComment buffer.
 -  uSizeBuf is the size of the szComment buffer.
 -  return the number of unsigned char copied or an error code <0
 -*/
 -
 -
 -/***************************************************************************/
 -/* Unzip package allow you browse the directory of the zipfile */
 -
 -extern int unzGoToFirstFile (unzFile file);
 -
 -/*
 -  Set the current file of the zipfile to the first file.
 -  return UNZ_OK if there is no problem
 -*/
 -
 -extern int unzGoToNextFile (unzFile file);
 -
 -/*
 -  Set the current file of the zipfile to the next file.
 -  return UNZ_OK if there is no problem
 -  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
 -*/
 -
 -extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity);
 -
 -/*
 -  Try locate the file szFileName in the zipfile.
 -  For the iCaseSensitivity signification, see unzStringFileNameCompare
 -
 -  return value :
 -  UNZ_OK if the file is found. It becomes the current file.
 -  UNZ_END_OF_LIST_OF_FILE if the file is not found
 -*/
 -
 -
 -extern int unzGetCurrentFileInfo (unzFile file, unz_file_info *pfile_info, char *szFileName, unsigned long fileNameBufferSize, void *extraField, unsigned long extraFieldBufferSize, char *szComment, unsigned long commentBufferSize);
 -
 -/*
 -  Get Info about the current file
 -  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
 -	    the current file
 -  if szFileName!=NULL, the filemane string will be copied in szFileName
 -			(fileNameBufferSize is the size of the buffer)
 -  if extraField!=NULL, the extra field information will be copied in extraField
 -			(extraFieldBufferSize is the size of the buffer).
 -			This is the Central-header version of the extra field
 -  if szComment!=NULL, the comment string of the file will be copied in szComment
 -			(commentBufferSize is the size of the buffer)
 -*/
 -
 -/***************************************************************************/
 -/* for reading the content of the current zipfile, you can open it, read data
 -   from it, and close it (you can close it before reading all the file)
 -   */
 -
 -extern int unzOpenCurrentFile (unzFile file);
 -
 -/*
 -  Open for reading data the current file in the zipfile.
 -  If there is no error, the return value is UNZ_OK.
 -*/
 -
 -extern int unzCloseCurrentFile (unzFile file);
 -
 -/*
 -  Close the file in zip opened with unzOpenCurrentFile
 -  Return UNZ_CRCERROR if all the file was read but the CRC is not good
 -*/
 -
 -												
 -extern int unzReadCurrentFile (unzFile file, void* buf, unsigned len);
 -
 -/*
 -  Read unsigned chars from the current file (opened by unzOpenCurrentFile)
 -  buf contain buffer where data must be copied
 -  len the size of buf.
 -
 -  return the number of unsigned char copied if somes unsigned chars are copied
 -  return 0 if the end of file was reached
 -  return <0 with error code if there is an error
 -    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
 -*/
 -
 -extern long unztell(unzFile file);
 -
 -/*
 -  Give the current position in uncompressed data
 -*/
 -
 -extern int unzeof (unzFile file);
 -
 -/*
 -  return 1 if the end of file was reached, 0 elsewhere 
 -*/
 -
 -extern int unzGetLocalExtrafield (unzFile file, void* buf, unsigned len);
 -
 -/*
 -  Read extra field from the current file (opened by unzOpenCurrentFile)
 -  This is the local-header version of the extra field (sometimes, there is
 -    more info in the local-header version than in the central-header)
 -
 -  if buf==NULL, it return the size of the local extra field
 -
 -  if buf!=NULL, len is the size of the buffer, the extra header is copied in
 -	buf.
 -  the return value is the number of unsigned chars copied in buf, or (if <0) 
 -	the error code
 -*/
 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted +    from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__;  +typedef unzFile__ *unzFile; +#else +typedef void* unzFile; +#endif + + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s  +{ +	unsigned int tm_sec;            /* seconds after the minute - [0,59] */ +	unsigned int tm_min;            /* minutes after the hour - [0,59] */ +	unsigned int tm_hour;           /* hours since midnight - [0,23] */ +	unsigned int tm_mday;           /* day of the month - [1,31] */ +	unsigned int tm_mon;            /* months since January - [0,11] */ +	unsigned int tm_year;           /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile +   These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ +	unsigned long number_entry;         /* total number of entries in the central dir on this disk */ +	unsigned long size_comment;         /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ +    unsigned long version;              /* version made by                 2 unsigned chars */ +    unsigned long version_needed;       /* version needed to extract       2 unsigned chars */ +    unsigned long flag;                 /* general purpose bit flag        2 unsigned chars */ +    unsigned long compression_method;   /* compression method              2 unsigned chars */ +    unsigned long dosDate;              /* last mod file date in Dos fmt   4 unsigned chars */ +    unsigned long crc;                  /* crc-32                          4 unsigned chars */ +    unsigned long compressed_size;      /* compressed size                 4 unsigned chars */  +    unsigned long uncompressed_size;    /* uncompressed size               4 unsigned chars */  +    unsigned long size_filename;        /* filename length                 2 unsigned chars */ +    unsigned long size_file_extra;      /* extra field length              2 unsigned chars */ +    unsigned long size_file_comment;    /* file comment length             2 unsigned chars */ + +    unsigned long disk_num_start;       /* disk number start               2 unsigned chars */ +    unsigned long internal_fa;          /* internal file attributes        2 unsigned chars */ +    unsigned long external_fa;          /* external file attributes        4 unsigned chars */ + +    tm_unz tmu_date; +} unz_file_info; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ +    unsigned long offset_curfile;/* relative offset of static header 4 unsigned chars */ +} unz_file_info_internal; + +typedef void* (*alloc_func) (void* opaque, unsigned int items, unsigned int size); +typedef void   (*free_func) (void* opaque, void* address); + +struct internal_state; + +typedef struct z_stream_s { +    unsigned char    *next_in;  /* next input unsigned char */ +    unsigned int     avail_in;  /* number of unsigned chars available at next_in */ +    unsigned long    total_in;  /* total nb of input unsigned chars read so */ + +    unsigned char    *next_out; /* next output unsigned char should be put there */ +    unsigned int     avail_out; /* remaining free space at next_out */ +    unsigned long    total_out; /* total nb of unsigned chars output so */ + +    char     *msg;      /* last error message, NULL if no error */ +    struct internal_state *state; /* not visible by applications */ + +    alloc_func zalloc;  /* used to allocate the internal state */ +    free_func  zfree;   /* used to free the internal state */ +    unsigned char*     opaque;  /* private data object passed to zalloc and zfree */ + +    int     data_type;  /* best guess about the data type: ascii or binary */ +    unsigned long   adler;      /* adler32 value of the uncompressed data */ +    unsigned long   reserved;   /* reserved for future use */ +} z_stream; + +typedef z_stream *z_streamp; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, +    when reading and decompress it */ +typedef struct +{ +	char  *read_buffer;         /* internal buffer for compressed data */ +	z_stream stream;            /* zLib stream structure for inflate */ + +	unsigned long pos_in_zipfile;       /* position in unsigned char on the zipfile, for fseek*/ +	unsigned long stream_initialised;   /* flag set if stream structure is initialised*/ + +	unsigned long offset_local_extrafield;/* offset of the static extra field */ +	unsigned int  size_local_extrafield;/* size of the static extra field */ +	unsigned long pos_local_extrafield;   /* position in the static extra field in read*/ + +	unsigned long crc32;                /* crc32 of all data uncompressed */ +	unsigned long crc32_wait;           /* crc32 we must obtain after decompress all */ +	unsigned long rest_read_compressed; /* number of unsigned char to be decompressed */ +	unsigned long rest_read_uncompressed;/*number of unsigned char to be obtained after decomp*/ +	FILE* file;                 /* io structore of the zipfile */ +	unsigned long compression_method;   /* compression method (0==store) */ +	unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ +	FILE* file;                 /* io structore of the zipfile */ +	unz_global_info gi;       /* public global information */ +	unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ +	unsigned long num_file;             /* number of the current file in the zipfile*/ +	unsigned long pos_in_central_dir;   /* pos of the current file in the central dir*/ +	unsigned long current_file_ok;      /* flag about the usability of the current file*/ +	unsigned long central_pos;          /* position of the beginning of the central dir*/ + +	unsigned long size_central_dir;     /* size of the central directory  */ +	unsigned long offset_central_dir;   /* offset of start of central directory with +								   respect to the starting disk number */ + +	unz_file_info cur_file_info; /* public info about the current file in zip*/ +	unz_file_info_internal cur_file_info_internal; /* private info about it*/ +    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current +	                                    file if we are decompressing it */ +} unz_s; + +#define UNZ_OK                                  (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO               (Z_ERRNO) +#define UNZ_EOF                 (0) +#define UNZ_PARAMERROR                  (-102) +#define UNZ_BADZIPFILE                  (-103) +#define UNZ_INTERNALERROR               (-104) +#define UNZ_CRCERROR                    (-105) + +#define UNZ_CASESENSITIVE		1 +#define UNZ_NOTCASESENSITIVE	2 +#define UNZ_OSDEFAULTCASE		0 + +extern int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity); + +/* +   Compare two filename (fileName1,fileName2). +   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) +   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi +								or strcasecmp) +   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system +	(like 1 on Unix, 2 on Windows) +*/ + +extern unzFile unzOpen (const char *path); +extern unzFile unzReOpen (const char* path, unzFile file); + +/* +  Open a Zip file. path contain the full pathname (by example, +     on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer +	 "zlib/zlib111.zip". +	 If the zipfile cannot be opened (file don't exist or in not valid), the +	   return value is NULL. +     Else, the return value is a unzFile Handle, usable with other function +	   of this unzip package. +*/ + +extern int unzClose (unzFile file); + +/* +  Close a ZipFile opened with unzipOpen. +  If there is files inside the .Zip opened with unzOpenCurrentFile (see later), +    these files MUST be closed with unzipCloseCurrentFile before call unzipClose. +  return UNZ_OK if there is no problem. */ + +extern int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info); + +/* +  Write info about the ZipFile in the *pglobal_info structure. +  No preparation of the structure is needed +  return UNZ_OK if there is no problem. */ + + +extern int unzGetGlobalComment (unzFile file, char *szComment, unsigned long uSizeBuf); + +/* +  Get the global comment string of the ZipFile, in the szComment buffer. +  uSizeBuf is the size of the szComment buffer. +  return the number of unsigned char copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int unzGoToFirstFile (unzFile file); + +/* +  Set the current file of the zipfile to the first file. +  return UNZ_OK if there is no problem +*/ + +extern int unzGoToNextFile (unzFile file); + +/* +  Set the current file of the zipfile to the next file. +  return UNZ_OK if there is no problem +  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity); + +/* +  Try locate the file szFileName in the zipfile. +  For the iCaseSensitivity signification, see unzStringFileNameCompare + +  return value : +  UNZ_OK if the file is found. It becomes the current file. +  UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int unzGetCurrentFileInfo (unzFile file, unz_file_info *pfile_info, char *szFileName, unsigned long fileNameBufferSize, void *extraField, unsigned long extraFieldBufferSize, char *szComment, unsigned long commentBufferSize); + +/* +  Get Info about the current file +  if pfile_info!=NULL, the *pfile_info structure will contain somes info about +	    the current file +  if szFileName!=NULL, the filemane string will be copied in szFileName +			(fileNameBufferSize is the size of the buffer) +  if extraField!=NULL, the extra field information will be copied in extraField +			(extraFieldBufferSize is the size of the buffer). +			This is the Central-header version of the extra field +  if szComment!=NULL, the comment string of the file will be copied in szComment +			(commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data +   from it, and close it (you can close it before reading all the file) +   */ + +extern int unzOpenCurrentFile (unzFile file); + +/* +  Open for reading data the current file in the zipfile. +  If there is no error, the return value is UNZ_OK. +*/ + +extern int unzCloseCurrentFile (unzFile file); + +/* +  Close the file in zip opened with unzOpenCurrentFile +  Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +												 +extern int unzReadCurrentFile (unzFile file, void* buf, unsigned len); + +/* +  Read unsigned chars from the current file (opened by unzOpenCurrentFile) +  buf contain buffer where data must be copied +  len the size of buf. + +  return the number of unsigned char copied if somes unsigned chars are copied +  return 0 if the end of file was reached +  return <0 with error code if there is an error +    (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern long unztell(unzFile file); + +/* +  Give the current position in uncompressed data +*/ + +extern int unzeof (unzFile file); + +/* +  return 1 if the end of file was reached, 0 elsewhere  +*/ + +extern int unzGetLocalExtrafield (unzFile file, void* buf, unsigned len); + +/* +  Read extra field from the current file (opened by unzOpenCurrentFile) +  This is the local-header version of the extra field (sometimes, there is +    more info in the local-header version than in the central-header) + +  if buf==NULL, it return the size of the local extra field + +  if buf!=NULL, len is the size of the buffer, the extra header is copied in +	buf. +  the return value is the number of unsigned chars copied in buf, or (if <0)  +	the error code +*/ diff --git a/libs/pakstuff.h b/libs/pakstuff.h index 2daf64b..820b5c6 100755 --- a/libs/pakstuff.h +++ b/libs/pakstuff.h @@ -19,123 +19,123 @@ along with Foobar; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  ===========================================================================  */ -#ifndef _PAKSTUFF_H_
 -#define _PAKSTUFF_H_
 -
 -#include <windows.h>
 -#ifdef __cplusplus
 -extern "C"
 -{
 -#endif
 -
 -typedef char           Int8;
 -typedef short          Int16;
 -typedef long           Int32;
 -typedef unsigned char  UInt8;
 -typedef unsigned short UInt16;
 -typedef unsigned long  UInt32;
 -typedef float          Float32;
 -typedef double         Float64;
 -#define MAX(a, b)              (((a) > (b)) ? (a) : (b))
 -#define MIN(a, b)              (((a) < (b)) ? (a) : (b))
 -#define RANDOM(x)              (random() % (x))
 -#define RANDOMIZE()             srand((int) time(NULL))
 -
 -#define FTYPE_UNKNOWN 0
 -#define FTYPE_IWAD    1    /* .wad  "IWAD" */
 -#define FTYPE_PWAD    2    /* .wad  "PWAD" */
 -#define FTYPE_PACK    3    /* .pak  "PACK" */
 -#define FTYPE_WAD2    4    /* .wad  "WAD2" */
 -#define FTYPE_BSP     10   /* .bsp  (0x17 0x00 0x00 0x00) */
 -#define FTYPE_MODEL   11   /* .mdl  "IDPO" */
 -#define FTYPE_SPRITE  12   /* .spr  "IDSP" */
 -#define FTYPE_WAV     20   /* .wav  "RIFF" */
 -#define FTYPE_AU      21   /* .au   ".snd" */
 -#define FTYPE_VOC     22   /* .voc  ?      */
 -#define FTYPE_PBM_ASC 30   /* .pbm  "P1"   */
 -#define FTYPE_PGM_ASC 31   /* .pgm  "P2"   */
 -#define FTYPE_PPM_ASC 32   /* .ppm  "P3"   */
 -#define FTYPE_PBM_RAW 33   /* .pbm  "P4"   */
 -#define FTYPE_PGM_RAW 34   /* .pgm  "P5"   */
 -#define FTYPE_PPM_RAW 35   /* .ppm  "P6"   */
 -#define FTYPE_BMP     36   /* .bmp  "BM"   */
 -#define FTYPE_GIF     37   /* .gif  "GIF8" */
 -#define FTYPE_PCX     38   /* .pcx  (0x0a 0x05 0x01 0x08) */
 -#define FTYPE_ERROR   -1
 -
 -#ifdef FAT_ENDIAN
 -Bool	ReadInt16		(FILE *file, UInt16 huge *x);
 -Bool	ReadInt32		(FILE *file, UInt32 huge *x);
 -Bool	ReadFloat32		(FILE *file, Float32 huge *x);
 -Bool	WriteInt16		(FILE *file, UInt16 huge *x);
 -Bool	WriteInt32		(FILE *file, UInt32 huge *x);
 -Bool	WriteFloat32	(FILE *file, Float32 huge *x);
 -UInt16	SwapInt16		(UInt16 x);
 -UInt32	SwapInt32		(UInt32 x);
 -Float32	SwapFloat32		(Float32 x);
 -#else
 -#define ReadInt16(f, p)		ReadBytes((f), (p), 2L)
 -#define ReadInt32(f, p)		ReadBytes((f), (p), 4L)
 -#define ReadFloat32(f, p)	ReadBytes((f), (p), 4L)
 -#define WriteInt16(f, p)	WriteBytes((f), (p), 2L)
 -#define WriteInt32(f, p)	WriteBytes((f), (p), 4L)
 -#define WriteFloat32(f, p)	WriteBytes((f), (p), 4L)
 -#define SwapInt16(x)		(x)
 -#define SwapInt32(x)		(x)
 -#define SwapFloat32(x)		(x)
 -#endif /* FAT_ENDIAN */
 -
 -#define FROMDISK	-1
 -struct PACKDirectory
 -{
 -   char   name[56];             /* name of file */
 -   UInt32 offset;               /* offset to start of data */
 -   UInt32 size;                 /* byte size of data */
 -};
 -typedef struct PACKDirectory *PACKDirPtr;
 -
 -typedef struct DirListStruct
 -{
 -	char					dirname[1024];
 -	int						from;
 -	struct	DirListStruct	*next;
 -} DIRLIST;
 -
 -typedef struct FileListStruct
 -{
 -	char					filename[1024];
 -	UInt32					offset;
 -	UInt32					size;
 -	struct	FileListStruct	*next;
 -} FILELIST;
 -
 -typedef struct DirStruct
 -{
 -	char				name[1024];
 -	FILELIST			*files;
 -	struct DirStruct	*next;
 -} DIRECTORY;
 -
 -
 -extern int m_nPAKIndex;
 -extern FILE* pakfile[16];
 -extern boolean pakopen;
 -extern DIRECTORY	*paktextures;
 -
 -void	ClearFileList				(FILELIST **);
 -void	ClearDirList				(DIRLIST **);
 -boolean		GetPackFileList				(FILELIST **, char *);
 -boolean		GetPackTextureDirs			(DIRLIST **);
 -boolean	AddToDirListAlphabetized	(DIRLIST **, char *, int);
 -boolean	AddToFileListAlphabetized	(FILELIST **t, char *, UInt32, UInt32, boolean);
 -boolean	PakLoadFile					(const char *, void **);
 -void	OpenPakFile					(const char *);
 -void	ClosePakFile				(void);
 -int PakLoadAnyFile(const char *filename, void **bufferptr);
 -void WINAPI InitPakFile(const char * pBasePath, const char *pName);
 -
 -#ifdef __cplusplus
 -}
 -#endif
 -
 -#endif
 +#ifndef _PAKSTUFF_H_ +#define _PAKSTUFF_H_ + +#include <windows.h> +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef char           Int8; +typedef short          Int16; +typedef long           Int32; +typedef unsigned char  UInt8; +typedef unsigned short UInt16; +typedef unsigned long  UInt32; +typedef float          Float32; +typedef double         Float64; +#define MAX(a, b)              (((a) > (b)) ? (a) : (b)) +#define MIN(a, b)              (((a) < (b)) ? (a) : (b)) +#define RANDOM(x)              (random() % (x)) +#define RANDOMIZE()             srand((int) time(NULL)) + +#define FTYPE_UNKNOWN 0 +#define FTYPE_IWAD    1    /* .wad  "IWAD" */ +#define FTYPE_PWAD    2    /* .wad  "PWAD" */ +#define FTYPE_PACK    3    /* .pak  "PACK" */ +#define FTYPE_WAD2    4    /* .wad  "WAD2" */ +#define FTYPE_BSP     10   /* .bsp  (0x17 0x00 0x00 0x00) */ +#define FTYPE_MODEL   11   /* .mdl  "IDPO" */ +#define FTYPE_SPRITE  12   /* .spr  "IDSP" */ +#define FTYPE_WAV     20   /* .wav  "RIFF" */ +#define FTYPE_AU      21   /* .au   ".snd" */ +#define FTYPE_VOC     22   /* .voc  ?      */ +#define FTYPE_PBM_ASC 30   /* .pbm  "P1"   */ +#define FTYPE_PGM_ASC 31   /* .pgm  "P2"   */ +#define FTYPE_PPM_ASC 32   /* .ppm  "P3"   */ +#define FTYPE_PBM_RAW 33   /* .pbm  "P4"   */ +#define FTYPE_PGM_RAW 34   /* .pgm  "P5"   */ +#define FTYPE_PPM_RAW 35   /* .ppm  "P6"   */ +#define FTYPE_BMP     36   /* .bmp  "BM"   */ +#define FTYPE_GIF     37   /* .gif  "GIF8" */ +#define FTYPE_PCX     38   /* .pcx  (0x0a 0x05 0x01 0x08) */ +#define FTYPE_ERROR   -1 + +#ifdef FAT_ENDIAN +Bool	ReadInt16		(FILE *file, UInt16 huge *x); +Bool	ReadInt32		(FILE *file, UInt32 huge *x); +Bool	ReadFloat32		(FILE *file, Float32 huge *x); +Bool	WriteInt16		(FILE *file, UInt16 huge *x); +Bool	WriteInt32		(FILE *file, UInt32 huge *x); +Bool	WriteFloat32	(FILE *file, Float32 huge *x); +UInt16	SwapInt16		(UInt16 x); +UInt32	SwapInt32		(UInt32 x); +Float32	SwapFloat32		(Float32 x); +#else +#define ReadInt16(f, p)		ReadBytes((f), (p), 2L) +#define ReadInt32(f, p)		ReadBytes((f), (p), 4L) +#define ReadFloat32(f, p)	ReadBytes((f), (p), 4L) +#define WriteInt16(f, p)	WriteBytes((f), (p), 2L) +#define WriteInt32(f, p)	WriteBytes((f), (p), 4L) +#define WriteFloat32(f, p)	WriteBytes((f), (p), 4L) +#define SwapInt16(x)		(x) +#define SwapInt32(x)		(x) +#define SwapFloat32(x)		(x) +#endif /* FAT_ENDIAN */ + +#define FROMDISK	-1 +struct PACKDirectory +{ +   char   name[56];             /* name of file */ +   UInt32 offset;               /* offset to start of data */ +   UInt32 size;                 /* byte size of data */ +}; +typedef struct PACKDirectory *PACKDirPtr; + +typedef struct DirListStruct +{ +	char					dirname[1024]; +	int						from; +	struct	DirListStruct	*next; +} DIRLIST; + +typedef struct FileListStruct +{ +	char					filename[1024]; +	UInt32					offset; +	UInt32					size; +	struct	FileListStruct	*next; +} FILELIST; + +typedef struct DirStruct +{ +	char				name[1024]; +	FILELIST			*files; +	struct DirStruct	*next; +} DIRECTORY; + + +extern int m_nPAKIndex; +extern FILE* pakfile[16]; +extern boolean pakopen; +extern DIRECTORY	*paktextures; + +void	ClearFileList				(FILELIST **); +void	ClearDirList				(DIRLIST **); +boolean		GetPackFileList				(FILELIST **, char *); +boolean		GetPackTextureDirs			(DIRLIST **); +boolean	AddToDirListAlphabetized	(DIRLIST **, char *, int); +boolean	AddToFileListAlphabetized	(FILELIST **t, char *, UInt32, UInt32, boolean); +boolean	PakLoadFile					(const char *, void **); +void	OpenPakFile					(const char *); +void	ClosePakFile				(void); +int PakLoadAnyFile(const char *filename, void **bufferptr); +void WINAPI InitPakFile(const char * pBasePath, const char *pName); + +#ifdef __cplusplus +} +#endif + +#endif @@ -19,196 +19,196 @@ along with Foobar; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  ===========================================================================  */ -#ifndef __STR__
 -#define __STR__
 -//
 -// class Str
 -// loose replacement for CString from MFC
 -//
 -//#include "cmdlib.h"
 -#include <string.h>
 -
 -char* __StrDup(char* pStr);
 -char* __StrDup(const char* pStr);
 -
 -
 -
 -static char *g_pStrWork = NULL;
 -
 -class Str
 -{
 -protected:
 -  bool m_bIgnoreCase;
 -  char *m_pStr;
 -
 -public:
 -  Str()
 -  {
 -    m_bIgnoreCase = true;
 -    m_pStr = NULL;
 -  }
 -
 -  Str(char *p)
 -  {
 -    m_bIgnoreCase = true;
 -    m_pStr = __StrDup(p);
 -  }
 -
 -  Str(const char *p)
 -  {
 -    m_bIgnoreCase = true;
 -    m_pStr = __StrDup(p);
 -  }
 -
 -  void Deallocate()
 -  {
 -    delete []m_pStr;
 -    m_pStr = NULL;
 -  }
 -
 -  void Allocate(int n)
 -  {
 -    Deallocate();
 -    m_pStr = new char[n];
 -  }
 -
 -  const char* GetBuffer()
 -  {
 -    return m_pStr;
 -  }
 -
 -  void MakeEmpty()
 -  {
 -    Deallocate();
 -    m_pStr = __StrDup("");
 -  }
 -
 -  ~Str()
 -  {
 -    Deallocate();
 -    delete []g_pStrWork;
 -    g_pStrWork = NULL;
 -  }
 -
 -  void MakeLower()
 -  {
 -    if (m_pStr)
 -    {
 -      strlwr(m_pStr);
 -    }
 -  }
 -
 -  int Find(const char *p)
 -  {
 -    char *pf = strstr(m_pStr, p);
 -    return (pf) ? (pf - m_pStr) : -1;
 -  }
 -
 -  int GetLength()
 -  {
 -    return (m_pStr) ? strlen(m_pStr) : 0;
 -  }
 -
 -  const char* Left(int n)
 -  {
 -    delete []g_pStrWork;
 -    if (n > 0)
 -    {
 -      g_pStrWork = new char[n+1];
 -      strncpy(g_pStrWork, m_pStr, n);
 -    }
 -    else
 -    {
 -      g_pStrWork = "";
 -      g_pStrWork = new char[1];
 -      g_pStrWork[0] = '\0';
 -    }
 -    return g_pStrWork;
 -  }
 -
 -  const char* Right(int n)
 -  {
 -    delete []g_pStrWork;
 -    if (n > 0)
 -    {
 -      g_pStrWork = new char[n+1];
 -      int nStart = GetLength() - n;
 -      strncpy(g_pStrWork, &m_pStr[nStart], n);
 -      g_pStrWork[n] = '\0';
 -    }
 -    else
 -    {
 -      g_pStrWork = new char[1];
 -      g_pStrWork[0] = '\0';
 -    }
 -    return g_pStrWork;
 -  }
 -
 -
 -  char& operator *() { return *m_pStr; }
 -  char& operator *() const { return *const_cast<Str*>(this)->m_pStr; }
 -  operator void*() { return m_pStr; }
 -  operator char*() { return m_pStr; }
 -  operator const char*(){ return reinterpret_cast<const char*>(m_pStr); }
 -  operator unsigned char*() { return reinterpret_cast<unsigned char*>(m_pStr); }
 -  operator const unsigned char*() { return reinterpret_cast<const unsigned char*>(m_pStr); }
 -  Str& operator =(const Str& rhs)
 -  {
 -    if (&rhs != this)
 -    {
 -      delete[] m_pStr;
 -      m_pStr = __StrDup(rhs.m_pStr);
 -    }
 -    return *this;
 -  }
 -  
 -  Str& operator =(const char* pStr)
 -  {
 -    if (m_pStr != pStr)
 -    {
 -      delete[] m_pStr;
 -      m_pStr = __StrDup(pStr);
 -    }
 -    return *this;
 -  }
 -
 -  Str& operator +=(const char *pStr)
 -  {
 -    if (pStr)
 -    {
 -      if (m_pStr)
 -      {
 -        char *p = new char[strlen(m_pStr) + strlen(pStr) + 1];
 -        strcpy(p, m_pStr);
 -        strcat(p, pStr);
 -        delete m_pStr;
 -        m_pStr = p;
 -      }
 -      else
 -      {
 -        m_pStr = __StrDup(pStr);
 -      }
 -    }
 -    return *this;
 -  }
 -  
 -  Str& operator +=(const char c)
 -  {
 -    return operator+=(&c);
 -  }
 -
 -
 -  bool operator ==(const Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) == 0 : strcmp(m_pStr, rhs.m_pStr) == 0; }
 -  bool operator ==(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; }
 -  bool operator ==(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; }
 -  bool operator !=(Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) != 0 : strcmp(m_pStr, rhs.m_pStr) != 0; }
 -  bool operator !=(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; }
 -  bool operator !=(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; }
 -  char& operator [](int nIndex) { return m_pStr[nIndex]; }
 -  char& operator [](int nIndex) const { return m_pStr[nIndex]; }
 -     
 -};
 -
 -
 -
 +#ifndef __STR__ +#define __STR__ +// +// class Str +// loose replacement for CString from MFC +// +//#include "cmdlib.h" +#include <string.h> + +char* __StrDup(char* pStr); +char* __StrDup(const char* pStr); + + + +static char *g_pStrWork = NULL; + +class Str +{ +protected: +  bool m_bIgnoreCase; +  char *m_pStr; + +public: +  Str() +  { +    m_bIgnoreCase = true; +    m_pStr = NULL; +  } + +  Str(char *p) +  { +    m_bIgnoreCase = true; +    m_pStr = __StrDup(p); +  } + +  Str(const char *p) +  { +    m_bIgnoreCase = true; +    m_pStr = __StrDup(p); +  } + +  void Deallocate() +  { +    delete []m_pStr; +    m_pStr = NULL; +  } + +  void Allocate(int n) +  { +    Deallocate(); +    m_pStr = new char[n]; +  } + +  const char* GetBuffer() +  { +    return m_pStr; +  } + +  void MakeEmpty() +  { +    Deallocate(); +    m_pStr = __StrDup(""); +  } + +  ~Str() +  { +    Deallocate(); +    delete []g_pStrWork; +    g_pStrWork = NULL; +  } + +  void MakeLower() +  { +    if (m_pStr) +    { +      strlwr(m_pStr); +    } +  } + +  int Find(const char *p) +  { +    char *pf = strstr(m_pStr, p); +    return (pf) ? (pf - m_pStr) : -1; +  } + +  int GetLength() +  { +    return (m_pStr) ? strlen(m_pStr) : 0; +  } + +  const char* Left(int n) +  { +    delete []g_pStrWork; +    if (n > 0) +    { +      g_pStrWork = new char[n+1]; +      strncpy(g_pStrWork, m_pStr, n); +    } +    else +    { +      g_pStrWork = ""; +      g_pStrWork = new char[1]; +      g_pStrWork[0] = '\0'; +    } +    return g_pStrWork; +  } + +  const char* Right(int n) +  { +    delete []g_pStrWork; +    if (n > 0) +    { +      g_pStrWork = new char[n+1]; +      int nStart = GetLength() - n; +      strncpy(g_pStrWork, &m_pStr[nStart], n); +      g_pStrWork[n] = '\0'; +    } +    else +    { +      g_pStrWork = new char[1]; +      g_pStrWork[0] = '\0'; +    } +    return g_pStrWork; +  } + + +  char& operator *() { return *m_pStr; } +  char& operator *() const { return *const_cast<Str*>(this)->m_pStr; } +  operator void*() { return m_pStr; } +  operator char*() { return m_pStr; } +  operator const char*(){ return reinterpret_cast<const char*>(m_pStr); } +  operator unsigned char*() { return reinterpret_cast<unsigned char*>(m_pStr); } +  operator const unsigned char*() { return reinterpret_cast<const unsigned char*>(m_pStr); } +  Str& operator =(const Str& rhs) +  { +    if (&rhs != this) +    { +      delete[] m_pStr; +      m_pStr = __StrDup(rhs.m_pStr); +    } +    return *this; +  } +   +  Str& operator =(const char* pStr) +  { +    if (m_pStr != pStr) +    { +      delete[] m_pStr; +      m_pStr = __StrDup(pStr); +    } +    return *this; +  } + +  Str& operator +=(const char *pStr) +  { +    if (pStr) +    { +      if (m_pStr) +      { +        char *p = new char[strlen(m_pStr) + strlen(pStr) + 1]; +        strcpy(p, m_pStr); +        strcat(p, pStr); +        delete m_pStr; +        m_pStr = p; +      } +      else +      { +        m_pStr = __StrDup(pStr); +      } +    } +    return *this; +  } +   +  Str& operator +=(const char c) +  { +    return operator+=(&c); +  } + + +  bool operator ==(const Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) == 0 : strcmp(m_pStr, rhs.m_pStr) == 0; } +  bool operator ==(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; } +  bool operator ==(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; } +  bool operator !=(Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) != 0 : strcmp(m_pStr, rhs.m_pStr) != 0; } +  bool operator !=(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; } +  bool operator !=(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; } +  char& operator [](int nIndex) { return m_pStr[nIndex]; } +  char& operator [](int nIndex) const { return m_pStr[nIndex]; } +      +}; + + +  #endif
\ No newline at end of file  | 
