xref: /plan9/sys/src/cmd/gs/jpeg/jmemdos.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier  * jmemdos.c
37dd7cddfSDavid du Colombier  *
4*593dc095SDavid du Colombier  * Copyright (C) 1992-1997, Thomas G. Lane.
57dd7cddfSDavid du Colombier  * This file is part of the Independent JPEG Group's software.
67dd7cddfSDavid du Colombier  * For conditions of distribution and use, see the accompanying README file.
77dd7cddfSDavid du Colombier  *
87dd7cddfSDavid du Colombier  * This file provides an MS-DOS-compatible implementation of the system-
97dd7cddfSDavid du Colombier  * dependent portion of the JPEG memory manager.  Temporary data can be
107dd7cddfSDavid du Colombier  * stored in extended or expanded memory as well as in regular DOS files.
117dd7cddfSDavid du Colombier  *
127dd7cddfSDavid du Colombier  * If you use this file, you must be sure that NEED_FAR_POINTERS is defined
137dd7cddfSDavid du Colombier  * if you compile in a small-data memory model; it should NOT be defined if
147dd7cddfSDavid du Colombier  * you use a large-data memory model.  This file is not recommended if you
157dd7cddfSDavid du Colombier  * are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
167dd7cddfSDavid du Colombier  * Also, this code will NOT work if struct fields are aligned on greater than
177dd7cddfSDavid du Colombier  * 2-byte boundaries.
187dd7cddfSDavid du Colombier  *
197dd7cddfSDavid du Colombier  * Based on code contributed by Ge' Weijers.
207dd7cddfSDavid du Colombier  */
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier /*
237dd7cddfSDavid du Colombier  * If you have both extended and expanded memory, you may want to change the
247dd7cddfSDavid du Colombier  * order in which they are tried in jopen_backing_store.  On a 286 machine
257dd7cddfSDavid du Colombier  * expanded memory is usually faster, since extended memory access involves
267dd7cddfSDavid du Colombier  * an expensive protected-mode-and-back switch.  On 386 and better, extended
277dd7cddfSDavid du Colombier  * memory is usually faster.  As distributed, the code tries extended memory
287dd7cddfSDavid du Colombier  * first (what? not everyone has a 386? :-).
297dd7cddfSDavid du Colombier  *
307dd7cddfSDavid du Colombier  * You can disable use of extended/expanded memory entirely by altering these
317dd7cddfSDavid du Colombier  * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
327dd7cddfSDavid du Colombier  */
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier #ifndef XMS_SUPPORTED
357dd7cddfSDavid du Colombier #define XMS_SUPPORTED  1
367dd7cddfSDavid du Colombier #endif
377dd7cddfSDavid du Colombier #ifndef EMS_SUPPORTED
387dd7cddfSDavid du Colombier #define EMS_SUPPORTED  1
397dd7cddfSDavid du Colombier #endif
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier 
427dd7cddfSDavid du Colombier #define JPEG_INTERNALS
437dd7cddfSDavid du Colombier #include "jinclude.h"
447dd7cddfSDavid du Colombier #include "jpeglib.h"
457dd7cddfSDavid du Colombier #include "jmemsys.h"		/* import the system-dependent declarations */
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier #ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare these */
487dd7cddfSDavid du Colombier extern void * malloc JPP((size_t size));
497dd7cddfSDavid du Colombier extern void free JPP((void *ptr));
507dd7cddfSDavid du Colombier extern char * getenv JPP((const char * name));
517dd7cddfSDavid du Colombier #endif
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier #ifdef NEED_FAR_POINTERS
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier #ifdef __TURBOC__
567dd7cddfSDavid du Colombier /* These definitions work for Borland C (Turbo C) */
577dd7cddfSDavid du Colombier #include <alloc.h>		/* need farmalloc(), farfree() */
587dd7cddfSDavid du Colombier #define far_malloc(x)	farmalloc(x)
597dd7cddfSDavid du Colombier #define far_free(x)	farfree(x)
607dd7cddfSDavid du Colombier #else
617dd7cddfSDavid du Colombier /* These definitions work for Microsoft C and compatible compilers */
627dd7cddfSDavid du Colombier #include <malloc.h>		/* need _fmalloc(), _ffree() */
637dd7cddfSDavid du Colombier #define far_malloc(x)	_fmalloc(x)
647dd7cddfSDavid du Colombier #define far_free(x)	_ffree(x)
657dd7cddfSDavid du Colombier #endif
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier #else /* not NEED_FAR_POINTERS */
687dd7cddfSDavid du Colombier 
697dd7cddfSDavid du Colombier #define far_malloc(x)	malloc(x)
707dd7cddfSDavid du Colombier #define far_free(x)	free(x)
717dd7cddfSDavid du Colombier 
727dd7cddfSDavid du Colombier #endif /* NEED_FAR_POINTERS */
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier #ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
757dd7cddfSDavid du Colombier #define READ_BINARY	"r"
767dd7cddfSDavid du Colombier #else
777dd7cddfSDavid du Colombier #define READ_BINARY	"rb"
787dd7cddfSDavid du Colombier #endif
797dd7cddfSDavid du Colombier 
80*593dc095SDavid du Colombier #ifndef USE_MSDOS_MEMMGR	/* make sure user got configuration right */
81*593dc095SDavid du Colombier   You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
82*593dc095SDavid du Colombier #endif
83*593dc095SDavid du Colombier 
847dd7cddfSDavid du Colombier #if MAX_ALLOC_CHUNK >= 65535L	/* make sure jconfig.h got this right */
857dd7cddfSDavid du Colombier   MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
867dd7cddfSDavid du Colombier #endif
877dd7cddfSDavid du Colombier 
887dd7cddfSDavid du Colombier 
897dd7cddfSDavid du Colombier /*
907dd7cddfSDavid du Colombier  * Declarations for assembly-language support routines (see jmemdosa.asm).
917dd7cddfSDavid du Colombier  *
927dd7cddfSDavid du Colombier  * The functions are declared "far" as are all their pointer arguments;
937dd7cddfSDavid du Colombier  * this ensures the assembly source code will work regardless of the
947dd7cddfSDavid du Colombier  * compiler memory model.  We assume "short" is 16 bits, "long" is 32.
957dd7cddfSDavid du Colombier  */
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier typedef void far * XMSDRIVER;	/* actually a pointer to code */
987dd7cddfSDavid du Colombier typedef struct {		/* registers for calling XMS driver */
997dd7cddfSDavid du Colombier 	unsigned short ax, dx, bx;
1007dd7cddfSDavid du Colombier 	void far * ds_si;
1017dd7cddfSDavid du Colombier       } XMScontext;
1027dd7cddfSDavid du Colombier typedef struct {		/* registers for calling EMS driver */
1037dd7cddfSDavid du Colombier 	unsigned short ax, dx, bx;
1047dd7cddfSDavid du Colombier 	void far * ds_si;
1057dd7cddfSDavid du Colombier       } EMScontext;
1067dd7cddfSDavid du Colombier 
1077dd7cddfSDavid du Colombier extern short far jdos_open JPP((short far * handle, char far * filename));
1087dd7cddfSDavid du Colombier extern short far jdos_close JPP((short handle));
1097dd7cddfSDavid du Colombier extern short far jdos_seek JPP((short handle, long offset));
1107dd7cddfSDavid du Colombier extern short far jdos_read JPP((short handle, void far * buffer,
1117dd7cddfSDavid du Colombier 				unsigned short count));
1127dd7cddfSDavid du Colombier extern short far jdos_write JPP((short handle, void far * buffer,
1137dd7cddfSDavid du Colombier 				 unsigned short count));
1147dd7cddfSDavid du Colombier extern void far jxms_getdriver JPP((XMSDRIVER far *));
1157dd7cddfSDavid du Colombier extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
1167dd7cddfSDavid du Colombier extern short far jems_available JPP((void));
1177dd7cddfSDavid du Colombier extern void far jems_calldriver JPP((EMScontext far *));
1187dd7cddfSDavid du Colombier 
1197dd7cddfSDavid du Colombier 
1207dd7cddfSDavid du Colombier /*
1217dd7cddfSDavid du Colombier  * Selection of a file name for a temporary file.
1227dd7cddfSDavid du Colombier  * This is highly system-dependent, and you may want to customize it.
1237dd7cddfSDavid du Colombier  */
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier static int next_file_num;	/* to distinguish among several temp files */
1267dd7cddfSDavid du Colombier 
1277dd7cddfSDavid du Colombier LOCAL(void)
select_file_name(char * fname)1287dd7cddfSDavid du Colombier select_file_name (char * fname)
1297dd7cddfSDavid du Colombier {
1307dd7cddfSDavid du Colombier   const char * env;
1317dd7cddfSDavid du Colombier   char * ptr;
1327dd7cddfSDavid du Colombier   FILE * tfile;
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier   /* Keep generating file names till we find one that's not in use */
1357dd7cddfSDavid du Colombier   for (;;) {
1367dd7cddfSDavid du Colombier     /* Get temp directory name from environment TMP or TEMP variable;
1377dd7cddfSDavid du Colombier      * if none, use "."
1387dd7cddfSDavid du Colombier      */
1397dd7cddfSDavid du Colombier     if ((env = (const char *) getenv("TMP")) == NULL)
1407dd7cddfSDavid du Colombier       if ((env = (const char *) getenv("TEMP")) == NULL)
1417dd7cddfSDavid du Colombier 	env = ".";
1427dd7cddfSDavid du Colombier     if (*env == '\0')		/* null string means "." */
1437dd7cddfSDavid du Colombier       env = ".";
1447dd7cddfSDavid du Colombier     ptr = fname;		/* copy name to fname */
1457dd7cddfSDavid du Colombier     while (*env != '\0')
1467dd7cddfSDavid du Colombier       *ptr++ = *env++;
1477dd7cddfSDavid du Colombier     if (ptr[-1] != '\\' && ptr[-1] != '/')
1487dd7cddfSDavid du Colombier       *ptr++ = '\\';		/* append backslash if not in env variable */
1497dd7cddfSDavid du Colombier     /* Append a suitable file name */
1507dd7cddfSDavid du Colombier     next_file_num++;		/* advance counter */
1517dd7cddfSDavid du Colombier     sprintf(ptr, "JPG%03d.TMP", next_file_num);
1527dd7cddfSDavid du Colombier     /* Probe to see if file name is already in use */
1537dd7cddfSDavid du Colombier     if ((tfile = fopen(fname, READ_BINARY)) == NULL)
1547dd7cddfSDavid du Colombier       break;
1557dd7cddfSDavid du Colombier     fclose(tfile);		/* oops, it's there; close tfile & try again */
1567dd7cddfSDavid du Colombier   }
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier 
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier /*
1617dd7cddfSDavid du Colombier  * Near-memory allocation and freeing are controlled by the regular library
1627dd7cddfSDavid du Colombier  * routines malloc() and free().
1637dd7cddfSDavid du Colombier  */
1647dd7cddfSDavid du Colombier 
1657dd7cddfSDavid du Colombier GLOBAL(void *)
jpeg_get_small(j_common_ptr cinfo,size_t sizeofobject)1667dd7cddfSDavid du Colombier jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
1677dd7cddfSDavid du Colombier {
1687dd7cddfSDavid du Colombier   return (void *) malloc(sizeofobject);
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier 
1717dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_free_small(j_common_ptr cinfo,void * object,size_t sizeofobject)1727dd7cddfSDavid du Colombier jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
1737dd7cddfSDavid du Colombier {
1747dd7cddfSDavid du Colombier   free(object);
1757dd7cddfSDavid du Colombier }
1767dd7cddfSDavid du Colombier 
1777dd7cddfSDavid du Colombier 
1787dd7cddfSDavid du Colombier /*
1797dd7cddfSDavid du Colombier  * "Large" objects are allocated in far memory, if possible
1807dd7cddfSDavid du Colombier  */
1817dd7cddfSDavid du Colombier 
1827dd7cddfSDavid du Colombier GLOBAL(void FAR *)
jpeg_get_large(j_common_ptr cinfo,size_t sizeofobject)1837dd7cddfSDavid du Colombier jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
1847dd7cddfSDavid du Colombier {
1857dd7cddfSDavid du Colombier   return (void FAR *) far_malloc(sizeofobject);
1867dd7cddfSDavid du Colombier }
1877dd7cddfSDavid du Colombier 
1887dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_free_large(j_common_ptr cinfo,void FAR * object,size_t sizeofobject)1897dd7cddfSDavid du Colombier jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
1907dd7cddfSDavid du Colombier {
1917dd7cddfSDavid du Colombier   far_free(object);
1927dd7cddfSDavid du Colombier }
1937dd7cddfSDavid du Colombier 
1947dd7cddfSDavid du Colombier 
1957dd7cddfSDavid du Colombier /*
1967dd7cddfSDavid du Colombier  * This routine computes the total memory space available for allocation.
1977dd7cddfSDavid du Colombier  * It's impossible to do this in a portable way; our current solution is
1987dd7cddfSDavid du Colombier  * to make the user tell us (with a default value set at compile time).
1997dd7cddfSDavid du Colombier  * If you can actually get the available space, it's a good idea to subtract
2007dd7cddfSDavid du Colombier  * a slop factor of 5% or so.
2017dd7cddfSDavid du Colombier  */
2027dd7cddfSDavid du Colombier 
2037dd7cddfSDavid du Colombier #ifndef DEFAULT_MAX_MEM		/* so can override from makefile */
2047dd7cddfSDavid du Colombier #define DEFAULT_MAX_MEM		300000L /* for total usage about 450K */
2057dd7cddfSDavid du Colombier #endif
2067dd7cddfSDavid du Colombier 
2077dd7cddfSDavid du Colombier GLOBAL(long)
jpeg_mem_available(j_common_ptr cinfo,long min_bytes_needed,long max_bytes_needed,long already_allocated)2087dd7cddfSDavid du Colombier jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
2097dd7cddfSDavid du Colombier 		    long max_bytes_needed, long already_allocated)
2107dd7cddfSDavid du Colombier {
2117dd7cddfSDavid du Colombier   return cinfo->mem->max_memory_to_use - already_allocated;
2127dd7cddfSDavid du Colombier }
2137dd7cddfSDavid du Colombier 
2147dd7cddfSDavid du Colombier 
2157dd7cddfSDavid du Colombier /*
2167dd7cddfSDavid du Colombier  * Backing store (temporary file) management.
2177dd7cddfSDavid du Colombier  * Backing store objects are only used when the value returned by
2187dd7cddfSDavid du Colombier  * jpeg_mem_available is less than the total space needed.  You can dispense
2197dd7cddfSDavid du Colombier  * with these routines if you have plenty of virtual memory; see jmemnobs.c.
2207dd7cddfSDavid du Colombier  */
2217dd7cddfSDavid du Colombier 
2227dd7cddfSDavid du Colombier /*
2237dd7cddfSDavid du Colombier  * For MS-DOS we support three types of backing storage:
2247dd7cddfSDavid du Colombier  *   1. Conventional DOS files.  We access these by direct DOS calls rather
2257dd7cddfSDavid du Colombier  *      than via the stdio package.  This provides a bit better performance,
2267dd7cddfSDavid du Colombier  *      but the real reason is that the buffers to be read or written are FAR.
2277dd7cddfSDavid du Colombier  *      The stdio library for small-data memory models can't cope with that.
2287dd7cddfSDavid du Colombier  *   2. Extended memory, accessed per the XMS V2.0 specification.
2297dd7cddfSDavid du Colombier  *   3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
2307dd7cddfSDavid du Colombier  * You'll need copies of those specs to make sense of the related code.
2317dd7cddfSDavid du Colombier  * The specs are available by Internet FTP from the SIMTEL archives
2327dd7cddfSDavid du Colombier  * (oak.oakland.edu and its various mirror sites).  See files
2337dd7cddfSDavid du Colombier  * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
2347dd7cddfSDavid du Colombier  */
2357dd7cddfSDavid du Colombier 
2367dd7cddfSDavid du Colombier 
2377dd7cddfSDavid du Colombier /*
2387dd7cddfSDavid du Colombier  * Access methods for a DOS file.
2397dd7cddfSDavid du Colombier  */
2407dd7cddfSDavid du Colombier 
2417dd7cddfSDavid du Colombier 
2427dd7cddfSDavid du Colombier METHODDEF(void)
read_file_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)2437dd7cddfSDavid du Colombier read_file_store (j_common_ptr cinfo, backing_store_ptr info,
2447dd7cddfSDavid du Colombier 		 void FAR * buffer_address,
2457dd7cddfSDavid du Colombier 		 long file_offset, long byte_count)
2467dd7cddfSDavid du Colombier {
2477dd7cddfSDavid du Colombier   if (jdos_seek(info->handle.file_handle, file_offset))
2487dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_TFILE_SEEK);
2497dd7cddfSDavid du Colombier   /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
2507dd7cddfSDavid du Colombier   if (byte_count > 65535L)	/* safety check */
2517dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
2527dd7cddfSDavid du Colombier   if (jdos_read(info->handle.file_handle, buffer_address,
2537dd7cddfSDavid du Colombier 		(unsigned short) byte_count))
2547dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_TFILE_READ);
2557dd7cddfSDavid du Colombier }
2567dd7cddfSDavid du Colombier 
2577dd7cddfSDavid du Colombier 
2587dd7cddfSDavid du Colombier METHODDEF(void)
write_file_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)2597dd7cddfSDavid du Colombier write_file_store (j_common_ptr cinfo, backing_store_ptr info,
2607dd7cddfSDavid du Colombier 		  void FAR * buffer_address,
2617dd7cddfSDavid du Colombier 		  long file_offset, long byte_count)
2627dd7cddfSDavid du Colombier {
2637dd7cddfSDavid du Colombier   if (jdos_seek(info->handle.file_handle, file_offset))
2647dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_TFILE_SEEK);
2657dd7cddfSDavid du Colombier   /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
2667dd7cddfSDavid du Colombier   if (byte_count > 65535L)	/* safety check */
2677dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
2687dd7cddfSDavid du Colombier   if (jdos_write(info->handle.file_handle, buffer_address,
2697dd7cddfSDavid du Colombier 		 (unsigned short) byte_count))
2707dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_TFILE_WRITE);
2717dd7cddfSDavid du Colombier }
2727dd7cddfSDavid du Colombier 
2737dd7cddfSDavid du Colombier 
2747dd7cddfSDavid du Colombier METHODDEF(void)
close_file_store(j_common_ptr cinfo,backing_store_ptr info)2757dd7cddfSDavid du Colombier close_file_store (j_common_ptr cinfo, backing_store_ptr info)
2767dd7cddfSDavid du Colombier {
2777dd7cddfSDavid du Colombier   jdos_close(info->handle.file_handle);	/* close the file */
2787dd7cddfSDavid du Colombier   remove(info->temp_name);	/* delete the file */
2797dd7cddfSDavid du Colombier /* If your system doesn't have remove(), try unlink() instead.
2807dd7cddfSDavid du Colombier  * remove() is the ANSI-standard name for this function, but
2817dd7cddfSDavid du Colombier  * unlink() was more common in pre-ANSI systems.
2827dd7cddfSDavid du Colombier  */
2837dd7cddfSDavid du Colombier   TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
2847dd7cddfSDavid du Colombier }
2857dd7cddfSDavid du Colombier 
2867dd7cddfSDavid du Colombier 
2877dd7cddfSDavid du Colombier LOCAL(boolean)
open_file_store(j_common_ptr cinfo,backing_store_ptr info,long total_bytes_needed)2887dd7cddfSDavid du Colombier open_file_store (j_common_ptr cinfo, backing_store_ptr info,
2897dd7cddfSDavid du Colombier 		 long total_bytes_needed)
2907dd7cddfSDavid du Colombier {
2917dd7cddfSDavid du Colombier   short handle;
2927dd7cddfSDavid du Colombier 
2937dd7cddfSDavid du Colombier   select_file_name(info->temp_name);
2947dd7cddfSDavid du Colombier   if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
2957dd7cddfSDavid du Colombier     /* might as well exit since jpeg_open_backing_store will fail anyway */
2967dd7cddfSDavid du Colombier     ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
2977dd7cddfSDavid du Colombier     return FALSE;
2987dd7cddfSDavid du Colombier   }
2997dd7cddfSDavid du Colombier   info->handle.file_handle = handle;
3007dd7cddfSDavid du Colombier   info->read_backing_store = read_file_store;
3017dd7cddfSDavid du Colombier   info->write_backing_store = write_file_store;
3027dd7cddfSDavid du Colombier   info->close_backing_store = close_file_store;
3037dd7cddfSDavid du Colombier   TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
3047dd7cddfSDavid du Colombier   return TRUE;			/* succeeded */
3057dd7cddfSDavid du Colombier }
3067dd7cddfSDavid du Colombier 
3077dd7cddfSDavid du Colombier 
3087dd7cddfSDavid du Colombier /*
3097dd7cddfSDavid du Colombier  * Access methods for extended memory.
3107dd7cddfSDavid du Colombier  */
3117dd7cddfSDavid du Colombier 
3127dd7cddfSDavid du Colombier #if XMS_SUPPORTED
3137dd7cddfSDavid du Colombier 
3147dd7cddfSDavid du Colombier static XMSDRIVER xms_driver;	/* saved address of XMS driver */
3157dd7cddfSDavid du Colombier 
3167dd7cddfSDavid du Colombier typedef union {			/* either long offset or real-mode pointer */
3177dd7cddfSDavid du Colombier 	long offset;
3187dd7cddfSDavid du Colombier 	void far * ptr;
3197dd7cddfSDavid du Colombier       } XMSPTR;
3207dd7cddfSDavid du Colombier 
3217dd7cddfSDavid du Colombier typedef struct {		/* XMS move specification structure */
3227dd7cddfSDavid du Colombier 	long length;
3237dd7cddfSDavid du Colombier 	XMSH src_handle;
3247dd7cddfSDavid du Colombier 	XMSPTR src;
3257dd7cddfSDavid du Colombier 	XMSH dst_handle;
3267dd7cddfSDavid du Colombier 	XMSPTR dst;
3277dd7cddfSDavid du Colombier       } XMSspec;
3287dd7cddfSDavid du Colombier 
3297dd7cddfSDavid du Colombier #define ODD(X)	(((X) & 1L) != 0)
3307dd7cddfSDavid du Colombier 
3317dd7cddfSDavid du Colombier 
3327dd7cddfSDavid du Colombier METHODDEF(void)
read_xms_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)3337dd7cddfSDavid du Colombier read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
3347dd7cddfSDavid du Colombier 		void FAR * buffer_address,
3357dd7cddfSDavid du Colombier 		long file_offset, long byte_count)
3367dd7cddfSDavid du Colombier {
3377dd7cddfSDavid du Colombier   XMScontext ctx;
3387dd7cddfSDavid du Colombier   XMSspec spec;
3397dd7cddfSDavid du Colombier   char endbuffer[2];
3407dd7cddfSDavid du Colombier 
3417dd7cddfSDavid du Colombier   /* The XMS driver can't cope with an odd length, so handle the last byte
3427dd7cddfSDavid du Colombier    * specially if byte_count is odd.  We don't expect this to be common.
3437dd7cddfSDavid du Colombier    */
3447dd7cddfSDavid du Colombier 
3457dd7cddfSDavid du Colombier   spec.length = byte_count & (~ 1L);
3467dd7cddfSDavid du Colombier   spec.src_handle = info->handle.xms_handle;
3477dd7cddfSDavid du Colombier   spec.src.offset = file_offset;
3487dd7cddfSDavid du Colombier   spec.dst_handle = 0;
3497dd7cddfSDavid du Colombier   spec.dst.ptr = buffer_address;
3507dd7cddfSDavid du Colombier 
3517dd7cddfSDavid du Colombier   ctx.ds_si = (void far *) & spec;
3527dd7cddfSDavid du Colombier   ctx.ax = 0x0b00;		/* EMB move */
3537dd7cddfSDavid du Colombier   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
3547dd7cddfSDavid du Colombier   if (ctx.ax != 1)
3557dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_XMS_READ);
3567dd7cddfSDavid du Colombier 
3577dd7cddfSDavid du Colombier   if (ODD(byte_count)) {
3587dd7cddfSDavid du Colombier     read_xms_store(cinfo, info, (void FAR *) endbuffer,
3597dd7cddfSDavid du Colombier 		   file_offset + byte_count - 1L, 2L);
3607dd7cddfSDavid du Colombier     ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
3617dd7cddfSDavid du Colombier   }
3627dd7cddfSDavid du Colombier }
3637dd7cddfSDavid du Colombier 
3647dd7cddfSDavid du Colombier 
3657dd7cddfSDavid du Colombier METHODDEF(void)
write_xms_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)3667dd7cddfSDavid du Colombier write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
3677dd7cddfSDavid du Colombier 		 void FAR * buffer_address,
3687dd7cddfSDavid du Colombier 		 long file_offset, long byte_count)
3697dd7cddfSDavid du Colombier {
3707dd7cddfSDavid du Colombier   XMScontext ctx;
3717dd7cddfSDavid du Colombier   XMSspec spec;
3727dd7cddfSDavid du Colombier   char endbuffer[2];
3737dd7cddfSDavid du Colombier 
3747dd7cddfSDavid du Colombier   /* The XMS driver can't cope with an odd length, so handle the last byte
3757dd7cddfSDavid du Colombier    * specially if byte_count is odd.  We don't expect this to be common.
3767dd7cddfSDavid du Colombier    */
3777dd7cddfSDavid du Colombier 
3787dd7cddfSDavid du Colombier   spec.length = byte_count & (~ 1L);
3797dd7cddfSDavid du Colombier   spec.src_handle = 0;
3807dd7cddfSDavid du Colombier   spec.src.ptr = buffer_address;
3817dd7cddfSDavid du Colombier   spec.dst_handle = info->handle.xms_handle;
3827dd7cddfSDavid du Colombier   spec.dst.offset = file_offset;
3837dd7cddfSDavid du Colombier 
3847dd7cddfSDavid du Colombier   ctx.ds_si = (void far *) & spec;
3857dd7cddfSDavid du Colombier   ctx.ax = 0x0b00;		/* EMB move */
3867dd7cddfSDavid du Colombier   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
3877dd7cddfSDavid du Colombier   if (ctx.ax != 1)
3887dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_XMS_WRITE);
3897dd7cddfSDavid du Colombier 
3907dd7cddfSDavid du Colombier   if (ODD(byte_count)) {
3917dd7cddfSDavid du Colombier     read_xms_store(cinfo, info, (void FAR *) endbuffer,
3927dd7cddfSDavid du Colombier 		   file_offset + byte_count - 1L, 2L);
3937dd7cddfSDavid du Colombier     endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
3947dd7cddfSDavid du Colombier     write_xms_store(cinfo, info, (void FAR *) endbuffer,
3957dd7cddfSDavid du Colombier 		    file_offset + byte_count - 1L, 2L);
3967dd7cddfSDavid du Colombier   }
3977dd7cddfSDavid du Colombier }
3987dd7cddfSDavid du Colombier 
3997dd7cddfSDavid du Colombier 
4007dd7cddfSDavid du Colombier METHODDEF(void)
close_xms_store(j_common_ptr cinfo,backing_store_ptr info)4017dd7cddfSDavid du Colombier close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
4027dd7cddfSDavid du Colombier {
4037dd7cddfSDavid du Colombier   XMScontext ctx;
4047dd7cddfSDavid du Colombier 
4057dd7cddfSDavid du Colombier   ctx.dx = info->handle.xms_handle;
4067dd7cddfSDavid du Colombier   ctx.ax = 0x0a00;
4077dd7cddfSDavid du Colombier   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
4087dd7cddfSDavid du Colombier   TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
4097dd7cddfSDavid du Colombier   /* we ignore any error return from the driver */
4107dd7cddfSDavid du Colombier }
4117dd7cddfSDavid du Colombier 
4127dd7cddfSDavid du Colombier 
4137dd7cddfSDavid du Colombier LOCAL(boolean)
open_xms_store(j_common_ptr cinfo,backing_store_ptr info,long total_bytes_needed)4147dd7cddfSDavid du Colombier open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
4157dd7cddfSDavid du Colombier 		long total_bytes_needed)
4167dd7cddfSDavid du Colombier {
4177dd7cddfSDavid du Colombier   XMScontext ctx;
4187dd7cddfSDavid du Colombier 
4197dd7cddfSDavid du Colombier   /* Get address of XMS driver */
4207dd7cddfSDavid du Colombier   jxms_getdriver((XMSDRIVER far *) & xms_driver);
4217dd7cddfSDavid du Colombier   if (xms_driver == NULL)
4227dd7cddfSDavid du Colombier     return FALSE;		/* no driver to be had */
4237dd7cddfSDavid du Colombier 
4247dd7cddfSDavid du Colombier   /* Get version number, must be >= 2.00 */
4257dd7cddfSDavid du Colombier   ctx.ax = 0x0000;
4267dd7cddfSDavid du Colombier   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
4277dd7cddfSDavid du Colombier   if (ctx.ax < (unsigned short) 0x0200)
4287dd7cddfSDavid du Colombier     return FALSE;
4297dd7cddfSDavid du Colombier 
4307dd7cddfSDavid du Colombier   /* Try to get space (expressed in kilobytes) */
4317dd7cddfSDavid du Colombier   ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
4327dd7cddfSDavid du Colombier   ctx.ax = 0x0900;
4337dd7cddfSDavid du Colombier   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
4347dd7cddfSDavid du Colombier   if (ctx.ax != 1)
4357dd7cddfSDavid du Colombier     return FALSE;
4367dd7cddfSDavid du Colombier 
4377dd7cddfSDavid du Colombier   /* Succeeded, save the handle and away we go */
4387dd7cddfSDavid du Colombier   info->handle.xms_handle = ctx.dx;
4397dd7cddfSDavid du Colombier   info->read_backing_store = read_xms_store;
4407dd7cddfSDavid du Colombier   info->write_backing_store = write_xms_store;
4417dd7cddfSDavid du Colombier   info->close_backing_store = close_xms_store;
4427dd7cddfSDavid du Colombier   TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
4437dd7cddfSDavid du Colombier   return TRUE;			/* succeeded */
4447dd7cddfSDavid du Colombier }
4457dd7cddfSDavid du Colombier 
4467dd7cddfSDavid du Colombier #endif /* XMS_SUPPORTED */
4477dd7cddfSDavid du Colombier 
4487dd7cddfSDavid du Colombier 
4497dd7cddfSDavid du Colombier /*
4507dd7cddfSDavid du Colombier  * Access methods for expanded memory.
4517dd7cddfSDavid du Colombier  */
4527dd7cddfSDavid du Colombier 
4537dd7cddfSDavid du Colombier #if EMS_SUPPORTED
4547dd7cddfSDavid du Colombier 
4557dd7cddfSDavid du Colombier /* The EMS move specification structure requires word and long fields aligned
4567dd7cddfSDavid du Colombier  * at odd byte boundaries.  Some compilers will align struct fields at even
4577dd7cddfSDavid du Colombier  * byte boundaries.  While it's usually possible to force byte alignment,
4587dd7cddfSDavid du Colombier  * that causes an overall performance penalty and may pose problems in merging
4597dd7cddfSDavid du Colombier  * JPEG into a larger application.  Instead we accept some rather dirty code
4607dd7cddfSDavid du Colombier  * here.  Note this code would fail if the hardware did not allow odd-byte
4617dd7cddfSDavid du Colombier  * word & long accesses, but all 80x86 CPUs do.
4627dd7cddfSDavid du Colombier  */
4637dd7cddfSDavid du Colombier 
4647dd7cddfSDavid du Colombier typedef void far * EMSPTR;
4657dd7cddfSDavid du Colombier 
4667dd7cddfSDavid du Colombier typedef union {			/* EMS move specification structure */
4677dd7cddfSDavid du Colombier 	long length;		/* It's easy to access first 4 bytes */
4687dd7cddfSDavid du Colombier 	char bytes[18];		/* Misaligned fields in here! */
4697dd7cddfSDavid du Colombier       } EMSspec;
4707dd7cddfSDavid du Colombier 
4717dd7cddfSDavid du Colombier /* Macros for accessing misaligned fields */
4727dd7cddfSDavid du Colombier #define FIELD_AT(spec,offset,type)  (*((type *) &(spec.bytes[offset])))
4737dd7cddfSDavid du Colombier #define SRC_TYPE(spec)		FIELD_AT(spec,4,char)
4747dd7cddfSDavid du Colombier #define SRC_HANDLE(spec)	FIELD_AT(spec,5,EMSH)
4757dd7cddfSDavid du Colombier #define SRC_OFFSET(spec)	FIELD_AT(spec,7,unsigned short)
4767dd7cddfSDavid du Colombier #define SRC_PAGE(spec)		FIELD_AT(spec,9,unsigned short)
4777dd7cddfSDavid du Colombier #define SRC_PTR(spec)		FIELD_AT(spec,7,EMSPTR)
4787dd7cddfSDavid du Colombier #define DST_TYPE(spec)		FIELD_AT(spec,11,char)
4797dd7cddfSDavid du Colombier #define DST_HANDLE(spec)	FIELD_AT(spec,12,EMSH)
4807dd7cddfSDavid du Colombier #define DST_OFFSET(spec)	FIELD_AT(spec,14,unsigned short)
4817dd7cddfSDavid du Colombier #define DST_PAGE(spec)		FIELD_AT(spec,16,unsigned short)
4827dd7cddfSDavid du Colombier #define DST_PTR(spec)		FIELD_AT(spec,14,EMSPTR)
4837dd7cddfSDavid du Colombier 
4847dd7cddfSDavid du Colombier #define EMSPAGESIZE	16384L	/* gospel, see the EMS specs */
4857dd7cddfSDavid du Colombier 
4867dd7cddfSDavid du Colombier #define HIBYTE(W)  (((W) >> 8) & 0xFF)
4877dd7cddfSDavid du Colombier #define LOBYTE(W)  ((W) & 0xFF)
4887dd7cddfSDavid du Colombier 
4897dd7cddfSDavid du Colombier 
4907dd7cddfSDavid du Colombier METHODDEF(void)
read_ems_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)4917dd7cddfSDavid du Colombier read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
4927dd7cddfSDavid du Colombier 		void FAR * buffer_address,
4937dd7cddfSDavid du Colombier 		long file_offset, long byte_count)
4947dd7cddfSDavid du Colombier {
4957dd7cddfSDavid du Colombier   EMScontext ctx;
4967dd7cddfSDavid du Colombier   EMSspec spec;
4977dd7cddfSDavid du Colombier 
4987dd7cddfSDavid du Colombier   spec.length = byte_count;
4997dd7cddfSDavid du Colombier   SRC_TYPE(spec) = 1;
5007dd7cddfSDavid du Colombier   SRC_HANDLE(spec) = info->handle.ems_handle;
5017dd7cddfSDavid du Colombier   SRC_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
5027dd7cddfSDavid du Colombier   SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
5037dd7cddfSDavid du Colombier   DST_TYPE(spec) = 0;
5047dd7cddfSDavid du Colombier   DST_HANDLE(spec) = 0;
5057dd7cddfSDavid du Colombier   DST_PTR(spec)    = buffer_address;
5067dd7cddfSDavid du Colombier 
5077dd7cddfSDavid du Colombier   ctx.ds_si = (void far *) & spec;
5087dd7cddfSDavid du Colombier   ctx.ax = 0x5700;		/* move memory region */
5097dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5107dd7cddfSDavid du Colombier   if (HIBYTE(ctx.ax) != 0)
5117dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_EMS_READ);
5127dd7cddfSDavid du Colombier }
5137dd7cddfSDavid du Colombier 
5147dd7cddfSDavid du Colombier 
5157dd7cddfSDavid du Colombier METHODDEF(void)
write_ems_store(j_common_ptr cinfo,backing_store_ptr info,void FAR * buffer_address,long file_offset,long byte_count)5167dd7cddfSDavid du Colombier write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
5177dd7cddfSDavid du Colombier 		 void FAR * buffer_address,
5187dd7cddfSDavid du Colombier 		 long file_offset, long byte_count)
5197dd7cddfSDavid du Colombier {
5207dd7cddfSDavid du Colombier   EMScontext ctx;
5217dd7cddfSDavid du Colombier   EMSspec spec;
5227dd7cddfSDavid du Colombier 
5237dd7cddfSDavid du Colombier   spec.length = byte_count;
5247dd7cddfSDavid du Colombier   SRC_TYPE(spec) = 0;
5257dd7cddfSDavid du Colombier   SRC_HANDLE(spec) = 0;
5267dd7cddfSDavid du Colombier   SRC_PTR(spec)    = buffer_address;
5277dd7cddfSDavid du Colombier   DST_TYPE(spec) = 1;
5287dd7cddfSDavid du Colombier   DST_HANDLE(spec) = info->handle.ems_handle;
5297dd7cddfSDavid du Colombier   DST_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
5307dd7cddfSDavid du Colombier   DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
5317dd7cddfSDavid du Colombier 
5327dd7cddfSDavid du Colombier   ctx.ds_si = (void far *) & spec;
5337dd7cddfSDavid du Colombier   ctx.ax = 0x5700;		/* move memory region */
5347dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5357dd7cddfSDavid du Colombier   if (HIBYTE(ctx.ax) != 0)
5367dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_EMS_WRITE);
5377dd7cddfSDavid du Colombier }
5387dd7cddfSDavid du Colombier 
5397dd7cddfSDavid du Colombier 
5407dd7cddfSDavid du Colombier METHODDEF(void)
close_ems_store(j_common_ptr cinfo,backing_store_ptr info)5417dd7cddfSDavid du Colombier close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
5427dd7cddfSDavid du Colombier {
5437dd7cddfSDavid du Colombier   EMScontext ctx;
5447dd7cddfSDavid du Colombier 
5457dd7cddfSDavid du Colombier   ctx.ax = 0x4500;
5467dd7cddfSDavid du Colombier   ctx.dx = info->handle.ems_handle;
5477dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5487dd7cddfSDavid du Colombier   TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
5497dd7cddfSDavid du Colombier   /* we ignore any error return from the driver */
5507dd7cddfSDavid du Colombier }
5517dd7cddfSDavid du Colombier 
5527dd7cddfSDavid du Colombier 
5537dd7cddfSDavid du Colombier LOCAL(boolean)
open_ems_store(j_common_ptr cinfo,backing_store_ptr info,long total_bytes_needed)5547dd7cddfSDavid du Colombier open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
5557dd7cddfSDavid du Colombier 		long total_bytes_needed)
5567dd7cddfSDavid du Colombier {
5577dd7cddfSDavid du Colombier   EMScontext ctx;
5587dd7cddfSDavid du Colombier 
5597dd7cddfSDavid du Colombier   /* Is EMS driver there? */
5607dd7cddfSDavid du Colombier   if (! jems_available())
5617dd7cddfSDavid du Colombier     return FALSE;
5627dd7cddfSDavid du Colombier 
5637dd7cddfSDavid du Colombier   /* Get status, make sure EMS is OK */
5647dd7cddfSDavid du Colombier   ctx.ax = 0x4000;
5657dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5667dd7cddfSDavid du Colombier   if (HIBYTE(ctx.ax) != 0)
5677dd7cddfSDavid du Colombier     return FALSE;
5687dd7cddfSDavid du Colombier 
5697dd7cddfSDavid du Colombier   /* Get version, must be >= 4.0 */
5707dd7cddfSDavid du Colombier   ctx.ax = 0x4600;
5717dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5727dd7cddfSDavid du Colombier   if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
5737dd7cddfSDavid du Colombier     return FALSE;
5747dd7cddfSDavid du Colombier 
5757dd7cddfSDavid du Colombier   /* Try to allocate requested space */
5767dd7cddfSDavid du Colombier   ctx.ax = 0x4300;
5777dd7cddfSDavid du Colombier   ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
5787dd7cddfSDavid du Colombier   jems_calldriver((EMScontext far *) & ctx);
5797dd7cddfSDavid du Colombier   if (HIBYTE(ctx.ax) != 0)
5807dd7cddfSDavid du Colombier     return FALSE;
5817dd7cddfSDavid du Colombier 
5827dd7cddfSDavid du Colombier   /* Succeeded, save the handle and away we go */
5837dd7cddfSDavid du Colombier   info->handle.ems_handle = ctx.dx;
5847dd7cddfSDavid du Colombier   info->read_backing_store = read_ems_store;
5857dd7cddfSDavid du Colombier   info->write_backing_store = write_ems_store;
5867dd7cddfSDavid du Colombier   info->close_backing_store = close_ems_store;
5877dd7cddfSDavid du Colombier   TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
5887dd7cddfSDavid du Colombier   return TRUE;			/* succeeded */
5897dd7cddfSDavid du Colombier }
5907dd7cddfSDavid du Colombier 
5917dd7cddfSDavid du Colombier #endif /* EMS_SUPPORTED */
5927dd7cddfSDavid du Colombier 
5937dd7cddfSDavid du Colombier 
5947dd7cddfSDavid du Colombier /*
5957dd7cddfSDavid du Colombier  * Initial opening of a backing-store object.
5967dd7cddfSDavid du Colombier  */
5977dd7cddfSDavid du Colombier 
5987dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_open_backing_store(j_common_ptr cinfo,backing_store_ptr info,long total_bytes_needed)5997dd7cddfSDavid du Colombier jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
6007dd7cddfSDavid du Colombier 			 long total_bytes_needed)
6017dd7cddfSDavid du Colombier {
6027dd7cddfSDavid du Colombier   /* Try extended memory, then expanded memory, then regular file. */
6037dd7cddfSDavid du Colombier #if XMS_SUPPORTED
6047dd7cddfSDavid du Colombier   if (open_xms_store(cinfo, info, total_bytes_needed))
6057dd7cddfSDavid du Colombier     return;
6067dd7cddfSDavid du Colombier #endif
6077dd7cddfSDavid du Colombier #if EMS_SUPPORTED
6087dd7cddfSDavid du Colombier   if (open_ems_store(cinfo, info, total_bytes_needed))
6097dd7cddfSDavid du Colombier     return;
6107dd7cddfSDavid du Colombier #endif
6117dd7cddfSDavid du Colombier   if (open_file_store(cinfo, info, total_bytes_needed))
6127dd7cddfSDavid du Colombier     return;
6137dd7cddfSDavid du Colombier   ERREXITS(cinfo, JERR_TFILE_CREATE, "");
6147dd7cddfSDavid du Colombier }
6157dd7cddfSDavid du Colombier 
6167dd7cddfSDavid du Colombier 
6177dd7cddfSDavid du Colombier /*
6187dd7cddfSDavid du Colombier  * These routines take care of any system-dependent initialization and
6197dd7cddfSDavid du Colombier  * cleanup required.
6207dd7cddfSDavid du Colombier  */
6217dd7cddfSDavid du Colombier 
6227dd7cddfSDavid du Colombier GLOBAL(long)
jpeg_mem_init(j_common_ptr cinfo)6237dd7cddfSDavid du Colombier jpeg_mem_init (j_common_ptr cinfo)
6247dd7cddfSDavid du Colombier {
6257dd7cddfSDavid du Colombier   next_file_num = 0;		/* initialize temp file name generator */
6267dd7cddfSDavid du Colombier   return DEFAULT_MAX_MEM;	/* default for max_memory_to_use */
6277dd7cddfSDavid du Colombier }
6287dd7cddfSDavid du Colombier 
6297dd7cddfSDavid du Colombier GLOBAL(void)
jpeg_mem_term(j_common_ptr cinfo)6307dd7cddfSDavid du Colombier jpeg_mem_term (j_common_ptr cinfo)
6317dd7cddfSDavid du Colombier {
6327dd7cddfSDavid du Colombier   /* Microsoft C, at least in v6.00A, will not successfully reclaim freed
6337dd7cddfSDavid du Colombier    * blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
6347dd7cddfSDavid du Colombier    */
6357dd7cddfSDavid du Colombier #ifdef NEED_FHEAPMIN
6367dd7cddfSDavid du Colombier   _fheapmin();
6377dd7cddfSDavid du Colombier #endif
6387dd7cddfSDavid du Colombier }
639